Index: acconfig.h
--- acconfig.h.orig	2004-06-01 10:34:19 +0200
+++ acconfig.h	2004-09-13 13:23:52 +0200
@@ -87,6 +87,13 @@
  */
 #undef DELAY_POOLS
 
+
+/* 
+ * ICAP - Internet Content Adaptation Protocol 
+ */
+#undef HS_FEAT_ICAP
+
+
 /*
  * If you want to log User-Agent request header values, define this.
  * By default, they are written to useragent.log in the Squid log
Index: configure.in
--- configure.in.orig	2004-07-09 01:44:39 +0200
+++ configure.in	2004-09-13 13:23:52 +0200
@@ -438,6 +438,17 @@
   fi
 ])
 
+dnl Enable ICAP Support
+AM_CONDITIONAL(USE_ICAP, false)
+AC_ARG_ENABLE(icap-support,
+[  --enable-icap-support   	   Enable iCAP client capability],
+[ if test "$enableval" = "yes" ; then
+    echo "ICAP support enabled"
+    AC_DEFINE(HS_FEAT_ICAP)
+    AM_CONDITIONAL(USE_ICAP, true)
+  fi
+])
+
 dnl This is a developer only option. Developers know how to set defines
 dnl
 dnl AC_ARG_ENABLE(mem-gen-trace,
@@ -1738,6 +1749,7 @@
 	srand48 \
 	srandom \
 	statfs \
+	strnstr \
 	sysconf \
 	syslog \
 	timegm \
@@ -1771,6 +1783,11 @@
   AM_CONDITIONAL(NEED_OWN_SNPRINTF, true)
 fi
 
+AM_CONDITIONAL(NEED_OWN_STRNSTR, false)
+if test "$ac_cv_func_strnstr" = "no" || test "$ac_cv_func_vstrnstr" = "no" ; then
+  AM_CONDITIONAL(NEED_OWN_STRNSTR, true)
+fi
+  
 dnl
 dnl Test for va_copy
 dnl
Index: configure
--- configure.orig	2004-07-09 01:44:39 +0200
+++ configure	2004-09-13 13:23:52 +0200
@@ -66,6 +66,8 @@
 ac_help="$ac_help
   --enable-delay-pools    Enable delay pools to limit bandwidth usage"
 ac_help="$ac_help
+  --enable-icap-support   	   Enable iCAP client capability"
+ac_help="$ac_help
   --enable-useragent-log  Enable logging of User-Agent header"
 ac_help="$ac_help
   --enable-referer-log    Enable logging of Referer header"
@@ -239,7 +241,6 @@
 program_transform_name=s,x,x,
 silent=
 site=
-sitefile=
 srcdir=
 target=NONE
 verbose=
@@ -354,7 +355,6 @@
   --help                  print this message
   --no-create             do not create output files
   --quiet, --silent       do not print \`checking...' messages
-  --site-file=FILE        use FILE as the site file
   --version               print the version of autoconf that created configure
 Directory and file names:
   --prefix=PREFIX         install architecture-independent files in PREFIX
@@ -525,11 +525,6 @@
   -site=* | --site=* | --sit=*)
     site="$ac_optarg" ;;
 
-  -site-file | --site-file | --site-fil | --site-fi | --site-f)
-    ac_prev=sitefile ;;
-  -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
-    sitefile="$ac_optarg" ;;
-
   -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
     ac_prev=srcdir ;;
   -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
@@ -695,16 +690,12 @@
 srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
 
 # Prefer explicitly selected file to automatically selected ones.
-if test -z "$sitefile"; then
-  if test -z "$CONFIG_SITE"; then
-    if test "x$prefix" != xNONE; then
-      CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-    else
-      CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-    fi
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
   fi
-else
-  CONFIG_SITE="$sitefile"
 fi
 for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
@@ -753,6 +744,10 @@
     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
@@ -778,7 +773,7 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:782: checking for a BSD compatible install" >&5
+echo "configure:777: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -831,7 +826,7 @@
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:835: checking whether build environment is sane" >&5
+echo "configure:830: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftest.file
@@ -902,7 +897,7 @@
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:906: checking for $ac_word" >&5
+echo "configure:901: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -932,7 +927,7 @@
 done
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:936: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:931: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1053,7 +1048,7 @@
 
 # From configure.in Revision: 1.251.2.59 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:1057: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:1052: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
@@ -1085,7 +1080,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1089: checking for $ac_word" >&5
+echo "configure:1084: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1115,7 +1110,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1119: checking for $ac_word" >&5
+echo "configure:1114: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1166,7 +1161,7 @@
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1170: checking for $ac_word" >&5
+echo "configure:1165: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1198,7 +1193,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1202: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1197: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -1209,12 +1204,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 1213 "configure"
+#line 1208 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:1218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -1240,12 +1235,12 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1244: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1239: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1249: checking whether we are using GNU C" >&5
+echo "configure:1244: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1254,7 +1249,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1258: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1253: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1273,7 +1268,7 @@
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1277: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1272: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1312,7 +1307,7 @@
 END
 # If we don't find an include directive, just comment out the code.
 echo $ac_n "checking for style of include used by $am_make""... $ac_c" 1>&6
-echo "configure:1316: checking for style of include used by $am_make" >&5
+echo "configure:1311: checking for style of include used by $am_make" >&5
 am__include='#'
 am__quote=
 _am_result=none
@@ -1346,7 +1341,7 @@
 depcc="$CC"   am_compiler_list=
 
 echo $ac_n "checking dependency style of $depcc""... $ac_c" 1>&6
-echo "configure:1350: checking dependency style of $depcc" >&5
+echo "configure:1345: checking dependency style of $depcc" >&5
 if eval "test \"`echo '$''{'am_cv_CC_dependencies_compiler_type'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1414,10 +1409,10 @@
 
 if test "x$CC" != xcc; then
   echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
-echo "configure:1418: checking whether $CC and cc understand -c and -o together" >&5
+echo "configure:1413: checking whether $CC and cc understand -c and -o together" >&5
 else
   echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
-echo "configure:1421: checking whether cc understands -c and -o together" >&5
+echo "configure:1416: checking whether cc understands -c and -o together" >&5
 fi
 set dummy $CC; ac_cc="`echo $2 |
 		       sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
@@ -1429,16 +1424,16 @@
 # We do the test twice because some compilers refuse to overwrite an
 # existing .o file with -o, though they will create one.
 ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
-if { (eval echo configure:1433: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
-   test -f conftest.o && { (eval echo configure:1434: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+if { (eval echo configure:1428: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+   test -f conftest.o && { (eval echo configure:1429: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
 then
   eval ac_cv_prog_cc_${ac_cc}_c_o=yes
   if test "x$CC" != xcc; then
     # Test first that cc exists at all.
-    if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1439: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1434: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
       ac_try='cc -c conftest.c -o conftest.o 1>&5'
-      if { (eval echo configure:1441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
-	 test -f conftest.o && { (eval echo configure:1442: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+      if { (eval echo configure:1436: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
+	 test -f conftest.o && { (eval echo configure:1437: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
       then
         # cc works too.
         :
@@ -1484,7 +1479,7 @@
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:1488: checking host system type" >&5
+echo "configure:1483: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -1513,7 +1508,7 @@
 # Extract the first word of "pkg-config", so it can be a program name with args.
 set dummy pkg-config; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1517: checking for $ac_word" >&5
+echo "configure:1512: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PKGCONFIG'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1548,12 +1543,12 @@
 
 
 echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:1552: checking for Cygwin environment" >&5
+echo "configure:1547: checking for Cygwin environment" >&5
 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1557 "configure"
+#line 1552 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1564,7 +1559,7 @@
 return __CYGWIN__;
 ; return 0; }
 EOF
-if { (eval echo configure:1568: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1563: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_cygwin=yes
 else
@@ -1581,19 +1576,19 @@
 CYGWIN=
 test "$ac_cv_cygwin" = yes && CYGWIN=yes
 echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:1585: checking for mingw32 environment" >&5
+echo "configure:1580: checking for mingw32 environment" >&5
 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1590 "configure"
+#line 1585 "configure"
 #include "confdefs.h"
 
 int main() {
 return __MINGW32__;
 ; return 0; }
 EOF
-if { (eval echo configure:1597: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1592: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_mingw32=yes
 else
@@ -1612,7 +1607,7 @@
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1616: checking for executable suffix" >&5
+echo "configure:1611: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1622,10 +1617,10 @@
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:1626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:1621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
-      *.c | *.C | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -1643,13 +1638,13 @@
 ac_exeext=$EXEEXT
 
 echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:1647: checking for object suffix" >&5
+echo "configure:1642: checking for object suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   rm -f conftest*
 echo 'int i = 1;' > conftest.$ac_ext
-if { (eval echo configure:1653: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1648: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   for ac_file in conftest.*; do
     case $ac_file in
     *.c) ;;
@@ -2140,6 +2135,38 @@
 
 
 
+
+if false; then
+  USE_ICAP_TRUE=
+  USE_ICAP_FALSE='#'
+else
+  USE_ICAP_TRUE='#'
+  USE_ICAP_FALSE=
+fi
+# Check whether --enable-icap-support or --disable-icap-support was given.
+if test "${enable_icap_support+set}" = set; then
+  enableval="$enable_icap_support"
+   if test "$enableval" = "yes" ; then
+    echo "ICAP support enabled"
+    cat >> confdefs.h <<\EOF
+#define HS_FEAT_ICAP 1
+EOF
+
+    
+
+if true; then
+  USE_ICAP_TRUE=
+  USE_ICAP_FALSE='#'
+else
+  USE_ICAP_TRUE='#'
+  USE_ICAP_FALSE=
+fi
+  fi
+
+fi
+
+
+
 # Check whether --enable-useragent-log or --disable-useragent-log was given.
 if test "${enable_useragent_log+set}" = set; then
   enableval="$enable_useragent_log"
@@ -2938,7 +2965,7 @@
 
 if test "$require_sasl" = "yes"; then
 	echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:2942: checking how to run the C preprocessor" >&5
+echo "configure:2969: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -2953,13 +2980,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 2957 "configure"
+#line 2984 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2963: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2990: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -2970,13 +2997,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 2974 "configure"
+#line 3001 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2980: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3007: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -2987,13 +3014,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 2991 "configure"
+#line 3018 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2997: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -3021,17 +3048,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3025: checking for $ac_hdr" >&5
+echo "configure:3052: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3030 "configure"
+#line 3057 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3035: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3062: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3165,7 +3192,7 @@
 esac
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:3169: checking how to run the C preprocessor" >&5
+echo "configure:3196: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -3180,13 +3207,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 3184 "configure"
+#line 3211 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3190: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -3197,13 +3224,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 3201 "configure"
+#line 3228 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3207: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3234: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -3214,13 +3241,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 3218 "configure"
+#line 3245 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3224: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3251: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -3256,7 +3283,7 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:3260: checking for a BSD compatible install" >&5
+echo "configure:3287: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3311,7 +3338,7 @@
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3315: checking for $ac_word" >&5
+echo "configure:3342: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3339,7 +3366,7 @@
 fi
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:3343: checking whether ln -s works" >&5
+echo "configure:3370: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3362,7 +3389,7 @@
 # Extract the first word of "sh", so it can be a program name with args.
 set dummy sh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3366: checking for $ac_word" >&5
+echo "configure:3393: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_SH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3398,7 +3425,7 @@
 # Extract the first word of "false", so it can be a program name with args.
 set dummy false; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3402: checking for $ac_word" >&5
+echo "configure:3429: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_FALSE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3434,7 +3461,7 @@
 # Extract the first word of "true", so it can be a program name with args.
 set dummy true; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3438: checking for $ac_word" >&5
+echo "configure:3465: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_TRUE'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3470,7 +3497,7 @@
 # Extract the first word of "rm", so it can be a program name with args.
 set dummy rm; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3474: checking for $ac_word" >&5
+echo "configure:3501: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_RM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3506,7 +3533,7 @@
 # Extract the first word of "mv", so it can be a program name with args.
 set dummy mv; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3510: checking for $ac_word" >&5
+echo "configure:3537: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MV'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3542,7 +3569,7 @@
 # Extract the first word of "mkdir", so it can be a program name with args.
 set dummy mkdir; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3546: checking for $ac_word" >&5
+echo "configure:3573: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_MKDIR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3578,7 +3605,7 @@
 # Extract the first word of "ln", so it can be a program name with args.
 set dummy ln; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3582: checking for $ac_word" >&5
+echo "configure:3609: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_LN'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3614,7 +3641,7 @@
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3618: checking for $ac_word" >&5
+echo "configure:3645: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3650,7 +3677,7 @@
 # Extract the first word of "ar", so it can be a program name with args.
 set dummy ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3654: checking for $ac_word" >&5
+echo "configure:3681: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -3710,12 +3737,12 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:3714: checking for $ac_hdr that defines DIR" >&5
+echo "configure:3741: checking for $ac_hdr that defines DIR" >&5
 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3719 "configure"
+#line 3746 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -3723,7 +3750,7 @@
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:3727: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3754: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -3748,7 +3775,7 @@
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:3752: checking for opendir in -ldir" >&5
+echo "configure:3779: checking for opendir in -ldir" >&5
 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3756,7 +3783,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3760 "configure"
+#line 3787 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3767,7 +3794,7 @@
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:3771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3789,7 +3816,7 @@
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:3793: checking for opendir in -lx" >&5
+echo "configure:3820: checking for opendir in -lx" >&5
 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3797,7 +3824,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3801 "configure"
+#line 3828 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3808,7 +3835,7 @@
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:3812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3839: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3831,12 +3858,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:3835: checking for ANSI C header files" >&5
+echo "configure:3862: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3840 "configure"
+#line 3867 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -3844,7 +3871,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3875: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3861,7 +3888,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 3865 "configure"
+#line 3892 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -3879,7 +3906,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 3883 "configure"
+#line 3910 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -3900,7 +3927,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 3904 "configure"
+#line 3931 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -3911,7 +3938,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:3915: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3942: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -4018,17 +4045,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4022: checking for $ac_hdr" >&5
+echo "configure:4049: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4027 "configure"
+#line 4054 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4032: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4059: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -4056,12 +4083,12 @@
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:4060: checking for working const" >&5
+echo "configure:4087: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 4065 "configure"
+#line 4092 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -4110,7 +4137,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:4114: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4141: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -4131,14 +4158,14 @@
 fi
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:4135: checking whether byte ordering is bigendian" >&5
+echo "configure:4162: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 4142 "configure"
+#line 4169 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4149,11 +4176,11 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:4153: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4180: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 4157 "configure"
+#line 4184 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -4164,7 +4191,7 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:4168: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4195: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -4184,7 +4211,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4188 "configure"
+#line 4215 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -4197,7 +4224,7 @@
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:4201: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4228: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -4222,20 +4249,20 @@
 
 
 echo $ac_n "checking if ANSI prototypes work""... $ac_c" 1>&6
-echo "configure:4226: checking if ANSI prototypes work" >&5
+echo "configure:4253: checking if ANSI prototypes work" >&5
 if eval "test \"`echo '$''{'ac_cv_have_ansi_prototypes'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 4232 "configure"
+#line 4259 "configure"
 #include "confdefs.h"
 int foo(char *); int foo (char *bar) {return 1;}
 int main() {
 foo("bar")
 ; return 0; }
 EOF
-if { (eval echo configure:4239: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4266: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_ansi_prototypes="yes"
 else
@@ -4257,13 +4284,13 @@
 fi
 
 echo $ac_n "checking for tm->tm_gmtoff""... $ac_c" 1>&6
-echo "configure:4261: checking for tm->tm_gmtoff" >&5
+echo "configure:4288: checking for tm->tm_gmtoff" >&5
 if eval "test \"`echo '$''{'ac_cv_have_tm_gmoff'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 4267 "configure"
+#line 4294 "configure"
 #include "confdefs.h"
 #include <time.h>
 #include <sys/time.h>
@@ -4272,7 +4299,7 @@
       foo.tm_gmtoff = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:4276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4303: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_tm_gmoff="yes"
 else
@@ -4294,13 +4321,13 @@
 fi
 
 echo $ac_n "checking for struct mallinfo""... $ac_c" 1>&6
-echo "configure:4298: checking for struct mallinfo" >&5
+echo "configure:4325: checking for struct mallinfo" >&5
 if eval "test \"`echo '$''{'ac_cv_have_struct_mallinfo'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 4304 "configure"
+#line 4331 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if HAVE_MALLOC_H
@@ -4318,7 +4345,7 @@
     foo.keepcost = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:4322: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4349: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_struct_mallinfo="yes"
 else
@@ -4340,13 +4367,13 @@
 fi
 
 echo $ac_n "checking for extended mallinfo""... $ac_c" 1>&6
-echo "configure:4344: checking for extended mallinfo" >&5
+echo "configure:4371: checking for extended mallinfo" >&5
 if eval "test \"`echo '$''{'ac_cv_have_ext_mallinfo'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 4350 "configure"
+#line 4377 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <malloc.h>
@@ -4355,7 +4382,7 @@
       foo.mxfast = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:4359: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4386: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_ext_mallinfo="yes"
 else
@@ -4377,13 +4404,13 @@
 fi
 
 echo $ac_n "checking for struct rusage""... $ac_c" 1>&6
-echo "configure:4381: checking for struct rusage" >&5
+echo "configure:4408: checking for struct rusage" >&5
 if eval "test \"`echo '$''{'ac_cv_have_struct_rusage'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 4387 "configure"
+#line 4414 "configure"
 #include "confdefs.h"
 
 #if HAVE_SYS_TIME_H
@@ -4396,7 +4423,7 @@
 struct rusage R;
 ; return 0; }
 EOF
-if { (eval echo configure:4400: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4427: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_struct_rusage="yes"
 else
@@ -4418,13 +4445,13 @@
 fi
 
 echo $ac_n "checking for ip->ip_hl""... $ac_c" 1>&6
-echo "configure:4422: checking for ip->ip_hl" >&5
+echo "configure:4449: checking for ip->ip_hl" >&5
 if eval "test \"`echo '$''{'ac_cv_have_ip_hl'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 4428 "configure"
+#line 4455 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <netinet/in.h>
@@ -4443,7 +4470,7 @@
       ip.ip_hl= 0;
 ; return 0; }
 EOF
-if { (eval echo configure:4447: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4474: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_ip_hl="yes"
 else
@@ -4465,7 +4492,7 @@
 fi
 
 echo $ac_n "checking size of void *""... $ac_c" 1>&6
-echo "configure:4469: checking size of void *" >&5
+echo "configure:4496: checking size of void *" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4473,7 +4500,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4477 "configure"
+#line 4504 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -4484,7 +4511,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4515: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_void_p=`cat conftestval`
 else
@@ -4504,7 +4531,7 @@
 
 
 echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:4508: checking size of short" >&5
+echo "configure:4535: checking size of short" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4512,7 +4539,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4516 "configure"
+#line 4543 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -4523,7 +4550,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4527: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_short=`cat conftestval`
 else
@@ -4543,7 +4570,7 @@
 
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:4547: checking size of int" >&5
+echo "configure:4574: checking size of int" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4551,7 +4578,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4555 "configure"
+#line 4582 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -4562,7 +4589,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4566: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int=`cat conftestval`
 else
@@ -4582,7 +4609,7 @@
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:4586: checking size of long" >&5
+echo "configure:4613: checking size of long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4590,7 +4617,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4594 "configure"
+#line 4621 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -4601,7 +4628,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4605: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4632: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long=`cat conftestval`
 else
@@ -4621,7 +4648,7 @@
 
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:4625: checking size of long long" >&5
+echo "configure:4652: checking size of long long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4629,7 +4656,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4633 "configure"
+#line 4660 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -4640,7 +4667,7 @@
   exit(0);
 }
 EOF
-if { (eval echo configure:4644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long_long=`cat conftestval`
 else
@@ -4660,7 +4687,7 @@
 
 
 echo $ac_n "checking size of __int64""... $ac_c" 1>&6
-echo "configure:4664: checking size of __int64" >&5
+echo "configure:4691: checking size of __int64" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof___int64'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4668,7 +4695,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4672 "configure"
+#line 4699 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4694,7 +4721,7 @@
 }
 
 EOF
-if { (eval echo configure:4698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4725: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof___int64=`cat conftestval`
 else
@@ -4714,7 +4741,7 @@
 
 
 echo $ac_n "checking size of int16_t""... $ac_c" 1>&6
-echo "configure:4718: checking size of int16_t" >&5
+echo "configure:4745: checking size of int16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4722,7 +4749,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4726 "configure"
+#line 4753 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4748,7 +4775,7 @@
 }
 
 EOF
-if { (eval echo configure:4752: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int16_t=`cat conftestval`
 else
@@ -4768,7 +4795,7 @@
 
 
 echo $ac_n "checking size of uint16_t""... $ac_c" 1>&6
-echo "configure:4772: checking size of uint16_t" >&5
+echo "configure:4799: checking size of uint16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_uint16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4776,7 +4803,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4780 "configure"
+#line 4807 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4802,7 +4829,7 @@
 }
 
 EOF
-if { (eval echo configure:4806: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_uint16_t=`cat conftestval`
 else
@@ -4822,7 +4849,7 @@
 
 
 echo $ac_n "checking size of u_int16_t""... $ac_c" 1>&6
-echo "configure:4826: checking size of u_int16_t" >&5
+echo "configure:4853: checking size of u_int16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_u_int16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4830,7 +4857,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4834 "configure"
+#line 4861 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4856,7 +4883,7 @@
 }
 
 EOF
-if { (eval echo configure:4860: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_u_int16_t=`cat conftestval`
 else
@@ -4876,7 +4903,7 @@
 
 
 echo $ac_n "checking size of int32_t""... $ac_c" 1>&6
-echo "configure:4880: checking size of int32_t" >&5
+echo "configure:4907: checking size of int32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4884,7 +4911,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4888 "configure"
+#line 4915 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4910,7 +4937,7 @@
 }
 
 EOF
-if { (eval echo configure:4914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int32_t=`cat conftestval`
 else
@@ -4930,7 +4957,7 @@
 
 
 echo $ac_n "checking size of uint32_t""... $ac_c" 1>&6
-echo "configure:4934: checking size of uint32_t" >&5
+echo "configure:4961: checking size of uint32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_uint32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4938,7 +4965,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4942 "configure"
+#line 4969 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -4964,7 +4991,7 @@
 }
 
 EOF
-if { (eval echo configure:4968: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_uint32_t=`cat conftestval`
 else
@@ -4984,7 +5011,7 @@
 
 
 echo $ac_n "checking size of u_int32_t""... $ac_c" 1>&6
-echo "configure:4988: checking size of u_int32_t" >&5
+echo "configure:5015: checking size of u_int32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_u_int32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -4992,7 +5019,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 4996 "configure"
+#line 5023 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -5018,7 +5045,7 @@
 }
 
 EOF
-if { (eval echo configure:5022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5049: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_u_int32_t=`cat conftestval`
 else
@@ -5038,7 +5065,7 @@
 
 
 echo $ac_n "checking size of int64_t""... $ac_c" 1>&6
-echo "configure:5042: checking size of int64_t" >&5
+echo "configure:5069: checking size of int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5046,7 +5073,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 5050 "configure"
+#line 5077 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -5072,7 +5099,7 @@
 }
 
 EOF
-if { (eval echo configure:5076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5103: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_int64_t=`cat conftestval`
 else
@@ -5092,7 +5119,7 @@
 
 
 echo $ac_n "checking size of uint64_t""... $ac_c" 1>&6
-echo "configure:5096: checking size of uint64_t" >&5
+echo "configure:5123: checking size of uint64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_uint64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5100,7 +5127,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 5104 "configure"
+#line 5131 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -5126,7 +5153,7 @@
 }
 
 EOF
-if { (eval echo configure:5130: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_uint64_t=`cat conftestval`
 else
@@ -5146,7 +5173,7 @@
 
 
 echo $ac_n "checking size of u_int64_t""... $ac_c" 1>&6
-echo "configure:5150: checking size of u_int64_t" >&5
+echo "configure:5177: checking size of u_int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_u_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -5154,7 +5181,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 5158 "configure"
+#line 5185 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -5180,7 +5207,7 @@
 }
 
 EOF
-if { (eval echo configure:5184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:5211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_u_int64_t=`cat conftestval`
 else
@@ -5202,12 +5229,12 @@
 
 if test "x$ac_cv_sizeof_short" = "x2"; then
 	echo $ac_n "checking for int16_t""... $ac_c" 1>&6
-echo "configure:5206: checking for int16_t" >&5
+echo "configure:5233: checking for int16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5211 "configure"
+#line 5238 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5251,12 +5278,12 @@
 
 elif test "x$ac_cv_sizeof_int" = "x2"; then
 	echo $ac_n "checking for int16_t""... $ac_c" 1>&6
-echo "configure:5255: checking for int16_t" >&5
+echo "configure:5282: checking for int16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5260 "configure"
+#line 5287 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5301,12 +5328,12 @@
 fi
 if test "x$ac_cv_sizeof_uint16_t" = "x2"; then
 	echo $ac_n "checking for u_int16_t""... $ac_c" 1>&6
-echo "configure:5305: checking for u_int16_t" >&5
+echo "configure:5332: checking for u_int16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5310 "configure"
+#line 5337 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5350,12 +5377,12 @@
 
 elif test "x$ac_cv_sizeof_short" = "x2"; then
 	echo $ac_n "checking for u_int16_t""... $ac_c" 1>&6
-echo "configure:5354: checking for u_int16_t" >&5
+echo "configure:5381: checking for u_int16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5359 "configure"
+#line 5386 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5399,12 +5426,12 @@
 
 elif test "x$ac_cv_sizeof_int" = "x2"; then
 	echo $ac_n "checking for u_int16_t""... $ac_c" 1>&6
-echo "configure:5403: checking for u_int16_t" >&5
+echo "configure:5430: checking for u_int16_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int16_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5408 "configure"
+#line 5435 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5449,12 +5476,12 @@
 fi
 if test "x$ac_cv_sizeof_int" = "x4"; then
 	echo $ac_n "checking for int32_t""... $ac_c" 1>&6
-echo "configure:5453: checking for int32_t" >&5
+echo "configure:5480: checking for int32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5458 "configure"
+#line 5485 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5498,12 +5525,12 @@
 
 elif "x$ac_cv_sizeof_long" = "x4"; then
 	echo $ac_n "checking for int32_t""... $ac_c" 1>&6
-echo "configure:5502: checking for int32_t" >&5
+echo "configure:5529: checking for int32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5507 "configure"
+#line 5534 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5548,12 +5575,12 @@
 fi
 if test "x$ac_cv_sizeof_uint32_t" = "x4"; then
 	echo $ac_n "checking for u_int32_t""... $ac_c" 1>&6
-echo "configure:5552: checking for u_int32_t" >&5
+echo "configure:5579: checking for u_int32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5557 "configure"
+#line 5584 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5597,12 +5624,12 @@
 
 elif test "x$ac_cv_sizeof_int" = "x4"; then
 	echo $ac_n "checking for u_int32_t""... $ac_c" 1>&6
-echo "configure:5601: checking for u_int32_t" >&5
+echo "configure:5628: checking for u_int32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5606 "configure"
+#line 5633 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5646,12 +5673,12 @@
 
 elif test "x$ac_cv_sizeof_long" = "x4"; then
 	echo $ac_n "checking for u_int32_t""... $ac_c" 1>&6
-echo "configure:5650: checking for u_int32_t" >&5
+echo "configure:5677: checking for u_int32_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int32_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5655 "configure"
+#line 5682 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5696,12 +5723,12 @@
 fi
 if test "x$ac_cv_sizeof_long" = "x8"; then
 	echo $ac_n "checking for int64_t""... $ac_c" 1>&6
-echo "configure:5700: checking for int64_t" >&5
+echo "configure:5727: checking for int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5705 "configure"
+#line 5732 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5745,12 +5772,12 @@
 
 elif test "x$ac_cv_sizeof_long_long" = "x8"; then
 	echo $ac_n "checking for int64_t""... $ac_c" 1>&6
-echo "configure:5749: checking for int64_t" >&5
+echo "configure:5776: checking for int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5754 "configure"
+#line 5781 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5794,12 +5821,12 @@
 
 elif test "x$ac_cv_sizeof___int64" = "x8"; then
 	echo $ac_n "checking for int64_t""... $ac_c" 1>&6
-echo "configure:5798: checking for int64_t" >&5
+echo "configure:5825: checking for int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5803 "configure"
+#line 5830 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5844,12 +5871,12 @@
 fi
 if test "x$ac_cv_sizeof_uint64_t" = "x8"; then
 	echo $ac_n "checking for u_int64_t""... $ac_c" 1>&6
-echo "configure:5848: checking for u_int64_t" >&5
+echo "configure:5875: checking for u_int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5853 "configure"
+#line 5880 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5893,12 +5920,12 @@
 
 elif test "x$ac_cv_sizeof_long" = "x8"; then
 	echo $ac_n "checking for u_int64_t""... $ac_c" 1>&6
-echo "configure:5897: checking for u_int64_t" >&5
+echo "configure:5924: checking for u_int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5902 "configure"
+#line 5929 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5942,12 +5969,12 @@
 
 elif test "x$ac_cv_sizeof_long_long" = "x8"; then
 	echo $ac_n "checking for u_int64_t""... $ac_c" 1>&6
-echo "configure:5946: checking for u_int64_t" >&5
+echo "configure:5973: checking for u_int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_u_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 5951 "configure"
+#line 5978 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -5991,12 +6018,12 @@
 
 elif test "x$ac_cv_sizeof___int64" = "x8"; then
 	echo $ac_n "checking for int64_t""... $ac_c" 1>&6
-echo "configure:5995: checking for int64_t" >&5
+echo "configure:6022: checking for int64_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_int64_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6000 "configure"
+#line 6027 "configure"
 #include "confdefs.h"
 
 /* What a mess.. many systems have added the (now standard) bit types
@@ -6041,12 +6068,12 @@
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:6045: checking for pid_t" >&5
+echo "configure:6072: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6050 "configure"
+#line 6077 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6074,12 +6101,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:6078: checking for size_t" >&5
+echo "configure:6105: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6083 "configure"
+#line 6110 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6107,12 +6134,12 @@
 fi
 
 echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:6111: checking for ssize_t" >&5
+echo "configure:6138: checking for ssize_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6116 "configure"
+#line 6143 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6140,12 +6167,12 @@
 fi
 
 echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:6144: checking for off_t" >&5
+echo "configure:6171: checking for off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6149 "configure"
+#line 6176 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6173,12 +6200,12 @@
 fi
 
 echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:6177: checking for mode_t" >&5
+echo "configure:6204: checking for mode_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6182 "configure"
+#line 6209 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6206,12 +6233,12 @@
 fi
 
 echo $ac_n "checking for fd_mask""... $ac_c" 1>&6
-echo "configure:6210: checking for fd_mask" >&5
+echo "configure:6237: checking for fd_mask" >&5
 if eval "test \"`echo '$''{'ac_cv_type_fd_mask'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6215 "configure"
+#line 6242 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -6240,7 +6267,7 @@
 
 
 echo $ac_n "checking size of off_t""... $ac_c" 1>&6
-echo "configure:6244: checking size of off_t" >&5
+echo "configure:6271: checking size of off_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_off_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6248,7 +6275,7 @@
   ac_cv_sizeof_off_t=4
 else
   cat > conftest.$ac_ext <<EOF
-#line 6252 "configure"
+#line 6279 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -6274,7 +6301,7 @@
 }
 
 EOF
-if { (eval echo configure:6278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6305: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_off_t=`cat conftestval`
 else
@@ -6294,7 +6321,7 @@
 
 
 echo $ac_n "checking size of size_t""... $ac_c" 1>&6
-echo "configure:6298: checking size of size_t" >&5
+echo "configure:6325: checking size of size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6302,7 +6329,7 @@
   ac_cv_sizeof_size_t=4
 else
   cat > conftest.$ac_ext <<EOF
-#line 6306 "configure"
+#line 6333 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -6328,7 +6355,7 @@
 }
 
 EOF
-if { (eval echo configure:6332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_size_t=`cat conftestval`
 else
@@ -6351,19 +6378,19 @@
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:6355: checking for working alloca.h" >&5
+echo "configure:6382: checking for working alloca.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6360 "configure"
+#line 6387 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:6367: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6394: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -6384,12 +6411,12 @@
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:6388: checking for alloca" >&5
+echo "configure:6415: checking for alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6393 "configure"
+#line 6420 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -6417,7 +6444,7 @@
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:6421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6448: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -6449,12 +6476,12 @@
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:6453: checking whether alloca needs Cray hooks" >&5
+echo "configure:6480: checking whether alloca needs Cray hooks" >&5
 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6458 "configure"
+#line 6485 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -6479,12 +6506,12 @@
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6483: checking for $ac_func" >&5
+echo "configure:6510: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 6488 "configure"
+#line 6515 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -6507,7 +6534,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:6511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6538: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -6534,7 +6561,7 @@
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:6538: checking stack direction for C alloca" >&5
+echo "configure:6565: checking stack direction for C alloca" >&5
 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -6542,7 +6569,7 @@
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 6546 "configure"
+#line 6573 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -6561,7 +6588,7 @@
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:6565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:6592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_stack_direction=1
 else
@@ -6585,13 +6612,13 @@
 
 
 echo $ac_n "checking for socklen_t""... $ac_c" 1>&6
-echo "configure:6589: checking for socklen_t" >&5
+echo "configure:6616: checking for socklen_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 6595 "configure"
+#line 6622 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -6622,13 +6649,13 @@
 fi
 
 echo $ac_n "checking for mtyp_t""... $ac_c" 1>&6
-echo "configure:6626: checking for mtyp_t" >&5
+echo "configure:6653: checking for mtyp_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_mtyp_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
   cat > conftest.$ac_ext <<EOF
-#line 6632 "configure"
+#line 6659 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/ipc.h>
@@ -6656,7 +6683,7 @@
  fi
 
 echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
-echo "configure:6660: checking for main in -lnsl" >&5
+echo "configure:6687: checking for main in -lnsl" >&5
 ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6664,14 +6691,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6668 "configure"
+#line 6695 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:6675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6699,7 +6726,7 @@
 fi
 
 echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6
-echo "configure:6703: checking for main in -lsocket" >&5
+echo "configure:6730: checking for main in -lsocket" >&5
 ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6707,14 +6734,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6711 "configure"
+#line 6738 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:6718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6743,13 +6770,13 @@
 
 
 echo $ac_n "checking for unix domain sockets""... $ac_c" 1>&6
-echo "configure:6747: checking for unix domain sockets" >&5
+echo "configure:6774: checking for unix domain sockets" >&5
 if eval "test \"`echo '$''{'squid_cv_unixsocket'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   
     cat > conftest.$ac_ext <<EOF
-#line 6753 "configure"
+#line 6780 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -6764,7 +6791,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:6768: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6795: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   squid_cv_unixsocket=yes
 else
@@ -6788,7 +6815,7 @@
   echo "skipping libmalloc check (--enable-dlmalloc specified)"
 else
   echo $ac_n "checking for main in -lgnumalloc""... $ac_c" 1>&6
-echo "configure:6792: checking for main in -lgnumalloc" >&5
+echo "configure:6819: checking for main in -lgnumalloc" >&5
 ac_lib_var=`echo gnumalloc'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6796,14 +6823,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lgnumalloc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6800 "configure"
+#line 6827 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:6807: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6846,7 +6873,7 @@
 			*)
   
 				echo $ac_n "checking for main in -lmalloc""... $ac_c" 1>&6
-echo "configure:6850: checking for main in -lmalloc" >&5
+echo "configure:6877: checking for main in -lmalloc" >&5
 ac_lib_var=`echo malloc'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6854,14 +6881,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lmalloc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6858 "configure"
+#line 6885 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:6865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6894,7 +6921,7 @@
 fi
 
 echo $ac_n "checking for main in -lbsd""... $ac_c" 1>&6
-echo "configure:6898: checking for main in -lbsd" >&5
+echo "configure:6925: checking for main in -lbsd" >&5
 ac_lib_var=`echo bsd'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6902,14 +6929,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lbsd  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6906 "configure"
+#line 6933 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:6913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6937,7 +6964,7 @@
 fi
 
 echo $ac_n "checking for main in -lregex""... $ac_c" 1>&6
-echo "configure:6941: checking for main in -lregex" >&5
+echo "configure:6968: checking for main in -lregex" >&5
 ac_lib_var=`echo regex'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6945,14 +6972,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lregex  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6949 "configure"
+#line 6976 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:6956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -6973,7 +7000,7 @@
 fi
 
 echo $ac_n "checking for gethostbyname in -lbind""... $ac_c" 1>&6
-echo "configure:6977: checking for gethostbyname in -lbind" >&5
+echo "configure:7004: checking for gethostbyname in -lbind" >&5
 ac_lib_var=`echo bind'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -6981,7 +7008,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lbind  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 6985 "configure"
+#line 7012 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -6992,7 +7019,7 @@
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:6996: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7026,7 +7053,7 @@
 		;;
 	*)
 		echo $ac_n "checking for inet_aton in -lresolv""... $ac_c" 1>&6
-echo "configure:7030: checking for inet_aton in -lresolv" >&5
+echo "configure:7057: checking for inet_aton in -lresolv" >&5
 ac_lib_var=`echo resolv'_'inet_aton | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7034,7 +7061,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7038 "configure"
+#line 7065 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7045,7 +7072,7 @@
 inet_aton()
 ; return 0; }
 EOF
-if { (eval echo configure:7049: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7061,7 +7088,7 @@
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   echo $ac_n "checking for inet_aton in -l44bsd""... $ac_c" 1>&6
-echo "configure:7065: checking for inet_aton in -l44bsd" >&5
+echo "configure:7092: checking for inet_aton in -l44bsd" >&5
 ac_lib_var=`echo 44bsd'_'inet_aton | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7069,7 +7096,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-l44bsd  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7073 "configure"
+#line 7100 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7080,7 +7107,7 @@
 inet_aton()
 ; return 0; }
 EOF
-if { (eval echo configure:7084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7112,7 +7139,7 @@
 fi
 
 		echo $ac_n "checking for main in -lresolv""... $ac_c" 1>&6
-echo "configure:7116: checking for main in -lresolv" >&5
+echo "configure:7143: checking for main in -lresolv" >&5
 ac_lib_var=`echo resolv'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7120,14 +7147,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lresolv  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7124 "configure"
+#line 7151 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:7131: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7158,7 +7185,7 @@
     esac
 fi
 echo $ac_n "checking for main in -lm""... $ac_c" 1>&6
-echo "configure:7162: checking for main in -lm" >&5
+echo "configure:7189: checking for main in -lm" >&5
 ac_lib_var=`echo m'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7166,14 +7193,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lm  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7170 "configure"
+#line 7197 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:7177: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7204: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7202,7 +7229,7 @@
 
 
 echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:7206: checking for crypt in -lcrypt" >&5
+echo "configure:7233: checking for crypt in -lcrypt" >&5
 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7210,7 +7237,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lcrypt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7214 "configure"
+#line 7241 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7221,7 +7248,7 @@
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:7225: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7245,7 +7272,7 @@
 
 if test "$with_dl" = "yes"; then
     echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:7249: checking for dlopen in -ldl" >&5
+echo "configure:7276: checking for dlopen in -ldl" >&5
 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7253,7 +7280,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7257 "configure"
+#line 7284 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7264,7 +7291,7 @@
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:7268: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7312,7 +7339,7 @@
     ;;
     esac
     echo $ac_n "checking for main in -lpthread""... $ac_c" 1>&6
-echo "configure:7316: checking for main in -lpthread" >&5
+echo "configure:7343: checking for main in -lpthread" >&5
 ac_lib_var=`echo pthread'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7320,14 +7347,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7324 "configure"
+#line 7351 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:7331: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7358,7 +7385,7 @@
 
 if test "$with_aio" = "yes"; then
     echo $ac_n "checking for aio_read in -lrt""... $ac_c" 1>&6
-echo "configure:7362: checking for aio_read in -lrt" >&5
+echo "configure:7389: checking for aio_read in -lrt" >&5
 ac_lib_var=`echo rt'_'aio_read | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7366,7 +7393,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lrt  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7370 "configure"
+#line 7397 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7377,7 +7404,7 @@
 aio_read()
 ; return 0; }
 EOF
-if { (eval echo configure:7381: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7409,7 +7436,7 @@
 case "$host" in
 	*-pc-sco3.2*)
 		echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
-echo "configure:7413: checking for strftime in -lintl" >&5
+echo "configure:7440: checking for strftime in -lintl" >&5
 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -7417,7 +7444,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 7421 "configure"
+#line 7448 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7428,7 +7455,7 @@
 strftime()
 ; return 0; }
 EOF
-if { (eval echo configure:7432: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7613,6 +7640,7 @@
 	srand48 \
 	srandom \
 	statfs \
+	strnstr \
 	sysconf \
 	syslog \
 	timegm \
@@ -7622,12 +7650,12 @@
 
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7626: checking for $ac_func" >&5
+echo "configure:7654: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7631 "configure"
+#line 7659 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7650,7 +7678,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:7654: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7676,7 +7704,7 @@
 
 
 echo $ac_n "checking if setresuid is implemented""... $ac_c" 1>&6
-echo "configure:7680: checking if setresuid is implemented" >&5
+echo "configure:7708: checking if setresuid is implemented" >&5
 if eval "test \"`echo '$''{'ac_cv_func_setresuid'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7684,7 +7712,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 7688 "configure"
+#line 7716 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -7697,7 +7725,7 @@
   }
   
 EOF
-if { (eval echo configure:7701: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7729: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_setresuid="yes"
 else
@@ -7741,8 +7769,29 @@
 fi
 fi
 
+
+
+if false; then
+  NEED_OWN_STRNSTR_TRUE=
+  NEED_OWN_STRNSTR_FALSE='#'
+else
+  NEED_OWN_STRNSTR_TRUE='#'
+  NEED_OWN_STRNSTR_FALSE=
+fi
+if test "$ac_cv_func_strnstr" = "no" || test "$ac_cv_func_vstrnstr" = "no" ; then
+  
+
+if true; then
+  NEED_OWN_STRNSTR_TRUE=
+  NEED_OWN_STRNSTR_FALSE='#'
+else
+  NEED_OWN_STRNSTR_TRUE='#'
+  NEED_OWN_STRNSTR_FALSE=
+fi
+fi
+  
 echo $ac_n "checking if va_copy is implemented""... $ac_c" 1>&6
-echo "configure:7746: checking if va_copy is implemented" >&5
+echo "configure:7795: checking if va_copy is implemented" >&5
 if eval "test \"`echo '$''{'ac_cv_func_va_copy'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7750,7 +7799,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 7754 "configure"
+#line 7803 "configure"
 #include "confdefs.h"
 
       #include <stdarg.h>
@@ -7768,7 +7817,7 @@
       }
       
 EOF
-if { (eval echo configure:7772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_va_copy="yes"
 else
@@ -7792,7 +7841,7 @@
 fi
 
 echo $ac_n "checking if __va_copy is implemented""... $ac_c" 1>&6
-echo "configure:7796: checking if __va_copy is implemented" >&5
+echo "configure:7845: checking if __va_copy is implemented" >&5
 if eval "test \"`echo '$''{'ac_cv_func___va_copy'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -7800,7 +7849,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 7804 "configure"
+#line 7853 "configure"
 #include "confdefs.h"
 
       #include <stdarg.h>
@@ -7818,7 +7867,7 @@
       }
       
 EOF
-if { (eval echo configure:7822: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7871: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func___va_copy="yes"
 else
@@ -7843,7 +7892,7 @@
 
 if test "$IPF_TRANSPARENT" ; then
     echo $ac_n "checking if IP-Filter header files are installed""... $ac_c" 1>&6
-echo "configure:7847: checking if IP-Filter header files are installed" >&5
+echo "configure:7896: checking if IP-Filter header files are installed" >&5
     # hold on to your hats...
     if test "$ac_cv_header_ip_compat_h" = "yes" ||
         test "$ac_cv_header_ip_fil_compat_h" = "yes" ||
@@ -7884,7 +7933,7 @@
 
 if test "$PF_TRANSPARENT" ; then
     echo $ac_n "checking if PF header file is installed""... $ac_c" 1>&6
-echo "configure:7888: checking if PF header file is installed" >&5
+echo "configure:7937: checking if PF header file is installed" >&5
     # hold on to your hats...
     if test "$ac_cv_header_net_pfvar_h" = "yes"; then
         PF_TRANSPARENT="yes"
@@ -7909,7 +7958,7 @@
 
 if test "$LINUX_NETFILTER" ; then
     echo $ac_n "checking if Linux 2.4 kernel header files are installed""... $ac_c" 1>&6
-echo "configure:7913: checking if Linux 2.4 kernel header files are installed" >&5
+echo "configure:7962: checking if Linux 2.4 kernel header files are installed" >&5
     # hold on to your hats...
     if test "$ac_cv_header_linux_netfilter_ipv4_h" = "yes"; then
         LINUX_NETFILTER="yes"
@@ -7943,13 +7992,13 @@
     esac
 fi
 echo $ac_n "checking if GNUregex needs to be compiled""... $ac_c" 1>&6
-echo "configure:7947: checking if GNUregex needs to be compiled" >&5
+echo "configure:7996: checking if GNUregex needs to be compiled" >&5
 if test -z "$USE_GNUREGEX"; then
 if test "$ac_cv_func_regcomp" = "no" || test "$USE_GNUREGEX" = "yes" ; then
 	USE_GNUREGEX="yes"
 else
 	cat > conftest.$ac_ext <<EOF
-#line 7953 "configure"
+#line 8002 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <regex.h>
@@ -7957,7 +8006,7 @@
 regex_t t; regcomp(&t,"",0);
 ; return 0; }
 EOF
-if { (eval echo configure:7961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8010: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   USE_GNUREGEX="no"
 else
@@ -7988,12 +8037,12 @@
 
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7992: checking for $ac_func" >&5
+echo "configure:8041: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 7997 "configure"
+#line 8046 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8016,7 +8065,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:8020: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8069: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8044,12 +8093,12 @@
 
 
 echo $ac_n "checking Default FD_SETSIZE value""... $ac_c" 1>&6
-echo "configure:8048: checking Default FD_SETSIZE value" >&5
+echo "configure:8097: checking Default FD_SETSIZE value" >&5
 if test "$cross_compiling" = yes; then
   DEFAULT_FD_SETSIZE=256
 else
   cat > conftest.$ac_ext <<EOF
-#line 8053 "configure"
+#line 8102 "configure"
 #include "confdefs.h"
 
 #if HAVE_STDIO_H
@@ -8074,7 +8123,7 @@
 }
 
 EOF
-if { (eval echo configure:8078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   DEFAULT_FD_SETSIZE=`cat conftestval`
 else
@@ -8093,7 +8142,7 @@
 
 
 echo $ac_n "checking Maximum number of filedescriptors we can open""... $ac_c" 1>&6
-echo "configure:8097: checking Maximum number of filedescriptors we can open" >&5
+echo "configure:8146: checking Maximum number of filedescriptors we can open" >&5
 TLDFLAGS="$LDFLAGS"
 case $host in
 i386-unknown-freebsd*)
@@ -8105,7 +8154,7 @@
   SQUID_MAXFD=256
 else
   cat > conftest.$ac_ext <<EOF
-#line 8109 "configure"
+#line 8158 "configure"
 #include "confdefs.h"
 
 #include <stdio.h>
@@ -8165,7 +8214,7 @@
 }
 
 EOF
-if { (eval echo configure:8169: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   SQUID_MAXFD=`cat conftestval`
 else
@@ -8192,12 +8241,12 @@
 LDFLAGS="$TLDFLAGS"
 
 echo $ac_n "checking Default UDP send buffer size""... $ac_c" 1>&6
-echo "configure:8196: checking Default UDP send buffer size" >&5
+echo "configure:8245: checking Default UDP send buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_UDP_SO_SNDBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 8201 "configure"
+#line 8250 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -8218,7 +8267,7 @@
 }
 
 EOF
-if { (eval echo configure:8222: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8271: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   SQUID_UDP_SO_SNDBUF=`cat conftestval`
 else
@@ -8237,12 +8286,12 @@
 
 
 echo $ac_n "checking Default UDP receive buffer size""... $ac_c" 1>&6
-echo "configure:8241: checking Default UDP receive buffer size" >&5
+echo "configure:8290: checking Default UDP receive buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_UDP_SO_RCVBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 8246 "configure"
+#line 8295 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -8263,7 +8312,7 @@
 }
 
 EOF
-if { (eval echo configure:8267: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   SQUID_UDP_SO_RCVBUF=`cat conftestval`
 else
@@ -8282,12 +8331,12 @@
 
 
 echo $ac_n "checking Default TCP send buffer size""... $ac_c" 1>&6
-echo "configure:8286: checking Default TCP send buffer size" >&5
+echo "configure:8335: checking Default TCP send buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_TCP_SO_SNDBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 8291 "configure"
+#line 8340 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -8308,7 +8357,7 @@
 }
 
 EOF
-if { (eval echo configure:8312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8361: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   SQUID_TCP_SO_SNDBUF=`cat conftestval`
 else
@@ -8327,12 +8376,12 @@
 
 
 echo $ac_n "checking Default TCP receive buffer size""... $ac_c" 1>&6
-echo "configure:8331: checking Default TCP receive buffer size" >&5
+echo "configure:8380: checking Default TCP receive buffer size" >&5
 if test "$cross_compiling" = yes; then
   SQUID_TCP_SO_RCVBUF=16384
 else
   cat > conftest.$ac_ext <<EOF
-#line 8336 "configure"
+#line 8385 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -8353,7 +8402,7 @@
 }
 
 EOF
-if { (eval echo configure:8357: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8406: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   SQUID_TCP_SO_RCVBUF=`cat conftestval`
 else
@@ -8372,19 +8421,19 @@
 
 
 echo $ac_n "checking if sys_errlist is already defined""... $ac_c" 1>&6
-echo "configure:8376: checking if sys_errlist is already defined" >&5
+echo "configure:8425: checking if sys_errlist is already defined" >&5
 if eval "test \"`echo '$''{'ac_cv_needs_sys_errlist'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8381 "configure"
+#line 8430 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 int main() {
 char *s = sys_errlist;
 ; return 0; }
 EOF
-if { (eval echo configure:8388: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8437: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_needs_sys_errlist="no"
 else
@@ -8406,16 +8455,16 @@
 fi
 
 echo $ac_n "checking for libresolv _dns_ttl_ hack""... $ac_c" 1>&6
-echo "configure:8410: checking for libresolv _dns_ttl_ hack" >&5
+echo "configure:8459: checking for libresolv _dns_ttl_ hack" >&5
 cat > conftest.$ac_ext <<EOF
-#line 8412 "configure"
+#line 8461 "configure"
 #include "confdefs.h"
 extern int _dns_ttl_;
 int main() {
 return _dns_ttl_;
 ; return 0; }
 EOF
-if { (eval echo configure:8419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:8468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 cat >> confdefs.h <<\EOF
@@ -8431,12 +8480,12 @@
 rm -f conftest*
 
 echo $ac_n "checking if inet_ntoa() actually works""... $ac_c" 1>&6
-echo "configure:8435: checking if inet_ntoa() actually works" >&5
+echo "configure:8484: checking if inet_ntoa() actually works" >&5
 if test "$cross_compiling" = yes; then
   INET_NTOA_RESULT="broken"
 else
   cat > conftest.$ac_ext <<EOF
-#line 8440 "configure"
+#line 8489 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -8455,7 +8504,7 @@
 }
 
 EOF
-if { (eval echo configure:8459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   INET_NTOA_RESULT=`cat conftestval`
 else
@@ -8481,9 +8530,9 @@
 
 if test "$ac_cv_header_sys_statvfs_h" = "yes" ; then
 echo $ac_n "checking for working statvfs() interface""... $ac_c" 1>&6
-echo "configure:8485: checking for working statvfs() interface" >&5
+echo "configure:8534: checking for working statvfs() interface" >&5
 cat > conftest.$ac_ext <<EOF
-#line 8487 "configure"
+#line 8536 "configure"
 #include "confdefs.h"
 
 #include <stdlib.h>
@@ -8500,7 +8549,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:8504: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_func_statvfs=yes
 else
@@ -8520,12 +8569,12 @@
 fi
 
 echo $ac_n "checking for _res.nsaddr_list""... $ac_c" 1>&6
-echo "configure:8524: checking for _res.nsaddr_list" >&5
+echo "configure:8573: checking for _res.nsaddr_list" >&5
 if eval "test \"`echo '$''{'ac_cv_have_res_nsaddr_list'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8529 "configure"
+#line 8578 "configure"
 #include "confdefs.h"
 
 #if HAVE_SYS_TYPES_H
@@ -8548,7 +8597,7 @@
 _res.nsaddr_list[0];
 ; return 0; }
 EOF
-if { (eval echo configure:8552: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8601: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_res_nsaddr_list="yes"
 else
@@ -8570,12 +8619,12 @@
 
 if test $ac_cv_have_res_nsaddr_list = "no" ; then
 echo $ac_n "checking for _res.ns_list""... $ac_c" 1>&6
-echo "configure:8574: checking for _res.ns_list" >&5
+echo "configure:8623: checking for _res.ns_list" >&5
 if eval "test \"`echo '$''{'ac_cv_have_res_ns_list'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 8579 "configure"
+#line 8628 "configure"
 #include "confdefs.h"
 
 #if HAVE_SYS_TYPES_H
@@ -8598,7 +8647,7 @@
 _res.ns_list[0].addr;
 ; return 0; }
 EOF
-if { (eval echo configure:8602: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8651: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_have_res_ns_list="yes"
 else
@@ -8877,6 +8926,8 @@
 s%@ENABLE_PINGER_FALSE@%$ENABLE_PINGER_FALSE%g
 s%@USE_DELAY_POOLS_TRUE@%$USE_DELAY_POOLS_TRUE%g
 s%@USE_DELAY_POOLS_FALSE@%$USE_DELAY_POOLS_FALSE%g
+s%@USE_ICAP_TRUE@%$USE_ICAP_TRUE%g
+s%@USE_ICAP_FALSE@%$USE_ICAP_FALSE%g
 s%@USE_SNMP_TRUE@%$USE_SNMP_TRUE%g
 s%@USE_SNMP_FALSE@%$USE_SNMP_FALSE%g
 s%@SNMPLIB@%$SNMPLIB%g
@@ -8922,6 +8973,8 @@
 s%@CRYPTLIB@%$CRYPTLIB%g
 s%@NEED_OWN_SNPRINTF_TRUE@%$NEED_OWN_SNPRINTF_TRUE%g
 s%@NEED_OWN_SNPRINTF_FALSE@%$NEED_OWN_SNPRINTF_FALSE%g
+s%@NEED_OWN_STRNSTR_TRUE@%$NEED_OWN_STRNSTR_TRUE%g
+s%@NEED_OWN_STRNSTR_FALSE@%$NEED_OWN_STRNSTR_FALSE%g
 s%@REGEXLIB@%$REGEXLIB%g
 s%@LIBREGEX@%$LIBREGEX%g
 s%@LIBOBJS@%$LIBOBJS%g
Index: errors/Bulgarian/ERR_ICAP_FAILURE
--- errors/Bulgarian/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Bulgarian/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Catalan/ERR_ICAP_FAILURE
--- errors/Catalan/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Catalan/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Czech/ERR_ICAP_FAILURE
--- errors/Czech/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Czech/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Danish/ERR_ICAP_FAILURE
--- errors/Danish/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Danish/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Dutch/ERR_ICAP_FAILURE
--- errors/Dutch/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Dutch/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/English/ERR_ICAP_FAILURE
--- errors/English/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/English/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Estonian/ERR_ICAP_FAILURE
--- errors/Estonian/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Estonian/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Finnish/ERR_ICAP_FAILURE
--- errors/Finnish/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Finnish/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/French/ERR_ICAP_FAILURE
--- errors/French/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/French/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/German/ERR_ICAP_FAILURE
--- errors/German/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/German/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>FEHLER: Der angeforderte URL konnte nicht geholt werden</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>FEHLER</H1>
+<H2>Der angeforderte URL konnte nicht geholt werden</H2>
+<HR noshade size="1px">
+<P>
+W&auml;hrend des Versuches, den URL<BR>
+<A HREF="%U">%U</A>
+
+<BR>
+zu laden, trat der folgende Fehler auf:
+<UL>
+<LI>
+<STRONG>
+ICAP-Protokollfehler
+</STRONG>
+</UL>
+
+<P>
+<P>
+Es trat ein Problem bei der ICAP-Kommunikation auf. M&ouml;gliche Gr&uuml;nde:
+<UL>
+<LI>Nicht erreichbarer ICAP-Server
+<LI>Ung&uuml;ltige Antwort vom ICAP-Server
+
+</UL>
+</P>
+
+<P>Ihr Cache Administrator ist <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Hebrew/ERR_ICAP_FAILURE
--- errors/Hebrew/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Hebrew/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Hungarian/ERR_ICAP_FAILURE
--- errors/Hungarian/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Hungarian/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Italian/ERR_ICAP_FAILURE
--- errors/Italian/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Italian/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Japanese/ERR_ICAP_FAILURE
--- errors/Japanese/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Japanese/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Korean/ERR_ICAP_FAILURE
--- errors/Korean/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Korean/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Lithuanian/ERR_ICAP_FAILURE
--- errors/Lithuanian/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Lithuanian/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Polish/ERR_ICAP_FAILURE
--- errors/Polish/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Polish/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Portuguese/ERR_ICAP_FAILURE
--- errors/Portuguese/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Portuguese/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Romanian/ERR_ICAP_FAILURE
--- errors/Romanian/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Romanian/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Russian-1251/ERR_ICAP_FAILURE
--- errors/Russian-1251/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Russian-1251/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Russian-koi8-r/ERR_ICAP_FAILURE
--- errors/Russian-koi8-r/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Russian-koi8-r/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Serbian/ERR_ICAP_FAILURE
--- errors/Serbian/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Serbian/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Simplify_Chinese/ERR_ICAP_FAILURE
--- errors/Simplify_Chinese/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Simplify_Chinese/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Slovak/ERR_ICAP_FAILURE
--- errors/Slovak/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Slovak/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Spanish/ERR_ICAP_FAILURE
--- errors/Spanish/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Spanish/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Swedish/ERR_ICAP_FAILURE
--- errors/Swedish/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Swedish/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Traditional_Chinese/ERR_ICAP_FAILURE
--- errors/Traditional_Chinese/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Traditional_Chinese/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: errors/Turkish/ERR_ICAP_FAILURE
--- errors/Turkish/ERR_ICAP_FAILURE.orig	2004-09-13 13:23:52 +0200
+++ errors/Turkish/ERR_ICAP_FAILURE	2004-09-13 13:23:52 +0200
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<HTML><HEAD>
+<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
+<STYLE type="text/css"><!--BODY{background-color:#ffffff; font-family:verdana,sans-serif}--></STYLE>
+</HEAD><BODY>
+<H1>ERROR</H1>
+<H2>The requested URL could not be retrieved</H2>
+<HR noshade size="1px">
+<P>
+While attempting to retrieve the URL:
+<A HREF="%U">%U</A>
+<P>
+the following error was encountered:
+<UL>
+<LI>
+<STRONG>
+ICAP protocol error.
+</STRONG>
+</UL>
+
+<P>
+<P>
+Some aspect of the ICAP communication failed. Possible problems:
+<UL>
+<LI>ICAP server is not reachable.
+<LI>Illegal response from ICAP server.
+</UL>
+</P>
+
+<P>Your cache administrator is <A HREF="mailto:%w">%w</A>. 
+
Index: include/autoconf.h.in
--- include/autoconf.h.in.orig	2004-06-08 13:37:22 +0200
+++ include/autoconf.h.in	2004-09-13 13:24:27 +0200
@@ -124,6 +124,11 @@
  */
 #undef DELAY_POOLS
 
+/* 
+ * ICAP - Internet Content Adaptation Protocol 
+ */
+#undef HS_FEAT_ICAP
+
 /*
  * If you want to log User-Agent request header values, define this.
  * By default, they are written to useragent.log in the Squid log
@@ -572,6 +577,9 @@
 /* Define if you have the strerror function.  */
 #undef HAVE_STRERROR
 
+/* Define if you have the strnstr function.  */
+#undef HAVE_STRNSTR
+
 /* Define if you have the sysconf function.  */
 #undef HAVE_SYSCONF
 
Index: include/util.h
--- include/util.h.orig	2001-10-17 03:36:07 +0200
+++ include/util.h	2004-09-13 13:23:52 +0200
@@ -132,4 +132,12 @@
  */
 int statMemoryAccounted(void);
 
+#ifndef HAVE_STRNSTR
+extern char *strnstr(const char *haystack, const char *needle, size_t haystacklen);
+#endif
+
+#ifndef HAVE_STRCASESTR
+extern char *strcasestr(const char *haystack, const char *needle);
+#endif
+
 #endif /* SQUID_UTIL_H */
Index: lib/Makefile.am
--- lib/Makefile.am.orig	2001-11-22 00:47:12 +0100
+++ lib/Makefile.am	2004-09-13 13:23:52 +0200
@@ -8,6 +8,19 @@
 else
 SNPRINTFSOURCE=
 endif
+
+if NEED_OWN_STRNSTR
+STRNSTRSOURCE=strnstr.c
+else
+STRNSTRSOURCE=
+endif
+
+if NEED_OWN_STRCASESTR
+STRCASESTRSOURCE=strcasestr.c
+else
+STRCASESTRSOURCE=
+endif
+
 if NEED_OWN_MD5
 MD5SOURCE=md5.c
 else
@@ -43,6 +56,8 @@
 	$(SNPRINTFSOURCE) \
 	splay.c \
 	Stack.c \
+	$(STRNSTRSOURCE) \
+	$(STRCASESTRSOURCE) \
 	stub_memaccount.c \
 	util.c \
 	uudecode.c
Index: lib/strcasestr.c
--- lib/strcasestr.c.orig	2004-09-13 13:23:52 +0200
+++ lib/strcasestr.c	2004-09-13 13:23:52 +0200
@@ -0,0 +1,126 @@
+/* Return the offset of one string within another.
+   Copyright (C) 1994,1996,1997,1998,1999,2000 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/*
+ * My personal strstr() implementation that beats most other algorithms.
+ * Until someone tells me otherwise, I assume that this is the
+ * fastest implementation of strstr() in C.
+ * I deliberately chose not to comment it.  You should have at least
+ * as much fun trying to understand it, as I had to write it :-).
+ *
+ * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de	*/
+
+/* 
+ * modified to work outside of glibc (rhorstmann, 06/04/2004)
+ */
+
+#include "config.h"
+#ifndef  HAVE_STRCASESTR
+#include <ctype.h>
+
+typedef unsigned chartype;
+
+char *
+strcasestr (phaystack, pneedle)
+     const char *phaystack;
+     const char *pneedle;
+{
+  register const unsigned char *haystack, *needle;
+  register chartype b, c;
+
+  haystack = (const unsigned char *) phaystack;
+  needle = (const unsigned char *) pneedle;
+
+  b = tolower (*needle);
+  if (b != '\0')
+    {
+      haystack--;				/* possible ANSI violation */
+      do
+	{
+	  c = *++haystack;
+	  if (c == '\0')
+	    goto ret0;
+	}
+      while (tolower (c) != (int) b);
+
+      c = tolower (*++needle);
+      if (c == '\0')
+	goto foundneedle;
+      ++needle;
+      goto jin;
+
+      for (;;)
+        {
+          register chartype a;
+	  register const unsigned char *rhaystack, *rneedle;
+
+	  do
+	    {
+	      a = *++haystack;
+	      if (a == '\0')
+		goto ret0;
+	      if (tolower (a) == (int) b)
+		break;
+	      a = *++haystack;
+	      if (a == '\0')
+		goto ret0;
+shloop:
+	      ;
+	    }
+          while (tolower (a) != (int) b);
+
+jin:	  a = *++haystack;
+	  if (a == '\0')
+	    goto ret0;
+
+	  if (tolower (a) != (int) c)
+	    goto shloop;
+
+	  rhaystack = haystack-- + 1;
+	  rneedle = needle;
+	  a = tolower (*rneedle);
+
+	  if (tolower (*rhaystack) == (int) a)
+	    do
+	      {
+		if (a == '\0')
+		  goto foundneedle;
+		++rhaystack;
+		a = tolower (*++needle);
+		if (tolower (*rhaystack) != (int) a)
+		  break;
+		if (a == '\0')
+		  goto foundneedle;
+		++rhaystack;
+		a = tolower (*++needle);
+	      }
+	    while (tolower (*rhaystack) == (int) a);
+
+	  needle = rneedle;		/* took the register-poor approach */
+
+	  if (a == '\0')
+	    break;
+        }
+    }
+foundneedle:
+  return (char*) haystack;
+ret0:
+  return 0;
+}
+#endif
Index: lib/strnstr.c
--- lib/strnstr.c.orig	2004-09-13 13:23:52 +0200
+++ lib/strnstr.c	2004-09-13 13:23:52 +0200
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (C) 2003 Nikos Mavroyanopoulos
+ *
+ *  This file is part of GNUTLS.
+ *
+ *  The GNUTLS library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public   
+ *  License as published by the Free Software Foundation; either 
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library 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
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+ /*
+  * DW 2003/10/17:
+  * Changed 'ssize_t' types to 'size_t'
+  */
+
+#include "config.h"
+#ifndef HAVE_STRNSTR
+#include <string.h>
+
+char *strnstr(const char *haystack, const char *needle, size_t haystacklen)
+{
+        char *p;
+        size_t plen;
+        size_t len = strlen(needle);
+
+        if (*needle == '\0')    /* everything matches empty string */
+                return (char*) haystack;
+
+        plen = haystacklen;
+        for (p = (char*) haystack; p != NULL; p = memchr(p + 1, *needle, plen-1)) {
+                plen = haystacklen - (p - haystack);
+
+                if (plen < len) return NULL;
+
+                if (strncmp(p, needle, len) == 0)
+                        return (p);
+        }
+        return NULL;
+}
+#endif
Index: src/Makefile.am
--- src/Makefile.am.orig	2002-11-10 16:30:03 +0100
+++ src/Makefile.am	2004-09-13 13:23:52 +0200
@@ -6,6 +6,12 @@
 #  Uncomment and customize the following to suit your needs:
 #
 
+if USE_ICAP
+ICAPSOURCE = icap_common.c icap_reqmod.c icap_respmod.c icap_opt.c
+else
+ICAPSOURCE = 
+endif
+
 if USE_DNSSERVER
 DNSSOURCE = dns.c
 DNSSERVER = dnsserver
@@ -150,6 +156,7 @@
 	HttpMsg.c \
 	HttpReply.c \
 	HttpRequest.c \
+	$(ICAPSOURCE) \
 	icmp.c \
 	icp_v2.c \
 	icp_v3.c \
Index: src/Makefile.in
--- src/Makefile.in.orig	2004-06-08 13:37:22 +0200
+++ src/Makefile.in	2004-09-13 13:23:52 +0200
@@ -122,6 +122,9 @@
 install_sh = @install_sh@
 makesnmplib = @makesnmplib@
 
+@USE_ICAP_TRUE@ICAPSOURCE = icap_common.c icap_reqmod.c icap_respmod.c icap_opt.c
+@USE_ICAP_FALSE@ICAPSOURCE = 
+
 @USE_DNSSERVER_TRUE@DNSSOURCE = dns.c
 @USE_DNSSERVER_FALSE@DNSSOURCE = dns_internal.c
 @USE_DNSSERVER_TRUE@DNSSERVER = dnsserver
@@ -245,6 +248,7 @@
 	HttpMsg.c \
 	HttpReply.c \
 	HttpRequest.c \
+	$(ICAPSOURCE) \
 	icmp.c \
 	icp_v2.c \
 	icp_v3.c \
@@ -462,6 +466,8 @@
 pinger_LDFLAGS =
 @USE_DELAY_POOLS_FALSE@am__objects_3 =
 @USE_DELAY_POOLS_TRUE@am__objects_3 = delay_pools.$(OBJEXT)
+@USE_ICAP_FALSE@am__objects_0 =
+@USE_ICAP_TRUE@am__objects_0 = icap_common.$(OBJEXT) icap_reqmod.$(OBJEXT) icap_respmod.$(OBJEXT) icap_opt.$(OBJEXT)
 @USE_DNSSERVER_FALSE@am__objects_4 = dns_internal.$(OBJEXT)
 @USE_DNSSERVER_TRUE@am__objects_4 = dns.$(OBJEXT)
 @ENABLE_HTCP_TRUE@am__objects_5 = htcp.$(OBJEXT)
@@ -480,7 +486,7 @@
 	cache_manager.$(OBJEXT) carp.$(OBJEXT) cbdata.$(OBJEXT) \
 	client_db.$(OBJEXT) client_side.$(OBJEXT) comm.$(OBJEXT) \
 	comm_select.$(OBJEXT) debug.$(OBJEXT) $(am__objects_3) \
-	disk.$(OBJEXT) $(am__objects_4) errorpage.$(OBJEXT) \
+	disk.$(OBJEXT) $(am__objects_0) $(am__objects_4) errorpage.$(OBJEXT) \
 	ETag.$(OBJEXT) event.$(OBJEXT) external_acl.$(OBJEXT) \
 	fd.$(OBJEXT) filemap.$(OBJEXT) forward.$(OBJEXT) \
 	fqdncache.$(OBJEXT) ftp.$(OBJEXT) gopher.$(OBJEXT) \
Index: src/MemBuf.c
--- src/MemBuf.c.orig	2004-06-06 17:07:16 +0200
+++ src/MemBuf.c	2004-09-13 13:23:52 +0200
@@ -386,3 +386,15 @@
     assert(mb);
     memBufPrintf(mb, "memBufReport is not yet implemented @?@\n");
 }
+
+int
+memBufRead(int fd, MemBuf * mb)
+{
+    int len;
+    if (mb->capacity == mb->size)
+	memBufGrow(mb, SQUID_TCP_SO_RCVBUF);
+    len = FD_READ_METHOD(fd, mb->buf + mb->size, mb->capacity - mb->size);
+    if (len)
+	mb->size += len;
+    return len;
+}
Index: src/String.c
--- src/String.c.orig	2001-01-12 01:37:14 +0100
+++ src/String.c	2004-09-13 13:23:52 +0200
@@ -1,4 +1,6 @@
 
+
+
 /*
  * $Id: String.c,v 1.9 2001/01/12 00:37:14 wessels Exp $
  *
Index: src/cache_cf.c
--- src/cache_cf.c.orig	2004-04-30 01:56:50 +0200
+++ src/cache_cf.c	2004-09-13 13:23:52 +0200
@@ -2073,6 +2073,541 @@
     return bodylist.head == NULL;
 }
 
+#ifdef HS_FEAT_ICAP
+
+/***************************************************
+ * prototypes
+ */
+static int icap_service_process(icap_service * s);
+static void icap_service_init(icap_service * s);
+static void icap_service_destroy(icap_service * s);
+icap_service *icap_service_lookup(char *name);
+static int icap_class_process(icap_class * c);
+static void icap_class_destroy(icap_class * c);
+static void icap_access_destroy(icap_access * a);
+static void dump_wordlist(StoreEntry * entry, const char *name, wordlist * list);
+static void icap_class_add(icap_class * c);
+
+/***************************************************
+ * icap_service
+ */
+
+/* 
+ * example:
+ * icap_service reqmode_precache 0 icap://192.168.0.1:1344/respmod
+ */
+
+static void
+parse_icap_service_type(IcapConfig * cfg)
+{
+    icap_service *A = NULL;
+    icap_service *B = NULL;
+    icap_service **T = NULL;
+
+    A = cbdataAlloc(icap_service);
+    icap_service_init(A);
+    parse_string(&A->name);
+    parse_string(&A->type_name);
+    parse_ushort(&A->bypass);
+    parse_string(&A->uri);
+    debug(3, 5) ("parse_icap_service_type (line %d): %s %s %d %s\n", config_lineno, A->name, A->type_name, A->bypass, A->name);
+
+    if (icap_service_process(A)) {
+	/* put into linked list */
+	for (B = cfg->service_head, T = &cfg->service_head; B; T = &B->next, B = B->next);
+	*T = A;
+    } else {
+	/* clean up structure */
+	debug(3, 0) ("parse_icap_service_type (line %d): skipping %s\n", config_lineno, A->name);
+	icap_service_destroy(A);
+	cbdataFree(A);
+    }
+
+}
+
+static void
+dump_icap_service_type(StoreEntry * e, const char *name, IcapConfig cfg)
+{
+    icap_service *current_node = NULL;
+
+    if (!cfg.service_head) {
+	storeAppendPrintf(e, "%s 0\n", name);
+	return;
+    }
+    current_node = cfg.service_head;
+
+    while (current_node) {
+	storeAppendPrintf(e, "%s %s %s %d %s\n", name, current_node->name, current_node->type_name, current_node->bypass, current_node->uri);
+	current_node = current_node->next;
+    }
+
+}
+
+static void
+free_icap_service_type(IcapConfig * cfg)
+{
+    while (cfg->service_head) {
+	icap_service *current_node = cfg->service_head;
+	cfg->service_head = current_node->next;
+	icap_service_destroy(current_node);
+	cbdataFree(current_node);
+    }
+}
+
+/* 
+ * parse the raw string and cache some parts that are needed later 
+ * returns 1 if everything was ok
+ */
+static int
+icap_service_process(icap_service * s)
+{
+    char *start, *end;
+    char *tailp;
+    unsigned int len;
+    int port_in_uri;
+    s->type = icapServiceToType(s->type_name);
+    if (s->type >= ICAP_SERVICE_MAX) {
+	debug(3, 0) ("icap_service_process (line %d): wrong service type %s\n", config_lineno, s->type_name);
+	return 0;
+    }
+    if (s->type == ICAP_SERVICE_REQMOD_PRECACHE)
+	s->method = ICAP_METHOD_REQMOD;
+    else if (s->type == ICAP_SERVICE_REQMOD_PRECACHE)
+	s->method = ICAP_METHOD_REQMOD;
+    else if (s->type == ICAP_SERVICE_REQMOD_POSTCACHE)
+	s->method = ICAP_METHOD_REQMOD;
+    else if (s->type == ICAP_SERVICE_RESPMOD_PRECACHE)
+	s->method = ICAP_METHOD_RESPMOD;
+    else if (s->type == ICAP_SERVICE_RESPMOD_POSTCACHE)
+	s->method = ICAP_METHOD_RESPMOD;
+    debug(3, 5) ("icap_service_process (line %d): type=%s\n", config_lineno, icapServiceToStr(s->type));
+    if (strncmp(s->uri, "icap://", 7) != 0) {
+	debug(3, 0) ("icap_service_process (line %d): wrong uri: %s\n", config_lineno, s->uri);
+	return 0;
+    }
+    start = s->uri + 7;
+    if ((end = strchr(start, ':')) != NULL) {
+	/* ok */
+	port_in_uri = 1;
+	debug(3, 5) ("icap_service_process (line %d): port given\n", config_lineno);
+    } else if ((end = strchr(start, '/')) != NULL) {
+	/* ok */
+	port_in_uri = 0;
+	debug(3, 5) ("icap_service_process (line %d): no port given\n", config_lineno);
+    } else {
+	debug(3, 0) ("icap_service_process (line %d): wrong service uri: %s\n", config_lineno, s->uri);
+	return 0;
+    }
+    len = end - start;
+    s->hostname = xstrndup(start, len + 1);
+    s->hostname[len] = 0;
+    start = end;
+
+    if (port_in_uri) {
+	start++;		/* skip ':' */
+	if ((end = strchr(start, '/')) != NULL) {
+	    s->port = strtoul(start, &tailp, 0) % 65536;
+	    if (tailp != end) {
+		debug(3, 0) ("icap_service_process (line %d): wrong service uri (port could not be parsed): %s\n", config_lineno, s->uri);
+		return 0;
+	    }
+	    debug(3, 5) ("icap_service_process (line %d): port=%d\n", config_lineno, s->port);
+	    start = end;
+	    if (start[0] != '/') {
+		debug(3, 0) ("icap_service_process (line %d): no '/' between port and resource found in %s\n", config_lineno, s->uri);
+		return 0;
+	    }
+	}
+    } else {
+	/* no explicit ICAP port; first ask by getservbyname or default to
+	 * hardwired port 1344 per ICAP specification section 4.2 */
+	struct servent *serv = getservbyname("icap", "tcp");
+	if (serv) {
+	    s->port = htons(serv->s_port);
+	    debug(3, 5) ("icap_service_process (line %d): default port=%d getservbyname(icap,tcp)\n", config_lineno, s->port);
+	} else {
+	    s->port = 1344;
+	    debug(3, 5) ("icap_service_process (line %d): default hardwired port=%d\n", config_lineno, s->port);
+	}
+    }
+
+    start++;			/* skip '/' */
+    /* the rest is resource name */
+    end = strchr(start, '\0');
+    len = end - start;
+    if (len > 1024) {
+	debug(3, 0) ("icap_service_process (line %d): long resource name (>1024), probably wrong\n", config_lineno);
+    }
+    s->resource = xstrndup(start, len + 1);
+    s->resource[len] = 0;
+    /* check bypass */
+    if ((s->bypass != 0) && (s->bypass != 1)) {
+	debug(3, 0) ("icap_service_process (line %d): invalid bypass value\n", config_lineno);
+	return 0;
+    }
+    return 1;
+}
+
+/*
+ * constructor
+ */
+static void
+icap_service_init(icap_service * s)
+{
+    s->type = ICAP_SERVICE_MAX;	/* means undefined */
+    s->preview = Config.icapcfg.preview_size;
+    s->opt = 0;
+    s->istag = StringNull;
+    s->transfer_preview = StringNull;
+    s->transfer_ignore = StringNull;
+    s->transfer_complete = StringNull;
+}
+
+/*
+ * destructor
+ * frees only strings, but don't touch the linked list
+ */
+static void
+icap_service_destroy(icap_service * s)
+{
+    xfree(s->name);
+    xfree(s->uri);
+    xfree(s->type_name);
+    xfree(s->hostname);
+    xfree(s->resource);
+    assert(s->opt == 0);	/* there should be no opt request running now */
+    stringClean(&s->istag);
+    stringClean(&s->transfer_preview);
+    stringClean(&s->transfer_ignore);
+    stringClean(&s->transfer_complete);
+}
+
+icap_service *
+icap_service_lookup(char *name)
+{
+    icap_service *iter;
+    for (iter = Config.icapcfg.service_head; iter; iter = iter->next) {
+	if (!strcmp(name, iter->name)) {
+	    return iter;
+	}
+    }
+    return NULL;
+}
+
+/***************************************************
+ * icap_service_list
+ */
+
+static void
+icap_service_list_add(icap_service_list ** isl, icap_service * service)
+{
+    icap_service_list **iter;
+    icap_service_list *new;
+
+    new = memAllocate(MEM_ICAP_SERVICE_LIST);
+    new->service = service;
+
+    if (*isl) {
+	iter = isl;
+	while ((*iter)->next)
+	    iter = &((*iter)->next);
+	(*iter)->next = new;
+    } else {
+	*isl = new;
+    }
+}
+
+/*
+ * free the linked list without touching references icap_service
+ */
+static void
+icap_service_list_destroy(icap_service_list * isl)
+{
+    icap_service_list *current;
+    icap_service_list *next;
+
+    current = isl;
+    while (current) {
+	next = current->next;
+	memFree(current, MEM_ICAP_SERVICE_LIST);
+	current = next;
+    }
+}
+
+/***************************************************
+ * icap_class
+ */
+static void
+parse_icap_class_type(IcapConfig * cfg)
+{
+    icap_class *s = NULL;
+
+    s = memAllocate(MEM_ICAP_CLASS);
+    parse_string(&s->name);
+    parse_wordlist(&s->services);
+
+    if (icap_class_process(s)) {
+	/* if ok, put into linked list */
+	icap_class_add(s);
+    } else {
+	/* clean up structure */
+	debug(3, 0) ("parse_icap_class_type (line %d): skipping %s\n", config_lineno, s->name);
+	icap_class_destroy(s);
+	memFree(s, MEM_ICAP_CLASS);
+    }
+}
+
+static void
+dump_icap_class_type(StoreEntry * e, const char *name, IcapConfig cfg)
+{
+    icap_class *current_node = NULL;
+    LOCAL_ARRAY(char, nom, 64);
+
+    if (!cfg.class_head) {
+	storeAppendPrintf(e, "%s 0\n", name);
+	return;
+    }
+    current_node = cfg.class_head;
+
+    while (current_node) {
+	snprintf(nom, 64, "%s %s", name, current_node->name);
+	dump_wordlist(e, nom, current_node->services);
+	current_node = current_node->next;
+    }
+}
+
+static void
+free_icap_class_type(IcapConfig * cfg)
+{
+    while (cfg->class_head) {
+	icap_class *current_node = cfg->class_head;
+	cfg->class_head = current_node->next;
+	icap_class_destroy(current_node);
+	memFree(current_node, MEM_ICAP_CLASS);
+    }
+}
+
+/*
+ * process services list, return 1, if at least one service was found
+ */
+static int
+icap_class_process(icap_class * c)
+{
+    icap_service_list *isl = NULL;
+    wordlist *iter;
+    icap_service *service;
+    /* take services list and build icap_service_list from it */
+    for (iter = c->services; iter; iter = iter->next) {
+	service = icap_service_lookup(iter->key);
+	if (service) {
+	    icap_service_list_add(&isl, service);
+	} else {
+	    debug(3, 0) ("icap_class_process (line %d): skipping service %s in class %s\n", config_lineno, iter->key, c->name);
+	}
+    }
+
+    if (isl) {
+	c->isl = isl;
+	return 1;
+    }
+    return 0;
+}
+
+/*
+ * search for an icap_class in the global IcapConfig
+ * classes with hidden-flag are skipped
+ */
+static icap_class *
+icap_class_lookup(char *name)
+{
+    icap_class *iter;
+    for (iter = Config.icapcfg.class_head; iter; iter = iter->next) {
+	if ((!strcmp(name, iter->name)) && (!iter->hidden)) {
+	    return iter;
+	}
+    }
+    return NULL;
+}
+
+/*
+ * adds an icap_class to the global IcapConfig
+ */
+static void
+icap_class_add(icap_class * c)
+{
+    icap_class *cp = NULL;
+    icap_class **t = NULL;
+    IcapConfig *cfg = &Config.icapcfg;
+    if (c) {
+	for (cp = cfg->class_head, t = &cfg->class_head; cp; t = &cp->next, cp = cp->next);
+	*t = c;
+    }
+}
+
+/*
+ * free allocated memory inside icap_class
+ */
+static void
+icap_class_destroy(icap_class * c)
+{
+    xfree(c->name);
+    wordlistDestroy(&c->services);
+    icap_service_list_destroy(c->isl);
+}
+
+/***************************************************
+ * icap_access
+ */
+
+/* format: icap_access <servicename> {allow|deny} acl, ... */
+static void
+parse_icap_access_type(IcapConfig * cfg)
+{
+    icap_access *A = NULL;
+    icap_access *B = NULL;
+    icap_access **T = NULL;
+    icap_service *s = NULL;
+    icap_class *c = NULL;
+    ushort no_class = 0;
+
+    A = memAllocate(MEM_ICAP_ACCESS);
+    parse_string(&A->service_name);
+
+    /* 
+     * try to find a class with the given name first. if not found, search 
+     * the services. if a service is found, create a new hidden class with 
+     * only this service. this is for backward compatibility.
+     *
+     * the special classname All is allowed only in deny rules, because
+     * the class is not used there.
+     */
+    if (!strcmp(A->service_name, "None")) {
+	no_class = 1;
+    } else {
+	A->class = icap_class_lookup(A->service_name);
+	if (!A->class) {
+	    s = icap_service_lookup(A->service_name);
+	    if (s) {
+		c = memAllocate(MEM_ICAP_CLASS);
+		c->name = xstrdup("(hidden)");
+		c->hidden = 1;
+		wordlistAdd(&c->services, A->service_name);
+		c->isl = memAllocate(MEM_ICAP_SERVICE_LIST);
+		c->isl->service = s;
+		icap_class_add(c);
+		A->class = c;
+	    } else {
+		debug(3, 0) ("parse_icap_access_type (line %d): servicename %s not found. skipping.\n", config_lineno, A->service_name);
+		memFree(A, MEM_ICAP_ACCESS);
+		return;
+	    }
+	}
+    }
+
+    aclParseAccessLine(&(A->access));
+    debug(3, 5) ("parse_icap_access_type (line %d): %s\n", config_lineno, A->service_name);
+
+    /* check that All class is only used in deny rule */
+    if (no_class && A->access->allow) {
+	memFree(A, MEM_ICAP_ACCESS);
+	debug(3, 0) ("parse_icap_access (line %d): special class 'None' only allowed in deny rule. skipping.\n", config_lineno);
+	return;
+    }
+    if (A->access) {
+	for (B = cfg->access_head, T = &cfg->access_head; B; T = &B->next, B = B->next);
+	*T = A;
+    } else {
+	debug(3, 0) ("parse_icap_access_type (line %d): invalid line skipped\n", config_lineno);
+	memFree(A, MEM_ICAP_ACCESS);
+    }
+}
+
+static void
+dump_icap_access_type(StoreEntry * e, const char *name, IcapConfig cfg)
+{
+    icap_access *current_node = NULL;
+    LOCAL_ARRAY(char, nom, 64);
+
+    if (!cfg.access_head) {
+	storeAppendPrintf(e, "%s 0\n", name);
+	return;
+    }
+    current_node = cfg.access_head;
+
+    while (current_node) {
+	snprintf(nom, 64, "%s %s", name, current_node->service_name);
+	dump_acl_access(e, nom, current_node->access);
+	current_node = current_node->next;
+    }
+}
+
+static void
+free_icap_access_type(IcapConfig * cfg)
+{
+    while (cfg->access_head) {
+	icap_access *current_node = cfg->access_head;
+	cfg->access_head = current_node->next;
+	icap_access_destroy(current_node);
+	memFree(current_node, MEM_ICAP_ACCESS);
+    }
+}
+
+/*
+ * destructor
+ * frees everything but the linked list
+ */
+static void
+icap_access_destroy(icap_access * a)
+{
+    xfree(a->service_name);
+    aclDestroyAccessList(&a->access);
+}
+
+/***************************************************
+ * for debugging purposes only
+ */
+void
+dump_icap_config(IcapConfig * cfg)
+{
+    icap_service *s_iter;
+    icap_class *c_iter;
+    icap_access *a_iter;
+    icap_service_list *isl_iter;
+    acl_list *l;
+    debug(3, 0) ("IcapConfig: onoff        = %d\n", cfg->onoff);
+    debug(3, 0) ("IcapConfig: service_head = %d\n", (int) cfg->service_head);
+    debug(3, 0) ("IcapConfig: class_head   = %d\n", (int) cfg->class_head);
+    debug(3, 0) ("IcapConfig: access_head  = %d\n", (int) cfg->access_head);
+
+    debug(3, 0) ("IcapConfig: services =\n");
+    for (s_iter = cfg->service_head; s_iter; s_iter = s_iter->next) {
+	printf("  %s: \n", s_iter->name);
+	printf("    bypass   = %d\n", s_iter->bypass);
+	printf("    hostname = %s\n", s_iter->hostname);
+	printf("    port     = %d\n", s_iter->port);
+	printf("    resource = %s\n", s_iter->resource);
+    }
+    debug(3, 0) ("IcapConfig: classes =\n");
+    for (c_iter = cfg->class_head; c_iter; c_iter = c_iter->next) {
+	printf("  %s: \n", c_iter->name);
+	printf("    services = \n");
+	for (isl_iter = c_iter->isl; isl_iter; isl_iter = isl_iter->next) {
+	    printf("      %s\n", isl_iter->service->name);
+	}
+    }
+    debug(3, 0) ("IcapConfig: access =\n");
+    for (a_iter = cfg->access_head; a_iter; a_iter = a_iter->next) {
+	printf("  service_name  = %s\n", a_iter->service_name);
+	printf("    access        = %s", a_iter->access->allow ? "allow" : "deny");
+	for (l = a_iter->access->acl_list; l != NULL; l = l->next) {
+	    printf(" %s%s",
+		l->op ? null_string : "!",
+		l->acl->name);
+	}
+	printf("\n");
+    }
+}
+#endif /* HS_FEAT_ICAP */
 
 static void
 parse_kb_size_t(size_t * var)
Index: src/cbdata.c
--- src/cbdata.c.orig	2003-07-16 09:18:43 +0200
+++ src/cbdata.c	2004-09-13 13:23:52 +0200
@@ -144,6 +144,10 @@
     CREATE_CBDATA(statefulhelper);
     CREATE_CBDATA(helper_stateful_server);
     CREATE_CBDATA(HttpStateData);
+#ifdef HS_FEAT_ICAP
+    CREATE_CBDATA(IcapStateData);
+    CREATE_CBDATA(icap_service);
+#endif
     CREATE_CBDATA_FREE(peer, peerDestroy);
     CREATE_CBDATA(ps_state);
     CREATE_CBDATA(RemovalPolicy);
Index: src/cf.data.pre
--- src/cf.data.pre.orig	2004-04-30 22:40:39 +0200
+++ src/cf.data.pre	2004-09-13 13:23:52 +0200
@@ -2605,6 +2605,160 @@
 DOC_END
 
 COMMENT_START
+ ICAP OPTIONS
+ -----------------------------------------------------------------------------
+COMMENT_END
+
+NAME: icap_enable
+TYPE: onoff
+IFDEF: HS_FEAT_ICAP
+COMMENT: on|off
+LOC: Config.icapcfg.onoff
+DEFAULT: off
+DOC_START
+	If you want to enable the ICAP client module, set this to on.
+DOC_END
+
+NAME: icap_preview_enable
+TYPE: onoff
+IFDEF: HS_FEAT_ICAP
+COMMENT: on|off
+LOC: Config.icapcfg.preview_enable
+DEFAULT: off
+DOC_START
+	Set this to 'on' if you want to enable the ICAP preview
+	feature in Squid.
+DOC_END
+
+NAME: icap_preview_size
+TYPE: int
+IFDEF: HS_FEAT_ICAP
+LOC: Config.icapcfg.preview_size
+DEFAULT: -1
+DOC_START
+	The default size of preview data to be sent to the ICAP server.
+	-1 means no preview. This value might be overwritten on a per server
+	basis by OPTIONS requests.
+DOC_END
+
+NAME: icap_check_interval
+TYPE: int
+IFDEF: HS_FEAT_ICAP
+LOC: Config.icapcfg.check_interval
+DEFAULT: 300
+DOC_START
+        If an ICAP server does not respond, it gets marked as unreachable. Squid
+	will try again to reach it after this time.
+DOC_END
+
+NAME: icap_send_client_ip
+TYPE: onoff
+IFDEF: HS_FEAT_ICAP
+COMMENT: on|off
+LOC: Config.icapcfg.send_client_ip
+DEFAULT: off
+DOC_START
+	This adds the header "X-Client-IP" to ICAP requests.
+DOC_END
+
+NAME: icap_send_auth_user
+TYPE: onoff
+IFDEF: HS_FEAT_ICAP
+COMMENT: on|off
+LOC: Config.icapcfg.send_auth_user
+DEFAULT: off
+DOC_START
+	This adds the header "X-Authenticated-User" to ICAP requests 
+	if proxy access is authentified.
+DOC_END
+
+NAME: icap_auth_scheme
+TYPE: string
+IFDEF: HS_FEAT_ICAP
+LOC: Config.icapcfg.auth_scheme
+DEFAULT: Local://%u
+DOC_START
+	Authentification scheme to pass to ICAP requests if
+	icap_send_auth_user is enabled. The first occurence of "%u"
+	is replaced by the authentified user name. If no "%u" is found,
+	the username is added at the end of the scheme.
+	
+	See http://www.ietf.org/internet-drafts/draft-stecher-icap-subid-00.txt,
+	section 3.4 for details on this.
+
+	Examples:
+
+	icap_auth_scheme Local://%u
+	icap_auth_scheme LDAP://ldap-server/cn=%u,dc=company,dc=com
+	icap_auth_scheme WinNT://nt-domain/%u
+	icap_auth_scheme Radius://radius-server/%u
+DOC_END
+
+NAME: icap_service
+TYPE: icap_service_type
+IFDEF: HS_FEAT_ICAP
+LOC: Config.icapcfg
+DEFAULT: none
+DOC_START
+	Defines a single ICAP service
+
+	icap_service servicename vectoring_point bypass service_url
+
+	vectoring_point = reqmod_precache|reqmod_postcache|respmod_precache|respmod_postcache
+		This specifies at which point of request processing the ICAP
+		service should be plugged in.
+	bypass = 1|0   
+		If set to 1 and the ICAP server cannot be reached, the request will go 
+		through without being processed by an ICAP server
+	service_url = icap://servername:port/service
+
+	Note: reqmod_precache and respmod_postcache is not yet implemented
+
+Example:
+icap_service service_1 reqmod_precache 0 icap://icap1.mydomain.net:1344/reqmod
+icap_service service_2 respmod_precache 0 icap://icap2.mydomain.net:1344/respmod
+DOC_END
+
+NAME: icap_class
+TYPE: icap_class_type
+IFDEF: HS_FEAT_ICAP
+LOC: Config.icapcfg
+DEFAULT: none
+DOC_START
+	Defines an ICAP service chain. If there are multiple services per 
+	vectoring point, they are processed in the specified order.
+
+	icap_class classname servicename...
+
+Example:
+icap_class class_1 service_1 service_2
+icap class class_2 service_1 service_3
+DOC_END
+
+NAME: icap_access
+TYPE: icap_access_type
+IFDEF: HS_FEAT_ICAP
+LOC: Config.icapcfg
+DEFAULT: none
+DOC_START
+	Redirects a request through an ICAP service class, depending
+	on given acls
+
+	icap_access classname allow|deny [!]aclname...
+
+	The icap_access statements are processed in the order they appear in
+	this configuration file. If an access list matches, the processing stops. 
+	For an "allow" rule, the specified class is used for the request. A "deny" 
+	rule simply stops processing without using the class. You can also use the 
+	special classname "None". 
+	
+	For backward compatibility, it is also possible to use services 
+	directly here.
+Example:
+icap_access class_1 allow all
+DOC_END
+
+COMMENT_START
  MISCELLANEOUS
  -----------------------------------------------------------------------------
 COMMENT_END
Index: src/cf_gen_defines
--- src/cf_gen_defines.orig	2001-12-03 09:01:53 +0100
+++ src/cf_gen_defines	2004-09-13 13:23:52 +0200
@@ -1,37 +1,38 @@
-#!/usr/bin/awk -f 
+#!/usr/bin/awk -f
 BEGIN {
-	print "/* Generated automatically from cf.data.pre"
+    print "/* Generated automatically from cf.data.pre"
 	print " * DO NOT EDIT"
 	print "*/"
 	print "struct { const char *name; const char *enable; int defined;} defines[] = {"
-	define["DELAY_POOLS"]="--enable-delay-pools"
-	define["HTTP_VIOLATIONS"]="--enable-http-violations"
-	define["SQUID_SNMP"]="--enable-snmp"
-	define["USE_CACHE_DIGESTS"]="--enable-cache-digests"
-	define["USE_DNSSERVERS"]="--disable-internal-dns"
-	define["!USE_DNSSERVERS"]="--enable-internal-dns"
-	define["USE_HTCP"]="--enable-htcp"
-	define["USE_ICMP"]="--enable-icmp"
-	define["USE_IDENT"]="--enable-ident-lookups"
-	define["USE_REFERER_LOG"]="--enable-referer-log"
-	define["USE_SSL"]="--enable-ssl"
-	define["USE_UNLINKD"]="--enable-unlinkd"
-	define["USE_USERAGENT_LOG"]="--enable-useragent-log"
-	define["USE_WCCP"]="--enable-wccp"
+	define["DELAY_POOLS"] = "--enable-delay-pools"
+	define["HTTP_VIOLATIONS"] = "--enable-http-violations"
+	define["SQUID_SNMP"] = "--enable-snmp"
+	define["USE_CACHE_DIGESTS"] = "--enable-cache-digests"
+	define["USE_DNSSERVERS"] = "--disable-internal-dns"
+	define["!USE_DNSSERVERS"] = "--enable-internal-dns"
+	define["USE_HTCP"] = "--enable-htcp"
+	define["USE_ICMP"] = "--enable-icmp"
+	define["USE_IDENT"] = "--enable-ident-lookups"
+	define["USE_REFERER_LOG"] = "--enable-referer-log"
+	define["USE_SSL"] = "--enable-ssl"
+	define["USE_UNLINKD"] = "--enable-unlinkd"
+	define["USE_USERAGENT_LOG"] = "--enable-useragent-log"
+	define["USE_WCCP"] = "--enable-wccp"
+	define["HS_FEAT_ICAP"] = "--enable-icap-support"
 }
 /^IFDEF:/ {
-	if (define[$2] != "")
-	    DEFINE=define[$2]
-	else  
-	    DEFINE="-D" $2
-	print "{\"" $2 "\", \"" DEFINE "\", "
-	print "#if " $2
-	print "1"
-	print "#else"
-	print "0"
-	print "#endif"
-	print "},"
-}
-END {
+    if (define[$2] != "")
+	DEFINE = define[$2]
+	    else
+	DEFINE = "-D" $2
+	    print "{\"" $2 "\", \"" DEFINE "\", "
+	    print "#if " $2
+	    print "1"
+	    print "#else"
+	    print "0"
+	    print "#endif"
+	    print "},"
+	}
+	END {
 	print "{(void *)0L, 0}};"
-}
+	}
Index: src/client_side.c
--- src/client_side.c.orig	2004-06-01 00:57:09 +0200
+++ src/client_side.c	2004-09-13 13:23:52 +0200
@@ -90,7 +90,7 @@
 static CWCB clientWriteComplete;
 static CWCB clientWriteBodyComplete;
 static PF clientReadRequest;
-static PF connStateFree;
+PF connStateFree;
 static PF requestTimeout;
 static PF clientLifetimeTimeout;
 static int clientCheckTransferDone(clientHttpRequest *);
@@ -117,18 +117,21 @@
 static void clientPackRangeHdr(const HttpReply * rep, const HttpHdrRangeSpec * spec, String boundary, MemBuf * mb);
 static void clientPackTermBound(String boundary, MemBuf * mb);
 static void clientInterpretRequestHeaders(clientHttpRequest *);
-static void clientProcessRequest(clientHttpRequest *);
+void clientProcessRequest(clientHttpRequest *);
 static void clientProcessExpired(void *data);
 static void clientProcessOnlyIfCachedMiss(clientHttpRequest * http);
-static int clientCachable(clientHttpRequest * http);
-static int clientHierarchical(clientHttpRequest * http);
-static int clientCheckContentLength(request_t * r);
+int clientCachable(clientHttpRequest * http);
+int clientHierarchical(clientHttpRequest * http);
+int clientCheckContentLength(request_t * r);
 static DEFER httpAcceptDefer;
 static log_type clientProcessRequest2(clientHttpRequest * http);
 static int clientReplyBodyTooLarge(clientHttpRequest *, ssize_t clen);
 static int clientRequestBodyTooLarge(int clen);
 static void clientProcessBody(ConnStateData * conn);
 static void clientEatRequestBody(clientHttpRequest *);
+#if HS_FEAT_ICAP
+static int clientIcapReqMod(clientHttpRequest * http);
+#endif
 
 static int
 checkAccelOnly(clientHttpRequest * http)
@@ -370,6 +373,10 @@
 	http->request = requestLink(new_request);
     }
     clientInterpretRequestHeaders(http);
+#if HS_FEAT_ICAP
+    if (Config.icapcfg.onoff)
+	icapCheckAcl(http);
+#endif
 #if HEADERS_LOG
     headersLog(0, 1, request->method, request);
 #endif
@@ -902,11 +909,19 @@
     *H = http->next;
     http->next = NULL;
     dlinkDelete(&http->active, &ClientActiveRequests);
+#if HS_FEAT_ICAP
+    if (NULL != http->icap_reqmod) {
+	if (cbdataValid(http->icap_reqmod))
+	    if (http->icap_reqmod->icap_fd > -1)
+		comm_close(http->icap_reqmod->icap_fd);
+	cbdataUnlock(http->icap_reqmod);
+    }
+#endif
     cbdataFree(http);
 }
 
 /* This is a handler normally called by comm_close() */
-static void
+void
 connStateFree(int fd, void *data)
 {
     ConnStateData *connState = data;
@@ -1075,7 +1090,7 @@
     }
 }
 
-static int
+int
 clientCheckContentLength(request_t * r)
 {
     switch (r->method) {
@@ -1094,7 +1109,7 @@
     /* NOT REACHED */
 }
 
-static int
+int
 clientCachable(clientHttpRequest * http)
 {
     request_t *req = http->request;
@@ -1120,7 +1135,7 @@
 }
 
 /* Return true if we can query our neighbors for this object */
-static int
+int
 clientHierarchical(clientHttpRequest * http)
 {
     const char *url = http->uri;
@@ -2395,7 +2410,7 @@
     return LOG_TCP_HIT;
 }
 
-static void
+void
 clientProcessRequest(clientHttpRequest * http)
 {
     char *url = http->uri;
@@ -2405,6 +2420,11 @@
     debug(33, 4) ("clientProcessRequest: %s '%s'\n",
 	RequestMethodStr[r->method],
 	url);
+#if HS_FEAT_ICAP
+    if (clientIcapReqMod(http)) {
+	return;
+    }
+#endif
     if (r->method == METHOD_CONNECT) {
 	http->log_type = LOG_TCP_MISS;
 	sslStart(http, &http->out.size, &http->al.http.code);
@@ -3048,6 +3068,7 @@
 			http->uri, prefix);
 		/* continue anyway? */
 	    }
+
 	    request->flags.accelerated = http->flags.accel;
 	    if (!http->flags.internal) {
 		if (internalCheck(strBuf(request->urlpath))) {
@@ -3104,6 +3125,8 @@
 	    if (request->content_length > 0) {
 		conn->body.size_left = request->content_length;
 		request->body_connection = conn;
+		request->body_reader = clientReadBody;
+		request->body_reader_data = request;
 		/* Is it too large? */
 		if (clientRequestBodyTooLarge(request->content_length)) {
 		    err = errorCon(ERR_TOO_BIG, HTTP_REQUEST_ENTITY_TOO_LARGE);
@@ -3160,8 +3183,9 @@
 
 /* file_read like function, for reading body content */
 void
-clientReadBody(request_t * request, char *buf, size_t size, CBCB * callback, void *cbdata)
+clientReadBody(void *data, char *buf, size_t size, CBCB * callback, void *cbdata)
 {
+    request_t *request = data;
     ConnStateData *conn = request->body_connection;
     if (!conn) {
 	debug(33, 5) ("clientReadBody: no body to read, request=%p\n", request);
@@ -3429,6 +3453,7 @@
 	commSetSelect(fd, COMM_SELECT_READ, clientReadRequest, connState, 0);
 	commSetDefer(fd, clientReadDefer, connState);
 	clientdbEstablished(peer.sin_addr, 1);
+	/* fix this later */
 	assert(N);
 	(*N)++;
     }
@@ -3830,3 +3855,48 @@
 	}
     }
 }
+
+#if HS_FEAT_ICAP
+static int
+clientIcapReqMod(clientHttpRequest * http)
+{
+    ErrorState *err;
+    if (http->flags.did_icap_reqmod)
+	return 0;
+    if (NULL == icapService(ICAP_SERVICE_REQMOD_PRECACHE, http->request))
+	return 0;
+    debug(33, 3) ("clientIcapReqMod: calling icapReqModStart for %p\n", http);
+    /*
+     * Note, we pass 'start' and 'log_addr' to ICAP so the access.log
+     * entry comes out right.  The 'clientHttpRequest' created by
+     * the ICAP side is the one that gets logged.  The first
+     * 'clientHttpRequest' does not get logged because its out.size
+     * is zero and log_type is unset.
+     */
+    http->icap_reqmod = icapReqModStart(ICAP_SERVICE_REQMOD_PRECACHE,
+	http->uri,
+	http->request,
+	http->conn->fd,
+	http->start,
+	http->conn->log_addr,
+	(void *) http->conn);
+    if (NULL == http->icap_reqmod) {
+	return 0;
+    } else if (-1 == (int) http->icap_reqmod) {
+	/* produce error */
+	http->icap_reqmod = NULL;
+	debug(33, 2) ("clientIcapReqMod: icap told us to send an error\n");
+	http->log_type = LOG_TCP_DENIED;
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	err->xerrno = ETIMEDOUT;
+	err->request = requestLink(http->request);
+	err->src_addr = http->conn->peer.sin_addr;
+	http->entry = clientCreateStoreEntry(http, http->request->method, null_request_flags);
+	errorAppendEntry(http->entry, err);
+	return 1;
+    }
+    cbdataLock(http->icap_reqmod);
+    http->flags.did_icap_reqmod = 1;
+    return 1;
+}
+#endif
Index: src/comm.c
--- src/comm.c.orig	2003-11-29 19:52:59 +0100
+++ src/comm.c	2004-09-13 13:23:52 +0200
@@ -271,6 +271,7 @@
     cs->data = data;
     cbdataLock(cs->data);
     comm_add_close_handler(fd, commConnectFree, cs);
+    xstrncpy(fd_table[fd].pconn_name, host, SQUIDHOSTNAMELEN);
     ipcache_nbgethostbyname(host, commConnectDnsHandle, cs);
 }
 
Index: src/defines.h
--- src/defines.h.orig	2002-08-08 22:17:39 +0200
+++ src/defines.h	2004-09-13 13:23:52 +0200
@@ -1,4 +1,6 @@
 
+
+
 /*
  * $Id: defines.h,v 1.97.2.3 2002/08/08 20:17:39 hno Exp $
  *
Index: src/enums.h
--- src/enums.h.orig	2004-02-04 18:42:28 +0100
+++ src/enums.h	2004-09-13 13:23:52 +0200
@@ -93,6 +93,7 @@
     ERR_ONLY_IF_CACHED_MISS,	/* failure to satisfy only-if-cached request */
     ERR_TOO_BIG,
     TCP_RESET,
+    ERR_ICAP_FAILURE,
     ERR_MAX
 } err_type;
 
@@ -431,6 +432,9 @@
     PROTO_WHOIS,
     PROTO_INTERNAL,
     PROTO_HTTPS,
+#if HS_FEAT_ICAP
+    PROTO_ICAP,
+#endif
     PROTO_MAX
 } protocol_t;
 
@@ -602,6 +606,12 @@
     MEM_TLV,
     MEM_SWAP_LOG_DATA,
     MEM_CLIENT_REQ_BUF,
+#if HS_FEAT_ICAP
+    MEM_ICAP_OPT_DATA,
+    MEM_ICAP_SERVICE_LIST,
+    MEM_ICAP_CLASS,
+    MEM_ICAP_ACCESS,
+#endif
     MEM_MAX
 } mem_type;
 
@@ -699,9 +709,14 @@
     CBDATA_RemovalPolicyWalker,
     CBDATA_RemovalPurgeWalker,
     CBDATA_store_client,
+#ifdef HS_FEAT_ICAP
+    CBDATA_IcapStateData,
+    CBDATA_icap_service,
+#endif
     CBDATA_FIRST_CUSTOM_TYPE = 1000
 } cbdata_type;
 
+
 /*
  * Return codes from checkVary(request)
  */
@@ -731,4 +746,68 @@
 
 #endif
 
+#if HS_FEAT_ICAP
+typedef enum {
+    ICAP_STATUS_NONE = 0,
+    ICAP_STATUS_CONTINUE = 100,
+    ICAP_STATUS_SWITCHING_PROTOCOLS = 101,
+    ICAP_STATUS_STATUS_OK = 200,
+    ICAP_CREATED = 201,
+    ICAP_STATUS_ACCEPTED = 202,
+    ICAP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203,
+    ICAP_STATUS_NO_MODIFICATION_NEEDED = 204,
+    ICAP_STATUS_RESET_CONTENT = 205,
+    ICAP_STATUS_PARTIAL_CONTENT = 206,
+    ICAP_STATUS_MULTIPLE_CHOICES = 300,
+    ICAP_STATUS_MOVED_PERMANENTLY = 301,
+    ICAP_STATUS_MOVED_TEMPORARILY = 302,
+    ICAP_STATUS_SEE_OTHER = 303,
+    ICAP_STATUS_NOT_MODIFIED = 304,
+    ICAP_STATUS_USE_PROXY = 305,
+    ICAP_STATUS_BAD_REQUEST = 400,
+    ICAP_STATUS_UNAUTHORIZED = 401,
+    ICAP_STATUS_PAYMENT_REQUIRED = 402,
+    ICAP_STATUS_FORBIDDEN = 403,
+    ICAP_STATUS_SERVICE_NOT_FOUND = 404,
+    ICAP_STATUS_METHOD_NOT_ALLOWED = 405,
+    ICAP_STATUS_NOT_ACCEPTABLE = 406,
+    ICAP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
+    ICAP_STATUS_REQUEST_TIMEOUT = 408,
+    ICAP_STATUS_CONFLICT = 409,
+    ICAP_STATUS_GONE = 410,
+    ICAP_STATUS_LENGTH_REQUIRED = 411,
+    ICAP_STATUS_PRECONDITION_FAILED = 412,
+    ICAP_STATUS_REQUEST_ENTITY_TOO_LARGE = 413,
+    ICAP_STATUS_REQUEST_URI_TOO_LARGE = 414,
+    ICAP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
+    ICAP_STATUS_INTERNAL_SERVER_ERROR = 500,
+    ICAP_STATUS_NOT_IMPLEMENTED = 501,
+    ICAP_STATUS_BAD_GATEWAY = 502,
+    ICAP_STATUS_SERVICE_OVERLOADED = 503,
+    ICAP_STATUS_GATEWAY_TIMEOUT = 504,
+    ICAP_STATUS_ICAP_VERSION_NOT_SUPPORTED = 505,
+    ICAP_STATUS_INVALID_HEADER = 600
+} icap_status;
+
+/*
+ * these values are used as index in an array, so it seems to be better to 
+ * assign some numbers
+ */
+typedef enum {
+    ICAP_SERVICE_REQMOD_PRECACHE = 0,
+    ICAP_SERVICE_REQMOD_POSTCACHE = 1,
+    ICAP_SERVICE_RESPMOD_PRECACHE = 2,
+    ICAP_SERVICE_RESPMOD_POSTCACHE = 3,
+    ICAP_SERVICE_MAX = 4
+} icap_service_t;
+
+typedef enum {
+    ICAP_METHOD_NONE,
+    ICAP_METHOD_OPTION,
+    ICAP_METHOD_REQMOD,
+    ICAP_METHOD_RESPMOD
+} icap_method_t;
+
+#endif /* HS_FEAT_ICAP */
+
 #endif /* SQUID_ENUMS_H */
Index: src/forward.c
--- src/forward.c.orig	2004-02-18 14:44:55 +0100
+++ src/forward.c	2004-09-13 13:23:52 +0200
@@ -41,7 +41,7 @@
 static void fwdConnectStart(void *);	/* should be same as EVH */
 static void fwdStateFree(FwdState * fwdState);
 static PF fwdConnectTimeout;
-static PF fwdServerClosed;
+PF fwdServerClosed;
 static PF fwdPeerClosed;
 static CNCB fwdConnectDone;
 static int fwdCheckRetry(FwdState * fwdState);
@@ -173,7 +173,7 @@
     return 1;
 }
 
-static void
+void
 fwdServerClosed(int fd, void *data)
 {
     FwdState *fwdState = data;
@@ -701,6 +701,8 @@
 void
 fwdFail(FwdState * fwdState, ErrorState * errorState)
 {
+    if (NULL == fwdState)
+	return;
     assert(EBIT_TEST(fwdState->entry->flags, ENTRY_FWD_HDR_WAIT));
     debug(17, 3) ("fwdFail: %s \"%s\"\n\t%s\n",
 	err_type_str[errorState->type],
@@ -738,6 +740,8 @@
 void
 fwdUnregister(int fd, FwdState * fwdState)
 {
+    if (NULL == fwdState)
+	return;
     debug(17, 3) ("fwdUnregister: %s\n", storeUrl(fwdState->entry));
     assert(fd == fwdState->server_fd);
     assert(fd > -1);
@@ -754,7 +758,10 @@
 void
 fwdComplete(FwdState * fwdState)
 {
-    StoreEntry *e = fwdState->entry;
+    StoreEntry *e;
+    if (NULL == fwdState)
+	return;
+    e = fwdState->entry;
     assert(e->store_status == STORE_PENDING);
     debug(17, 3) ("fwdComplete: %s\n\tstatus %d\n", storeUrl(e),
 	e->mem_obj->reply->sline.status);
Index: src/globals.h
--- src/globals.h.orig	2003-01-14 00:01:13 +0100
+++ src/globals.h	2004-09-13 13:23:52 +0200
@@ -166,5 +166,8 @@
 #if HAVE_SBRK
 extern void *sbrk_start;	/* 0 */
 #endif
+#if HS_FEAT_ICAP
+extern char *icap_service_type_str[];
+#endif
 
 #endif /* SQUID_GLOBALS_H */
Index: src/http.c
--- src/http.c.orig	2004-06-08 12:54:07 +0200
+++ src/http.c	2004-09-13 13:23:52 +0200
@@ -47,7 +47,7 @@
 
 static PF httpReadReply;
 static void httpSendRequest(HttpStateData *);
-static PF httpStateFree;
+PF httpStateFree;
 static PF httpTimeout;
 static void httpCacheNegatively(StoreEntry *);
 static void httpMakePrivate(StoreEntry *);
@@ -55,15 +55,17 @@
 static int httpCachableReply(HttpStateData *);
 static void httpMaybeRemovePublic(StoreEntry *, http_status);
 
-static void
+void
 httpStateFree(int fd, void *data)
 {
     HttpStateData *httpState = data;
 #if DELAY_POOLS
-    delayClearNoDelay(fd);
+    if (fd >= 0)
+	delayClearNoDelay(fd);
 #endif
     if (httpState == NULL)
 	return;
+    debug(11, 3) ("httpStateFree: FD %d, httpState = %p\n", fd, data);
     if (httpState->body_buf) {
 	if (httpState->orig_request->body_connection) {
 	    clientAbortBody(httpState->orig_request);
@@ -82,6 +84,9 @@
     requestUnlink(httpState->orig_request);
     httpState->request = NULL;
     httpState->orig_request = NULL;
+#if HS_FEAT_ICAP
+    cbdataUnlock(httpState->icap_writer);
+#endif
     cbdataFree(httpState);
 }
 
@@ -506,19 +511,19 @@
 }
 
 static int
-httpPconnTransferDone(HttpStateData * httpState)
+httpPconnTransferDone(int fd, HttpStateData * httpState)
 {
     /* return 1 if we got the last of the data on a persistent connection */
     MemObject *mem = httpState->entry->mem_obj;
     HttpReply *reply = mem->reply;
     int clen;
-    debug(11, 3) ("httpPconnTransferDone: FD %d\n", httpState->fd);
+    off_t content_bytes_read;
+
+    debug(11, 3) ("httpPconnTransferDone: FD %d\n", fd);
     /*
      * If we didn't send a keep-alive request header, then this
      * can not be a persistent connection.
      */
-    if (!httpState->flags.keepalive)
-	return 0;
     /*
      * What does the reply have to say about keep-alive?
      */
@@ -531,24 +536,45 @@
      * and an error status code, and we might have to wait until
      * the server times out the socket.
      */
+
+    debug(11, 3) ("httpPconnTransferDone: reply->keep_alive=%d\n", reply->keep_alive);
     if (!reply->keep_alive)
 	return 0;
     debug(11, 5) ("httpPconnTransferDone: content_length=%d\n",
 	reply->content_length);
     /* If we haven't seen the end of reply headers, we are not done */
-    if (httpState->reply_hdr_state < 2)
+    if (httpState->reply_hdr_state < 2) {
+	debug(11, 3) ("httpPconnTransferDone: reply_hdr_state=%d, returning 0\n",
+	    httpState->reply_hdr_state);
 	return 0;
+    }
     clen = httpReplyBodySize(httpState->request->method, reply);
     /* If there is no message body, we can be persistent */
-    if (0 == clen)
+    if (0 == clen) {
+	debug(11, 3) ("httpPconnTransferDone: no content returning 1\n");
 	return 1;
+    }
     /* If the body size is unknown we must wait for EOF */
-    if (clen < 0)
+    if (clen < 0) {
+	debug(11, 3) ("httpPconnTransferDone: body size unknown, wait for EOF, returning 0\n");
 	return 0;
+    }
+    content_bytes_read = mem->inmem_hi;
+#ifdef HS_FEAT_ICAP
+    if (httpState->icap_writer) {
+	content_bytes_read = httpState->icap_writer->fake_content_length;
+	debug(11, 3) ("using fake conten length %d\n", (int) content_bytes_read);
+    }
+#endif
     /* If the body size is known, we must wait until we've gotten all of it.  */
-    if (mem->inmem_hi < reply->content_length + reply->hdr_sz)
+    if (content_bytes_read < reply->content_length + reply->hdr_sz) {
+	debug(11, 3) ("httpPconnTransferDone: content_bytes_read=%d, returning 0\n",
+	    (int) content_bytes_read);
 	return 0;
+    }
     /* We got it all */
+    debug(11, 3) ("httpPconnTransferDone: FD %d we got it all %d %d %d\n",
+	httpState->fd, (int) content_bytes_read, reply->content_length, reply->hdr_sz);
     return 1;
 }
 
@@ -575,6 +601,7 @@
     else
 	delay_id = delayMostBytesAllowed(entry->mem_obj);
 #endif
+    debug(11, 5) ("httpReadReply: FD %d: httpState %p.\n", fd, data);
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
 	comm_close(fd);
 	return;
@@ -585,6 +612,33 @@
 #if DELAY_POOLS
     read_sz = delayBytesWanted(delay_id, 1, read_sz);
 #endif
+#if HS_FEAT_ICAP
+    if (httpState->icap_writer) {
+       IcapStateData * icap = httpState->icap_writer;
+       /*
+	* Ok we have a received a response from the web server, so try to 
+	* connect the icap server if it's the first attemps. If we try
+	* to connect to the icap server, defer this request (do not read
+	* the buffer), and defer until icapConnectOver() is not called.
+	*/
+       if (icap->flags.connect_requested == 0) {
+	  debug(81, 2) ("icapSendRespMod: Create a new connection to icap server\n");
+	  if (!icapConnect(icap, icapConnectOver))
+	   {
+	     debug(81, 2) ("icapSendRespMod: Something strange while creating a socket to icap server\n");
+	     commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0);
+	     return;
+	   }
+	  debug(81, 2) ("icapSendRespMod: new connection to icap server (using FD=%d)\n",icap->icap_fd);
+	  icap->flags.connect_requested = 1;
+	  /* Wait for more data or EOF condition */
+	  commSetTimeout(fd, httpState->flags.keepalive_broken?10:Config.Timeout.read, NULL, NULL);
+	  commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0);
+	  return;
+       }
+    }
+#endif
+
     statCounter.syscalls.sock.reads++;
     len = FD_READ_METHOD(fd, buf, read_sz);
     debug(11, 5) ("httpReadReply: FD %d: len %d.\n", fd, len);
@@ -600,6 +654,12 @@
 	    clen >>= 1;
 	IOStats.Http.read_hist[bin]++;
     }
+#ifdef HS_FEAT_ICAP
+    if (httpState->icap_writer)
+	(void) 0;
+    else
+#endif
+
     if (!httpState->reply_hdr && len > 0 && fd_table[fd].uses > 1) {
 	/* Skip whitespace */
 	while (len > 0 && xisspace(*buf))
@@ -626,6 +686,14 @@
 	} else {
 	    comm_close(fd);
 	}
+#ifdef HS_FEAT_ICAP
+    } else if (len == 0 && httpState->icap_writer) {
+	debug(81, 3) ("httpReadReply: EOF for ICAP writer\n");
+	if (cbdataValid(httpState->icap_writer))
+	    icapSendRespMod(httpState->icap_writer, buf, len, 1);
+	httpState->eof = 1;
+	comm_close(fd);
+#endif
     } else if (len == 0 && entry->mem_obj->inmem_hi == 0) {
 	ErrorState *err;
 	err = errorCon(ERR_ZERO_SIZE_OBJECT, HTTP_SERVICE_UNAVAILABLE);
@@ -648,6 +716,27 @@
 	fwdComplete(httpState->fwd);
 	comm_close(fd);
     } else {
+
+#ifdef HS_FEAT_ICAP
+	if (httpState->icap_writer) {
+	    /*
+	     * We need to parse this HTTP reply here, at least to
+	     * get the connection: keep-alive status
+	     */
+	    if (httpState->reply_hdr_state < 2)
+		httpProcessReplyHeader(httpState, buf, len);
+	    /*
+	     * this is where we give data coming from an origin
+	     * server to a "respmod" service
+	     */
+	    debug(11, 5) ("calling icapSendRespMod from %s:%d\n", __FILE__, __LINE__);
+	    if (cbdataValid(httpState->icap_writer)) {
+		icapSendRespMod(httpState->icap_writer, buf, len, 0);
+		httpState->icap_writer->fake_content_length += len;
+	    }
+	} else
+#endif
+
 	if (httpState->reply_hdr_state < 2) {
 	    httpProcessReplyHeader(httpState, buf, len);
 	    if (httpState->reply_hdr_state == 2) {
@@ -663,7 +752,17 @@
 		    EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
 	    }
 	}
-	storeAppend(entry, buf, len);
+#ifdef HS_FEAT_ICAP
+	if (httpState->icap_writer)
+	    (void) 0;
+	else
+#endif
+	if (fd == httpState->fd)
+	    storeAppend(entry, buf, len);
+
+
+	debug(11, 5) ("httpReadReply: after storeAppend FD %d read %d\n", fd, len);
+
 	if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
 	    /*
 	     * the above storeAppend() call could ABORT this entry,
@@ -671,7 +770,7 @@
 	     * there's nothing for us to do.
 	     */
 	    (void) 0;
-	} else if (httpPconnTransferDone(httpState)) {
+	} else if (httpPconnTransferDone(fd, httpState)) {
 	    /* yes we have to clear all these! */
 	    commSetDefer(fd, NULL, NULL);
 	    commSetTimeout(fd, -1, NULL, NULL);
@@ -679,9 +778,13 @@
 #if DELAY_POOLS
 	    delayClearNoDelay(fd);
 #endif
+#ifdef HS_FEAT_ICAP
+	    if (httpState->icap_writer)
+		icapSendRespMod(httpState->icap_writer, NULL, 0, 1);
+#endif
 	    comm_remove_close_handler(fd, httpStateFree, httpState);
 	    fwdUnregister(fd, httpState->fwd);
-	    pconnPush(fd, request->host, request->port);
+	    pconnPush(fd, fd_table[fd].pconn_name, fd_table[fd].remote_port);
 	    fwdComplete(httpState->fwd);
 	    httpState->fd = -1;
 	    httpStateFree(fd, httpState);
@@ -697,6 +800,34 @@
     }
 }
 
+#ifdef HS_FEAT_ICAP
+int
+httpReadReplyWaitForIcap(int fd, void *data)
+{
+    HttpStateData *httpState = data;
+    if (NULL == httpState->icap_writer)
+	return 0;
+    /* 
+     * Do not defer when we are not connected to the icap server.
+     * Defer when the icap server connection is not established but pending
+     * Defer when the icap server is busy (writing on the socket)
+     */
+    debug(11, 5) ("httpReadReplyWaitForIcap: FD %d, connect_requested=%d\n",
+	fd, httpState->icap_writer->flags.connect_requested);
+    if (!httpState->icap_writer->flags.connect_requested)
+      return 0;
+    debug(11, 5) ("httpReadReplyWaitForIcap: FD %d, connect_pending=%d\n",
+	fd, httpState->icap_writer->flags.connect_pending);
+    if (httpState->icap_writer->flags.connect_pending)
+	return 1;
+    debug(11, 5) ("httpReadReplyWaitForIcap: FD %d, write_pending=%d\n",
+	fd, httpState->icap_writer->flags.write_pending);
+    if (httpState->icap_writer->flags.write_pending)
+	return 1;
+    return 0;
+}
+#endif
+
 /* This will be called when request write is complete. Schedule read of
  * reply. */
 static void
@@ -727,6 +858,62 @@
 	comm_close(fd);
 	return;
     } else {
+	/* Schedule read reply. */
+#ifdef HS_FEAT_ICAP
+	if (icapService(ICAP_SERVICE_RESPMOD_PRECACHE, httpState->orig_request)) {
+	    httpState->icap_writer = icapRespModStart(
+		ICAP_SERVICE_RESPMOD_PRECACHE,
+		httpState->orig_request, httpState->entry, httpState->flags);
+	    if (-1 == (int) httpState->icap_writer) {
+		/* TODO: send error here and exit */
+		httpState->icap_writer = 0;
+		err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+		err->xerrno = errno;
+		err->request = requestLink(httpState->orig_request);
+		errorAppendEntry(entry, err);
+		comm_close(fd);
+		return;
+	    } else if (httpState->icap_writer) {
+		request_flags fake_flags = httpState->orig_request->flags;
+		method_t fake_method = entry->mem_obj->method;
+		const char *fake_msg = "this is a fake entry for "
+		" response sent to an ICAP RESPMOD server";
+		cbdataLock(httpState->icap_writer);
+		/*
+		 * this httpState will give the data it reads to
+		 * the icap server, rather than put it into
+		 * a StoreEntry
+		 */
+		storeUnlockObject(httpState->entry);
+		storeUnregisterAbort(httpState->entry);
+		/*
+		 * create a bogus entry because the code assumes one is
+		 * always there.
+		 */
+		fake_flags.cachable = 0;
+		fake_flags.hierarchical = 0;	/* force private key */
+		httpState->entry = storeCreateEntry("fake", "fake", fake_flags, fake_method);
+		storeAppend(httpState->entry, fake_msg, strlen(fake_msg));
+		/*
+		 * pull a switcheroo on fwdState->entry.
+		 */
+		storeUnlockObject(httpState->fwd->entry);
+		httpState->fwd->entry = httpState->entry;
+		storeLockObject(httpState->fwd->entry);
+		/*
+		 * Note that we leave fwdState connected to httpState,
+		 * but we changed the entry.  So when fwdComplete
+		 * or whatever is called it does no harm -- its
+		 * just the fake entry.
+		 */
+	    } else {
+		/*
+		 * failed to open connection to ICAP server. 
+		 * But bypass request, so just continue here.
+		 */
+	    }
+	}
+#endif
 	/*
 	 * Set the read timeout here because it hasn't been set yet.
 	 * We only set the read timeout after the request has been
@@ -735,8 +922,18 @@
 	 * the timeout for POST/PUT requests that have very large
 	 * request bodies.
 	 */
+
+	/* removed in stable5:
+	 * commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0);
+	 */
 	commSetTimeout(fd, Config.Timeout.read, httpTimeout, httpState);
-	commSetDefer(fd, fwdCheckDeferRead, entry);
+#ifdef HS_FEAT_ICAP
+	if (httpState->icap_writer) {
+	    debug(11, 5) ("FD %d, setting httpReadReplyWaitForIcap\n", httpState->fd);
+	    commSetDefer(httpState->fd, httpReadReplyWaitForIcap, httpState);
+	} else
+#endif
+	commSetDefer(httpState->fd, fwdCheckDeferRead, entry);
     }
 }
 
@@ -933,8 +1130,11 @@
 	if (!EBIT_TEST(cc->mask, CC_MAX_AGE)) {
 	    const char *url = entry ? storeUrl(entry) : urlCanonical(orig_request);
 	    httpHdrCcSetMaxAge(cc, getMaxAge(url));
+#ifndef HS_FEAT_ICAP
+	    /* Don;t bother - if  the url you want to cache is redirected? */
 	    if (strLen(request->urlpath))
 		assert(strstr(url, strBuf(request->urlpath)));
+#endif
 	}
 	/* Set no-cache if determined needed but not found */
 	if (orig_request->flags.nocache && !httpHeaderHas(hdr_in, HDR_PRAGMA))
@@ -1002,7 +1202,7 @@
     commSetTimeout(fd, Config.Timeout.lifetime, httpTimeout, httpState);
     commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0);
 
-    if (httpState->orig_request->body_connection)
+    if (httpState->orig_request->body_reader)
 	sendHeaderDone = httpSendRequestEntry;
     else
 	sendHeaderDone = httpSendComplete;
@@ -1042,6 +1242,7 @@
     int fd = fwd->server_fd;
     HttpStateData *httpState;
     request_t *proxy_req;
+    /* ErrorState *err; */
     request_t *orig_req = fwd->request;
     debug(11, 3) ("httpStart: \"%s %s\"\n",
 	RequestMethodStr[orig_req->method],
@@ -1079,12 +1280,22 @@
 	httpState->request = requestLink(orig_req);
 	httpState->orig_request = requestLink(orig_req);
     }
+#ifdef HS_FEAT_ICAP
+    if (icapService(ICAP_SERVICE_REQMOD_POSTCACHE, httpState->orig_request)) {
+	httpState->icap_writer = icapRespModStart(ICAP_SERVICE_REQMOD_POSTCACHE,
+	    httpState->orig_request, httpState->entry, httpState->flags);
+	if (httpState->icap_writer) {
+	    return;
+	}
+    }
+#endif
     /*
      * register the handler to free HTTP state data when the FD closes
      */
     comm_add_close_handler(fd, httpStateFree, httpState);
     statCounter.server.all.requests++;
     statCounter.server.http.requests++;
+
     httpSendRequest(httpState);
     /*
      * We used to set the read timeout here, but not any more.
@@ -1188,7 +1399,9 @@
 	return;
     }
     httpState->body_buf = memAllocate(MEM_8K_BUF);
-    clientReadBody(httpState->orig_request, httpState->body_buf, 8192, httpRequestBodyHandler, httpState);
+    httpState->orig_request->body_reader(
+	httpState->orig_request->body_reader_data,
+	httpState->body_buf, 8192, httpRequestBodyHandler, httpState);
 }
 
 void
Index: src/icap_common.c
--- src/icap_common.c.orig	2004-09-13 13:23:52 +0200
+++ src/icap_common.c	2004-09-13 13:23:52 +0200
@@ -0,0 +1,702 @@
+/*
+ * $Id: squid-icap-2_5-s2_5,v 1.1 2004/08/17 20:55:12 hno Exp $
+ *
+ * DEBUG: section 81    Internet Content Adaptation Protocol (ICAP) Client
+ * AUTHOR: Geetha Manjunath, Hewlett Packard Company
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  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 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+
+extern PF httpStateFree;
+
+#define EXPECTED_ICAP_HEADER_LEN 256
+#define ICAP_OPTIONS_REQUEST
+
+
+void
+icapInit()
+{
+#ifdef ICAP_OPTIONS_REQUEST
+    if (Config.icapcfg.onoff) {
+	icapOptInit();
+    }
+#endif
+}
+
+void
+icapClose()
+{
+    icapOptShutdown();
+}
+
+/*
+ * search for a HTTP-like header in the buffer. 
+ * Note, buf must be 0-terminated
+ *
+ * This function is not very good.  It should probably look for
+ * header tokens only at the start of a line, not just anywhere in
+ * the buffer.
+ */
+int
+icapFindHeader(const char *buf, const char *hdr, const char **Start, const char **End)
+{
+    const char *start = NULL;
+    const char *end = NULL;
+    start = strcasestr(buf, hdr);
+    if (NULL == start)
+	return 0;
+    end = start + strcspn(start, "\r\n");
+    if (start == end)
+	return 0;
+    *Start = start;
+    *End = end;
+    return 1;
+}
+
+/* 
+ * parse the contents of the encapsulated header (buffer between enc_start
+ * and enc_end) and put the result into IcapStateData
+ */
+void
+icapParseEncapsulated(IcapStateData * icap, const char *enc_start,
+    const char *enc_end)
+{
+    char *current, *end;
+
+    assert(icap);
+    assert(enc_start);
+    assert(enc_end);
+
+    current = strchr(enc_start, ':');
+    current++;
+    while (current < enc_end) {
+	while (isspace(*current))
+	    current++;
+	if (!strncmp(current, "res-hdr=", 8)) {
+	    current += 8;
+	    icap->enc.res_hdr = strtol(current, &end, 10);
+	} else if (!strncmp(current, "req-hdr=", 8)) {
+	    current += 8;
+	    icap->enc.req_hdr = strtol(current, &end, 10);
+	} else if (!strncmp(current, "null-body=", 10)) {
+	    current += 10;
+	    icap->enc.null_body = strtol(current, &end, 10);
+	} else if (!strncmp(current, "res-body=", 9)) {
+	    current += 9;
+	    icap->enc.res_body = strtol(current, &end, 10);
+	} else if (!strncmp(current, "req-body=", 9)) {
+	    current += 9;
+	    icap->enc.req_body = strtol(current, &end, 10);
+	} else if (!strncmp(current, "opt-body=", 9)) {
+	    current += 9;
+	    icap->enc.opt_body = strtol(current, &end, 10);
+	} else {
+	    /* invalid header */
+	    debug(81, 5) ("icapParseEncapsulated: error in: %s\n", current);
+	    return;
+	}
+	current = end;
+	current = strchr(current, ',');
+	if (current == NULL)
+	    break;
+	else
+	    current++;		/* skip ',' */
+    }
+    debug(81, 3) ("icapParseEncapsulated: res-hdr=%d, req-hdr=%d, null-body=%d, "
+	"res-body=%d, req-body=%d, opt-body=%d\n",
+	icap->enc.res_hdr, icap->enc.req_hdr, icap->enc.null_body,
+	icap->enc.res_body, icap->enc.req_body, icap->enc.opt_body);
+
+}
+
+icap_service *
+icapService(icap_service_t type, request_t * r)
+{
+    icap_service_list *isl_iter;
+    debug(81, 8) ("icapService: type=%s\n", icapServiceToStr(type));
+    if (NULL == r) {
+	debug(81, 8) ("icapService: no request_t\n");
+	return NULL;
+    }
+    if (NULL == r->class) {
+	debug(81, 8) ("icapService: no class\n");
+	return NULL;
+    }
+    for (isl_iter = r->class->isl; isl_iter; isl_iter = isl_iter->next) {
+	if (type == isl_iter->service->type) {
+	    debug(81, 8) ("icapService: found service %s\n", isl_iter->service->name);
+	    return isl_iter->service;
+	}
+    }
+    debug(81, 8) ("icapService: no service found\n");
+    return NULL;
+}
+
+int
+icapConnect(IcapStateData * icap, CNCB * theCallback)
+{
+    int rc;
+    icap->icap_fd = pconnPop(icap->current_service->hostname,
+	icap->current_service->port);
+    if (icap->icap_fd >= 0) {
+	debug(81, 3) ("icapConnect: reused pconn FD %d\n", icap->icap_fd);
+	fd_note(icap->icap_fd, icap->current_service->uri);
+	comm_add_close_handler(icap->icap_fd, icapStateFree, icap);
+	theCallback(icap->icap_fd, 0, icap);
+	return 1;
+    }
+    icap->icap_fd = comm_open(SOCK_STREAM, 0, getOutgoingAddr(NULL), 0,
+	COMM_NONBLOCKING, icap->current_service->uri);
+    debug(81, 5) ("icapConnect: new socket, FD %d, local address %s\n",
+	icap->icap_fd, inet_ntoa(getOutgoingAddr(NULL)));
+    if (icap->icap_fd < 0) {
+	icapStateFree(-1, icap);	/* XXX test */
+	return 0;
+    }
+    icap->flags.connect_pending = 1;
+    /*
+     * Configure timeout and close handler before calling
+     * connect because commConnectStart() might get an error
+     * immediately and close the descriptor before it returns.
+     */
+    commSetTimeout(icap->icap_fd, Config.Timeout.connect,
+	icapConnectTimeout, icap);
+    comm_add_close_handler(icap->icap_fd, icapStateFree, icap);
+    /*
+     * This sucks.  commConnectStart() may fail before returning,
+     * so lets lock the data and check its validity afterwards.
+     */
+    cbdataLock(icap);
+    commConnectStart(icap->icap_fd,
+	icap->current_service->hostname,
+	icap->current_service->port,
+	theCallback,
+	icap);
+    rc = cbdataValid(icap);
+    cbdataUnlock(icap);
+    debug(81, 3) ("icapConnect: returning %d\n", rc);
+    return rc;
+}
+
+IcapStateData *
+icapAllocate(void)
+{
+    IcapStateData *icap;
+
+    if (!Config.icapcfg.onoff)
+	return 0;
+
+    icap = cbdataAlloc(IcapStateData);
+    icap->icap_fd = -1;
+    icap->enc.res_hdr = -1;
+    icap->enc.res_body = -1;
+    icap->enc.req_hdr = -1;
+    icap->enc.req_body = -1;
+    icap->enc.opt_body = -1;
+    icap->enc.null_body = -1;
+    icap->chunk_size = -1;
+    memBufDefInit(&icap->icap_hdr);
+
+    debug(81, 3) ("New ICAP state\n");
+    return icap;
+}
+
+void
+icapStateFree(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    debug(81, 3) ("icapStateFree: FD %d, icap %p\n", fd, icap);
+    assert(icap);
+    assert(-1 == fd || fd == icap->icap_fd);
+    if (icap->respmod.entry) {
+	/*
+	 * If we got some error on this side (like ECONNRESET)
+	 * we must signal the other side(s) with a storeAbort()
+	 * call.
+	 */
+	if (icap->respmod.entry->store_status != STORE_OK)
+	    storeAbort(icap->respmod.entry);
+	storeUnlockObject(icap->respmod.entry);
+	icap->respmod.entry = NULL;
+    }
+    requestUnlink(icap->request);
+    icap->request = NULL;
+    if (!memBufIsNull(&icap->icap_hdr))
+	memBufClean(&icap->icap_hdr);
+    if (!memBufIsNull(&icap->respmod.buffer))
+	memBufClean(&icap->respmod.buffer);
+    if (!memBufIsNull(&icap->respmod.req_hdr_copy))
+	memBufClean(&icap->respmod.req_hdr_copy);
+    if (!memBufIsNull(&icap->respmod.resp_copy))
+	memBufClean(&icap->respmod.resp_copy);
+    if (!memBufIsNull(&icap->reqmod.hdr_buf))
+	memBufClean(&icap->reqmod.hdr_buf);
+    if (!memBufIsNull(&icap->reqmod.http_entity.buf))
+	memBufClean(&icap->reqmod.http_entity.buf);
+    if (!memBufIsNull(&icap->chunk_buf))
+	memBufClean(&icap->chunk_buf);
+    if (icap->httpState)
+	httpStateFree(-1, icap->httpState);
+    cbdataUnlock(icap->reqmod.client_cookie);
+    cbdataFree(icap);
+}
+
+void
+icapConnectTimeout(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    debug(81, 3) ("icapConnectTimeout: FD %d, unreachable=1\n", fd);
+    assert(fd == icap->icap_fd);
+    icapOptSetUnreachable(icap->current_service);
+    comm_close(fd);
+}
+
+void
+icapReadTimeout(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    debug(81, 3) ("icapReadTimeout: FD %d, unreachable=1\n", fd);
+    assert(fd == icap->icap_fd);
+    icapOptSetUnreachable(icap->current_service);
+    comm_close(fd);
+}
+
+icap_service_t
+icapServiceToType(const char *s)
+{
+    if (!strcmp(s, "reqmod_precache"))
+	return ICAP_SERVICE_REQMOD_PRECACHE;
+    if (!strcmp(s, "reqmod_postcache"))
+	return ICAP_SERVICE_REQMOD_POSTCACHE;
+    if (!strcmp(s, "respmod_precache"))
+	return ICAP_SERVICE_RESPMOD_PRECACHE;
+    if (!strcmp(s, "respmod_postcache"))
+	return ICAP_SERVICE_RESPMOD_POSTCACHE;
+    return ICAP_SERVICE_MAX;
+}
+
+const char *
+icapServiceToStr(const icap_service_t type)
+{
+    if (type >= 0 && type < ICAP_SERVICE_MAX)
+	return icap_service_type_str[type];
+    else
+	return "error";
+}
+
+
+/* copied from clientAclChecklistCreate */
+static aclCheck_t *
+icapAclChecklistCreate(const acl_access * acl, const clientHttpRequest * http)
+{
+    aclCheck_t *ch;
+    ConnStateData *conn = http->conn;
+    ch = aclChecklistCreate(acl,
+	http->request,
+	0);
+    ch->conn = conn;
+    cbdataLock(ch->conn);
+    return ch;
+}
+
+/*
+ * check wether we do icap for a request
+ */
+int
+icapCheckAcl(clientHttpRequest * http)
+{
+    icap_access *iter;
+    aclCheck_t *icapChecklist;
+
+    for (iter = Config.icapcfg.access_head; iter; iter = iter->next) {
+	acl_access *A = iter->access;
+	icapChecklist = icapAclChecklistCreate(A, http);
+	if (aclMatchAclList(A->acl_list, icapChecklist)) {
+	    debug(81, 5) ("icapCheckAcl: match for class=%s\n",
+		iter->class->name);
+	    if (A->allow) {
+		/* allow rule, do icap and use associated class */
+		http->request->class = iter->class;
+		aclChecklistFree(icapChecklist);
+		return 1;
+	    } else {
+		/* deny rule, stop processing */
+		aclChecklistFree(icapChecklist);
+		return 0;
+	    }
+	}
+	aclChecklistFree(icapChecklist);
+    }
+    return 0;
+}
+
+/* icapLineLength
+ *
+ * returns the amount of data until lineending ( \r\n )
+ * This function is NOT tolerant of variations of \r\n.
+ */
+size_t
+icapLineLength(const char *start, int len)
+{
+    size_t lineLen = 0;
+    char *end = (char *) memchr(start, '\r', len);
+    if (NULL == end)
+	return 0;
+    end++;			/* advance to where '\n' should be */
+    lineLen = end - start + 1;
+    if (lineLen > len) {
+	debug(0, 0) ("icapLineLength: warning lineLen (%d) > len (%d)\n",
+	    lineLen, len);
+	return 0;
+    }
+    if (*end != '\n') {
+	debug(0, 0) ("icapLineLength: warning *end (%x) != '\\n'\n", *end);
+	return 0;
+    }
+    debug(81, 7) ("icapLineLength: returning %d\n", lineLen);
+    return lineLen;
+}
+
+/*
+ * return:
+ *   -1 if EOF before getting end of ICAP header
+ *    0 if we don't have the entire ICAP header yet
+ *    1 if we got the whole header
+ */
+int
+icapReadHeader(int fd, IcapStateData * icap, int *isIcap)
+{
+    int headlen = 0;
+    int len = 0;
+    int peek_sz = EXPECTED_ICAP_HEADER_LEN;
+    int read_sz = 0;
+    LOCAL_ARRAY(char, tmpbuf, SQUID_TCP_SO_RCVBUF);
+    for (;;) {
+	len = recv(fd, tmpbuf, peek_sz, MSG_PEEK);
+	debug(81, 5) ("recv(FD %d, ..., MSG_PEEK) ret %d\n", fd, len);
+	if (len < 0) {
+	    debug(81, 1) ("icapReadHeader: FD %d recv error: %s\n", fd, xstrerror());
+	    return -1;
+	}
+	if (len == 0) {
+	    debug(81, 1) ("icapReadHeader: FD %d recv EOF\n", fd);
+	    return -1;
+	}
+	headlen = headersEnd(tmpbuf, len);
+	debug(81, 3) ("headlen=%d\n", headlen);
+	/*
+	 * break if we now know where the ICAP headers end
+	 */
+	if (headlen)
+	    break;
+	/*
+	 * break if we know there is no more data to read
+	 */
+	if (len < peek_sz)
+	    break;
+	/*
+	 * The ICAP header is larger than (or equal to) our read
+	 * buffer, so double it and try to peek again.
+	 */
+	peek_sz *= 2;
+	if (peek_sz >= SQUID_TCP_SO_RCVBUF) {
+	    debug(81, 1) ("icapReadHeader: Failed to find end of ICAP header\n");
+	    debug(81, 1) ("\twithin first %d bytes of response\n", SQUID_TCP_SO_RCVBUF);
+	    debug(81, 1) ("\tpossible persistent connection bug/confusion\n");
+	    return -1;
+	}
+    }
+    /*
+     * Now actually read the data from the kernel
+     */
+    if (headlen)
+	read_sz = headlen;
+    else
+	read_sz = len;
+    len = FD_READ_METHOD(fd, tmpbuf, read_sz);
+    assert(len == read_sz);
+    fd_bytes(fd, len, FD_READ);
+    memBufAppend(&icap->icap_hdr, tmpbuf, len);
+    if (headlen) {
+	/* End of ICAP header found */
+	if (icap->icap_hdr.size < 4)
+	    *isIcap = 0;
+	else if (0 == strncmp(icap->icap_hdr.buf, "ICAP", 4))
+	    *isIcap = 1;
+	else
+	    *isIcap = 0;
+	return 1;
+    }
+    /*
+     * We don't have all the headers yet
+     */
+    return 0;
+}
+
+static int
+icapParseConnectionClose(const IcapStateData * icap, const char *s, const char *e)
+{
+    char *t;
+    char *q;
+    /*
+     * s points to the start of the line "Connection: ... "
+     * e points to *after* the last character on the line
+     */
+    s += 11;	/* skip past Connection: */
+    while (s < e && isspace(*s))
+	s++;
+    if (e - s < 5)
+	return 0;
+    /*
+     * create a buffer that we can use strtok on
+     */
+    t = xmalloc(e-s+1);
+    strncpy(t, s, e-s);
+    *(t+(e-s)) = '\0';
+    for (q = strtok(t, ","); q; q = strtok(NULL, ",")) {
+        if (0 == strcasecmp(q, "close"))
+	    return 1;
+    }
+    return 0;
+}
+
+void
+icapSetKeepAlive(IcapStateData * icap, const char *hdrs)
+{
+    const char *start;
+    const char *end;
+    if (0 == icap->flags.keep_alive)
+	return;
+    if (0 == icapFindHeader(hdrs, "Connection:", &start, &end)) {
+	icap->flags.keep_alive = 1;
+	return;
+    }
+    if (icapParseConnectionClose(icap, start, end))
+	icap->flags.keep_alive = 0;
+    else
+	icap->flags.keep_alive = 1;
+}
+
+/*
+ * icapParseChunkSize
+ *
+ * Returns the offset where the next chunk starts
+ * return parameter chunk_size;
+ */
+static int
+icapParseChunkSize(const char *buf, int len, int *chunk_size)
+{
+    int chunkSize = 0;
+    char c;
+    size_t start;
+    size_t end;
+    size_t nextStart = 0;
+    debug(81, 3) ("icapParseChunkSize: buf=%p, len=%d\n", buf, len);
+    do {
+	start = nextStart;
+	debug(81, 3) ("icapParseChunkSize: start=%d\n", start);
+	if (len <= start) {
+	    /*
+	     * end of buffer, so far no lines or only empty lines,
+	     * wait for more data. read chunk size with next buffer.
+	     */
+	    *chunk_size = 0;
+	    return 0;
+	}
+	end = start + icapLineLength(buf + start, len - start);
+	nextStart = end;
+	if (end <= start) {
+	    /*
+	     * no line found, need more code here, now we are in
+	     * deep trouble, buffer stops with half a chunk size
+	     * line. For now stop here.
+	     */
+	    debug(81, 1) ("icapParseChunkSize: WARNING in mid-line, ret 0\n");
+	    *chunk_size = 0;
+	    return 0;
+	}
+	while (start < end) {
+	    if (NULL == strchr(w_space, buf[start]))
+		break;
+	    start++;
+	}
+	while (start < end) {
+	    if (NULL == strchr(w_space, buf[end - 1]))
+		break;
+	    end--;
+	}
+	/*
+	 * if now end <= start we got an empty line. The previous
+	 * chunk data should stop with a CRLF. In case that the
+	 * other end does not follow the specs and sends no CRLF
+	 * or too many empty lines, just continue till we have a
+	 * non-empty line.
+	 */
+    } while (end <= start);
+    debug(81, 3) ("icapParseChunkSize: start=%d, end=%d\n", start, end);
+
+    /* Non-empty line: Parse the chunk size */
+    while (start < end) {
+	c = buf[start++];
+	if (c >= 'a' && c <= 'f') {
+	    chunkSize = chunkSize * 16 + c - 'a' + 10;
+	} else if (c >= 'A' && c <= 'F') {
+	    chunkSize = chunkSize * 16 + c - 'A' + 10;
+	} else if (c >= '0' && c <= '9') {
+	    chunkSize = chunkSize * 16 + c - '0';
+	} else {
+	    if (!(c == ';' || c == ' ' || c == '\t')) {
+		/*Syntax error: Chunksize expected. */
+		*chunk_size = -2;	/* we are done */
+		return nextStart;
+	    }
+	    /* Next comes a chunk extension */
+	    break;
+	}
+    }
+    /*
+     * if we read a zero chunk, we reached the end. Mark this for
+     * icapPconnTransferDone
+     */
+    *chunk_size = (chunkSize > 0) ? chunkSize : -2;
+    debug(81, 3) ("icapParseChunkSize: return nextStart=%d\n", nextStart);
+    return nextStart;
+}
+
+/*
+ * icapParseChunkedBody
+ *
+ * De-chunk an HTTP entity received from the ICAP server.
+ * The 'store' function pointer is storeAppend() or memBufAppend().
+ */
+size_t
+icapParseChunkedBody(IcapStateData * icap, STRCB * store, void *store_data)
+{
+    int bufOffset = 0;
+    size_t bw = 0;
+    MemBuf *cb = &icap->chunk_buf;
+    const char *buf = cb->buf;
+    int len = cb->size;
+
+    if (icap->chunk_size == -2) {
+	debug(81, 3) ("zero end chunk reached\n");
+	return 0;
+    }
+    debug(81, 3) ("%s:%d: chunk_size=%d\n", __FILE__, __LINE__,
+	icap->chunk_size);
+    if (icap->chunk_size < 0) {
+	store(store_data, buf, len);
+	cb->size = 0;
+	return (size_t) len;
+    }
+    debug(81, 3) ("%s:%d: bufOffset=%d, len=%d\n", __FILE__, __LINE__,
+	bufOffset, len);
+    while (bufOffset < len) {
+	debug(81, 3) ("%s:%d: bufOffset=%d, len=%d\n", __FILE__, __LINE__,
+	    bufOffset, len);
+	if (icap->chunk_size == 0) {
+	    int x;
+	    x = icapParseChunkSize(buf + bufOffset,
+		len - bufOffset, &icap->chunk_size);
+	    if (x < 1) {
+		/* didn't find a valid chunk spec */
+		break;
+	    }
+	    bufOffset += x;
+	    debug(81, 3) ("got chunksize %d, new offset %d\n",
+		icap->chunk_size, bufOffset);
+	    if (icap->chunk_size == -2) {
+		debug(81, 3) ("zero end chunk reached\n");
+		break;
+	    }
+	}
+	debug(81, 3) ("%s:%d: X\n", __FILE__, __LINE__);
+	if (icap->chunk_size > 0) {
+	    if (icap->chunk_size >= len - bufOffset) {
+		store(store_data, buf + bufOffset, len - bufOffset);
+		bw += (len - bufOffset);
+		icap->chunk_size -= (len - bufOffset);
+		bufOffset = len;
+	    } else {
+		store(store_data, buf + bufOffset, icap->chunk_size);
+		bufOffset += icap->chunk_size;
+		bw += icap->chunk_size;
+		icap->chunk_size = 0;
+	    }
+	}
+    }
+    if (0 == bufOffset) {
+	(void) 0;
+    } else if (bufOffset == cb->size) {
+	cb->size = 0;
+    } else {
+	assert(bufOffset <= cb->size);
+	xmemmove(cb->buf, cb->buf + bufOffset, cb->size - bufOffset);
+	cb->size -= bufOffset;
+    }
+    return bw;
+}
+
+/*
+ *  icapAddAuthUserHeader
+ *
+ *  Builds and adds the X-Authenticated-User header to an ICAP request headers.
+ */
+void
+icapAddAuthUserHeader(MemBuf * mb, auth_user_request_t * auth_user_request)
+{
+    char *user = authenticateUserRequestUsername(auth_user_request);
+    char *authuser;
+    size_t len, userlen, schemelen, userofslen;
+    char *userofs;
+
+    if (user == NULL) {
+	debug(81, 5) ("icapAddAuthUserHeader: NULL username\n");
+	return;
+    }
+    userlen = strlen(user);
+    schemelen = strlen(Config.icapcfg.auth_scheme);
+    len = userlen + schemelen + 1;
+    authuser = xcalloc(len, 1);
+
+    if ((userofs = strstr(Config.icapcfg.auth_scheme, "%u")) == NULL) {
+	/* simply add user at end of string */
+	snprintf(authuser, len, "%s%s", Config.icapcfg.auth_scheme, user);
+    } else {
+	userofslen = userofs - Config.icapcfg.auth_scheme;
+	xmemcpy(authuser, Config.icapcfg.auth_scheme, userofslen);
+	xmemcpy(authuser + userofslen, user, userlen);
+	xmemcpy(authuser + userofslen + userlen,
+	    userofs + 2, schemelen - (userofslen + 2) + 1);
+    }
+
+    memBufPrintf(mb, "X-Authenticated-User: %s\r\n", base64_encode(authuser));
+    xfree(authuser);
+}
Index: src/icap_opt.c
--- src/icap_opt.c.orig	2004-09-13 13:23:52 +0200
+++ src/icap_opt.c	2004-09-13 13:23:52 +0200
@@ -0,0 +1,507 @@
+
+/*
+ * $Id: squid-icap-2_5-s2_5,v 1.1 2004/08/17 20:55:12 hno Exp $
+ * 
+ * DEBUG: section 81    Internet Content Adaptation Protocol (ICAP) Client OPTIONS
+ * AUTHOR: Ralf Horstmann
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  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 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+
+/*************************************************************/
+
+/*
+ * network related functions for OPTIONS request
+ */
+static void icapOptStart(void *data);
+static void icapOptTimeout(int fd, void *data);
+static void icapOptConnectDone(int server_fd, int status, void *data);
+static void icapOptWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *data);
+static void icapOptReadReply(int fd, void *data);
+
+/*
+ * reply parsing functions
+ */
+static int icapOptParseReply(icap_service * s, IcapOptData * i);
+static void icapOptParseEntry(icap_service * s, const char *blk_start, const char *blk_end);
+static int icapIsolateLine(const char **parse_start, const char **blk_start, const char **blk_end);
+
+/*
+ * helper functions
+ */
+static void icapOptDataInit(IcapOptData * i);
+static void icapOptDataFree(IcapOptData * i);
+
+/*************************************************************/
+
+#define TIMEOUT 10
+
+void
+icapOptInit()
+{
+    icap_service *s;
+
+    /* iterate over configured services */
+    s = Config.icapcfg.service_head;
+    while (s) {
+	eventAdd("icapOptStart", icapOptStart, s, 5.0, 1);
+	s = s->next;
+    }
+}
+
+void
+icapOptShutdown()
+{
+    icap_service *s;
+
+    s = Config.icapcfg.service_head;
+    while (s) {
+	if (eventFind(icapOptStart, s)) {
+	    eventDelete(icapOptStart, s);
+	}
+	s = s->next;
+    }
+}
+
+/*
+ * mark a service as unreachable
+ */
+void
+icapOptSetUnreachable(icap_service * s)
+{
+    s->unreachable = 1;
+    debug(81, 5) ("icapOptSetUnreachable: got called for %s\n", s->uri);
+    /*
+     * if there is an options request scheduled, delete it and add
+     * it again to reset the time to the default check_interval.
+     */
+    if (eventFind(icapOptStart, s)) {
+	eventDelete(icapOptStart, s);
+	eventAdd("icapOptStart", icapOptStart, s, Config.icapcfg.check_interval, 1);
+    }
+}
+
+static void
+icapOptStart(void *data)
+{
+    icap_service *s = data;
+    int fd;
+    int ctimeout = TIMEOUT;
+    const char *host = s->hostname;
+    unsigned short port = s->port;
+    debug(81, 3) ("icapOptStart: starting OPTIONS request for %s (%s)\n", s->name, s->uri);
+    fd = comm_open(SOCK_STREAM,
+	0,
+	getOutgoingAddr(NULL),
+	0,
+	COMM_NONBLOCKING,
+	"ICAP OPTIONS connection");
+    if (fd < 0) {
+	debug(81, 4) ("icapConnectStart: %s\n", xstrerror());
+	eventAdd("icapOptStart", icapOptStart, s, Config.icapcfg.check_interval, 1);
+	return;
+    }
+    assert(s->opt == NULL);	/* if not null, another options request might be running, which should not happen */
+    s->opt = memAllocate(MEM_ICAP_OPT_DATA);
+    icapOptDataInit(s->opt);
+    cbdataLock(s);
+    commSetTimeout(fd, ctimeout, icapOptTimeout, s);
+    commConnectStart(fd, host, port, icapOptConnectDone, s);
+}
+
+static void
+icapOptTimeout(int fd, void *data)
+{
+    icap_service *s = data;
+    IcapOptData *i = s->opt;
+    int valid;
+
+    debug(81, 4) ("icapOptConnectTimeout: fd=%d, service=%s\n", fd, s->uri);
+
+    comm_close(fd);
+    valid = cbdataValid(s);
+    cbdataUnlock(s);
+    if (!valid) {
+	icapOptDataFree(i);
+	s->opt = NULL;
+	return;
+    }
+    /* try again later */
+    icapOptDataFree(i);
+    s->opt = NULL;
+    s->unreachable = 1;
+    debug(81, 3) ("icapOptConnectTimeout: unreachable=1, service=%s\n", s->uri);
+    eventAdd("icapOptStart", icapOptStart, s, Config.icapcfg.check_interval, 1);
+
+}
+
+static void
+icapOptConnectDone(int server_fd, int status, void *data)
+{
+    icap_service *s = data;
+    IcapOptData *i = s->opt;
+    MemBuf request;
+    int valid;
+
+    valid = cbdataValid(s);
+    cbdataUnlock(s);
+    if (!valid) {
+	comm_close(server_fd);
+	icapOptDataFree(i);
+	s->opt = NULL;
+	return;
+    }
+    if (status != COMM_OK) {
+	debug(81, 3) ("icapOptConnectDone: unreachable=1, service=%s\n", s->uri);
+	comm_close(server_fd);
+	icapOptDataFree(i);
+	s->opt = NULL;
+	s->unreachable = 1;
+	eventAdd("icapOptStart", icapOptStart, s, Config.icapcfg.check_interval, 1);
+	return;
+    }
+    debug(81, 3) ("icapOptConnectDone: Connection ok. Sending Options request for %s\n", s->name);
+    memBufDefInit(&request);
+    memBufPrintf(&request, "OPTIONS %s ICAP/1.0\r\n", s->uri);
+    memBufPrintf(&request, "Host: %s\r\n", s->hostname);
+    memBufPrintf(&request, "Connection: close\r\n");
+    memBufPrintf(&request, "User-Agent: ICAP-Client-Squid/1.2\r\n");
+    memBufPrintf(&request, "\r\n");
+    cbdataLock(s);
+    commSetTimeout(server_fd, TIMEOUT, icapOptTimeout, s);
+    comm_write_mbuf(server_fd, request, icapOptWriteComplete, s);
+}
+
+static void
+icapOptWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *data)
+{
+    icap_service *s = data;
+    IcapOptData *i = s->opt;
+    int valid;
+
+    valid = cbdataValid(s);
+    cbdataUnlock(s);
+    if (!valid) {
+	comm_close(fd);
+	icapOptDataFree(i);
+	s->opt = NULL;
+	return;
+    }
+    debug(81, 5) ("icapOptWriteComplete: FD %d: size %d: errflag %d.\n",
+	fd, size, errflag);
+    if (size > 0) {
+	fd_bytes(fd, size, FD_WRITE);
+	kb_incr(&statCounter.icap.all.kbytes_out, size);
+    }
+    if (errflag) {
+	/* cancel this for now */
+	debug(81, 3) ("icapOptWriteComplete: unreachable=1, service=%s\n", s->uri);
+	icapOptDataFree(i);
+	s->opt = NULL;
+	s->unreachable = 1;
+	eventAdd("icapOptStart", icapOptStart, s, Config.icapcfg.check_interval, 1);
+	comm_close(fd);
+	return;
+    }
+    cbdataLock(s);
+    commSetSelect(fd, COMM_SELECT_READ, icapOptReadReply, s, 0);
+}
+
+static void
+icapOptReadReply(int fd, void *data)
+{
+    icap_service *s = data;
+    IcapOptData *i = s->opt;
+    int size;
+    int len = i->size - i->offset - 1;
+    int valid;
+
+    valid = cbdataValid(s);
+    cbdataUnlock(s);
+    if (!valid) {
+	comm_close(fd);
+	icapOptDataFree(i);
+	s->opt = NULL;
+	return;
+    }
+    if (len == 0) {
+	/* Grow the request memory area to accomodate for a large request */
+	printf("PANIC: not enough memory\n");
+#if 0
+	i->buf = memReallocBuf(i->buf, i->size * 2, &i->size);
+	debug(81, 2) ("icapoptReadReply: growing reply buffer: offset=%ld size=%ld\n",
+	    (long) i->offset, (long) i->size);
+	len = i->size - i->offset - 1;
+#endif
+    }
+    size = FD_READ_METHOD(fd, i->buf + i->offset, len);
+    i->offset += size;
+    debug(81, 3) ("icapOptReadReply: Got %d bytes of data\n", size);
+    if (size > 0) {
+	/* do some statistics */
+	fd_bytes(fd, size, FD_READ);
+	kb_incr(&statCounter.icap.all.kbytes_in, size);
+
+	/* 
+	 * some icap servers seem to ignore the  "Connection: close" header. so 
+	 * after getting the complete option reply we close the connection 
+	 * ourself.
+	 */
+	if ((i->headlen = headersEnd(i->buf, i->offset))) {
+	    debug(81, 3) ("icapOptReadReply: EndOfResponse\n");
+	    size = 0;
+	}
+    }
+    if (size < 0) {
+	debug(81, 3) ("icapOptReadReply: FD %d: read failure: %s.\n", fd, xstrerror());
+	debug(81, 3) ("icapOptReadReply: unreachable=1, service=%s.\n", s->uri);
+	s->unreachable = 1;
+	icapOptDataFree(i);
+	s->opt = NULL;
+	eventAdd("icapOptStart", icapOptStart, s, Config.icapcfg.check_interval, 1);
+	comm_close(fd);
+    } else if (size == 0) {
+	/* no more data, now we can parse the reply */
+	debug(81, 3) ("icapOptReadReply: FD %d: connection closed\n", fd);
+	i->buf[i->offset] = '\0';	/* for string functions */
+	debug(81, 3) ("icapOptReadReply: unreachable=0, service=%s\n", s->uri);
+	s->unreachable = 0;
+	if (icapOptParseReply(s, i) && s->options_ttl > 0) {
+	    debug(81, 3) ("icapOptReadReply: OPTIONS request successful. scheduling again in %d seconds\n", s->options_ttl);
+	    eventAdd("icapOptStart", icapOptStart, s, s->options_ttl, 1);
+	} else {
+	    /* use a default ttl */
+	    debug(81, 3) ("icapOptReadReply: OPTIONS request not successful. scheduling again in %d seconds\n", Config.icapcfg.check_interval);
+	    eventAdd("icapOptStart", icapOptStart, s, Config.icapcfg.check_interval, 1);
+	}
+	icapOptDataFree(i);
+	s->opt = NULL;
+	comm_close(fd);
+    } else {
+	/* data received */
+	/* commSetSelect(fd, Type, handler, client_data, timeout) */
+	cbdataLock(s);
+	commSetSelect(fd, COMM_SELECT_READ, icapOptReadReply, data, 0);
+    }
+}
+
+static int
+icapIsolateLine(const char **parse_start, const char **blk_start, const char **blk_end)
+{
+    int slen = strcspn(*parse_start, "\r\n");
+
+    if (!(*parse_start)[slen])	/* no crlf */
+	return 0;
+
+    if (slen == 0)		/* empty line */
+	return 0;
+
+    *blk_start = *parse_start;
+    *blk_end = *blk_start + slen;
+
+    /* set it to the beginning of next line */
+    *parse_start = *blk_end;
+    while (**parse_start == '\r')	/* CR */
+	(*parse_start)++;
+    if (**parse_start == '\n')	/* LF */
+	(*parse_start)++;
+    return 1;
+}
+
+/* process a single header entry between blk_start and blk_end */
+static void
+icapOptParseEntry(icap_service * s, const char *blk_start, const char *blk_end)
+{
+    const char *name_end = strchr(blk_start, ':');
+    const int name_len = name_end ? name_end - blk_start : 0;
+    const char *value_start = blk_start + name_len + 1;		/* skip ':' */
+    int value_len;
+    int new;
+
+    if (!name_len || name_end > blk_end) {
+	debug(81, 5) ("icapOptParseEntry: strange header. skipping\n");
+	return;
+    }
+    if (name_len > 65536) {
+	debug(81, 5) ("icapOptParseEntry: unusual long header item. skipping.\n");
+	return;
+    }
+    while (xisspace(*value_start) && value_start < blk_end) {
+	value_start++;
+    }
+    if (value_start >= blk_end) {
+	debug(81, 5) ("icapOptParseEntry: no value found\n");
+	return;
+    }
+    value_len = blk_end - value_start;
+
+
+    /* extract information */
+    if (!strncasecmp("Allow", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Allow\n");
+	if (!strncmp("204", value_start, 3)) {
+	    s->flags.allow_204 = 1;
+	} else {
+	    debug(81, 3) ("icapOptParseEntry: Allow value unknown");
+	}
+    } else if (!strncasecmp("Connection", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Connection\n");
+    } else if (!strncasecmp("Encapsulated", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Encapsulated\n");
+    } else if (!strncasecmp("ISTAG", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found ISTAG\n");
+	stringClean(&s->istag);
+	stringLimitInit(&s->istag, value_start, value_len);
+    } else if (!strncasecmp("Max-Connections", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Max-Connections\n");
+	errno = 0;
+	new = strtol(value_start, NULL, 10);
+	if (errno) {
+	    debug(81, 5) ("icapOptParseEntry: Max-Connections: could not parse value\n");
+	} else {
+	    debug(81, 5) ("icapOptParseEntry: Max-Connections: new value=%d\n", new);
+	    s->max_connections = new;
+	}
+    } else if (!strncasecmp("Methods", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Methods\n");
+    } else if (!strncasecmp("Options-TTL", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Options-TTL\n");
+	errno = 0;
+	new = strtol(value_start, NULL, 10);
+	if (errno) {
+	    debug(81, 5) ("icapOptParseEntry: Options-TTL: could not parse value\n");
+	} else {
+	    debug(81, 5) ("icapOptParseEntry: Options-TTL: new value=%d\n", new);
+	    s->options_ttl = new;
+	}
+    } else if (!strncasecmp("Preview", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Preview\n");
+	errno = 0;
+	new = strtol(value_start, NULL, 10);
+	if (errno) {
+	    debug(81, 5) ("icapOptParseEntry: Preview: could not parse value\n");
+	} else {
+	    debug(81, 5) ("icapOptParseEntry: Preview: new value=%d\n", new);
+	    s->preview = new;
+	}
+    } else if (!strncasecmp("Service", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Service\n");
+    } else if (!strncasecmp("Service-ID", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Service-ID\n");
+    } else if (!strncasecmp("Transfer-Preview", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Transfer-Preview\n");
+	stringClean(&s->transfer_preview);
+	stringLimitInit(&s->transfer_preview, value_start, value_len);
+    } else if (!strncasecmp("Transfer-Ignore", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Transfer-Ignore\n");
+	stringClean(&s->transfer_ignore);
+	stringLimitInit(&s->transfer_ignore, value_start, value_len);
+    } else if (!strncasecmp("Transfer-Complete", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found Transfer-Complete\n");
+	stringClean(&s->transfer_complete);
+	stringLimitInit(&s->transfer_complete, value_start, value_len);
+    } else if (!strncasecmp("X-Include", blk_start, name_len)) {
+	debug(81, 5) ("icapOptParseEntry: found X-Include\n");
+    } else {
+	debug(81, 5) ("icapOptParseEntry: unknown options header\n");
+    }
+}
+
+/* parse OPTIONS reply */
+static int
+icapOptParseReply(icap_service * s, IcapOptData * i)
+{
+    LOCAL_ARRAY(char, tmpbuf, SQUID_TCP_SO_RCVBUF);
+    float ver;
+    int status;
+    const char *buf = i->buf;
+    const char *parse_start;
+    const char *head_end;
+    const char *blk_start;
+    const char *blk_end;
+
+    if (sscanf(buf, "ICAP/%f %d %s\r", &ver, &status, tmpbuf) < 3
+	|| ver <= 0.0) {
+	debug(81, 2) ("icapOptParseReply: bad status line <%s>\n", buf);
+	return 0;
+    }
+    debug(81, 3) ("icapOptParseReply: got reply: <ICAP/%1.1f %d %s>\n", ver, status, tmpbuf);
+
+    if (status != 200) {
+	debug(81, 3) ("icapOptParseReply: status = %d != 200\n", status);
+	return 0;
+    }
+    parse_start = buf;
+    if (i->headlen == 0)
+	i->headlen = headersEnd(parse_start, s->opt->offset);
+
+    if (!i->headlen) {
+	debug(81, 2) ("icapOptParseReply: end of headers could not be found\n");
+	return 0;
+    }
+    head_end = parse_start + i->headlen - 1;
+    while (*(head_end - 1) == '\r')
+	head_end--;
+    assert(*(head_end - 1) == '\n');
+    if (*head_end != '\r' && *head_end != '\n')
+	return 0;		/* failure */
+
+    /* skip status line */
+    if (!icapIsolateLine(&parse_start, &blk_start, &blk_end)) {
+	debug(81, 3) ("icapOptParseReply: failure in isolating status line\n");
+	return 0;
+    }
+    /* now we might start real parsing */
+    while (icapIsolateLine(&parse_start, &blk_start, &blk_end)) {
+	if (blk_end > head_end || blk_start > head_end || blk_start >= blk_end) {
+	    debug(81, 3) ("icapOptParseReply: header limit exceeded. finished.\n");
+	    break;
+	}
+	icapOptParseEntry(s, blk_start, blk_end);
+    }
+    return 1;
+}
+
+static void
+icapOptDataInit(IcapOptData * i)
+{
+    i->buf = memAllocBuf(HTTP_REPLY_BUF_SZ, &i->size);
+    i->offset = 0;
+    i->headlen = 0;
+}
+
+static void
+icapOptDataFree(IcapOptData * i)
+{
+    if (i) {
+	memFreeBuf(i->size, i->buf);
+	memFree(i, MEM_ICAP_OPT_DATA);
+    }
+}
Index: src/icap_reqmod.c
--- src/icap_reqmod.c.orig	2004-09-13 13:23:52 +0200
+++ src/icap_reqmod.c	2004-09-13 13:23:52 +0200
@@ -0,0 +1,874 @@
+
+/*
+ * $Id: squid-icap-2_5-s2_5,v 1.1 2004/08/17 20:55:12 hno Exp $
+ *
+ * DEBUG: section 81    Internet Content Adaptation Protocol (ICAP) Client
+ * AUTHOR: Geetha Manjunath, Hewlett Packard Company
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  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 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+
+/*
+ * These once-static functions are required to be global for ICAP
+ */
+PF clientReadRequest;
+PF connStateFree;
+int clientCheckContentLength(request_t * r);
+void clientProcessRequest(clientHttpRequest *);
+int clientCachable(clientHttpRequest *);
+int clientHierarchical(clientHttpRequest *);
+
+
+static PF icapReqModReadHttpHdrs;
+static PF icapReqModReadHttpBody;
+static CWCB icapReqModSendBodyChunk;
+static CBCB icapReqModBodyHandler;
+static CB icapReqModPassHttpBody;
+static STRCB icapReqModMemBufAppend;
+
+#define EXPECTED_ICAP_HEADER_LEN 256
+static const char *crlf = "\r\n";
+
+/*
+ * icapExpectedHttpReqHdrSize
+ *
+ * calculate the size of the HTTP headers that we expect
+ * to read from the ICAP server.
+ */
+static int
+icapExpectedHttpReqHdrSize(IcapStateData * icap)
+{
+    if (icap->enc.req_body > -1 && icap->enc.req_hdr > -1)
+	return (icap->enc.req_body - icap->enc.req_hdr);
+    if (icap->enc.null_body > -1)
+	return icap->enc.null_body;
+    fatal("icapExpectedHttpReqHdrSize: unexpected case");
+    return 0;
+}
+
+/*
+ * icapReqModCreateClientState
+ *
+ * Creates fake client_side data structures so we can use
+ * that module to read/parse the HTTP request that we read
+ * from the ICAP server.
+ */
+static clientHttpRequest *
+icapReqModCreateClientState(IcapStateData * icap, request_t * request)
+{
+    clientHttpRequest *http;
+    if (!cbdataValid(icap->reqmod.client_cookie)) {
+	debug(81, 3) ("Whups, client cookie invalid\n");
+	icap->reqmod.client_fd = -1;
+	return NULL;
+    }
+    http = cbdataAlloc(clientHttpRequest);
+    /*
+     * use our own urlCanonicalClean here, because urlCanonicalClean
+     * may strip everything after a question-mark. As http->uri
+     * is used when doing a request to a parent proxy, we need the full
+     * url here.
+     */
+    http->uri = xstrdup(urlCanonical(icap->request));
+    http->log_uri = xstrndup(http->uri, MAX_URL);
+    http->range_iter.boundary = StringNull;
+    http->request = requestLink(request ? request : icap->request);
+    http->flags.did_icap_reqmod = 1;
+    http->start = icap->reqmod.start;
+    http->conn = cbdataAlloc(ConnStateData);
+    http->conn->fd = icap->reqmod.client_fd;
+    http->conn->in.size = 0;
+    http->conn->in.buf = NULL;
+    http->conn->log_addr = icap->reqmod.log_addr;
+    http->conn->chr = http;
+    comm_add_close_handler(http->conn->fd, connStateFree, http->conn);
+    return http;
+}
+
+/*
+ * icapReqModInterpretHttpRequest
+ *
+ * Interpret an HTTP request that we read from the ICAP server.
+ * Create some "fake" clientHttpRequest and ConnStateData structures
+ * so we can pass this new request off to the routines in
+ * client_side.c.
+ */
+static void
+icapReqModInterpretHttpRequest(IcapStateData * icap, request_t * request)
+{
+    clientHttpRequest *http = icapReqModCreateClientState(icap, request);
+    if (NULL == http)
+	return;
+    /*
+     * bits from clientReadRequest
+     */
+    request->content_length = httpHeaderGetInt(&request->header,
+	HDR_CONTENT_LENGTH);
+    if (!urlCheckRequest(request) ||
+	httpHeaderHas(&request->header, HDR_TRANSFER_ENCODING)) {
+	ErrorState *err;
+	err = errorCon(ERR_UNSUP_REQ, HTTP_NOT_IMPLEMENTED);
+	err->request = requestLink(request);
+	request->flags.proxy_keepalive = 0;
+	http->entry = clientCreateStoreEntry(http, request->method, null_request_flags);
+	errorAppendEntry(http->entry, err);
+	return;
+    }
+    if (!clientCheckContentLength(request)) {
+	ErrorState *err;
+	err = errorCon(ERR_INVALID_REQ, HTTP_LENGTH_REQUIRED);
+	err->request = requestLink(request);
+	http->entry = clientCreateStoreEntry(http, request->method, null_request_flags);
+	errorAppendEntry(http->entry, err);
+	return;
+    }
+    /* Do we expect a request-body? */
+    if (request->content_length > 0) {
+	debug(81, 5) ("handing request bodies in ICAP REQMOD\n");
+	request->body_reader = icapReqModPassHttpBody;
+	request->body_reader_data = icap;	/* XXX cbdataLock? */
+	memBufDefInit(&icap->reqmod.http_entity.buf);
+    }
+    if (clientCachable(http))
+	request->flags.cachable = 1;
+    if (clientHierarchical(http))
+	request->flags.hierarchical = 1;
+    clientProcessRequest(http);
+}
+
+/*
+ * icapReqModParseHttpError
+ *
+ * Handle an error when parsing the new HTTP request we read
+ * from the ICAP server.
+ */
+static void
+icapReqModParseHttpError(IcapStateData * icap, const char *reason)
+{
+    debug(81, 1) ("icapReqModParseHttpError: %s\n", reason);
+}
+
+/*
+ * icapEntryError
+ *
+ * A wrapper for errorCon() and errorAppendEntry().
+ */
+static void
+icapEntryError(IcapStateData * icap, err_type et, http_status hs, int xerrno)
+{
+    ErrorState *err;
+    clientHttpRequest *http = icapReqModCreateClientState(icap, NULL);
+    if (NULL == http)
+	return;
+    http->entry = clientCreateStoreEntry(http,
+	icap->request->method,
+	null_request_flags);
+    err = errorCon(et, hs);
+    err->xerrno = xerrno;
+    err->request = requestLink(icap->request);
+    errorAppendEntry(http->entry, err);
+}
+
+/*
+ * icapReqModParseHttpRequest
+ * 
+ * Parse the HTTP request that we read from the ICAP server.
+ * Creates and fills in the request_t structure.
+ */
+static void
+icapReqModParseHttpRequest(IcapStateData * icap)
+{
+    char *mstr;
+    char *uri;
+    char *inbuf;
+    char *t;
+    char *token;
+    char *headers;
+    method_t method;
+    request_t *request;
+    http_version_t http_ver;
+    int reqlen = icap->reqmod.hdr_buf.size;
+    int hdrlen;
+
+    /*
+     * Lazy, make a copy of the buf so I can chop it up with strtok()
+     */
+    inbuf = xcalloc(reqlen + 1, 1);
+    memcpy(inbuf, icap->reqmod.hdr_buf.buf, reqlen);
+
+    if ((mstr = strtok(inbuf, "\t ")) == NULL) {
+	debug(81, 1) ("icapReqModParseHttpRequest: Can't get request method\n");
+	icapReqModParseHttpError(icap, "error:invalid-request-method");
+	xfree(inbuf);
+	return;
+    }
+    method = urlParseMethod(mstr);
+    if (method == METHOD_NONE) {
+	debug(81, 1) ("icapReqModParseHttpRequest: Unsupported method '%s'\n", mstr);
+	icapReqModParseHttpError(icap, "error:unsupported-request-method");
+	xfree(inbuf);
+	return;
+    }
+    /* look for URL+HTTP/x.x */
+    if ((uri = strtok(NULL, "\n")) == NULL) {
+	debug(81, 1) ("icapReqModParseHttpRequest: Missing URI\n");
+	icapReqModParseHttpError(icap, "error:missing-url");
+	xfree(inbuf);
+	return;
+    }
+    while (xisspace(*uri))
+	uri++;
+    t = uri + strlen(uri);
+    assert(*t == '\0');
+    token = NULL;
+    while (t > uri) {
+	t--;
+	if (xisspace(*t) && !strncmp(t + 1, "HTTP/", 5)) {
+	    token = t + 1;
+	    break;
+	}
+    }
+    while (t > uri && xisspace(*t))
+	*(t--) = '\0';
+    debug(81, 5) ("icapReqModParseHttpRequest: URI is '%s'\n", uri);
+    if (token == NULL) {
+	debug(81, 3) ("icapReqModParseHttpRequest: Missing HTTP identifier\n");
+	icapReqModParseHttpError(icap, "error:missing-http-ident");
+	xfree(inbuf);
+	return;
+    }
+    if (sscanf(token + 5, "%d.%d", &http_ver.major, &http_ver.minor) != 2) {
+	debug(81, 3) ("icapReqModParseHttpRequest: Invalid HTTP identifier.\n");
+	icapReqModParseHttpError(icap, "error:invalid-http-ident");
+	xfree(inbuf);
+	return;
+    }
+    debug(81, 6) ("icapReqModParseHttpRequest: Client HTTP version %d.%d.\n", http_ver.major, http_ver.minor);
+
+    headers = strtok(NULL, null_string);
+    hdrlen = inbuf + reqlen - headers;
+
+    if ((request = urlParse(method, uri)) == NULL) {
+	debug(81, 3) ("Invalid URL: %s at %s:%d\n", uri, __FILE__, __LINE__);
+	icapEntryError(icap, ERR_INVALID_URL, HTTP_BAD_REQUEST, 0);
+	xfree(inbuf);
+	return;
+    }
+    /* compile headers */
+    if (!httpHeaderParse(&request->header, headers, headers + hdrlen)) {
+	debug(81, 3) ("Failed to parse HTTP headers for: %s at %s:%d",
+	    uri, __FILE__, __LINE__);
+	icapEntryError(icap, ERR_INVALID_REQ, HTTP_BAD_REQUEST, 0);
+	xfree(inbuf);
+	return;
+    }
+    debug(81, 3) ("icapReqModParseHttpRequest: successfully parsed the HTTP request\n");
+    request->http_ver = http_ver;
+    request->client_addr = icap->request->client_addr;
+    request->my_addr = icap->request->my_addr;
+    request->my_port = icap->request->my_port;
+    request->class = icap->request->class;
+    if (icap->request->auth_user_request != NULL) {
+	/* Copy authentification info in new request */
+	request->auth_user_request = icap->request->auth_user_request;
+	authenticateAuthUserRequestLock(request->auth_user_request);
+    }
+    icapReqModInterpretHttpRequest(icap, request);
+    xfree(inbuf);
+}
+
+/*
+ * icapReqModHandoffRespMod
+ *
+ * Handles the case where a REQMOD request results in an HTTP REPLY
+ * (instead of an ICAP REPLY that contains a new HTTP REQUEST).  We
+ * prepare the IcapStateData for passing off to the icap_reqmod
+ * code, where we have functions for reading HTTP replies in ICAP
+ * messages.
+ */
+static void
+icapReqModHandoffRespMod(IcapStateData * icap)
+{
+    extern PF icapReadReply;
+    clientHttpRequest *http = icapReqModCreateClientState(icap, NULL);
+    if (NULL == http)
+	return;
+    assert(icap->request);
+
+    http->entry = clientCreateStoreEntry(http,
+	icap->request->method,
+	icap->request->flags);
+    icap->respmod.entry = http->entry;
+    storeLockObject(icap->respmod.entry);
+
+    /* icap->http_flags = ? */
+    memBufDefInit(&icap->respmod.buffer);
+    memBufDefInit(&icap->chunk_buf);
+    assert(icap->current_service);
+    icapReadReply(icap->icap_fd, icap);
+}
+
+/*
+ * icapReqModKeepAliveOrClose
+ *
+ * Called when we are done reading from the ICAP server.
+ * Either close the connection or keep it open for a future
+ * transaction.
+ */
+static void
+icapReqModKeepAliveOrClose(IcapStateData * icap)
+{
+    int fd = icap->icap_fd;
+    debug(81, 3) ("%s:%d FD %d\n", __FILE__, __LINE__, fd);
+    if (fd < 0)
+	return;
+    if (!icap->flags.keep_alive) {
+	debug(81, 3) ("%s:%d keep_alive not set, closing\n", __FILE__, __LINE__);
+	comm_close(fd);
+	return;
+    }
+    if (icap->request->content_length < 0) {
+	/* no message body */
+	debug(81, 3) ("%s:%d no message body\n", __FILE__, __LINE__);
+	if (1 != icap->reqmod.hdr_state) {
+	    /* didn't get to end of HTTP headers */
+	    debug(81, 3) ("%s:%d didnt find end of headers, closing\n", __FILE__, __LINE__);
+	    comm_close(fd);
+	    return;
+	}
+    } else if (icap->reqmod.http_entity.bytes_read != icap->request->content_length) {
+	debug(81, 3) ("%s:%d bytes_read (%d) != content_length (%d)\n", __FILE__, __LINE__,
+	    icap->reqmod.http_entity.bytes_read,
+	    icap->request->content_length);
+	/* an error */
+	comm_close(fd);
+	return;
+    }
+    debug(81, 3) ("%s:%d looks good, keeping alive\n", __FILE__, __LINE__);
+    commSetDefer(fd, NULL, NULL);
+    commSetTimeout(fd, -1, NULL, NULL);
+    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+    comm_remove_close_handler(fd, icapStateFree, icap);
+    pconnPush(fd, fd_table[fd].pconn_name, fd_table[fd].remote_port);
+    icap->icap_fd = -1;
+    icapStateFree(-1, icap);
+}
+
+/*
+ * icapReqModReadHttpHdrs
+ *
+ * Read the HTTP reply from the ICAP server.  Uses the values
+ * from the ICAP Encapsulation header to know how many bytes
+ * to read.
+ */
+static void
+icapReqModReadHttpHdrs(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    LOCAL_ARRAY(char, tmpbuf, SQUID_TCP_SO_RCVBUF);
+    int rl;
+    debug(81, 3) ("icapReqModReadHttpHdrs:\n");
+    assert(fd == icap->icap_fd);
+    assert(icap->enc.req_hdr == 0);
+    if (0 == icap->reqmod.hdr_state) {
+	int expect = icapExpectedHttpReqHdrSize(icap);
+	int so_far = icap->http_header_bytes_read_so_far;
+	int needed = expect - so_far;
+	debug(81, 3) ("expect=%d\n", expect);
+	debug(81, 3) ("so_far=%d\n", so_far);
+	debug(81, 3) ("needed=%d\n", needed);
+	assert(needed >= 0);
+	if (0 == expect) {
+	    fatalf("unexpected condition in %s:%d", __FILE__, __LINE__);
+	}
+	rl = FD_READ_METHOD(fd, tmpbuf, needed);
+	debug(81, 3) ("icapReqModReadHttpHdrs: read %d bytes\n", rl);
+	if (rl < 0) {
+	    fatalf("need to handle read error at %s:%d", __FILE__, __LINE__);
+	}
+	fd_bytes(fd, rl, FD_READ);
+	kb_incr(&statCounter.icap.all.kbytes_in, rl);
+	memBufAppend(&icap->reqmod.hdr_buf, tmpbuf, rl);
+	icap->http_header_bytes_read_so_far += rl;
+	if (rl != needed) {
+	    /* still more header data to read */
+	    commSetSelect(fd, COMM_SELECT_READ, icapReqModReadHttpHdrs, icap, 0);
+	    return;
+	}
+	icap->reqmod.hdr_state = 1;
+    }
+    assert(1 == icap->reqmod.hdr_state);
+    debug(81, 3) ("icapReqModReadHttpHdrs: read the entire request headers\n");
+    icapReqModParseHttpRequest(icap);
+    if (-1 == icap->reqmod.client_fd) {
+	/* we detected that the original client_side went away */
+	icapReqModKeepAliveOrClose(icap);
+    } else if (icap->request->body_reader) {
+	icap->chunk_size = 0;
+	memBufDefInit(&icap->chunk_buf);
+	commSetSelect(fd, COMM_SELECT_READ, icapReqModReadHttpBody, icap, 0);
+    } else {
+	icapReqModKeepAliveOrClose(icap);
+    }
+}
+
+
+/*
+ * icapReqModReadIcapPart
+ *
+ * Read the ICAP reply header.
+ */
+static void
+icapReqModReadIcapPart(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    LOCAL_ARRAY(char, tmpbuf, SQUID_TCP_SO_RCVBUF);
+    int x;
+    const char *start;
+    const char *end;
+    int status;
+    int isIcap = 0;
+    int directResponse = 0;
+    float ver;
+
+    debug(81, 5) ("icapReqModReadIcapPart: FD %d httpState = %p\n", fd, data);
+    statCounter.syscalls.sock.reads++;
+
+    x = icapReadHeader(fd, icap, &isIcap);
+    if (x < 0) {
+	/* Did not find a proper ICAP response */
+	debug(81, 3) ("ICAP : Error path!\n");
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
+	comm_close(fd);
+	return;
+    }
+    if (x == 0) {
+	/*
+	 * Waiting for more headers.  Schedule new read hander, but
+	 * don't reset timeout.
+	 */
+	commSetSelect(fd, COMM_SELECT_READ, icapReqModReadIcapPart, icap, 0);
+	return;
+    }
+    /*
+     * Parse the ICAP header
+     */
+    assert(icap->icap_hdr.size);
+    debug(81, 3) ("Read icap header : <%s>\n", icap->icap_hdr.buf);
+    ver = -999.999;		/* initalize the version to a bogus number. I
+				 * think that we should parse it using 2
+				 * integers and a %d.%d scanf format - Basile
+				 * june 2002 */
+    if (sscanf(icap->icap_hdr.buf, "ICAP/%f %d %s\r", &ver, &status, tmpbuf) < 3
+	|| ver <= 0.0) {
+	debug(81, 1) ("BAD ICAP status line <%s>\n", icap->icap_hdr.buf);
+	/* is this correct in case of ICAP protocol error? */
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
+	comm_close(fd);
+	return;
+    };
+    icapSetKeepAlive(icap, icap->icap_hdr.buf);
+    if (icapFindHeader(icap->icap_hdr.buf, "Encapsulated:", &start, &end)) {
+	icapParseEncapsulated(icap, start, end);
+    } else {
+	debug(81, 1) ("WARNING: icapReqModReadIcapPart() did not find 'Encapsulated' header\n");
+    }
+    if (icap->enc.res_hdr > -1)
+	directResponse = 1;
+    else if (icap->enc.res_body > -1)
+	directResponse = 1;
+    else
+	directResponse = 0;
+    debug(81, 3) ("icapReqModReadIcapPart: directResponse=%d\n", directResponse);
+
+    /* Check whether it is a direct reply - if so over to http part */
+    if (directResponse) {
+	debug(81, 3) ("icapReqModReadIcapPart: FD %d, processing HTTP response for REQMOD!\n", fd);
+	/* got the reply, no need to come here again */
+	icap->flags.wait_for_reply = 0;
+	icap->flags.got_reply = 1;
+	icapReqModHandoffRespMod(icap);
+	return;
+    }
+    memBufDefInit(&icap->reqmod.hdr_buf);
+    commSetSelect(fd, COMM_SELECT_READ, icapReqModReadHttpHdrs, icap, 0);
+    return;
+}
+
+/*
+ * icapSendReqModDone
+ *
+ * Called after we've sent the ICAP request.  Checks for errors
+ * and installs the handler functions for the next step.
+ */
+static void
+icapSendReqModDone(int fd, char *bufnotused, size_t size, int errflag,
+    void *data)
+{
+    IcapStateData *icap = data;
+
+    debug(81, 5) ("icapSendReqModDone: FD %d: size %d: errflag %d.\n",
+	fd, size, errflag);
+    if (size > 0) {
+	fd_bytes(fd, size, FD_WRITE);
+	kb_incr(&statCounter.icap.all.kbytes_out, size);
+    }
+    if (errflag == COMM_ERR_CLOSING)
+	return;
+    if (errflag) {
+	debug(81, 3) ("icapSendReqModDone: unreachable=1, service=%s\n", icap->current_service->uri);
+	icapOptSetUnreachable(icap->current_service);
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
+	comm_close(fd);
+	return;
+    }
+    /* Schedule read reply. */
+    commSetSelect(fd, COMM_SELECT_READ, icapReqModReadIcapPart, icap, 0);
+    /*
+     * Set the read timeout here because it hasn't been set yet.
+     * We only set the read timeout after the request has been
+     * fully written to the server-side.  If we start the timeout
+     * after connection establishment, then we are likely to hit
+     * the timeout for POST/PUT requests that have very large
+     * request bodies.
+     */
+    commSetTimeout(fd, Config.Timeout.read, icapConnectTimeout, icap);
+}
+
+
+/*
+ * icapSendReqMod
+ *
+ * Send the ICAP request, including HTTP request, to the ICAP server
+ * after connection has been established.
+ */
+static void
+icapSendReqMod(int fd, int status, void *data)
+{
+    MemBuf mb;
+    MemBuf mb_hdr;
+    Packer p;
+    IcapStateData *icap = data;
+    char *client_addr;
+    int icap_fd = icap->icap_fd;
+    icap_service *service;
+    CWCB *theCallback;
+
+    debug(81, 5) ("icapSendReqMod FD %d, status %d\n", fd, status);
+    icap->flags.connect_pending = 0;
+
+    if (COMM_OK != status) {
+	debug(81, 1) ("Could not connect to ICAP server %s:%d: %s\n",
+	    icap->current_service->hostname,
+	    icap->current_service->port,
+	    xstrerror());
+	debug(81, 3) ("icapSendReqMod: unreachable=1, service=%s\n", icap->current_service->uri);
+	icapOptSetUnreachable(icap->current_service);
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_SERVICE_UNAVAILABLE, errno);
+	comm_close(fd);
+	return;
+    }
+    if (icap->request->content_length > 0)
+	theCallback = icapReqModSendBodyChunk;
+    else
+	theCallback = icapSendReqModDone;
+
+    memBufDefInit(&mb);
+    memBufDefInit(&mb_hdr);
+    memBufPrintf(&mb_hdr, "%s %s HTTP/%d.%d\r\n",
+	RequestMethodStr[icap->request->method],
+	icap->reqmod.uri,
+	icap->request->http_ver.major,
+	icap->request->http_ver.minor);
+    packerToMemInit(&p, &mb_hdr);
+    httpHeaderPackInto(&icap->request->header, &p);
+    packerClean(&p);
+    memBufAppend(&mb_hdr, crlf, 2);
+    service = icap->current_service;
+    assert(service);
+    client_addr = inet_ntoa(icap->request->client_addr);
+
+    memBufPrintf(&mb, "REQMOD %s ICAP/1.0\r\n", service->uri);
+    memBufPrintf(&mb, "Encapsulated: req-hdr=0");
+    /* TODO: Change the offset using 'request' if needed */
+    if (icap->request->content_length > 0)
+	memBufPrintf(&mb, ", req-body=%d", mb_hdr.size+2);
+    else
+	memBufPrintf(&mb, ", null-body=%d", mb_hdr.size+2);
+    memBufAppend(&mb, crlf, 2);
+    if (Config.icapcfg.send_client_ip)
+	memBufPrintf(&mb, "X-Client-IP: %s\r\n", client_addr);
+    if (Config.icapcfg.send_auth_user && icap->request->auth_user_request != NULL)
+	icapAddAuthUserHeader(&mb, icap->request->auth_user_request);
+    icap->flags.keep_alive = 1;
+    if (!icap->flags.keep_alive)
+	memBufAppend(&mb, "Connection: close\r\n", 19);
+    memBufAppend(&mb, crlf, 2);
+    memBufAppend(&mb, mb_hdr.buf, mb_hdr.size);
+    memBufClean(&mb_hdr);
+
+    debug(81, 5) ("icapSendReqMod: FD %d writing {%s}\n", icap->icap_fd, mb.buf);
+    comm_write_mbuf(icap_fd, mb, theCallback, icap);
+}
+
+/*
+ * icapReqModStart
+ *
+ * Initiate an ICAP REQMOD transaction.  Create and fill in IcapStateData
+ * structure and request a TCP connection to the server.
+ */
+IcapStateData *
+icapReqModStart(icap_service_t type, const char *uri, request_t * request, int fd, struct timeval start, struct in_addr log_addr, void *cookie)
+{
+    IcapStateData *icap = NULL;
+    icap_service *service = NULL;
+
+    debug(81, 3) ("icapReqModStart: type=%d\n", (int) type);
+    assert(type >= 0 && type < ICAP_SERVICE_MAX);
+
+    service = icapService(type, request);
+    if (!service) {
+	debug(81, 3) ("icapReqModStart: no service found\n");
+	return NULL;		/* no service found */
+    }
+    switch (type) {
+    case ICAP_SERVICE_REQMOD_PRECACHE:
+	break;
+    default:
+	fatalf("icapReqModStart: unsupported service type '%s'\n",
+	    icap_service_type_str[type]);
+	break;
+    }
+
+    if (service->unreachable) {
+	if (service->bypass) {
+	    debug(81, 5) ("icapReqModStart: BYPASS because service unreachable: %s\n", service->uri);
+	    return NULL;
+	} else {
+	    debug(81, 5) ("icapReqModStart: ERROR  because service unreachable: %s\n", service->uri);
+	    return (IcapStateData *) - 1;
+	}
+    }
+    icap = icapAllocate();
+    if (!icap) {
+	debug(81, 3) ("icapReqModStart: icapAllocate() failed\n");
+	return NULL;
+    }
+    icap->current_service = service;
+    icap->preview_size = service->preview;
+    icap->reqmod.uri = uri;	/* XXX should be xstrdup? */
+    icap->reqmod.start = start;
+    icap->reqmod.log_addr = log_addr;
+    icap->request = requestLink(request);
+    icap->reqmod.hdr_state = 0;
+    icap->reqmod.client_fd = fd;
+    icap->reqmod.client_cookie = cookie;
+    cbdataLock(icap->reqmod.client_cookie);
+
+    if (!icapConnect(icap, icapSendReqMod))
+	return NULL;
+
+    statCounter.icap.all.requests++;
+    debug(81, 3) ("icapReqModStart: returning %p\n", icap);
+    return icap;
+}
+
+/*
+ * icapReqModSendBodyChunk
+ *
+ * A "comm_write" callback.  This is called after comm_write() does
+ * its job to let us know how things went.  If there are no errors,
+ * get another chunk of the body from client_side.
+ */
+static void
+icapReqModSendBodyChunk(int fd, char *bufnotused, size_t size, int errflag, void *data)
+{
+    IcapStateData *icap = data;
+    debug(81, 3) ("icapReqModSendBodyChunk: FD %d wrote %d errflag %d.\n",
+	fd, (int) size, errflag);
+    if (errflag == COMM_ERR_CLOSING)
+	return;
+    if (errflag) {
+	icapEntryError(icap, ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR, errno);
+	comm_close(fd);
+	return;
+    }
+    clientReadBody(icap->request,
+	memAllocate(MEM_8K_BUF),
+	8192,
+	icapReqModBodyHandler,
+	icap);
+}
+
+/*
+ * icapReqModBodyHandler
+ *
+ * Called after Squid gets a chunk of the request entity from the
+ * client side.  The body is chunkified and passed to comm_write.
+ * The comm_write callback depends on whether or not this is the
+ * last chunk.
+ */
+static void
+icapReqModBodyHandler(char *buf, ssize_t size, void *data)
+{
+    IcapStateData *icap = data;
+    MemBuf mb;
+    CWCB *theCallback = icapReqModSendBodyChunk;
+    if (size < 0) {
+	debug(81, 1) ("icapReqModBodyHandler: %s\n", xstrerror());
+	memFree8K(buf);
+	return;
+    }
+    memBufDefInit(&mb);
+    debug(81, 3) ("icapReqModBodyHandler: writing chunk size %d\n", size);
+    memBufPrintf(&mb, "%x\r\n", size);
+    if (size)
+	memBufAppend(&mb, buf, size);
+    else
+	theCallback = icapSendReqModDone;
+    memBufAppend(&mb, crlf, 2);
+    memFree8K(buf);
+    comm_write_mbuf(icap->icap_fd, mb, theCallback, icap);
+}
+
+/*
+ * icapReqModReadHttpBody
+ *
+ * The read handler for the client's HTTP connection when reading
+ * message bodies.  Called by comm_select().
+ */
+static void
+icapReqModReadHttpBody(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    int len;
+    debug(81, 3) ("icapReqModReadHttpBody: FD %d called\n", fd);
+    len = memBufRead(fd, &icap->chunk_buf);
+    debug(81, 3) ("icapReqModReadHttpBody: read returns %d\n", len);
+    if (len < 0) {
+	debug(81, 3) ("icapReqModReadHttpBody: FD %d %s\n",
+	    fd, xstrerror());
+	if (!ignoreErrno(errno))
+	    icap->flags.reqmod_http_entity_eof = 1;
+    } else if (0 == len) {
+	debug(81, 3) ("icapReqModReadHttpBody: FD %d EOF\n", fd);
+	icap->flags.reqmod_http_entity_eof = 1;
+    } else {
+	fd_bytes(fd, len, FD_READ);
+	kb_incr(&statCounter.icap.all.kbytes_in, len);
+	icap->reqmod.http_entity.bytes_read +=
+	    icapParseChunkedBody(icap,
+	    icapReqModMemBufAppend, &icap->reqmod.http_entity.buf);
+    }
+    if (icap->reqmod.http_entity.bytes_read >= icap->request->content_length)
+	icap->flags.reqmod_http_entity_eof = 1;
+
+    if (!icap->flags.reqmod_http_entity_eof)
+	commSetSelect(fd, COMM_SELECT_READ, icapReqModReadHttpBody, icap, 0);
+    /*
+     * Notify the other side if it is waiting for data from us
+     */
+    debug(81, 3) ("%s:%d http_entity.callback=%p\n", __FILE__, __LINE__, icap->reqmod.http_entity.callback);
+    debug(81, 3) ("%s:%d http_entity.buf.size=%d\n", __FILE__, __LINE__, icap->reqmod.http_entity.buf.size);
+    if (icap->reqmod.http_entity.callback && icap->reqmod.http_entity.buf.size) {
+	icapReqModPassHttpBody(icap,
+	    icap->reqmod.http_entity.callback_buf,
+	    icap->reqmod.http_entity.callback_bufsize,
+	    icap->reqmod.http_entity.callback,
+	    icap->reqmod.http_entity.callback_data);
+	icap->reqmod.http_entity.callback = NULL;
+	cbdataUnlock(icap->reqmod.http_entity.callback_data);
+    }
+}
+
+/*
+ * icapReqModPassHttpBody
+ *
+ * Called from http.c after request headers have been sent.
+ * This function feeds the http.c module chunks of the request
+ * body that were stored in the http_entity.buf MemBuf.
+ */
+static void
+icapReqModPassHttpBody(void *data, char *buf, size_t size, CBCB * callback, void *cbdata)
+{
+    IcapStateData *icap = data;
+    debug(81, 3) ("icapReqModPassHttpBody: called\n");
+    if (!cbdataValid(cbdata)) {
+	debug(81, 1) ("icapReqModPassHttpBody: FD %d callback data invalid, closing\n", icap->icap_fd);
+	icapReqModKeepAliveOrClose(icap);
+	return;
+    }
+    debug(81, 3) ("icapReqModPassHttpBody: entity buf size = %d\n",
+	icap->reqmod.http_entity.buf.size);
+    if (icap->reqmod.http_entity.buf.size) {
+	int copy_sz = icap->reqmod.http_entity.buf.size;
+	if (copy_sz > size)
+	    copy_sz = size;
+	xmemcpy(buf, icap->reqmod.http_entity.buf.buf, copy_sz);
+	/* XXX don't let Alex see this ugliness */
+	xmemmove(icap->reqmod.http_entity.buf.buf,
+	    icap->reqmod.http_entity.buf.buf + copy_sz,
+	    icap->reqmod.http_entity.buf.size - copy_sz);
+	icap->reqmod.http_entity.buf.size -= copy_sz;
+	debug(81, 3) ("icapReqModPassHttpBody: giving %d bytes to other side\n",
+	    copy_sz);
+	callback(buf, copy_sz, cbdata);
+	debug(81, 3) ("icapReqModPassHttpBody: entity buf size now = %d\n",
+	    icap->reqmod.http_entity.buf.size);
+	return;
+    }
+    if (icap->flags.reqmod_http_entity_eof) {
+	debug(81, 3) ("icapReqModPassHttpBody: signalling EOF\n");
+	callback(buf, 0, cbdata);
+	icapReqModKeepAliveOrClose(icap);
+	return;
+    }
+    /*
+     * We have no data for the other side at this point.  Save all
+     * these values and use them when we do have data.
+     */
+    assert(NULL == icap->reqmod.http_entity.callback);
+    icap->reqmod.http_entity.callback = callback;
+    icap->reqmod.http_entity.callback_data = cbdata;
+    icap->reqmod.http_entity.callback_buf = buf;
+    icap->reqmod.http_entity.callback_bufsize = size;
+    cbdataLock(icap->reqmod.http_entity.callback_data);
+}
+
+/*
+ * icapReqModMemBufAppend
+ *
+ * stupid wrapper to eliminate compiler warnings
+ */
+static void
+icapReqModMemBufAppend(void *data, const char *buf, ssize_t size)
+{
+    memBufAppend(data, buf, size);
+}
Index: src/icap_respmod.c
--- src/icap_respmod.c.orig	2004-09-13 13:23:52 +0200
+++ src/icap_respmod.c	2004-09-13 13:23:52 +0200
@@ -0,0 +1,918 @@
+
+/*
+ * $Id: squid-icap-2_5-s2_5,v 1.1 2004/08/17 20:55:12 hno Exp $
+ *
+ * DEBUG: section 81    Internet Content Adaptation Protocol (ICAP) Client
+ * AUTHOR: Geetha Manjunath, Hewlett Packard Company
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  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 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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+
+static CWCB icapSendRespModDone;
+static PF icapRespModGobble;
+extern PF icapReadReply;
+static PF icapRespModReadReply;
+static int icapReadReply2(IcapStateData * icap);
+static void icapReadReply3(IcapStateData * icap);
+
+#define EXPECTED_ICAP_HEADER_LEN 256
+const char *crlf = "\r\n";
+
+static void
+getICAPRespModString(MemBuf * mb, int o1, int o2, int o3, char *service, char *client_addr,
+    IcapStateData * icap, int allow_204)
+{
+    memBufPrintf(mb, "RESPMOD %s ICAP/1.0\r\nEncapsulated:", service);
+    if (o1 >= 0)
+	memBufPrintf(mb, " req-hdr=%1d", o1);
+    if (o2 >= 0)
+	memBufPrintf(mb, ", res-hdr=%1d", o2);
+    if (o3 >= 0)
+	memBufPrintf(mb, ", res-body=%1d", o3);
+    else
+	memBufPrintf(mb, ", null-body=%1d", -o3);
+
+    memBufPrintf(mb, crlf);
+    if (Config.icapcfg.send_client_ip) {
+	memBufPrintf(mb, "X-Client-IP: %s\r\n", client_addr);
+    }
+    if (Config.icapcfg.send_auth_user && icap->request->auth_user_request != NULL) {
+	icapAddAuthUserHeader(mb, icap->request->auth_user_request);
+    }
+#if NOT_YET_FINISHED
+    if (Config.icapcfg.trailers) {
+	memBufPrintf(mb, "X-TE: trailers\r\n");
+    }
+#endif
+   if (allow_204)
+	memBufPrintf(mb, "Allow: 204\r\n");
+}
+
+static int
+buildRespModHeader(MemBuf * mb, IcapStateData * icap, char *buf,
+    ssize_t len, int theEnd)
+{
+    MemBuf mb_hdr;
+    char *client_addr;
+    int o2;
+    int o3;
+    int hlen;
+    int consumed;
+    icap_service *service;
+    HttpReply *r;
+
+    if (memBufIsNull(&icap->respmod.req_hdr_copy))
+	memBufDefInit(&icap->respmod.req_hdr_copy);
+
+    memBufAppend(&icap->respmod.req_hdr_copy, buf, len);
+    hlen = headersEnd(icap->respmod.req_hdr_copy.buf,
+	icap->respmod.req_hdr_copy.size);
+    debug(81, 3) ("buildRespModHeader: headersEnd = %d\n", hlen);
+    if (0 == hlen)
+	return 0;
+
+    /*
+     * calc how many bytes from this 'buf' went towards the
+     * reply header.
+     */
+    consumed = hlen - (icap->respmod.req_hdr_copy.size - len);
+    debug(81, 3) ("buildRespModHeader: consumed = %d\n", consumed);
+
+    /*
+     * now, truncate our req_hdr_copy at the header end.
+     * this 'if' statement might be unncessary?
+     */
+    if (hlen < icap->respmod.req_hdr_copy.size)
+	icap->respmod.req_hdr_copy.size = hlen;
+
+    /* Copy request header */
+    memBufDefInit(&mb_hdr);
+    httpBuildRequestPrefix(icap->request, icap->request,
+	icap->respmod.entry, &mb_hdr, icap->http_flags);
+    o2 = mb_hdr.size;
+
+    /* Copy response header - Append to request header mbuffer */
+    memBufAppend(&mb_hdr,
+	icap->respmod.req_hdr_copy.buf,
+	icap->respmod.req_hdr_copy.size);
+    o3 = mb_hdr.size;
+
+    service = icap->current_service;
+    assert(service);
+    client_addr = inet_ntoa(icap->request->client_addr);
+
+    r = httpReplyCreate();
+    httpReplyParse(r, icap->respmod.req_hdr_copy.buf,
+	icap->respmod.req_hdr_copy.size);
+    icap->respmod.res_body_sz = httpReplyBodySize(icap->request->method, r);
+    httpReplyDestroy(r);
+    if (icap->respmod.res_body_sz)
+	getICAPRespModString(mb, 0, o2, o3, service->uri, client_addr, icap, service->flags.allow_204);
+    else
+	getICAPRespModString(mb, 0, o2, -o3, service->uri, client_addr, icap, service->flags.allow_204);
+    if (Config.icapcfg.preview_enable)
+	if (icap->preview_size >= 0)
+	    memBufPrintf(mb, "Preview: %d\r\n", icap->preview_size);
+
+    memBufAppend(mb, "Connection: keep-alive\r\n", 24);
+    memBufAppend(mb, crlf, 2);
+    memBufAppend(mb, mb_hdr.buf, mb_hdr.size);
+    memBufClean(&mb_hdr);
+    icap->flags.keep_alive = 1;
+
+    return consumed;
+}
+
+
+void
+icapSendRespMod(IcapStateData * icap, char *buf, int len, int theEnd)
+{
+    MemBuf mb;
+#if ICAP_PREVIEW
+    int size;
+    const int preview_size = icap->preview_size;
+#endif
+    debug(81, 5) ("icapSendRespMod: FD %d, len %d, theEnd %d\n",
+	icap->icap_fd, len, theEnd);
+
+    if (icap->flags.no_content) {
+	/*
+	 * ICAP server said there are no modifications to make, so
+	 * just append this data to the StoreEntry
+	 */
+	if (icap->respmod.resp_copy.size) {
+	    /*
+	     * first copy the data that we already sent to the ICAP server
+	     */
+	    memBufAppend(&icap->chunk_buf,
+		icap->respmod.resp_copy.buf,
+		icap->respmod.resp_copy.size);
+	    icap->respmod.resp_copy.size = 0;
+	}
+	if (len) {
+	    /*
+	     * also copy any new data from the HTTP side
+	     */
+	    memBufAppend(&icap->chunk_buf, buf, len);
+	}
+	(void) icapReadReply2(icap);
+	return;
+    }
+    if (theEnd) {
+	if (icap->respmod.res_body_sz)
+	    icap->flags.send_zero_chunk = 1;
+	else
+	    icap->flags.http_server_eof = 1;
+    }
+    /*
+     * httpReadReply is going to call us with a chunk and then
+     * right away again with an EOF if httpPconnTransferDone() is true.
+     * Since the first write is already dispatched, we'll have to 
+     * hack this in somehow.
+     */
+    if (icap->flags.write_pending) {
+	debug(81, 3) ("icapSendRespMod: oops, write_pending=1\n");
+	assert(theEnd);
+	assert(len == 0);
+	return;
+    }
+    if (!cbdataValid(icap)) {
+	debug(81, 3) ("icapSendRespMod: failed to establish connection?\n");
+	return;
+    }
+    memBufDefInit(&mb);
+
+    /*
+     * make a copy of the response in case ICAP server gives us a 204
+     */
+    if (len && icap->flags.copy_response) {
+	if (memBufIsNull(&icap->respmod.resp_copy))
+	    memBufDefInit(&icap->respmod.resp_copy);
+	memBufAppend(&icap->respmod.resp_copy, buf, len);
+    }
+    if (icap->sc == 0) {
+	/* No data sent yet. Start with headers */
+	icap->sc = buildRespModHeader(&mb, icap, buf, len, theEnd);
+	buf += icap->sc;
+	len -= icap->sc;
+    }
+    if (0 == icap->sc) {
+	/* check again; bail if we're not ready to send ICAP/HTTP hdrs */
+	debug(81, 5) ("icapSendRespMod: dont have full HTTP response hdrs\n");
+	memBufClean(&mb);
+	return;
+    }
+#if ICAP_PREVIEW
+    if (preview_size < 0)	/* preview feature off */
+	icap->flags.preview_done = 1;
+
+    if (!icap->flags.preview_done) {
+	/* preview not yet sent */
+	if (icap->sc > 0 && icap->respmod.buffer.size <= preview_size && len > 0) {
+	    /* Try to collect at least preview_size+1 bytes */
+	    /* By collecting one more byte than needed for preview we know best */
+	    /* whether we have to send the ieof chunk extension */
+	    size = icap->respmod.buffer.size + len;
+	    if (size > preview_size + 1)
+		size = preview_size + 1;
+	    size -= icap->respmod.buffer.size;
+	    debug(81, 3) ("icapSendRespMod: FD %d: copy %d more bytes to preview buffer.\n", icap->icap_fd, size);
+	    memBufAppend(&icap->respmod.buffer, buf, size);
+	    buf = ((char *) buf) + size;
+	    len -= size;
+	}
+	if (icap->respmod.buffer.size > preview_size || theEnd) {
+	    /* we got enough bytes for preview or this is the last call */
+	    /* add preview preview now */
+	    if (icap->respmod.buffer.size > 0) {
+		size = icap->respmod.buffer.size;
+		if (size > preview_size)
+		    size = preview_size;
+		memBufPrintf(&mb, "%x\r\n", size);
+		memBufAppend(&mb, icap->respmod.buffer.buf, size);
+		memBufAppend(&mb, crlf, 2);
+		icap->sc += size;
+	    }
+	    if (icap->respmod.buffer.size <= preview_size) {
+		/* content length is less than preview size+1 */
+		if (icap->respmod.res_body_sz)
+		    memBufAppend(&mb, "0; ieof\r\n\r\n", 11);
+		memBufReset(&icap->respmod.buffer);	/* will now be used for other data */
+	    } else {
+		char ch;
+		memBufAppend(&mb, "0\r\n\r\n", 5);
+		/* end of preview, wait for continue or 204 signal */
+		/* copy the extra byte and all other data to the icap buffer */
+		/* so that it can be handled next time */
+		ch = icap->respmod.buffer.buf[preview_size];
+		memBufReset(&icap->respmod.buffer);	/* will now be used for other data */
+		memBufAppend(&icap->respmod.buffer, &ch, 1);
+		debug(81, 3) ("icapSendRespMod: FD %d: sending preview and keeping %d bytes in internal buf.\n", icap->icap_fd, len + 1);
+		if (len > 0)
+		    memBufAppend(&icap->respmod.buffer, buf, len);
+	    }
+	    icap->flags.preview_done = 1;
+	    icap->flags.wait_for_preview_reply = 1;
+	}
+    } else if (icap->flags.wait_for_preview_reply) {
+	/* received new data while waiting for preview response */
+	/* add data to internal buffer and send later */
+	debug(81, 3) ("icapSendRespMod: FD %d: add %d more bytes to internal buf while waiting for preview-response.\n", icap->icap_fd, len);
+	if (len > 0)
+	    memBufAppend(&icap->respmod.buffer, buf, len);
+	/* do not send any data now while waiting for preview response */
+	/* but prepare for read more data on the HTTP connection */
+	if (!icap->flags.http_server_eof) {
+	    debug(81, 3) ("icapSendRespMod: FD %d: commSetSelect on read icapRespModReadReply waiting for preview response.\n", icap->icap_fd);
+	    commSetSelect(icap->icap_fd, COMM_SELECT_READ, icapRespModReadReply,
+		icap, 0);
+	}
+	return;
+    } else
+#endif
+    {
+	/* after preview completed and ICAP preview response received */
+	/* there may still be some data in the buffer */
+	if (icap->respmod.buffer.size > 0) {
+	    memBufPrintf(&mb, "%x\r\n", icap->respmod.buffer.size);
+	    memBufAppend(&mb, icap->respmod.buffer.buf, icap->respmod.buffer.size);
+	    memBufAppend(&mb, crlf, 2);
+	    icap->sc += icap->respmod.buffer.size;
+	    memBufReset(&icap->respmod.buffer);
+	}
+	if (len > 0) {
+	    memBufPrintf(&mb, "%x\r\n", len);
+	    memBufAppend(&mb, buf, len);
+	    memBufAppend(&mb, crlf, 2);
+	    icap->sc += len;
+	}
+	if (icap->flags.send_zero_chunk) {
+	    /* send zero end chunk */
+	    icap->flags.send_zero_chunk = 0;
+	    icap->flags.http_server_eof = 1;
+	    memBufAppend(&mb, "0\r\n\r\n", 5);
+	}
+	/* wait for data coming from ICAP server as soon as we sent something */
+	/* but of course only until we got the response header */
+	if (!icap->flags.got_reply)
+	    icap->flags.wait_for_reply = 1;
+    }
+    commSetTimeout(icap->icap_fd, -1, NULL, NULL);
+
+    if (!mb.size) {
+	memBufClean(&mb);
+	return;
+    }
+    debug(81, 5) ("icapSendRespMod: FD %d writing {%s}\n", icap->icap_fd, mb.buf);
+    icap->flags.write_pending = 1;
+    comm_write_mbuf(icap->icap_fd, mb, icapSendRespModDone, icap);
+}
+
+static void
+icapRespModReadReply(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    LOCAL_ARRAY(char, tmpbuf, SQUID_TCP_SO_RCVBUF);
+    int x;
+    int status = 0;
+    int isIcap = 0;
+    int directResponse = 0;
+    float ver;
+    ErrorState *err;
+    const char *start;
+    const char *end;
+
+    debug(81, 5) ("icapRespModReadReply: FD %d data = %p\n", fd, data);
+    statCounter.syscalls.sock.reads++;
+
+    x = icapReadHeader(fd, icap, &isIcap);
+    if (x < 0) {
+	/* Did not find a proper ICAP response */
+	debug(81, 3) ("ICAP : Error path!\n");
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	err->request = requestLink(icap->request);
+	err->xerrno = errno;
+	errorAppendEntry(icap->respmod.entry, err);
+	comm_close(fd);
+	return;
+    }
+    if (x == 0) {
+	/*
+	 * Waiting for more headers.  Schedule new read hander, but
+	 * don't reset timeout.
+	 */
+	commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
+	return;
+    }
+    /*
+     * Parse the ICAP header
+     */
+    assert(icap->icap_hdr.size);
+    debug(81, 3) ("Parse icap header : <%s>\n", icap->icap_hdr.buf);
+    ver = -999.999;		/* initalize the version to a bogus number. I
+				 * think that we should parse it using 2
+				 * integers and a %d.%d scanf format - Basile
+				 * june 2002 */
+    if (sscanf(icap->icap_hdr.buf, "ICAP/%f %d %s\r", &ver, &status, tmpbuf) < 3 || ver <= 0.0) {
+	debug(81, 1) ("BAD ICAP status line <%s>\n", icap->icap_hdr.buf);
+	/* is this correct in case of ICAP protocol error? */
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	err->request = requestLink(icap->request);
+	err->xerrno = errno;
+	errorAppendEntry(icap->respmod.entry, err);
+	comm_close(fd);
+	return;
+    };
+    if (icap->flags.wait_for_preview_reply) {
+	if (status == 100) {
+	    debug(81, 5) ("icapRespModReadReply: 100 Continue received\n");
+	    icap->flags.wait_for_preview_reply = 0;
+	    /*
+	     * call again icapSendRespMod to handle data that
+	     * was received while waiting fot this ICAP response
+	     */
+	    icapSendRespMod(icap, NULL, 0, 0);
+	    /*
+	     * reset the header to send the rest of the preview
+	     */
+	    if (!memBufIsNull(&icap->icap_hdr))
+		memBufReset(&icap->icap_hdr); 
+	    return;
+#if SUPPORT_ICAP_204
+	} else if (status == 204) {
+	    debug(81, 5) ("icapRespModReadReply: 204 No modification received\n");
+	    icap->flags.wait_for_preview_reply = 0;
+	    if (icap->flags.http_server_eof) {
+		/* Reset is required to avoid duplicate stmemFreeDataUpto ,
+		 * but will I loose all info now ? */
+		/* storeEntryReset(icap->respmod.entry); */
+		/* stmemFreeDataUpto(&(entry->mem_obj->data_hdr), -icap->sc); */
+		fwdComplete(icap->httpState->fwd);
+	    } else {
+		commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply,
+		    icap, 0);
+	    }
+	    comm_close(fd);
+	    return;
+#endif
+	}
+    }
+    if (100 == status) {
+	debug(81, 3) ("icapRespModReadReply: 100 Continue received\n");
+	commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
+	return;
+    }
+    icapSetKeepAlive(icap, icap->icap_hdr.buf);
+    if (204 == status) {
+	debug(81, 3) ("got 204 status from ICAP server\n");
+	debug(81, 3) ("setting icap->flags.no_content\n");
+	icap->flags.no_content = 1;
+	/*
+	 * copy the response already written to the ICAP server
+	 */
+	debug(81, 3) ("copying %d bytes from resp_copy to chunk_buf\n",
+	    icap->respmod.resp_copy.size);
+	memBufAppend(&icap->chunk_buf,
+	    icap->respmod.resp_copy.buf,
+	    icap->respmod.resp_copy.size);
+	icap->respmod.resp_copy.size = 0;
+	if (icapReadReply2(icap) < 0)
+	    comm_close(fd);
+	/*
+	 * XXX ideally want to clean icap->respmod.resp_copy here
+	 * XXX ideally want to "close" ICAP server connection here
+	 */
+	return;
+    }
+    icap->flags.copy_response = 0;
+    if (200 != status) {
+	debug(81, 1) ("Unsupported status '%d' from ICAP server\n", status);
+	/* Did not find a proper ICAP response */
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	err->request = requestLink(icap->request);
+	err->xerrno = errno;
+	errorAppendEntry(icap->respmod.entry, err);
+	comm_close(fd);
+	return;
+    }
+    if (icapFindHeader(icap->icap_hdr.buf, "Encapsulated:", &start, &end)) {
+	icapParseEncapsulated(icap, start, end);
+    } else {
+	debug(81, 1) ("WARNING: icapRespModReadReply() did not find 'Encapsulated' header\n");
+    }
+    if (icap->enc.res_hdr > -1)
+	directResponse = 1;
+    else if (icap->enc.res_body > -1)
+	directResponse = 1;
+    else
+	directResponse = 0;
+
+    /*
+     * "directResponse" is the normal case here.  If we don't have
+     * a response header or body, it is an error.
+     */
+    if (!directResponse) {
+	/* Did not find a proper ICAP response */
+	debug(81, 3) ("ICAP : Error path!\n");
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	err->request = requestLink(icap->request);
+	err->xerrno = errno;
+	errorAppendEntry(icap->respmod.entry, err);
+	comm_close(fd);
+	return;
+    }
+    /* got the reply, no need to come here again */
+    icap->flags.wait_for_reply = 0;
+    icap->flags.got_reply = 1;
+    /* Next, gobble any data before the HTTP response starts */
+    if (icap->enc.res_hdr > -1)
+	icap->bytes_to_gobble = icap->enc.res_hdr;
+    commSetSelect(fd, COMM_SELECT_READ, icapRespModGobble, icap, 0);
+}
+
+
+/*
+ * Gobble up (read) some bytes until we get to the start of the body
+ */
+static void
+icapRespModGobble(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    int len;
+    LOCAL_ARRAY(char, junk, SQUID_TCP_SO_RCVBUF);
+    debug(81, 3) ("icapRespModGobble: FD %d gobbling %d bytes\n", fd, icap->bytes_to_gobble);
+    len = FD_READ_METHOD(fd, junk, icap->bytes_to_gobble);
+    debug(81, 3) ("icapRespModGobble: gobbled %d bytes\n", len);
+    if (len < 0) {
+	/* XXX error */
+	abort();
+    }
+    icap->bytes_to_gobble -= len;
+    if (icap->bytes_to_gobble)
+	commSetSelect(fd, COMM_SELECT_READ, icapRespModGobble, icap, 0);
+    else
+	icapReadReply(fd, icap);
+}
+
+
+static void
+icapSendRespModDone(int fd, char *bufnotused, size_t size, int errflag,
+    void *data)
+{
+    IcapStateData *icap = data;
+    ErrorState *err;
+
+    icap->flags.write_pending = 0;
+    debug(81, 5) ("icapSendRespModDone: FD %d: size %d: errflag %d.\n",
+	fd, size, errflag);
+    if (size > 0) {
+	fd_bytes(fd, size, FD_WRITE);
+	kb_incr(&statCounter.icap.all.kbytes_out, size);
+    }
+    if (errflag == COMM_ERR_CLOSING)
+	return;
+    if (errflag) {
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	err->xerrno = errno;
+	if (cbdataValid(icap))
+	    err->request = requestLink(icap->request);
+	storeEntryReset(icap->respmod.entry);
+	errorAppendEntry(icap->respmod.entry, err);
+	comm_close(fd);
+	return;
+    }
+    if (EBIT_TEST(icap->respmod.entry->flags, ENTRY_ABORTED)) {
+	comm_close(fd);
+	return;
+    }
+    if (icap->flags.send_zero_chunk) {
+	debug(81, 3) ("icapSendRespModDone: I'm supposed to send zero chunk now\n");
+	icap->flags.send_zero_chunk = 0;
+	icapSendRespMod(icap, NULL, 0, 1);
+	return;
+    }
+    if (icap->flags.wait_for_preview_reply || icap->flags.wait_for_reply) {
+	/* Schedule reading the ICAP response */
+	debug(81, 3) ("icapSendRespModDone: FD %d: commSetSelect on read icapRespModReadReply.\n", fd);
+	commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
+#if 1
+	commSetTimeout(fd, Config.Timeout.read, icapReadTimeout, icap);
+#else
+	if (icap->flags.wait_for_preview_reply || icap->flags.http_server_eof) {
+	    /*
+	     * Set the read timeout only after all data has been sent
+	     * or we are waiting for a preview response
+	     * If the ICAP server does not return any data till all data
+	     * has been sent, we are likely to hit the timeout for large
+	     * HTTP bodies
+	     */
+	    commSetTimeout(fd, Config.Timeout.read, icapReadTimeout, icap);
+	}
+#endif
+    }
+}
+
+void
+icapConnectOver(int fd, int status, void *data)
+{
+    ErrorState *err;
+    IcapStateData *icap = data;
+    debug(81, 3) ("icapConnectOver: FD %d, status=%d\n", fd, status);
+    icap->flags.connect_pending = 0;
+    if (status < 0) {
+	err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	err->xerrno = errno;
+	err->request = requestLink(icap->request);
+	errorAppendEntry(icap->respmod.entry, err);
+	comm_close(fd);
+	debug(81, 3) ("icapConnectOver: status < 0, unreachable=1\n");
+	icapOptSetUnreachable(icap->current_service);
+	return;
+    }
+    commSetSelect(fd, COMM_SELECT_READ, icapRespModReadReply, icap, 0);
+}
+
+
+
+IcapStateData *
+icapRespModStart(icap_service_t type, request_t * request, StoreEntry * entry, http_state_flags http_flags)
+{
+    IcapStateData *icap = NULL;
+    CNCB *theCallback = NULL;
+    icap_service *service = NULL;
+
+    debug(81, 3) ("icapRespModStart: type=%d\n", (int) type);
+    assert(type >= 0 && type < ICAP_SERVICE_MAX);
+
+    service = icapService(type, request);
+    if (!service) {
+	debug(81, 3) ("icapRespModStart: no service found\n");
+	return NULL;		/* no service found */
+    }
+    if (service->unreachable) {
+	if (service->bypass) {
+	    debug(81, 5) ("icapRespModStart: BYPASS because service unreachable: %s\n", service->uri);
+	    return NULL;
+	} else {
+	    debug(81, 5) ("icapRespModStart: ERROR  because service unreachable: %s\n", service->uri);
+	    return (IcapStateData *) - 1;
+	}
+    }
+    switch (type) {
+       /* TODO: When we support more than ICAP_SERVICE_RESPMOD_PRECACHE, we needs to change
+	* this switch, because callbacks isn't keep */
+    case ICAP_SERVICE_RESPMOD_PRECACHE:
+	theCallback = icapConnectOver;
+	break;
+    default:
+	fatalf("icapRespModStart: unsupported service type '%s'\n",
+	    icap_service_type_str[type]);
+	break;
+    }
+
+    icap = icapAllocate();
+    if (!icap) {
+	debug(81, 3) ("icapRespModStart: icapAllocate() failed\n");
+	return NULL;
+    }
+    icap->request = requestLink(request);
+    icap->respmod.entry = entry;
+    if (entry)
+	storeLockObject(entry);
+    icap->http_flags = http_flags;
+    memBufDefInit(&icap->respmod.buffer);
+    memBufDefInit(&icap->chunk_buf);
+
+    icap->current_service = service;
+    icap->preview_size = service->preview;
+
+    /* 
+     * Don't create socket to the icap server now, but only for the first
+     * packet receive from the http server. This will resolve all timeout
+     * between the web server and icap server.
+     */
+    debug(81, 3) ("icapRespModStart: setting connect_requested to 0\n");
+    icap->flags.connect_requested = 0;
+
+    /*
+     * make a copy the HTTP response that we send to the ICAP server in
+     * case it turns out to be a 204
+     */
+    icap->flags.copy_response = 1;
+    statCounter.icap.all.requests++;
+    debug(81, 3) ("icapRespModStart: returning %p\n", icap);
+    return icap;
+}
+
+static int
+icapHttpReplyHdrState(IcapStateData * icap)
+{
+    assert(icap);
+    if (NULL == icap->httpState)
+	return 0;
+    return icap->httpState->reply_hdr_state;
+}
+
+void
+icapProcessHttpReplyHeader(IcapStateData * icap, const char *buf, int size)
+{
+    if (NULL == icap->httpState) {
+	icap->httpState = cbdataAlloc(HttpStateData);
+	icap->httpState->request = requestLink(icap->request);
+	icap->httpState->orig_request = requestLink(icap->request);
+	icap->httpState->entry = icap->respmod.entry;
+	storeLockObject(icap->httpState->entry);	/* lock it */
+    }
+    httpProcessReplyHeader(icap->httpState, buf, size);
+    if (2 == icap->httpState->reply_hdr_state)
+	EBIT_CLR(icap->httpState->entry->flags, ENTRY_FWD_HDR_WAIT);
+}
+
+/*
+ * copied from httpPconnTransferDone
+ *
+ */
+static int
+icapPconnTransferDone(int fd, IcapStateData * icap)
+{
+    debug(81, 3) ("icapPconnTransferDone: FD %d\n", fd);
+    /*
+     * Did we request a persistent connection?
+     */
+    /*
+     * What does the reply have to say about keep-alive?
+     */
+    if (!icap->flags.keep_alive) {
+	debug(81, 5) ("icapPconnTransferDone: keep_alive not set, ret 0\n");
+	return 0;
+    }
+    /*
+     * Be careful with 204 responses.  Normally we are done when we
+     * see the zero-end chunk, but that won't happen for 204s, so we
+     * use an EOF indicator on the HTTP side instead.
+     */
+    if (icap->flags.no_content && icap->flags.http_server_eof) {
+	debug(81, 5) ("icapPconnTransferDone: no content, ret 1\n");
+	return 1;
+    }
+    if (icapHttpReplyHdrState(icap) != 2) {
+	debug(81, 5) ("icapPconnTransferDone: didn't see end of HTTP hdrs, ret 0\n");
+	return 0;
+    }
+    if (icap->enc.null_body > -1) {
+	debug(81, 5) ("icapPconnTransferDone: no message body, ret 1\n");
+	return 1;
+    }
+    if (icap->chunk_size != -2) {
+	/* zero end chunk reached */
+	debug(81, 5) ("icapPconnTransferDone: didnt get zero end chunk yet\n");
+	return 0;
+    }
+    debug(81, 5) ("icapPconnTransferDone: got zero end chunk\n");
+    return 1;
+}
+
+static int
+icapExpectedHttpReplyHdrSize(IcapStateData * icap)
+{
+    if (icap->enc.res_body > -1 && icap->enc.res_hdr > -1)
+	return (icap->enc.res_body - icap->enc.res_hdr);
+    if (icap->enc.null_body > -1 && icap->enc.res_hdr > -1)
+	return icap->enc.null_body - icap->enc.res_hdr;
+    if (icap->enc.null_body > -1)
+	return icap->enc.null_body;
+    return -1;
+}
+
+/*
+ * copied from httpReadReply()
+ *
+ * by the time this is called, the ICAP headers have already
+ * been read.
+ */
+void
+icapReadReply(int fd, void *data)
+{
+    IcapStateData *icap = data;
+    StoreEntry *entry = icap->respmod.entry;
+    const request_t *request = icap->request;
+    int len;
+    debug(81, 5) ("icapReadReply: FD %d: icap %p.\n", fd, data);
+    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+	comm_close(fd);
+	return;
+    }
+    errno = 0;
+    statCounter.syscalls.sock.reads++;
+    len = memBufRead(fd, &icap->chunk_buf);
+    debug(81, 5) ("icapReadReply: FD %d: len %d.\n", fd, len);
+    if (len > 0) {
+	fd_bytes(fd, len, FD_READ);
+	kb_incr(&statCounter.icap.all.kbytes_in, len);
+	commSetTimeout(fd, Config.Timeout.read, icapReadTimeout, icap);
+	if (icap->chunk_buf.size < icap->chunk_buf.capacity) {
+	    *(icap->chunk_buf.buf + icap->chunk_buf.size) = '\0';
+	    debug(81, 9) ("{%s}\n", icap->chunk_buf.buf);
+	}
+    }
+    if (len <= 0) {
+	debug(81, 2) ("icapReadReply: FD %d: read failure: %s.\n",
+	    fd, xstrerror());
+	if (ignoreErrno(errno)) {
+	    debug(81, 2) ("icapReadReply: FD %d: ignored errno\n", fd);
+	    commSetSelect(fd, COMM_SELECT_READ, icapReadReply, icap, 0);
+	} else if (entry->mem_obj->inmem_hi == 0) {
+	    ErrorState *err;
+	    debug(81, 2) ("icapReadReply: FD %d: generating error page\n", fd);
+	    err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+	    err->request = requestLink((request_t *) request);
+	    err->xerrno = errno;
+	    errorAppendEntry(entry, err);
+	    comm_close(fd);
+	} else {
+	    debug(81, 2) ("icapReadReply: FD %d: just calling comm_close()\n", fd);
+	    comm_close(fd);
+	}
+	return;
+    }
+    if (icapReadReply2(icap) < 0)
+	comm_close(fd);
+}
+
+static int
+icapReadReply2(IcapStateData * icap)
+{
+    StoreEntry *entry = icap->respmod.entry;
+    const request_t *request = icap->request;
+    debug(81, 3) ("icapReadReply2\n");
+    if (icap->chunk_buf.size == 0 && entry->mem_obj->inmem_hi == 0) {
+	ErrorState *err;
+	err = errorCon(ERR_ZERO_SIZE_OBJECT, HTTP_SERVICE_UNAVAILABLE);
+	err->xerrno = errno;
+	err->request = requestLink((request_t *) request);
+	errorAppendEntry(entry, err);
+	icap->flags.http_server_eof = 1;
+	return -1;
+    }
+    if (icap->chunk_buf.size == 0) {
+	/* Retrieval done. */
+	if (icapHttpReplyHdrState(icap) < 2)
+	    icapProcessHttpReplyHeader(icap, icap->chunk_buf.buf, icap->chunk_buf.size);
+	icap->flags.http_server_eof = 1;
+	icapReadReply3(icap);
+	return 0;
+    }
+    if (icapHttpReplyHdrState(icap) == 0) {
+	int expect = icapExpectedHttpReplyHdrSize(icap);
+	int so_far = icap->http_header_bytes_read_so_far;
+	int needed = expect - so_far;
+	debug(81, 3) ("expect=%d\n", expect);
+	debug(81, 3) ("so_far=%d\n", so_far);
+	debug(81, 3) ("needed=%d\n", needed);
+	assert(needed < 0 || needed >= 0);
+	if (0 > expect) {
+	    icapProcessHttpReplyHeader(icap,
+		icap->chunk_buf.buf,
+		icap->chunk_buf.size);
+	} else if (0 == expect) {
+	    /*
+	     * this icap reply doesn't give us new HTTP headers
+	     * so we must copy them from our copy
+	     */
+	    debug(81, 1) ("WARNING: untested code at %s:%d\n", __FILE__, __LINE__);
+	    assert(icap->respmod.req_hdr_copy.size);
+	    storeAppend(entry,
+		icap->respmod.req_hdr_copy.buf,
+		icap->respmod.req_hdr_copy.size);
+	    icapProcessHttpReplyHeader(icap, icap->chunk_buf.buf, icap->chunk_buf.size);
+	    assert(icapHttpReplyHdrState(icap) == 2);
+	} else if (needed) {
+	    icapProcessHttpReplyHeader(icap,
+		icap->chunk_buf.buf,
+		icap->chunk_buf.size);
+	    if (icap->chunk_buf.size >= needed) {
+		storeAppend(entry, icap->chunk_buf.buf, needed);
+		so_far += needed;
+		xmemmove(icap->chunk_buf.buf,
+		    icap->chunk_buf.buf + needed,
+		    icap->chunk_buf.size - needed);
+		icap->chunk_buf.size -= needed;
+		assert(icapHttpReplyHdrState(icap) == 2);
+		icap->chunk_size = 0;
+	    } else {
+		/*
+		 * We don't have the full HTTP reply headers yet, so keep
+		 * the partial reply buffered in 'chunk_buf' and wait
+		 * for more.
+		 */
+		assert(icapHttpReplyHdrState(icap) == 0);
+	    }
+	}
+	icap->http_header_bytes_read_so_far = so_far;
+    }
+    debug(81, 3) ("%s:%d: icap->chunk_buf.size=%d\n", __FILE__, __LINE__, (int) icap->chunk_buf.size);
+    debug(81, 3) ("%s:%d: flags.no_content=%d\n", __FILE__, __LINE__, icap->flags.no_content);
+    if (icap->flags.no_content) {
+	/* data from http.c is not chunked */
+	debug(81, 3) ("copying %d bytes from chunk_buf to entry\n",
+	    icap->chunk_buf.size);
+	storeAppend(entry, icap->chunk_buf.buf, icap->chunk_buf.size);
+	icap->chunk_buf.size = 0;
+    } else if (2 == icapHttpReplyHdrState(icap)) {
+	if (icap->chunk_buf.size)
+	    icapParseChunkedBody(icap, storeAppend, entry);
+    }
+    icapReadReply3(icap);
+    return 0;
+}
+
+static void
+icapReadReply3(IcapStateData * icap)
+{
+    StoreEntry *entry = icap->respmod.entry;
+    int fd = icap->icap_fd;
+    debug(81, 3) ("icapReadReply3\n");
+    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+	comm_close(fd);
+    } else if (icapPconnTransferDone(fd, icap)) {
+	/* yes we have to clear all these! */
+	commSetDefer(fd, NULL, NULL);
+	commSetTimeout(fd, -1, NULL, NULL);
+	commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+	comm_remove_close_handler(fd, icapStateFree, icap);
+	pconnPush(fd, fd_table[fd].pconn_name, fd_table[fd].remote_port);
+	storeComplete(entry);
+	icap->icap_fd = -1;
+	icapStateFree(-1, icap);
+    } else {
+	/* Wait for EOF condition */
+	commSetSelect(fd, COMM_SELECT_READ, icapReadReply, icap, 0);
+    }
+}
Index: src/main.c
--- src/main.c.orig	2003-12-17 22:10:30 +0100
+++ src/main.c	2004-09-13 13:23:52 +0200
@@ -348,6 +348,9 @@
 #else
     idnsShutdown();
 #endif
+#ifdef HS_FEAT_ICAP
+    icapClose();
+#endif
     redirectShutdown();
     authenticateShutdown();
     externalAclShutdown();
@@ -376,6 +379,9 @@
     idnsInit();
 #endif
     redirectInit();
+#ifdef HS_FEAT_ICAP
+    icapInit();
+#endif
     authenticateInit(&Config.authConfig);
     externalAclInit();
 #if USE_WCCP
@@ -504,6 +510,9 @@
     idnsInit();
 #endif
     redirectInit();
+#ifdef HS_FEAT_ICAP
+    icapInit();
+#endif
     authenticateInit(&Config.authConfig);
     externalAclInit();
     useragentOpenLog();
Index: src/mem.c
--- src/mem.c.orig	2001-09-07 20:02:45 +0200
+++ src/mem.c	2004-09-13 13:23:52 +0200
@@ -243,6 +243,13 @@
     memDataInit(MEM_CLIENT_REQ_BUF, "clientRequestBuffer", CLIENT_REQ_BUF_SZ, 0);
     memDataInit(MEM_SWAP_LOG_DATA, "storeSwapLogData", sizeof(storeSwapLogData), 0);
 
+#ifdef HS_FEAT_ICAP
+    memDataInit(MEM_ICAP_OPT_DATA, "IcapOptData", sizeof(IcapOptData), 0);
+    memDataInit(MEM_ICAP_SERVICE_LIST, "icap_service_list", sizeof(icap_service_list), 0);
+    memDataInit(MEM_ICAP_CLASS, "icap_class", sizeof(icap_class), 0);
+    memDataInit(MEM_ICAP_ACCESS, "icap_access", sizeof(icap_access), 0);
+#endif
+
     /* init string pools */
     for (i = 0; i < mem_str_pool_count; i++) {
 	StrPools[i].pool = memPoolCreate(StrPoolsAttrs[i].name, StrPoolsAttrs[i].obj_size);
Index: src/mk-string-arrays.pl
--- src/mk-string-arrays.pl.orig	1998-04-08 01:31:51 +0200
+++ src/mk-string-arrays.pl	2004-09-13 13:23:52 +0200
@@ -16,6 +16,7 @@
 $pat{'icp_opcode'} = "icp_opcode_str";
 $pat{'swap_log_op'} = "swap_log_op_str";
 $pat{'lookup_t'} = "lookup_t_str";
+$pat{'icap_service_t'} = "icap_service_type_str";
 
 $state = 0;	# start state
 while (<>) {
Index: src/protos.h
--- src/protos.h.orig	2004-02-04 18:42:28 +0100
+++ src/protos.h	2004-09-13 13:23:52 +0200
@@ -141,7 +141,7 @@
 extern void clientHttpConnectionsClose(void);
 extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags);
 extern int isTcpHit(log_type);
-extern void clientReadBody(request_t * req, char *buf, size_t size, CBCB * callback, void *data);
+extern CB clientReadBody;
 extern void clientAbortBody(request_t * req);
 
 extern int commSetNonBlocking(int fd);
@@ -623,6 +623,7 @@
 extern FREE *memBufFreeFunc(MemBuf * mb);
 /* puts report on MemBuf _module_ usage into mb */
 extern void memBufReport(MemBuf * mb);
+extern int memBufRead(int fd, MemBuf * mb);
 
 extern char *mime_get_header(const char *mime, const char *header);
 extern char *mime_get_header_field(const char *mime, const char *name, const char *prefix);
@@ -1346,4 +1347,49 @@
 extern void externalAclShutdown(void);
 extern char *strtokFile(void);
 
+#ifdef HS_FEAT_ICAP
+/*
+ * icap_common.c
+ */
+void icapInit(void);
+void icapClose(void);
+void icapParseEncapsulated(IcapStateData *, const char *, const char *);
+icap_service *icapService(icap_service_t, request_t *);
+int icapConnect(IcapStateData *, CNCB *);
+IcapStateData *icapAllocate(void);
+PF icapStateFree;
+PF icapConnectTimeout;
+PF icapReadTimeout;
+icap_service_t icapServiceToType(const char *);
+const char *icapServiceToStr(const icap_service_t);
+int icapCheckAcl(clientHttpRequest *);
+size_t icapLineLength(const char *, int);
+int icapReadHeader(int, IcapStateData *, int *);
+int icapFindHeader(const char *, const char *, const char **, const char **);
+int icapParseKeepAlive(const IcapStateData *, const char *, const char *);
+void icapSetKeepAlive(IcapStateData * icap, const char *hdrs);
+size_t icapParseChunkedBody(IcapStateData *, STRCB *, void *);
+void icapAddAuthUserHeader(MemBuf *, auth_user_request_t *);
+
+
+/*
+ * icap_respmod.c
+ */
+IcapStateData *icapRespModStart(icap_service_t, request_t *, StoreEntry *, http_state_flags);
+void icapSendRespMod(IcapStateData *, char *, int, int);
+CNCB icapConnectOver;
+
+/*
+ * icap_reqmod.c
+ */
+IcapStateData *icapReqModStart(icap_service_t, const char *, request_t *, int, struct timeval, struct in_addr, void *);
+
+/* icap_opt.c */
+void icapOptInit(void);
+void icapOptShutdown(void);
+void icapOptSetUnreachable(icap_service * s);
+/* for debugging purposes only */
+void dump_icap_config(IcapConfig * cfg);
+#endif
+
 #endif /* SQUID_PROTOS_H */
Index: src/squid.h
--- src/squid.h.orig	2003-03-09 19:41:27 +0100
+++ src/squid.h	2004-09-13 13:23:52 +0200
@@ -38,6 +38,14 @@
 #include "config.h"
 
 /*
+ * experimental defines for ICAP
+ */
+#ifdef HS_FEAT_ICAP
+#define ICAP_PREVIEW 1
+#define SUPPORT_ICAP_204 1
+#endif
+
+/*
  * On some systems, FD_SETSIZE is set to something lower than the
  * actual number of files which can be opened.  IRIX is one case,
  * NetBSD is another.  So here we increase FD_SETSIZE to our
Index: src/stat.c
--- src/stat.c.orig	2003-06-22 23:32:10 +0200
+++ src/stat.c	2004-09-13 13:23:52 +0200
@@ -748,6 +748,17 @@
     storeAppendPrintf(sentry, "server.other.kbytes_out = %f/sec\n",
 	XAVG(server.other.kbytes_out.kb));
 
+#ifdef HS_FEAT_ICAP
+    storeAppendPrintf(sentry, "icap.all.requests = %f/sec\n",
+	XAVG(icap.all.requests));
+    storeAppendPrintf(sentry, "icap.all.errors = %f/sec\n",
+	XAVG(icap.all.errors));
+    storeAppendPrintf(sentry, "icap.all.kbytes_in = %f/sec\n",
+	XAVG(icap.all.kbytes_in.kb));
+    storeAppendPrintf(sentry, "icap.all.kbytes_out = %f/sec\n",
+	XAVG(icap.all.kbytes_out.kb));
+#endif
+
     storeAppendPrintf(sentry, "icp.pkts_sent = %f/sec\n",
 	XAVG(icp.pkts_sent));
     storeAppendPrintf(sentry, "icp.pkts_recv = %f/sec\n",
@@ -1129,6 +1140,17 @@
     storeAppendPrintf(sentry, "server.other.kbytes_out = %d\n",
 	(int) f->server.other.kbytes_out.kb);
 
+#if HS_FEAT_ICAP
+    storeAppendPrintf(sentry, "icap.all.requests = %d\n",
+	(int) f->icap.all.requests);
+    storeAppendPrintf(sentry, "icap.all.errors = %d\n",
+	(int) f->icap.all.errors);
+    storeAppendPrintf(sentry, "icap.all.kbytes_in = %d\n",
+	(int) f->icap.all.kbytes_in.kb);
+    storeAppendPrintf(sentry, "icap.all.kbytes_out = %d\n",
+	(int) f->icap.all.kbytes_out.kb);
+#endif
+
     storeAppendPrintf(sentry, "icp.pkts_sent = %d\n",
 	f->icp.pkts_sent);
     storeAppendPrintf(sentry, "icp.pkts_recv = %d\n",
Index: src/structs.h
--- src/structs.h.orig	2004-04-19 01:43:30 +0200
+++ src/structs.h	2004-09-13 13:23:53 +0200
@@ -374,6 +374,22 @@
     wordlist *args;
 };
 
+#if HS_FEAT_ICAP
+struct _IcapConfig {
+    int onoff;
+    int preview_enable;
+    icap_service *service_head;
+    icap_class *class_head;
+    icap_access *access_head;
+    int preview_size;
+    int check_interval;
+    int send_client_ip;
+    int send_auth_user;
+    char *auth_scheme;
+};
+
+#endif /* HS_FEAT_ICAP */
+
 struct _SquidConfig {
     struct {
 	size_t maxSize;
@@ -695,6 +711,9 @@
     char *store_dir_select_algorithm;
     int sleep_after_fork;	/* microseconds */
     external_acl *externalAclHelperList;
+#ifdef HS_FEAT_ICAP
+    IcapConfig icapcfg;
+#endif
 };
 
 struct _SquidConfig2 {
@@ -764,6 +783,7 @@
     unsigned char tos;
     char ipaddr[16];		/* dotted decimal address of peer */
     char desc[FD_DESC_SZ];
+    char pconn_name[SQUIDHOSTNAMELEN];
     struct {
 	unsigned int open:1;
 	unsigned int close_request:1;
@@ -973,6 +993,125 @@
     unsigned int abuse_detected:1;
 };
 
+#ifdef HS_FEAT_ICAP
+struct _IcapStateData {
+    request_t *request;
+    http_state_flags http_flags;
+    HttpStateData *httpState;	/* needed to parse HTTP headers only */
+    int icap_fd;
+    int sc;
+    icap_service *current_service;
+    MemBuf icap_hdr;
+    struct {
+	int res_hdr;
+	int res_body;
+	int req_hdr;
+	int req_body;
+	int opt_body;
+	int null_body;
+    } enc;
+    int bytes_to_gobble;
+    int chunk_size;
+    MemBuf chunk_buf;
+    int preview_size;
+    off_t fake_content_length;
+    int http_header_bytes_read_so_far;
+    struct {
+	const char *uri;	/* URI for REQMODs */
+	int client_fd;
+	struct timeval start;	/* for logging */
+	struct in_addr log_addr;	/* for logging */
+	int hdr_state;
+	MemBuf hdr_buf;
+	void *client_cookie;
+	struct {
+	    MemBuf buf;
+	    CBCB *callback;
+	    void *callback_data;
+	    char *callback_buf;
+	    size_t callback_bufsize;
+	    size_t bytes_read;
+	} http_entity;
+    } reqmod;
+    struct {
+	StoreEntry *entry;
+	MemBuf buffer;
+	MemBuf req_hdr_copy;	/* XXX barf */
+	MemBuf resp_copy;	/* XXX barf^max */
+	int res_body_sz;
+    } respmod;
+    struct {
+	unsigned int connect_requested:1;
+	unsigned int connect_pending:1;
+	unsigned int write_pending:1;
+	unsigned int keep_alive:1;
+	unsigned int http_server_eof:1;
+	unsigned int send_zero_chunk:1;
+	unsigned int got_reply:1;
+	unsigned int wait_for_reply:1;
+	unsigned int wait_for_preview_reply:1;
+	unsigned int preview_done:1;
+	unsigned int copy_response:1;
+	unsigned int no_content:1;
+	unsigned int reqmod_http_entity_eof:1;
+    } flags;
+};
+
+struct _icap_service {
+    icap_service *next;
+    char *name;			/* name to be used when referencing ths service */
+    char *uri;			/* uri of server/service to use */
+    char *type_name;		/* {req|resp}mod_{pre|post}cache */
+
+    char *hostname;
+    unsigned short int port;
+    char *resource;
+    icap_service_t type;	/* parsed type */
+    icap_method_t method;
+    ushort bypass;		/* flag: bypass allowed */
+    ushort unreachable;		/* flag: set to 1 if options request fails */
+    IcapOptData *opt;		/* temp data needed during opt request */
+    struct {
+	unsigned int allow_204:1;
+    } flags;
+    int preview;
+    String istag;
+    String transfer_preview;
+    String transfer_ignore;
+    String transfer_complete;
+    int max_connections;
+    int options_ttl;
+};
+
+struct _icap_service_list {
+    icap_service_list *next;
+    icap_service *service;
+};
+
+struct _icap_class {
+    icap_class *next;
+    char *name;
+    wordlist *services;
+    icap_service_list *isl;
+    ushort hidden;		/* for unnamed classes */
+};
+
+struct _icap_access {
+    icap_access *next;
+    char *service_name;
+    icap_class *class;
+    acl_access *access;
+};
+
+struct _IcapOptData {
+    char *buf;
+    off_t offset;
+    size_t size;
+    off_t headlen;
+};
+
+#endif
+
 struct _HttpStateData {
     StoreEntry *entry;
     request_t *request;
@@ -985,10 +1124,14 @@
     int fd;
     http_state_flags flags;
     FwdState *fwd;
+#ifdef HS_FEAT_ICAP
+    struct _IcapStateData *icap_writer;
+#endif
     char *body_buf;
     int body_buf_sz;
 };
 
+
 struct _icpUdpData {
     struct sockaddr_in address;
     void *msg;
@@ -1084,6 +1227,7 @@
 	unsigned int internal:1;
 	unsigned int done_copying:1;
 	unsigned int purging:1;
+	unsigned int did_icap_reqmod:1;
     } flags;
     struct {
 	http_status status;
@@ -1091,6 +1235,9 @@
     } redirect;
     dlink_node active;
     size_t maxBodySize;
+#if HS_FEAT_ICAP
+    IcapStateData *icap_reqmod;
+#endif
 };
 
 struct _ConnStateData {
@@ -1123,6 +1270,8 @@
 	int n;
 	time_t until;
     } defer;
+    REQHOOK *read_request_hook;
+    void *read_request_hook_data;
 };
 
 struct _ipcache_addrs {
@@ -1668,6 +1817,11 @@
     char *peer_login;		/* Configured peer login:password */
     time_t lastmod;		/* Used on refreshes */
     const char *vary_headers;	/* Used when varying entities are detected. Changes how the store key is calculated */
+#if HS_FEAT_ICAP
+    icap_class *class;
+#endif
+    CB *body_reader;
+    void *body_reader_data;
 };
 
 struct _cachemgr_passwd {
@@ -1772,7 +1926,11 @@
 	    kb_t kbytes_in;
 	    kb_t kbytes_out;
 	} all , http, ftp, other;
-    } server;
+    }
+#if HS_FEAT_ICAP
+	icap,
+#endif
+	server;
     struct {
 	int pkts_sent;
 	int queries_sent;
Index: src/typedefs.h
--- src/typedefs.h.orig	2004-02-04 18:42:29 +0100
+++ src/typedefs.h	2004-09-13 13:23:53 +0200
@@ -111,6 +111,15 @@
 typedef struct _HttpBody HttpBody;
 typedef struct _HttpReply HttpReply;
 typedef struct _HttpStateData HttpStateData;
+#ifdef HS_FEAT_ICAP
+typedef struct _IcapStateData IcapStateData;
+typedef struct _IcapConfig IcapConfig;
+typedef struct _icap_service icap_service;
+typedef struct _icap_service_list icap_service_list;
+typedef struct _icap_class icap_class;
+typedef struct _icap_access icap_access;
+typedef struct _IcapOptData IcapOptData;
+#endif
 typedef struct _icpUdpData icpUdpData;
 typedef struct _clientHttpRequest clientHttpRequest;
 typedef struct _ConnStateData ConnStateData;
@@ -235,6 +244,7 @@
 typedef int READ_HANDLER(int, char *, int);
 typedef int WRITE_HANDLER(int, const char *, int);
 typedef void CBCB(char *buf, ssize_t size, void *data);
+typedef void CB(void *, char *, size_t, CBCB *, void *);
 
 typedef void STIOCB(void *their_data, int errflag, storeIOState *);
 typedef void STFNCB(void *their_data, int errflag, storeIOState *);
@@ -363,4 +373,7 @@
 typedef struct _external_acl external_acl;
 typedef struct _external_acl_entry external_acl_entry;
 
+/* Request hooks */
+typedef int REQHOOK(ConnStateData * connState, clientHttpRequest * http, void *data);
+
 #endif /* SQUID_TYPEDEFS_H */
Index: src/url.c
--- src/url.c.orig	2003-01-18 15:16:49 +0100
+++ src/url.c	2004-09-13 13:23:53 +0200
@@ -102,6 +102,9 @@
     "whois",
     "internal",
     "https",
+#ifdef HS_FEAT_ICAP
+    "icap",
+#endif
     "TOTAL"
 };
 
@@ -220,6 +223,10 @@
 	return PROTO_WHOIS;
     if (strcasecmp(s, "internal") == 0)
 	return PROTO_INTERNAL;
+#ifdef HS_FEAT_ICAP
+    if (strcasecmp(s, "icap") == 0)
+	return PROTO_ICAP;
+#endif
     return PROTO_NONE;
 }
 
@@ -243,6 +250,10 @@
 	return CACHE_HTTP_PORT;
     case PROTO_WHOIS:
 	return 43;
+#ifdef HS_FEAT_ICAP
+    case PROTO_ICAP:
+	return 1344;
+#endif
     default:
 	return 0;
     }
