changeset 195:8dee38ea9117

nginx-0.0.1-2003-11-25-23:44:56 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 25 Nov 2003 20:44:56 +0000
parents 2357fa41738a
children 11fbd0fc041d
files auto/cc auto/configure auto/fmt/fmt auto/fmt/longlong auto/func auto/init auto/lib/lib auto/lib/make auto/lib/md5/makefile.msvc auto/lib/pcre/makefile.msvc auto/lib/zlib/patch.zlib auto/make auto/options auto/os/conf auto/os/freebsd auto/sources auto/types/longlong auto/types/sizeof auto/types/socklen_t auto/types/time_t auto/types/typedef auto/types/uint64_t auto/types/uintptr_t auto/unix src/core/nginx.c src/core/ngx_alloc.h src/core/ngx_conf_file.c src/core/ngx_conf_file.h src/core/ngx_config.h src/core/ngx_core.h src/core/ngx_file.c src/core/ngx_log.c src/core/ngx_modules.c src/core/ngx_regex.c src/core/ngx_regex.h src/core/ngx_times.c src/core/ngx_times.h src/event/modules/ngx_kqueue_module.c src/event/ngx_event.h src/event/ngx_event_connect.h src/event/ngx_event_timer.c src/event/ngx_event_timer.h src/event/ngx_event_write.c src/event/ngx_event_write.h src/event/ngx_event_wsarecv.c src/http/modules/ngx_http_chunked_filter.c src/http/modules/ngx_http_not_modified_filter.c src/http/modules/ngx_http_range_filter.c src/http/modules/ngx_http_static_handler.c src/http/modules/proxy/ngx_http_proxy_cache.c src/http/modules/proxy/ngx_http_proxy_handler.c src/http/modules/proxy/ngx_http_proxy_upstream.c src/http/ngx_http_busy_lock.c src/http/ngx_http_cache.c src/http/ngx_http_cache.h src/http/ngx_http_core_module.c src/http/ngx_http_core_module.h src/http/ngx_http_header_filter.c src/http/ngx_http_log_handler.c src/os/unix/ngx_files.h src/os/unix/ngx_freebsd_config.h src/os/unix/ngx_freebsd_init.c src/os/unix/ngx_freebsd_sendfile_chain.c src/os/unix/ngx_linux.h src/os/unix/ngx_linux_config.h src/os/unix/ngx_linux_sendfile_chain.c src/os/unix/ngx_posix_init.c src/os/unix/ngx_process.c src/os/unix/ngx_socket.c src/os/unix/ngx_socket.h src/os/unix/ngx_solaris_config.h src/os/unix/ngx_writev_chain.c src/os/win32/ngx_sendfile.c src/os/win32/ngx_win32_config.h
diffstat 74 files changed, 1936 insertions(+), 917 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/auto/cc
@@ -0,0 +1,109 @@
+
+case $CC in
+
+    *gcc)
+
+         # optimization
+         #CFLAGS="$CFLAGS -O2 -fomit-frame-pointer"
+
+         # warnings
+         CFLAGS="$CFLAGS -O -W"
+         CFLAGS="$CFLAGS -Wall -Wpointer-arith"
+         #CFLAGS="$CFLAGS -Wconversion"
+         #CFLAGS="$CFLAGS -Winline"
+
+         # we have a lot of the unused function arguments
+         CFLAGS="$CFLAGS -Wno-unused"
+
+         # stop on warning
+         CFLAGS="$CFLAGS -Werror"
+
+         # ANSI C warnings
+         #CFLAGS="$CFLAGS -pedantic"
+
+         # debug
+         CFLAGS="$CFLAGS -g"
+
+         OBJEXT=o
+         OBJOUT="-o "
+         BINOUT="-o "
+
+         CC_STRONG="$CC -Wall -Werror"
+    ;;
+
+
+    *icc)
+         # Intel C++ compiler 7.1
+
+         # optimization
+         CFLAGS="$CFLAGS -O"
+         # optimize for Pentium Pro, Pentium II and Pentium III
+         #CFLAGS="$CFLAGS -mcpu=pentiumpro"
+         # optimize for Pentium 4, default
+         #CFLAGS="$CFLAGS -mcpu=pentium4"
+
+         # warnings
+         CFLAGS="$CFLAGS -w1"
+
+         # stop on warning
+         CFLAGS="$CFLAGS -Werror"
+
+         OBJEXT=o
+         OBJOUT="-o "
+         BINOUT="-o "
+
+         CC_STRONG="$CC -w1 -Werror"
+    ;;
+
+
+    cl)
+         # MSVC 6.0 SP2
+
+         # optimization
+
+         # maximize speed
+         CFLAGS="$CFLAGS -O2"
+         # enable global optimization
+         CFLAGS="$CFLAGS -Og"
+         # enable intrinsic functions
+         CFLAGS="$CFLAGS -Oi"
+         # inline expansion
+         CFLAGS="$CFLAGS -Ob1"
+         # enable frame pointer omission
+         CFLAGS="$CFLAGS -Oy"
+         # disable stack checking calls
+         CFLAGS="$CFLAGS -Gs"
+         # optimize for Pentium Pro
+         CFLAGS="$CFLAGS -G6"
+
+         # warnings
+         CFLAGS="$CFLAGS -W3"
+         #CFLAGS="$CFLAGS -W4"
+
+         # stop on warning
+         CFLAGS="$CFLAGS -WX"
+
+         # multithreaded
+         CFLAGS="$CFLAGS -MT"
+
+         # disable logo
+         CFLAGS="$CFLAGS -nologo"
+
+         # link flags
+         CORE_LINK="$CORE_LINK -link"
+         CORE_LINK="$CORE_LINK -nodefaultlib:msvcrt"
+         CORE_LINK="$CORE_LINK -nodefaultlib:libcpmt"
+         CORE_LINK="$CORE_LINK -verbose:lib"
+
+         # debug
+         CFLAGS="$CFLAGS -Yd"
+         CORE_LINK="$CORE_LINK -debug -debugtype:coff"
+
+         OBJEXT=obj
+         OBJOUT="-Fo"
+         BINOUT="-Fe"
+
+         CC_STRONG="$CC -W3 -WX"
+    ;;
+
+esac
--- a/auto/configure
+++ b/auto/configure
@@ -1,53 +1,17 @@
 
-CC=cc
-CC_STRONG="$CC -Wall -Werror"
-CPP="$CC -E"
+. auto/options
+. auto/init
+. auto/sources
 
-NGX_AUTO_CONFIG_H=ngx_auto_config.h
+. auto/os/conf
+
+. auto/cc
+. auto/lib/lib
+. auto/make
+. auto/lib/make
 
 echo > $NGX_AUTO_CONFIG_H
 
-
-CC_WARN=$CC_STRONG
-
-NGX_FMT_NAME=OFF_FMT
-NGX_TYPE="off_t"; . auto/types/sizeof
-NGX_FORMATS="%ld %lld %qd"; . auto/fmt/fmt
-
-NGX_FMT_NAME=TIME_FMT
-NGX_TYPE="time_t"; . auto/types/sizeof
-NGX_FORMATS="%d %ld %lld %qd"; . auto/fmt/fmt
-
-
-CC_WARN=$CC
-
-exit
-
-
-NGX_TYPE="long"; . auto/types/sizeof; NGX_MAX_LONG=$NGX_MAX_SIZE
-NGX_FORMATS="l"; . auto/fmt/fmt
-
-
-NGX_TYPE="long long"; . auto/types/sizeof; NGX_MAX_LONG_LONG=$NGX_MAX_SIZE
-NGX_FORMATS="ll q"; . auto/fmt/fmt
-
-
-CC_WARN=$CC_STRONG
-
-NGX_TYPE="off_t"; . auto/types/sizeof
-NGX_FORMATS="l ll q"; . auto/fmt/fmt
-
-
-CC_WARN=$CC
-
-#NGX_TYPE="__int64_t"; . auto/types/typedef; NGX_TIME_T_FMT=$NGX_FMT
-
-#NGX_TYPE="time_t"; . auto/types/typedef; NGX_TIME_T_FMT=$NGX_FMT
-
-
-#exit
-
-. auto/types/uint64_t
-. auto/types/uintptr_t
-
-. auto/types/socklen_t
+if [ "$PLATFORM" != win32 ]; then
+    . auto/unix
+fi
--- a/auto/fmt/fmt
+++ b/auto/fmt/fmt
@@ -1,22 +1,27 @@
 
-echo "Checking for $NGX_TYPE printf() format"
+echo "checking for $NGX_TYPE printf() format"
 
 NGX_FMT=NO
 
 for FMT in $NGX_FORMATS
 do
-    echo "#include <unistd.h>" > autotest.c
     echo "#include <stdio.h>" >> autotest.c
     echo "#include <sys/types.h>" >> autotest.c
     echo "int main() {" >> autotest.c
     echo "printf(\"${FMT}\", ($NGX_TYPE) $NGX_MAX_SIZE);" >> autotest.c
     echo "return 0; }" >> autotest.c
 
-    eval "${CC_WARN} -o autotest autotest.c > /dev/null 2>&1"
+    eval "$CC_WARN $CC_TEST_FLAGS -o autotest autotest.c > /dev/null 2>&1"
+
+    MAX_SIZE=`echo $NGX_MAX_SIZE | sed -e "s/L*\$//"`
 
     if [ -x ./autotest ]; then
-        if [ "`./autotest`" = $NGX_MAX_SIZE ]; then
-            echo " + \"${FMT}\" used"
+        if [ "`./autotest`" = $MAX_SIZE ]; then
+            if [ $NGX_FMT_COLLECT = YES ]; then
+                echo " + \"${FMT}\" is appropriate"
+            else
+                echo " + \"${FMT}\" used"
+            fi
             NGX_FMT=$FMT
         fi
     fi
@@ -24,7 +29,12 @@ do
     rm autotest*
 
     if [ $NGX_FMT != NO ]; then
-        break
+        if [ $NGX_FMT_COLLECT = YES ]; then
+            eval "NGX_${NGX_BYTES}_FMT=\"\${NGX_${NGX_BYTES}_FMT} \$NGX_FMT\""
+            continue
+        else
+            break
+        fi
     fi
 
     echo " + \"${FMT}\" is not appropriate"
@@ -32,12 +42,14 @@ done
 
 
 if [ $NGX_FMT = NO ]; then
-    echo "printf() $NGX_TYPE format not found"
+    echo "$0: error: printf() $NGX_TYPE format not found"
     exit 1
 fi
 
 
-echo "#ifndef $NGX_FMT_NAME"                 >> $NGX_AUTO_CONFIG_H
-echo "#define $NGX_FMT_NAME  \"$NGX_FMT\""   >> $NGX_AUTO_CONFIG_H
-echo "#endif"                                >> $NGX_AUTO_CONFIG_H
-echo                                         >> $NGX_AUTO_CONFIG_H
+if [ $NGX_FMT_COLLECT = NO ]; then
+    echo "#ifndef $NGX_FMT_NAME"                 >> $NGX_AUTO_CONFIG_H
+    echo "#define $NGX_FMT_NAME  \"$NGX_FMT\""   >> $NGX_AUTO_CONFIG_H
+    echo "#endif"                                >> $NGX_AUTO_CONFIG_H
+    echo                                         >> $NGX_AUTO_CONFIG_H
+fi
deleted file mode 100644
--- a/auto/fmt/longlong
+++ /dev/null
@@ -1,45 +0,0 @@
-
-echo "Checking for printf() long long format"
-
-NGX_LONG_LONG_FMT=NO
-
-    echo "int main() {" > autotest.c
-    echo "printf(\"%llu\", (unsigned long long) -1);" >> autotest.c
-    echo "return 0; }" >> autotest.c
-
-    eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
-
-    if [ -x ./autotest -a "`./autotest`" = $NGX_MAX_LONG_LONG ]; then
-        echo " + \"%ll\" used"
-        NGX_LONG_LONG_FMT="ll"
-    else
-        echo " + \"%ll\" is not appropriate"
-    fi
-
-    rm autotest*
-
-
-if [ $NGX_LONG_LONG_FMT = NO ]; then
-
-    echo "int main() {" > autotest.c
-    echo "printf(\"%qu\", (unsigned long long) -1);" >> autotest.c
-    echo "return 0; }" >> autotest.c
-
-    eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
-
-    if [ -x ./autotest -a "`./autotest`" = $NGX_MAX_LONG_LONG ]; then
-        echo " + \"%q\" used"
-        NGX_LONG_LONG_FMT="q"
-    else
-        echo " + \"%q\" is not appropriate"
-    fi
-
-    rm autotest*
-
-fi
-
-
-if [ $NGX_LONG_LONG_FMT = NO ]; then
-    echo "printf() long long format not found"
-    exit 1
-fi
new file mode 100644
--- /dev/null
+++ b/auto/func
@@ -0,0 +1,21 @@
+
+echo "checking for $NGX_FUNC"
+
+echo "$NGX_UNISTD_H" > autotest.c
+echo "$NGX_FUNC_INC" >> autotest.c
+echo "int main() { $NGX_FUNC_TEST; return 0; }" >> autotest.c
+
+eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
+
+if [ -x autotest ]; then
+    echo " + $NGX_FUNC found"
+
+    echo "#ifndef $NGX_HAVE"      >> $NGX_AUTO_CONFIG_H
+    echo "#define $NGX_HAVE  1"   >> $NGX_AUTO_CONFIG_H
+    echo "#endif"                 >> $NGX_AUTO_CONFIG_H
+    echo                          >> $NGX_AUTO_CONFIG_H
+else
+    echo " + $NGX_FUNC not found"
+fi
+
+rm autotest*
new file mode 100644
--- /dev/null
+++ b/auto/init
@@ -0,0 +1,9 @@
+
+MAKEFILE=$OBJS/Makefile
+
+NGX_AUTO_CONFIG_H=$OBJS/ngx_auto_config.h
+NGX_MODULES_C=$OBJS/ngx_modules.c
+
+
+NGX_UNISTD_H="#include <unistd.h>"
+NGX_INTTYPES_H="#include <inttypes.h>"
new file mode 100644
--- /dev/null
+++ b/auto/lib/lib
@@ -0,0 +1,48 @@
+
+if [ $PCRE != NO ]; then
+
+    CORE_INCS="$CORE_INCS -I $PCRE"
+
+    if [ "$PLATFORM" = "win32" ]; then
+        CFLAGS="$CFLAGS -D PCRE_STATIC"
+        CORE_LIBS="$CORE_LIBS pcre.lib"
+        CORE_LINK="$CORE_LINK -libpath:$PCRE"
+    else 
+        CORE_DEPS="$CORE_DEPS $PCRE/.libs/libpcre.a"
+        CORE_LIBS="$CORE_LIBS -L $PCRE/.libs -lpcre"
+    fi
+fi
+
+
+if [ $MD5 != NO ]; then
+
+    CFLAGS="$CFLAGS -D HAVE_OPENSSL_MD5"
+    CORE_INCS="$CORE_INCS -I $MD5"
+
+    if [ "$PLATFORM" = "win32" ]; then
+        CORE_LIBS="$CORE_LIBS md5.lib"
+        CORE_LINK="$CORE_LINK -libpath:$MD5"
+    else 
+        LINK_DEPS="$LINK_DEPS $MD5/libmd5.a"
+        CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5"
+    fi
+
+elif [ $MD5_LIB != NO ]; then
+    CORE_LIBS="$CORE_LIBS $MD5_LIB"
+fi
+
+
+if [ $ZLIB != NO ]; then
+    CORE_INCS="$CORE_INCS -I $ZLIB"
+
+    if [ "$PLATFORM" = "win32" ]; then
+        CORE_LIBS="$CORE_LIBS zlib.lib"
+        CORE_LINK="$CORE_LINK -libpath:$ZLIB"
+    else 
+        LINK_DEPS="$LINK_DEPS $ZLIB/libz.a"
+        CORE_LIBS="$CORE_LIBS -L $ZLIB -lz"
+    fi
+
+elif [ $ZLIB_LIB != NO ]; then
+    CORE_LIBS="$CORE_LIBS $ZLIB_LIB"
+fi
new file mode 100644
--- /dev/null
+++ b/auto/lib/make
@@ -0,0 +1,26 @@
+
+if [ "$PLATFORM" != "win32" ]; then
+
+    if [ $PCRE != NO ]; then
+        echo "$PCRE/.libs/libpcre.a:"                  >> $MAKEFILE
+        echo "	cd $PCRE \\"                           >> $MAKEFILE
+        echo "	&& ./configure --disable-shared \\"    >> $MAKEFILE
+        echo "	&& \$(MAKE)"                           >> $MAKEFILE
+        echo                                           >> $MAKEFILE
+    fi
+
+
+    if [ $MD5 != NO ]; then
+        echo "$MD5/libmd5.a:"                          >> $MAKEFILE
+        echo "	cd $MD5 && \$(MAKE) x86-elf"           >> $MAKEFILE
+        echo                                           >> $MAKEFILE
+    fi
+
+
+    if [ $ZLIB != NO ]; then
+        echo "$ZLIB/libz.a:"                           >> $MAKEFILE
+        echo "	cd $ZLIB && ./configure && \$(MAKE)"   >> $MAKEFILE
+        echo                                           >> $MAKEFILE
+    fi
+
+fi
new file mode 100644
--- /dev/null
+++ b/auto/lib/md5/makefile.msvc
@@ -0,0 +1,4 @@
+
+all:
+	cl -nologo -c -MT -O2 -D MD5_ASM -D L_ENDIAN md5_dgst.c md5_one.c
+	link -lib -out:md5.lib md5_dgst.obj md5_one.obj asm/m-win32.obj
new file mode 100644
--- /dev/null
+++ b/auto/lib/pcre/makefile.msvc
@@ -0,0 +1,18 @@
+
+CC =		cl
+CFLAGS =	-O2 -Ob1 -Oi -Gs -MT
+LINK =		link
+
+PCREFLAGS =	-DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10
+
+
+all:
+	$(CC) -Fedftables dftables.c
+
+	dftables > chartables.c
+
+	$(CC) -nologo -c $(CFLAGS) $(PCREFLAGS)				\
+		maketables.c get.c study.c pcre.c
+
+	$(LINK) -lib -out:pcre.lib -verbose:lib				\
+		maketables.obj get.obj study.obj pcre.obj
new file mode 100644
--- /dev/null
+++ b/auto/lib/zlib/patch.zlib
@@ -0,0 +1,19 @@
+--- msdos/Makefile.w32	Sat Nov 15 13:01:29 2003
++++ msdos/Makefile.w32	Sat Nov 15 13:02:06 2003
+@@ -10,7 +10,7 @@
+ 
+ # ------------- Microsoft Visual C++ 4.0 and later -------------
+ MODEL=
+-CFLAGS=-Ox -GA3s -nologo -W3
++CFLAGS=-nologo -O2 -Ob1 -Oi -Gs -MT
+ CC=cl
+ LD=link
+ LDFLAGS=
+@@ -79,7 +79,6 @@
+   $(CC) -c $(CFLAGS) $*.c
+ 
+ zlib.lib: $(OBJ1) $(OBJ2)
+-  if exist zlib.lib del zlib.lib
+   lib /OUT:zlib.lib $(OBJ1) $(OBJ2)
+ 
+ example.exe: example.obj zlib.lib
new file mode 100644
--- /dev/null
+++ b/auto/make
@@ -0,0 +1,146 @@
+
+mkdir -p $OBJS/src/core $OBJS/src/event $OBJS/src/event/modules \
+         $OBJS/src/os/unix $OBJS/src/os/win32 \
+         $OBJS/src/http $OBJS/src/http/modules $OBJS/src/http/modules/proxy
+
+
+HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES \
+                     $HTTP_CHUNKED_FILTER_MODULE \
+                     $HTTP_RANGE_FILTER_MODULE \
+                     $HTTP_CHARSET_FILTER_MODULE"
+
+HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE $HTTP_INDEX_MODULE"
+
+if [ $HTTP_GZIP = YES ]; then
+    HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS"
+fi
+
+if [ $HTTP_PROXY = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_PROXY_MODULE"
+    HTTP_INCS="$HTTP_INCS $HTTP_PROXY_INCS"
+    HTTP_DEPS="$HTTP_DEPS $HTTP_PROXY_DEPS"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_PROXY_SRCS"
+fi
+
+modules="$CORE_MODULES $EVENT_MODULES $HTTP_MODULES \
+         $HTTP_FILTER_MODULES $HTTP_NOT_MODIFIED_FILTER_MODULE"
+
+
+echo "#include <ngx_config.h>"                > $NGX_MODULES_C
+echo "#include <ngx_core.h>"                  >> $NGX_MODULES_C
+echo                                          >> $NGX_MODULES_C
+
+for mod in $modules
+do
+    echo "extern ngx_module_t  $mod;"         >> $NGX_MODULES_C
+done
+
+echo                                          >> $NGX_MODULES_C
+echo 'ngx_module_t *ngx_modules[] = {'        >> $NGX_MODULES_C
+
+for mod in $modules
+do
+    echo "    &$mod,"                         >> $NGX_MODULES_C
+done
+
+echo "    NULL"                               >> $NGX_MODULES_C
+echo "};"                                     >> $NGX_MODULES_C
+
+
+echo "CC = $CC"                               > $MAKEFILE
+echo "CFLAGS = $CFLAGS"                       >> $MAKEFILE
+echo                                          >> $MAKEFILE
+
+echo "CORE_DEPS = \\"                         >> $MAKEFILE
+for dep in $CORE_DEPS
+do
+    echo "	$dep \\"                      >> $MAKEFILE
+done
+echo                                          >> $MAKEFILE
+
+echo "CORE_INCS = $CORE_INCS -I $OBJS"        >> $MAKEFILE
+echo                                          >> $MAKEFILE
+
+echo "HTTP_DEPS = \\"                         >> $MAKEFILE
+for inc in $HTTP_DEPS
+do
+    echo "	$inc \\"                      >> $MAKEFILE
+done
+echo                                          >> $MAKEFILE
+
+echo "HTTP_INCS = $HTTP_INCS"                 >> $MAKEFILE
+echo                                          >> $MAKEFILE
+
+
+
+echo "nginx: \\"                              >> $MAKEFILE
+
+for src in $CORE_SRCS $HTTP_SRCS
+do
+    obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+    echo "	$OBJS/$obj \\"                >> $MAKEFILE
+done
+
+for src in $NGX_MODULES_C $LINK_DEPS
+do
+    obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+    echo "	$obj \\"                      >> $MAKEFILE
+done
+
+echo                                          >> $MAKEFILE
+echo "	\$(CC) ${BINOUT}nginx \\"             >> $MAKEFILE
+
+for src in $CORE_SRCS $HTTP_SRCS
+do
+    obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+    echo "	$OBJS/$obj \\"                >> $MAKEFILE
+done
+
+obj=`echo $NGX_MODULES_C | sed -e "s/\.c\$/.$OBJEXT/"`
+echo "	$obj \\"                              >> $MAKEFILE
+echo "	$CORE_LIBS \\"                        >> $MAKEFILE
+echo "	$CORE_LINK"                           >> $MAKEFILE
+echo                                          >> $MAKEFILE
+
+
+deps="\$(CORE_DEPS)"
+args="\$(CFLAGS) \$(CORE_INCS)"
+
+echo "$obj: \\"                               >> $MAKEFILE
+echo "	$NGX_MODULES_C $deps"                 >> $MAKEFILE
+echo "	\$(CC) -c $args \\"                   >> $MAKEFILE
+echo "		$OBJOUT$obj \\"               >> $MAKEFILE
+echo "		$NGX_MODULES_C"               >> $MAKEFILE
+echo                                          >> $MAKEFILE
+
+
+
+
+for src in $CORE_SRCS
+do
+    obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+
+    echo "$OBJS/$obj: \\"                     >> $MAKEFILE
+    echo "	$src $deps"                   >> $MAKEFILE
+    echo "	\$(CC) -c $args \\"           >> $MAKEFILE
+    echo "		$OBJOUT$OBJS/$obj \\" >> $MAKEFILE
+    echo "		$src"                 >> $MAKEFILE
+    echo                                      >> $MAKEFILE
+done
+
+
+deps="\$(CORE_DEPS) \$(HTTP_DEPS)"
+args="\$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)"
+
+for src in $HTTP_SRCS
+do
+    obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"`
+
+    echo "$OBJS/$obj: \\"                     >> $MAKEFILE
+    echo "	$src $deps"                   >> $MAKEFILE
+    echo "	\$(CC) -c $args \\"           >> $MAKEFILE
+    echo "		$OBJOUT$OBJS/$obj \\" >> $MAKEFILE
+    echo "		$src"                 >> $MAKEFILE
+    echo                                      >> $MAKEFILE
+done
new file mode 100644
--- /dev/null
+++ b/auto/options
@@ -0,0 +1,68 @@
+
+HELP=NO
+
+CC=gcc
+OBJS=objs
+
+TEST_BUILD_DEVPOLL=NO
+
+HTTP_GZIP=YES
+HTTP_PROXY=YES
+
+PCRE=NO
+
+MD5=NO
+MD5_LIB=NO
+
+ZLIB=NO
+ZLIB_LIB=NO
+
+
+for option
+do
+    case "$option" in
+        -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+           *) value="" ;;
+    esac
+
+    case "$option" in
+        --help)                          HELP=YES                   ;;
+
+        --crossbuild=*)                  PLATFORM="$value"          ;;
+
+        --builddir=*)                    OBJS="$value"              ;;
+
+        --without-http_gzip_module)      HTTP_GZIP=NO               ;;
+        --without-http_proxy_module)     HTTP_PROXY=NO              ;;
+
+        --with-cc=*)                     CC="$value"                ;;
+
+        --with-pcre=*)                   PCRE="$value"              ;;
+        --with-md5=*)                    MD5="$value"               ;;
+        --with-zlib=*)                   ZLIB="$value"              ;;
+
+        --test-build-devpoll)            TEST_BUILD_DEVPOLL=YES     ;;
+
+        *)
+            echo "$0: error: invalid option \"$option\""
+            exit 1
+        ;;
+    esac
+done
+
+
+if [ $HELP = YES ]; then
+    echo "  --help                        this message"
+
+    echo "  --without-http_gzip_module    disable http_gzip_module"
+    echo "  --without-http_proxy_module   disable http_proxy_module"
+
+    echo "  --with-cc=NAME                name of or path to C compiler"
+    echo
+
+    echo "  --with-pcre=DIR               path to PCRE library"
+    echo "  --with-md5=DIR                path to md5 library"
+    echo "  --with-zlib=DIR               path to zlib library"
+
+    exit 1
+fi
new file mode 100644
--- /dev/null
+++ b/auto/os/conf
@@ -0,0 +1,47 @@
+
+if [ ".$PLATFORM" = "." ]; then
+    echo "checking for OS"
+
+    SYSTEM=`uname -s 2>/dev/null`
+    RELEASE=`uname -r 2>/dev/null`
+    MACHINE=`uname -m 2>/dev/null`
+
+    echo " + $SYSTEM $RELEASE $MACHINE"
+
+    PLATFORM="$SYSTEM:$RELEASE:$MACHINE";
+else
+    echo "building for $PLATFORM"
+fi
+
+case $PLATFORM in
+
+    FreeBSD:*)
+        . auto/os/freebsd
+    ;;
+
+    Solaris:*)
+        CC_TEST_FLAGS="-D_FILE_OFFSET_BITS=64"
+        CORE_LIBS="$CORE_LIBS -lsocket -lnsl"
+    ;;
+
+    Linux:*)
+        CC_TEST_FLAGS="-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE"
+    ;;
+
+    win32)
+        CORE_INCS="$WIN32_INCS"
+        CORE_DEPS="$WIN32_DEPS"
+        CORE_SRCS="$WIN32_SRCS $SELECT_SRCS $IOCP_SRCS"
+        EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE $IOCP_MODULE"
+
+        CFLAGS="$CFLAGS -D HAVE_AIO=1 -D HAVE_IOCP=1"
+        CORE_LIBS="$CORE_LIBS ws2_32.lib"
+    ;;
+
+esac
+
+
+if [ $TEST_BUILD_DEVPOLL = YES ]; then
+    EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
+    EVENT_SRCS="$EVENT_SRCS $DEVPOLL_SRCS"
+fi
new file mode 100644
--- /dev/null
+++ b/auto/os/freebsd
@@ -0,0 +1,40 @@
+
+
+CORE_INCS="$UNIX_INCS"
+CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
+CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS $SELECT_SRCS $POLL_SRCS"
+EVENT_MODULES="$EVENT_MODULES $SELECT_MODULE $POLL_MODULE"
+
+MD5_LIB="-lmd"
+ZLIB_LIB="-lz"
+
+version=`grep "#define __FreeBSD_version" /usr/include/osreldate.h \
+         | sed -e 's/^.* \(.*\)$/\1/'`
+
+
+# sendfile
+
+if [ $version -gt 300007 ]; then
+    CFLAGS="$CFLAGS -D HAVE_SENDFILE=1"
+    CORE_SRCS="$CORE_SRCS $FREEBSD_SENDFILE_SRCS"
+fi
+
+
+# kqueue
+
+if [ \( $version -lt 500000 -a $version -ge 410000 \) \
+     -o $version -ge 500011 ]
+then
+    CFLAGS="$CFLAGS -D HAVE_KQUEUE=1"
+    CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
+    EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
+fi
+
+
+# kqueue's NOTE_LAWAT
+
+if [ \( $version -lt 500000 -a $version -ge 430000 \) \
+     -o $version -ge 500018 ]
+then
+    CFLAGS="$CFLAGS -D HAVE_LOWAT_EVENT=1"
+fi
new file mode 100644
--- /dev/null
+++ b/auto/sources
@@ -0,0 +1,194 @@
+
+CORE_MODULES="ngx_core_module ngx_errlog_module"
+
+CORE_INCS="-I src/core"
+
+CORE_DEPS="src/core/nginx.h \
+            src/core/ngx_config.h \
+            src/core/ngx_log.h \
+            src/core/ngx_alloc.h \
+            src/core/ngx_array.h \
+            src/core/ngx_table.h \
+            src/core/ngx_hunk.h \
+            src/core/ngx_string.h \
+            src/core/ngx_parse.h \
+            src/core/ngx_inet.h \
+            src/core/ngx_file.h \
+            src/core/ngx_regex.h \
+            src/core/ngx_times.h \
+            src/core/ngx_connection.h \
+            src/core/ngx_conf_file.h \
+            src/core/ngx_garbage_collector.h"
+
+CORE_SRCS="src/core/nginx.c \
+            src/core/ngx_log.c \
+            src/core/ngx_alloc.c \
+            src/core/ngx_array.c \
+            src/core/ngx_hunk.c \
+            src/core/ngx_output_chain.c \
+            src/core/ngx_string.c \
+            src/core/ngx_parse.c \
+            src/core/ngx_inet.c \
+            src/core/ngx_file.c \
+            src/core/ngx_regex.c \
+            src/core/ngx_times.c \
+            src/core/ngx_conf_file.c \
+            src/core/ngx_garbage_collector.c"
+
+
+EVENT_MODULES="ngx_events_module ngx_event_core_module"
+
+EVENT_INCS="-I src/event -I src/event/modules"
+
+EVENT_DEPS="src/event/ngx_event.h \
+            src/event/ngx_event_timer.h \
+            src/event/ngx_event_connect.h \
+            src/event/ngx_event_pipe.h"
+
+EVENT_SRCS="src/event/ngx_event.c \
+            src/event/ngx_event_timer.c \
+            src/event/ngx_event_close.c \
+            src/event/ngx_event_accept.c \
+            src/event/ngx_event_connect.c \
+            src/event/ngx_event_pipe.c"
+
+
+SELECT_MODULE="ngx_select_module"
+SELECT_SRCS=src/event/modules/ngx_select_module.c
+
+POLL_MODULE="ngx_poll_module"
+POLL_SRCS=src/event/modules/ngx_poll_module.c
+
+KQUEUE_MODULE="ngx_kqueue_module"
+KQUEUE_SRCS=src/event/modules/ngx_kqueue_module.c
+
+DEVPOLL_MODULE="ngx_devpoll_module"
+DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c
+
+IOCP_MODULE="ngx_iocp_module"
+IOCP_SRCS=src/event/modules/ngx_iocp_module.c
+
+AIO_MODULE="ngx_aio_module"
+AIO_SRCS=src/event/modules/ngx_aio_module.c
+
+
+UNIX_INCS="$CORE_INCS $EVENT_INCS -I src/os/unix"
+
+UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
+            src/os/unix/ngx_time.h \
+            src/os/unix/ngx_types.h \
+            src/os/unix/ngx_errno.h \
+            src/os/unix/ngx_files.h \
+            src/os/unix/ngx_process.h \
+            src/os/unix/ngx_socket.h \
+            src/os/unix/ngx_os.h"
+
+UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
+            src/os/unix/ngx_time.c \
+            src/os/unix/ngx_sendv.c \
+            src/os/unix/ngx_files.c \
+            src/os/unix/ngx_socket.c \
+            src/os/unix/ngx_recv.c \
+            src/os/unix/ngx_readv_chain.c \
+            src/os/unix/ngx_writev_chain.c \
+            src/os/unix/ngx_posix_init.c \
+            src/os/unix/ngx_process.c \
+            src/os/unix/ngx_daemon.c"
+
+
+LINUX_SENDFILE_SRCS=src/os/unix/ngx_linux_sendfile_chain.c
+
+FREEBSD_DEPS=src/os/unix/ngx_freebsd_config.h
+FREEBSD_SRCS=src/os/unix/ngx_freebsd_init.c
+FREEBSD_SENDFILE_SRCS=src/os/unix/ngx_freebsd_sendfile_chain.c
+
+
+WIN32_INCS="$CORE_INCS $EVENT_INCS -I src/os/win32"
+
+WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \
+            src/os/win32/ngx_win32_config.h \
+            src/os/win32/ngx_time.h \
+            src/os/win32/ngx_types.h \
+            src/os/win32/ngx_errno.h \
+            src/os/win32/ngx_files.h \
+            src/os/win32/ngx_process.h \
+            src/os/win32/ngx_socket.h \
+            src/os/win32/ngx_os.h"
+
+WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \
+            src/os/win32/ngx_errno.c \
+            src/os/win32/ngx_files.c \
+            src/os/win32/ngx_time.c \
+            src/os/win32/ngx_socket.c \
+            src/os/win32/ngx_wsarecv.c \
+            src/os/win32/ngx_wsarecv_chain.c \
+            src/os/win32/ngx_wsasend_chain.c \
+            src/os/win32/ngx_sendv.c \
+            src/os/win32/ngx_win32_init.c \
+            src/event/ngx_event_acceptex.c"
+
+
+HTTP_MODULES="ngx_http_module \
+            ngx_http_core_module \
+            ngx_http_log_module \
+            ngx_http_cache_module"
+
+HTTP_FILTER_MODULES="ngx_http_write_filter_module \
+            ngx_http_output_filter_module \
+            ngx_http_header_filter_module"
+
+HTTP_CHUNKED_FILTER_MODULE=ngx_http_chunked_filter_module
+HTTP_RANGE_FILTER_MODULE=ngx_http_range_filter_module
+HTTP_CHARSET_FILTER_MODULE=ngx_http_charset_filter_module
+HTTP_NOT_MODIFIED_FILTER_MODULE=ngx_http_not_modified_filter_module
+
+HTTP_STATIC_MODULE=ngx_http_static_module
+HTTP_INDEX_MODULE=ngx_http_index_module
+
+HTTP_INCS="-I src/http -I src/http/modules"
+
+HTTP_DEPS="src/http/ngx_http.h \
+            src/http/ngx_http_request.h \
+            src/http/ngx_http_filter.h \
+            src/http/ngx_http_config.h \
+            src/http/ngx_http_core_module.h \
+            src/http/ngx_http_cache.h \
+            src/http/ngx_http_busy_lock.h \
+            src/http/ngx_http_log_handler.h"
+
+HTTP_SRCS="src/http/ngx_http.c \
+            src/http/ngx_http_core_module.c \
+            src/http/ngx_http_special_response.c \
+            src/http/ngx_http_request.c \
+            src/http/ngx_http_cache.c \
+            src/http/ngx_http_busy_lock.c \
+            src/http/ngx_http_parse.c \
+            src/http/ngx_http_headers.c \
+            src/http/ngx_http_header_filter.c \
+            src/http/ngx_http_write_filter.c \
+            src/http/ngx_http_output_filter.c \
+            src/http/ngx_http_log_handler.c \
+            src/http/ngx_http_request_body.c \
+            src/http/ngx_http_parse_time.c \
+            src/http/modules/ngx_http_static_handler.c \
+            src/http/modules/ngx_http_index_handler.c \
+            src/http/modules/ngx_http_chunked_filter.c \
+            src/http/modules/ngx_http_range_filter.c \
+            src/http/modules/ngx_http_charset_filter.c \
+            src/http/modules/ngx_http_not_modified_filter.c"
+
+
+HTTP_GZIP_FILTER_MODULE=ngx_http_gzip_filter_module
+HTTP_GZIP_SRCS=src/http/modules/ngx_http_gzip_filter.c
+HTTP_GZIP_UNIX_LIBS=-lz
+HTTP_GZIP_WIN_LIBS=zlib.lib
+
+
+HTTP_PROXY_MODULE=ngx_http_proxy_module
+HTTP_PROXY_INCS="-I src/http/modules/proxy"
+HTTP_PROXY_DEPS=src/http/modules/proxy/ngx_http_proxy_handler.h
+HTTP_PROXY_SRCS="src/http/modules/proxy/ngx_http_proxy_handler.c \
+            src/http/modules/proxy/ngx_http_proxy_upstream.c \
+            src/http/modules/proxy/ngx_http_proxy_cache.c \
+            src/http/modules/proxy/ngx_http_proxy_parse.c \
+            src/http/modules/proxy/ngx_http_proxy_header.c"
deleted file mode 100644
--- a/auto/types/longlong
+++ /dev/null
@@ -1,31 +0,0 @@
-
-echo "Checking for long long size"
-
-BYTES=
-
-echo "int main() {" > autotest.c
-echo "printf(\"%d\", sizeof(long long));" >> autotest.c
-echo "return 0; }" >> autotest.c
-
-eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
-
-if [ -x ./autotest ]; then
-    BYTES=`./autotest`
-    echo " + long long is $BYTES bytes"
-fi
-
-rm autotest*
-
-case $BYTES in
-    4)
-        NGX_MAX_LONG_LONG=4294967295
-    ;;
-
-    8)
-        NGX_MAX_LONG_LONG=18446744073709551615
-    ;;
-
-    *)
-        echo "$0: error: can not detect long long size"
-        exit 1
-esac
--- a/auto/types/sizeof
+++ b/auto/types/sizeof
@@ -1,29 +1,37 @@
 
-echo "Checking for $NGX_TYPE size"
+echo "checking for $NGX_TYPE size"
 
-BYTES=
+NGX_BYTES=
 
 echo "#include <sys/types.h>" > autotest.c
 echo "int main() {" >> autotest.c
 echo "printf(\"%d\", sizeof($NGX_TYPE));" >> autotest.c
 echo "return 0; }" >> autotest.c
 
-eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
+eval "$CC $CC_TEST_FLAGS -o autotest autotest.c > /dev/null 2>&1"
 
 if [ -x ./autotest ]; then
-    BYTES=`./autotest`
-    echo " + $NGX_TYPE is $BYTES bytes"
+    NGX_BYTES=`./autotest`
+    echo " + $NGX_TYPE is $NGX_BYTES bytes"
 fi
 
 rm autotest*
 
-case $BYTES in
+case $NGX_BYTES in
     4)
-        NGX_MAX_SIZE=2147483647
+        if [ "$NGX_TYPE"="long" ]; then
+            NGX_MAX_SIZE=2147483647L
+        else
+            NGX_MAX_SIZE=2147483647
+        fi
     ;;
 
     8)
-        NGX_MAX_SIZE=9223372036854775807
+        if [ "$NGX_TYPE"="long long" ]; then
+            NGX_MAX_SIZE=9223372036854775807LL
+        else
+            NGX_MAX_SIZE=9223372036854775807L
+        fi
     ;;
 
     *)
deleted file mode 100644
--- a/auto/types/socklen_t
+++ /dev/null
@@ -1,28 +0,0 @@
-
-found=0
-
-echo 'Checking for socklen_t'
-
-echo '#include <sys/types.h>' > autotest.c
-echo '#include <sys/socket.h>' >> autotest.c
-echo 'int main() { socklen_t i = 0; return 0; }' >> autotest.c
-
-eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
-
-if [ -x autotest ]; then
-    echo ' + socklen_t found'
-    found=1
-else
-    echo ' + socklen_t not found'
-    echo ' + uint32_t used'
-    type='typedef uint32_t  socklen_t;'
-    found=2
-fi
-
-rm autotest*
-
-
-if [ $found = 2 ]; then
-    echo $type >> ngx_auto_config.h
-    echo >> ngx_auto_config.h
-fi
deleted file mode 100644
--- a/auto/types/time_t
+++ /dev/null
@@ -1,30 +0,0 @@
-
-echo "Checking for printf() time_t format"
-
-echo '#include <sys/types.h>' > autotest.c
-type=`${CPP} autotest.c | awk '/^typedef.*time_t/ {print \$2}'`
-rm autotest.c
-
-case $type in
-    long)
-        echo ' + long: "%ld" used'
-        fmt='"%ld"'
-    ;;
-
-    int)
-        echo ' + int: "%d" used'
-        fmt='"%d"'
-    ;;
-
-    *)
-        echo "$0: error: unknown time_t definition: \"$type\""
-        exit 1
-    ;;
-
-esac
-
-
-echo "#ifndef TIME_FMT" >> ngx_auto_config.h
-echo "#define TIME_FMT  $fmt" >> ngx_auto_config.h
-echo "#endif" >> ngx_auto_config.h
-echo >> ngx_auto_config.h
--- a/auto/types/typedef
+++ b/auto/types/typedef
@@ -1,32 +1,42 @@
-
-echo "Checking for $NGX_TYPE definition"
 
-echo "#include <sys/types.h>" > autotest.c
-TYPE=`${CPP} autotest.c | \
-      awk "/^typedef.*$NGX_TYPE/ { for (i = 1; i< NF; i++) print $i}"`
-#rm autotest.c
+echo "checking for $NGX_TYPE"
+
+FOUND=NO
 
-echo $TYPE
+for TYPE in $NGX_TYPE $NGX_TYPES
+do
+    echo "#include <sys/types.h>" > autotest.c
+    echo "#include <sys/socket.h>" >> autotest.c
+    echo "$NGX_INTTYPES_H" >> autotest.c
+    echo "int main() { $TYPE i = 0; return 0; }" >> autotest.c
 
-case $TYPE in
-    "long long")
-        echo ' + defined as long long'
-        NGX_FMT=$NGX_LONG_LONG_FMT
-    ;;
+    eval "$CC -o autotest autotest.c > /dev/null 2>&1"
 
-    long)
-        echo ' + defined as long'
-        NGX_FMT=$NGX_LONG_FMT
-    ;;
+    if [ -x autotest ]; then
+        if [ $TYPE = $NGX_TYPE ]; then
+            echo " + $NGX_TYPE found"
+            FOUND=YES
+        else
+            echo " + $TYPE used"
+            FOUND=$TYPE
+        fi
+    fi
+
+    rm autotest*
 
-    int)
-        echo ' + defined as int'
-        NGX_FMT=$NGX_INT_FMT
-    ;;
+    if [ $FOUND = NO ]; then
+        echo " + $TYPE not found"
+    else
+        break
+    fi
+done
 
-    *)
-        echo "$0: error: unknown $NGX_TYPE definition: \"$TYPE\""
-        exit 1
-    ;;
+if [ $FOUND = NO ]; then
+    echo "$0: error: can not define $NGX_TYPE"
+    exit 1
+fi
 
-esac
+if [ $FOUND != YES ]; then
+    echo "typedef $FOUND  $NGX_TYPE;"   >> $NGX_AUTO_CONFIG_H
+    echo                                >> $NGX_AUTO_CONFIG_H
+fi
deleted file mode 100644
--- a/auto/types/uint64_t
+++ /dev/null
@@ -1,50 +0,0 @@
-
-found=0
-
-echo 'Checking for uint64_t'
-
-    echo '#include <sys/types.h>' > autotest.c
-    echo 'int main() { uint64_t i = 0; return 0; }' >> autotest.c
-
-    eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
-
-    if [ -x autotest ]; then
-        echo ' + uint64_t found'
-        found=1
-    else
-        echo ' + uint64_t not found'
-    fi
-
-    rm autotest*
-
-
-if [ $found = 0 ]; then
-
-    echo '#include <sys/types.h>' > autotest.c
-    echo 'int main() { u_int64_t i = 0; return 0; }' >> autotest.c
-
-    eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
-
-    if [ -x autotest ]; then
-        echo ' + u_int64_t used'
-        type='typedef u_int64_t  uint64_t;'
-        found=2
-    else
-        echo ' + u_int64_t not found'
-    fi
-
-    rm autotest*
-
-fi
-
-
-if [ $found = 0 ]; then
-    echo "$0: error: uint64_t not found"
-    exit 1
-fi
-
-
-if [ $found = 2 ]; then
-    echo $type >> ngx_auto_config.h
-    echo >> ngx_auto_config.h
-fi
--- a/auto/types/uintptr_t
+++ b/auto/types/uintptr_t
@@ -1,47 +1,26 @@
 
-found=0
+echo 'checking for uintptr_t'
 
-echo 'Checking for uintptr_t'
+FOUND=NO
 
-    echo '#include <sys/types.h>' > autotest.c
-    echo 'int main() { uintptr_t i = 0; return i; }' >> autotest.c
+echo "#include <sys/types.h>" > autotest.c
+echo "int main() { uintptr_t i = 0; return 0; }" >> autotest.c
 
-    eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
+eval "$CC -o autotest autotest.c > /dev/null 2>&1"
 
-    if [ -x autotest ]; then
-        echo ' + uintptr_t found'
-        found=1
-    else
-        echo ' + uintptr_t not found'
-    fi
+if [ -x autotest ]; then
+    echo " + uintptr_t found"
+    FOUND=YES
+else
+    echo " + uintptr_t not found"
+fi
 
-    rm autotest*
+rm autotest*
 
 
-if [ $found = 0 ]; then
-    echo 'int main() { printf("%d", 8 * sizeof(void *)); return 0; }'	\
-          > autotest.c
-    eval "${CC} -o autotest autotest.c > /dev/null 2>&1"
-
-    if [ -x autotest ]; then
-        type="uint`./autotest`_t"
-        echo " + $type used"
-        type="typedef $type  uintptr_t;"
-        found=2
-    fi
-
-    rm autotest*
+if [ $FOUND = NO ]; then
+    FOUND="uint`expr 8 \* $NGX_PTR_BYTES`_t"
+    echo " + $FOUND used"
+    echo "typedef $FOUND  uintptr_t;"   >> $NGX_AUTO_CONFIG_H
+    echo                                >> $NGX_AUTO_CONFIG_H
 fi
-
-
-if [ $found = 0 ]; then
-    echo "$0: error: uintptr_t not found"
-    exit 1
-fi
-
-
-if [ $found = 2 ]; then
-    echo $type >> ngx_auto_config.h
-    echo >> ngx_auto_config.h
-fi
-
new file mode 100755
--- /dev/null
+++ b/auto/unix
@@ -0,0 +1,70 @@
+
+CC_WARN=$CC
+NGX_FMT_COLLECT=YES
+
+NGX_TYPE="int"; . auto/types/sizeof;
+NGX_FORMATS="%d"; . auto/fmt/fmt
+
+NGX_TYPE="long"; . auto/types/sizeof;
+NGX_FORMATS="%ld"; . auto/fmt/fmt
+
+NGX_TYPE="long long"; . auto/types/sizeof;
+NGX_FORMATS="%lld %qd"; . auto/fmt/fmt
+
+NGX_TYPE="void *"; . auto/types/sizeof; NGX_PTR_BYTES=$NGX_BYTES
+
+
+CC_WARN=$CC_STRONG
+NGX_FMT_COLLECT=NO
+
+NGX_FMT_NAME=OFF_T_FMT
+NGX_TYPE="off_t"; . auto/types/sizeof
+eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+
+NGX_FMT_NAME=TIME_T_FMT
+NGX_TYPE="time_t"; . auto/types/sizeof
+eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+
+NGX_FMT_NAME=SIZE_T_FMT
+NGX_TYPE="size_t"; . auto/types/sizeof
+eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+
+NGX_FMT_NAME=SIZE_T_X_FMT; . auto/fmt/xfmt
+
+NGX_FMT_NAME=PID_T_FMT
+NGX_TYPE="pid_t"; . auto/types/sizeof
+eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+
+NGX_FMT_NAME=RLIM_T_FMT
+NGX_TYPE="rlim_t"; . auto/types/sizeof
+eval NGX_FORMATS=\${NGX_${NGX_BYTES}_FMT}; . auto/fmt/fmt
+
+
+CC_WARN=$CC
+
+NGX_TYPE="uint64_t"
+NGX_TYPES="u_int64_t"; . auto/types/typedef
+
+NGX_TYPE="socklen_t"
+NGX_TYPES="u_int32_t"; . auto/types/typedef
+
+. auto/types/uintptr_t
+
+
+NGX_FUNC_INC=
+NGX_FUNC_TEST="int fd = 0; char buf[1]; size_t size = 1;
+               ssize_t n; off_t offset = 0;
+               n = pread(fd, buf, size, offset)"
+NGX_HAVE=HAVE_PREAD; NGX_FUNC="pread()"; . auto/func
+
+
+NGX_FUNC_INC=
+NGX_FUNC_TEST="int fd = 1; char buf[1]; size_t size = 1;
+               ssize_t n; off_t offset = 0;
+               n = pwrite(fd, buf, size, offset)"
+NGX_HAVE=HAVE_PWRITE; NGX_FUNC="pwrite()"; . auto/func
+
+
+NGX_FUNC_INC="#include <time.h>"
+NGX_FUNC_TEST="struct tm t; time_t c=0; localtime_r(&c, &t)"
+NGX_HAVE=HAVE_LOCALTIME_R; NGX_FUNC="localtime_r()"; . auto/func
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -59,6 +59,7 @@ ngx_array_t            ngx_old_cycles;
 static ngx_pool_t     *ngx_temp_pool;
 static ngx_event_t     ngx_cleaner_event;
 
+
 /* STUB NAME */
 static ngx_connection_t  dumb;
 
@@ -91,7 +92,8 @@ int main(int argc, char *const *argv)
 
     /* TODO */ ngx_max_sockets = -1;
 
-    ngx_init_time();
+    ngx_time_init();
+    ngx_regex_init();
 
     log = ngx_log_init_errlog();
 
--- a/src/core/ngx_alloc.h
+++ b/src/core/ngx_alloc.h
@@ -7,9 +7,9 @@
 
 
 /*
- * NGX_MAX_ALLOC_FROM_POOL should be (PAGE_SIZE - 1), i.e. 4095 on x86.
+ * NGX_MAX_ALLOC_FROM_POOL should be (NGX_PAGE_SIZE - 1), i.e. 4095 on x86.
  * On FreeBSD 5.x it allows to use zero copy send.
- * On Windows NT it decreases number of locked pages in kernel.
+ * On Windows NT it decreases a number of locked pages in a kernel.
  */
 #define NGX_MAX_ALLOC_FROM_POOL 4095
 
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -3,9 +3,6 @@
 #include <ngx_core.h>
 
 
-
-#define MAX_CONF_ERRSTR  256
-
 /* Ten fixed arguments */
 
 static int argument_number[] = {
@@ -471,7 +468,29 @@ ngx_log_debug(cf->log, "%d:%d:%d:%d:%d '
                      len++)
                 {
                     if (*src == '\\') {
-                        src++;
+                        switch (src[1]) {
+                        case '"':
+                        case '\'':
+                        case '\\':
+                            src++;
+                            break;
+
+                        case 't':
+                            *dst++ = '\t';
+                            src += 2;
+                            continue;
+
+                        case 'r':
+                            *dst++ = '\r';
+                            src += 2;
+                            continue;
+
+                        case 'n':
+                            *dst++ = '\n';
+                            src += 2;
+                            continue;
+                        }
+
                     }
                     *dst++ = *src++;
                 }
@@ -525,7 +544,7 @@ void ngx_conf_log_error(int level, ngx_c
                         char *fmt, ...)
 {
     int      len;
-    char     errstr[MAX_CONF_ERRSTR];
+    char     errstr[NGX_MAX_CONF_ERRSTR];
     va_list  args;
 
     va_start(args, fmt);
--- a/src/core/ngx_conf_file.h
+++ b/src/core/ngx_conf_file.h
@@ -56,6 +56,9 @@
 #define NGX_CONF_MODULE      0x464E4F43  /* "CONF" */
 
 
+#define NGX_MAX_CONF_ERRSTR  256
+
+
 struct ngx_command_s {
     ngx_str_t     name;
     int           type;
--- a/src/core/ngx_config.h
+++ b/src/core/ngx_config.h
@@ -2,9 +2,6 @@
 #define _NGX_CONFIG_H_INCLUDED_
 
 
-#include <ngx_auto_config.h>
-
-
 #if defined __FreeBSD__
 #include <ngx_freebsd_config.h>
 
@@ -32,6 +29,13 @@
 #endif
 
 
+/* STUB: autoconf */
+typedef int    ngx_int_t;
+typedef u_int  ngx_uint_t;
+
+#include <ngx_auto_config.h>
+
+
 #ifndef NGX_SERVER_ROOT
 #define NGX_SERVER_ROOT   "./"
 #if 0
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -28,6 +28,7 @@ typedef struct ngx_connection_s  ngx_con
 #include <ngx_types.h>
 #include <ngx_file.h>
 #include <ngx_files.h>
+#include <ngx_regex.h>
 #include <ngx_times.h>
 #include <ngx_inet.h>
 #include <ngx_conf_file.h>
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -70,7 +70,10 @@ int ngx_create_temp_file(ngx_file_t *fil
 #endif
 #endif
 
+#if 0
         file->fd = ngx_open_tempfile(file->name.data, persistent);
+#endif
+        file->fd = ngx_open_tempfile(file->name.data, 1);
 
 ngx_log_debug(file->log, "temp fd: %d" _ file->fd);
 
@@ -225,14 +228,15 @@ char *ngx_conf_set_path_slot(ngx_conf_t 
             return "invalid value";
         }
 
-        path->len += path->level[i] + level + 1;
+        path->level[i] = level;
+        path->len += level + 1;
     }
 
     while (i < 3) {
         path->level[i++] = 0;
     }
 
-    path->gc_handler = cmd->post;
+    path->gc_handler = (ngx_gc_handler_pt) cmd->post;
 
     return NGX_CONF_OK;
 }
--- a/src/core/ngx_log.c
+++ b/src/core/ngx_log.c
@@ -89,7 +89,7 @@ void ngx_log_error_core(int level, ngx_l
 
     /* pid#tid */
     len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,
-                        PID_FMT "#%d: ", ngx_getpid(), 0);
+                        PID_T_FMT "#%d: ", ngx_getpid(), 0);
 
     if (log->data) {
         len += ngx_snprintf(errstr + len, sizeof(errstr) - len - 1,
--- a/src/core/ngx_modules.c
+++ b/src/core/ngx_modules.c
@@ -28,6 +28,7 @@ extern ngx_module_t  ngx_aio_module;
 extern ngx_module_t  ngx_http_module;
 extern ngx_module_t  ngx_http_core_module;
 extern ngx_module_t  ngx_http_log_module;
+extern ngx_module_t  ngx_http_cache_module;
 
 extern ngx_module_t  ngx_http_write_filter_module;
 extern ngx_module_t  ngx_http_output_filter_module;
@@ -78,6 +79,8 @@ ngx_module_t *ngx_modules[] = {
 
     &ngx_http_core_module,
     &ngx_http_log_module,
+    &ngx_http_cache_module,
+
     &ngx_http_write_filter_module,
     &ngx_http_output_filter_module,
     &ngx_http_header_filter_module,
new file mode 100644
--- /dev/null
+++ b/src/core/ngx_regex.c
@@ -0,0 +1,71 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+static void *ngx_regex_malloc(size_t size);
+static void ngx_regex_free(void *p);
+
+
+/* THREADS: this pool should be private for each thread */
+static ngx_pool_t  *ngx_pcre_pool;
+
+
+void ngx_regex_init()
+{
+    pcre_malloc = ngx_regex_malloc;
+    pcre_free = ngx_regex_free;
+}
+
+
+ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
+                               ngx_pool_t *pool, ngx_str_t *err)
+{
+    int           erroff;
+    const char   *errstr;
+    ngx_regex_t  *re;
+
+    ngx_pcre_pool = pool;
+
+    re = pcre_compile(pattern->data, (int) options, &errstr, &erroff, NULL);
+
+    if (re == NULL) {
+       if ((size_t) erroff == pattern->len) { 
+           ngx_snprintf(err->data, err->len - 1,
+                        "pcre_compile() failed: %s in \"%s\"",
+                        errstr, pattern->data);
+        } else {
+           ngx_snprintf(err->data, err->len - 1,
+                        "pcre_compile() failed: %s in \"%s\" at \"%s\"",
+                        errstr, pattern->data, pattern->data + erroff);
+        }
+    }
+
+    return re;
+}
+
+
+ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s)
+{
+    int  rc;
+
+    rc = pcre_exec(re, NULL, s->data, s->len, 0, 0, NULL, 0);
+
+    if (rc == -1) {
+        return NGX_DECLINED;
+    }
+
+    return rc;
+}
+
+
+static void *ngx_regex_malloc(size_t size)
+{
+    return ngx_palloc(ngx_pcre_pool, size);
+}
+
+
+static void ngx_regex_free(void *p)
+{
+    return;
+}
new file mode 100644
--- /dev/null
+++ b/src/core/ngx_regex.h
@@ -0,0 +1,23 @@
+#ifndef _NGX_REGEX_H_INCLUDED_
+#define _NGX_REGEX_H_INCLUDED_
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+#include <pcre.h>
+
+
+#define NGX_REGEX_CASELESS  PCRE_CASELESS
+
+typedef pcre  ngx_regex_t;
+
+void ngx_regex_init();
+ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
+                               ngx_pool_t *pool, ngx_str_t *err);
+ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s);
+
+#define ngx_regex_exec_n  "pcre_exec()"
+
+
+#endif /* _NGX_REGEX_H_INCLUDED_ */
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -22,7 +22,7 @@ static char  *months[] = { "Jan", "Feb",
                            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
 
 
-void ngx_init_time()
+void ngx_time_init()
 {
     struct timeval  tv;
 
--- a/src/core/ngx_times.h
+++ b/src/core/ngx_times.h
@@ -6,7 +6,7 @@
 #include <ngx_core.h>
 
 
-void ngx_init_time();
+void ngx_time_init();
 void ngx_time_update();
 size_t ngx_http_time(char *buf, time_t t);
 void ngx_gmtime(time_t t, ngx_tm_t *tp);
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -190,6 +190,7 @@ static void ngx_kqueue_done(ngx_cycle_t 
 
 static int ngx_kqueue_add_event(ngx_event_t *ev, int event, u_int flags)
 {
+    ngx_event_t       *e;
     ngx_connection_t  *c;
 
     ev->active = 1;
@@ -200,6 +201,28 @@ static int ngx_kqueue_add_event(ngx_even
         && ((uintptr_t) change_list[ev->index].udata & (uintptr_t) ~1)
                                                              == (uintptr_t) ev)
     {
+        if (change_list[ev->index].flags == EV_DISABLE) {
+
+#if (NGX_DEBUG_EVENT)
+            ngx_connection_t *c = (ngx_connection_t *) ev->data;
+            ngx_log_debug(ev->log, "kqueue event activated: %d: ft:%d" _
+                          c->fd _ event);
+#endif
+
+           /*
+            * if the EV_DISABLE is still not passed to a kernel
+            * we will not pass it
+            */
+
+            if (ev->index < (u_int) --nchanges) {
+                e = (ngx_event_t *) change_list[nchanges].udata;
+                change_list[ev->index] = change_list[nchanges];
+                e->index = ev->index;
+            }
+
+            return NGX_OK;
+        }
+
         c = ev->data;
         ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
                       "previous event on #%d were not passed in kernel", c->fd);
@@ -207,7 +230,7 @@ static int ngx_kqueue_add_event(ngx_even
         return NGX_ERROR;
     }
 
-    return ngx_kqueue_set_event(ev, event, EV_ADD|flags);
+    return ngx_kqueue_set_event(ev, event, EV_ADD|EV_ENABLE|flags);
 }
 
 
@@ -286,24 +309,27 @@ static int ngx_kqueue_set_event(ngx_even
     change_list[nchanges].flags = flags;
     change_list[nchanges].udata = (void *) ((uintptr_t) ev | ev->instance);
 
-#if (HAVE_LOWAT_EVENT)
-
-    if (flags & NGX_LOWAT_EVENT) {
-        change_list[nchanges].fflags = NOTE_LOWAT;
-        change_list[nchanges].data = ev->available;
+    if (filter == EVFILT_VNODE) {
+        change_list[nchanges].fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND
+                                       |NOTE_ATTRIB|NOTE_RENAME|NOTE_REVOKE;
+        change_list[nchanges].data = 0;
 
     } else {
+#if (HAVE_LOWAT_EVENT)
+        if (flags & NGX_LOWAT_EVENT) {
+            change_list[nchanges].fflags = NOTE_LOWAT;
+            change_list[nchanges].data = ev->available;
+
+        } else {
+            change_list[nchanges].fflags = 0;
+            change_list[nchanges].data = 0;
+        }
+#else
         change_list[nchanges].fflags = 0;
         change_list[nchanges].data = 0;
+#endif
     }
 
-#else
-
-    change_list[nchanges].fflags = 0;
-    change_list[nchanges].data = 0;
-
-#endif
-
     ev->index = nchanges;
 
     nchanges++;
@@ -365,12 +391,16 @@ static int ngx_kqueue_process_events(ngx
         ngx_log_debug(log, "kevent timer: %d, delta: %d" _ timer _ (int) delta);
 #endif
 
+#if 0
         /*
          * The expired timers must be handled before a processing of the events
          * because the new timers can be added during a processing
          */
 
         ngx_event_expire_timers((ngx_msec_t) delta);
+#endif
+
+        ngx_event_set_timer_delta((ngx_msec_t) delta);
 
     } else {
         if (events == 0) {
@@ -452,6 +482,13 @@ static int ngx_kqueue_process_events(ngx
 
             break;
 
+        case EVFILT_VNODE:
+            ev->kq_vnode = 1;
+
+            ev->event_handler(ev);
+
+            break;
+
         case EVFILT_AIO:
             ev->complete = 1;
             ev->ready = 1;
@@ -463,10 +500,15 @@ static int ngx_kqueue_process_events(ngx
 
         default:
             ngx_log_error(NGX_LOG_ALERT, log, 0,
-                          "unexpected kevent filter %d" _ event_list[i].filter);
+                          "unexpected kevent() filter %d",
+                          event_list[i].filter);
         }
     }
 
+    if (timer) {
+        ngx_event_expire_timers((ngx_msec_t) delta);
+    }
+
     return NGX_OK;
 }
 
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -107,6 +107,8 @@ struct ngx_event_s {
 #endif
 
 #if (HAVE_KQUEUE)
+    unsigned         kq_vnode:1;
+
     /* the pending errno reported by kqueue */
     int              kq_errno;
 #endif
@@ -212,7 +214,7 @@ extern ngx_event_actions_t   ngx_event_a
 
 /*
  * Need to add socket or handle only once - i/o completion port.
- * It also requires HAVE_AIO_EVENT and NGX_HAVE_AIO_EVENT to be set.
+ * It also requires HAVE_AIO and NGX_USE_AIO_EVENT to be set.
  */
 #define NGX_USE_IOCP_EVENT     0x00000100
 
@@ -233,6 +235,7 @@ extern ngx_event_actions_t   ngx_event_a
 /* these flags have a meaning only for kqueue */
 #define NGX_LOWAT_EVENT    0
 #define NGX_DISABLE_EVENT  0
+#define NGX_VNODE_EVENT    0
 
 
 #if (HAVE_KQUEUE)
@@ -240,6 +243,9 @@ extern ngx_event_actions_t   ngx_event_a
 #define NGX_READ_EVENT     EVFILT_READ
 #define NGX_WRITE_EVENT    EVFILT_WRITE
 
+#undef  NGX_VNODE_EVENT
+#define NGX_VNODE_EVENT    EVFILT_VNODE
+
 /*
  * NGX_CLOSE_EVENT and NGX_LOWAT_EVENT are the module flags and they would
  * not go into a kernel so we need to choose the value that would not interfere
@@ -289,7 +295,7 @@ extern ngx_event_actions_t   ngx_event_a
 #endif /* HAVE_KQUEUE */
 
 
-#if (HAVE_IOCP_EVENT)
+#if (HAVE_IOCP)
 #define NGX_IOCP_ACCEPT      0
 #define NGX_IOCP_IO          1
 #define NGX_IOCP_CONNECT     2
@@ -444,7 +450,8 @@ ngx_inline static int ngx_handle_write_e
 
         if (!wev->active && !wev->ready) {
             if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags)
-                                                                == NGX_ERROR) {
+                                                                  == NGX_ERROR)
+            {
                 return NGX_ERROR;
             }
         }
@@ -457,7 +464,8 @@ ngx_inline static int ngx_handle_write_e
 
         if (!wev->active && !wev->ready) {
             if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
-                                                                == NGX_ERROR) {
+                                                                  == NGX_ERROR)
+            {
                 return NGX_ERROR;
             }
 
@@ -484,7 +492,8 @@ ngx_inline static int ngx_handle_level_w
     if (ngx_event_flags & NGX_USE_LEVEL_EVENT) {
         if (!wev->active && !wev->ready) {
             if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT)
-                                                                == NGX_ERROR) {
+                                                                  == NGX_ERROR)
+            {
                 return NGX_ERROR;
             }
 
--- a/src/event/ngx_event_connect.h
+++ b/src/event/ngx_event_connect.h
@@ -11,7 +11,7 @@
 
 
 typedef struct {
-    u_int32_t          addr;
+    in_addr_t          addr;
     ngx_str_t          host;
     int                port;
     ngx_str_t          addr_port_text;
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -8,15 +8,21 @@
    protected by the single mutex */
 
 
+#if 0
 static ngx_event_t  *ngx_timer_queue, ngx_temp_timer_queue;
+static int           ngx_expire_timers;
+#endif
+
+static ngx_event_t  *ngx_timer_queue;
+static ngx_msec_t   *ngx_timer_delta;
 static int           ngx_timer_cur_queue;
 static int           ngx_timer_queue_num;
-static int           ngx_expire_timers;
 
 
 int ngx_event_timer_init(ngx_cycle_t *cycle)
 {
-    int                i;
+    ngx_int_t          i;
+    ngx_msec_t        *new_delta;
     ngx_event_t       *new_queue;
     ngx_event_conf_t  *ecf;
 
@@ -38,6 +44,21 @@ int ngx_event_timer_init(ngx_cycle_t *cy
 
         ngx_timer_queue = new_queue;
 
+        ngx_test_null(new_delta,
+                      ngx_calloc(ecf->timer_queues * sizeof(ngx_msec_t),
+                                 cycle->log),
+                      NGX_ERROR);
+
+        for (i = 0; i < ngx_timer_queue_num; i++) {
+            new_delta[i] = ngx_timer_delta[i];
+        }
+
+        if (ngx_timer_delta) {
+            ngx_free(ngx_timer_delta);
+        }
+
+        ngx_timer_delta = new_delta;
+
         ngx_timer_queue_num = ecf->timer_queues;
         ngx_timer_cur_queue = 0;
 
@@ -52,8 +73,10 @@ int ngx_event_timer_init(ngx_cycle_t *cy
         exit(1);
     }
 
+#if 0
     ngx_temp_timer_queue.timer_prev = &ngx_temp_timer_queue;
     ngx_temp_timer_queue.timer_next = &ngx_temp_timer_queue;
+#endif
 
     return NGX_OK;;
 }
@@ -63,6 +86,10 @@ void ngx_event_timer_done(ngx_cycle_t *c
 {
     ngx_free(ngx_timer_queue);
     ngx_timer_queue = NULL;
+
+    ngx_free(ngx_timer_delta);
+    ngx_timer_delta = NULL;
+
     ngx_timer_queue_num = 0;
 }
 
@@ -89,6 +116,15 @@ void ngx_event_add_timer(ngx_event_t *ev
         return;
     }
 
+    queue = &ngx_timer_queue[ngx_timer_cur_queue];
+    timer += ngx_timer_delta[ngx_timer_cur_queue++];
+
+    if (ngx_timer_cur_queue >= ngx_timer_queue_num) {
+        ngx_timer_cur_queue = 0;
+    }
+
+
+#if 0
     if (ngx_expire_timers) {
         queue = &ngx_temp_timer_queue;
 
@@ -99,6 +135,7 @@ void ngx_event_add_timer(ngx_event_t *ev
             ngx_timer_cur_queue = 0;
         }
     }
+#endif
 
     for (e = queue->timer_next;
          e != queue && timer > e->timer_delta;
@@ -123,7 +160,7 @@ void ngx_event_add_timer(ngx_event_t *ev
 
 int ngx_event_find_timer(void)
 {
-    int         i;
+    ngx_int_t   i;
     ngx_msec_t  timer;
 
     timer = NGX_MAX_MSEC;
@@ -146,17 +183,34 @@ int ngx_event_find_timer(void)
 }
 
 
+void ngx_event_set_timer_delta(ngx_msec_t timer)
+{
+    ngx_int_t  i;
+
+    for (i = 0; i < ngx_timer_queue_num; i++) {
+        ngx_timer_delta[i] = timer;
+    }
+}
+
+
+/* void ngx_event_expire_timers() */
 void ngx_event_expire_timers(ngx_msec_t timer)
 {
-    int           i;
+    ngx_int_t     i;
+#if 0
     ngx_msec_t    delta;
+#endif
     ngx_event_t  *ev;
 
+#if 0
     ngx_expire_timers = 1;
+#endif
 
     for (i = 0; i < ngx_timer_queue_num; i++) {
 
+#if 0
         delta = timer;
+#endif
 
         for ( ;; ) {
             ev = ngx_timer_queue[i].timer_next;
@@ -165,12 +219,21 @@ void ngx_event_expire_timers(ngx_msec_t 
                 break;
             }
 
+            if (ev->timer_delta > ngx_timer_delta[i]) {
+                ev->timer_delta -= ngx_timer_delta[i];
+                break;
+            }
+
+            ngx_timer_delta[i] -= ev->timer_delta;
+
+#if 0
             if (ev->timer_delta > delta) {
                 ev->timer_delta -= delta;
                 break;
             }
 
             delta -= ev->timer_delta;
+#endif
 
             ngx_del_timer(ev);
 
@@ -186,8 +249,11 @@ void ngx_event_expire_timers(ngx_msec_t 
 
             ev->event_handler(ev);
         }
+
+        ngx_timer_delta[i] = 0;
     }
 
+#if 0
     ngx_expire_timers = 0;
 
     if (ngx_temp_timer_queue.timer_next == &ngx_temp_timer_queue) {
@@ -207,4 +273,5 @@ void ngx_event_expire_timers(ngx_msec_t 
         ngx_del_timer(ev);
         ngx_add_timer(ev, timer);
     }
+#endif
 }
--- a/src/event/ngx_event_timer.h
+++ b/src/event/ngx_event_timer.h
@@ -11,6 +11,7 @@ int  ngx_event_timer_init(ngx_cycle_t *c
 void ngx_event_timer_done(ngx_cycle_t *cycle);
 void ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer);
 int  ngx_event_find_timer(void);
+void ngx_event_set_timer_delta(ngx_msec_t timer);
 void ngx_event_expire_timers(ngx_msec_t timer);
 
 
deleted file mode 100644
--- a/src/event/ngx_event_write.c
+++ /dev/null
@@ -1,203 +0,0 @@
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_types.h>
-#include <ngx_alloc.h>
-#include <ngx_array.h>
-#include <ngx_hunk.h>
-#include <ngx_connection.h>
-#include <ngx_sendv.h>
-#include <ngx_sendfile.h>
-#include <ngx_event_write.h>
-
-
-ngx_chain_t *ngx_event_write(ngx_connection_t *c, ngx_chain_t *in, off_t flush)
-{
-    int           rc, i, last;
-    u_int         flags;
-    char         *prev;
-    off_t         sent;
-    ngx_iovec_t  *iov;
-    ngx_array_t  *header, *trailer;
-    ngx_hunk_t   *file;
-    ngx_chain_t  *ch;
-
-    ch = in;
-    file = NULL;
-    last = 0;
-
-    ngx_test_null(header, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
-                  (ngx_chain_t *) -1);
-
-    ngx_test_null(trailer, ngx_create_array(c->pool, 10, sizeof(ngx_iovec_t)),
-                  (ngx_chain_t *) -1);
-
-    do {
-        header->nelts = 0;
-        trailer->nelts = 0;
-
-        if (ch->hunk->type & NGX_HUNK_IN_MEMORY) {
-            prev = NULL;
-            iov = NULL;
-
-            while (ch && (ch->hunk->type & NGX_HUNK_IN_MEMORY))
-            {
-                if (prev == ch->hunk->pos.mem) {
-                    iov->ngx_iov_len += ch->hunk->last.mem - ch->hunk->pos.mem;
-
-                } else {
-                    ngx_test_null(iov, ngx_push_array(header),
-                                  (ngx_chain_t *) -1);
-                    iov->ngx_iov_base = ch->hunk->pos.mem;
-                    iov->ngx_iov_len = ch->hunk->last.mem - ch->hunk->pos.mem;
-                    prev = ch->hunk->last.mem;
-                }
-
-                if (ch->hunk->type & NGX_HUNK_LAST) {
-                    last = 1;
-                }
-
-                ch = ch->next;
-            }
-        }
-
-        if (ch && (ch->hunk->type & NGX_HUNK_FILE)) {
-            file = ch->hunk;
-            ch = ch->next;
-
-            if (ch->hunk->type & NGX_HUNK_LAST) {
-                last = 1;
-            }
-        }
-
-#if (HAVE_MAX_SENDFILE_IOVEC)
-        if (file && header->nelts > HAVE_MAX_SENDFILE_IOVEC) {
-            rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts, header->nelts,
-                           &sent);
-        } else {
-#endif
-            if (ch && ch->hunk->type & NGX_HUNK_IN_MEMORY) {
-                prev = NULL;
-                iov = NULL;
-
-                while (ch && (ch->hunk->type & NGX_HUNK_IN_MEMORY)) {
-
-                    if (prev == ch->hunk->pos.mem) {
-                        iov->ngx_iov_len +=
-                                        ch->hunk->last.mem - ch->hunk->pos.mem;
-
-                    } else {
-                        ngx_test_null(iov, ngx_push_array(trailer),
-                                      (ngx_chain_t *) -1);
-                        iov->ngx_iov_base = ch->hunk->pos.mem;
-                        iov->ngx_iov_len =
-                                        ch->hunk->last.mem - ch->hunk->pos.mem;
-                        prev = ch->hunk->last.mem;
-                    }
-
-                    if (ch->hunk->type & NGX_HUNK_LAST) {
-                        last = 1;
-                    }
-
-                    ch = ch->next;
-                }
-            }
-
-            if (file) {
-                flags = ngx_sendfile_flags;
-#if (HAVE_SENDFILE_DISCONNECT)
-                if (last && c->close) {
-                    flags |= HAVE_SENDFILE_DISCONNECT;
-                }
-#endif
-                rc = ngx_sendfile(c,
-                                  (ngx_iovec_t *) header->elts, header->nelts,
-                                  file->file->fd, file->pos.file,
-                                  (size_t) (file->last.file - file->pos.file),
-                                  (ngx_iovec_t *) trailer->elts, trailer->nelts,
-                                  &sent, flags);
-
-#if (HAVE_AIO_EVENT) && !(HAVE_IOCP_EVENT)
-            } else if (ngx_event_flags & NGX_HAVE_AIO_EVENT) {
-
-                sent = 0;
-                rc = NGX_AGAIN;
-                iov = (ngx_iovec_t *) header->elts;
-                for (i = 0; i < header->nelts; i++) {
-                    rc = ngx_event_aio_write(c, iov[i].ngx_iov_base,
-                                             iov[i].ngx_iov_len);
-
-                    if (rc > 0) {
-                        sent += rc;
-                    } else {
-                        break;
-                    }
-
-                    if (rc < (int) iov->ngx_iov_len) {
-                        break;
-                    }
-                }
-#endif
-            } else {
-                rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, header->nelts);
-
-                sent = rc > 0 ? rc: 0;
-
-#if (NGX_DEBUG_EVENT_WRITE)
-                ngx_log_debug(c->log, "sendv: " OFF_FMT _ sent);
-#endif
-            }
-#if (HAVE_MAX_SENDFILE_IOVEC)
-        }
-#endif
-        if (rc == NGX_ERROR)
-            return (ngx_chain_t *) NGX_ERROR;
-
-        c->sent += sent;
-        flush -= sent;
-
-        for (ch = in; ch; ch = ch->next) {
-
-#if (NGX_DEBUG_EVENT_WRITE)
-            ngx_log_debug(c->log, "event write: %x " QX_FMT " " OFF_FMT _
-                          ch->hunk->type _
-                          ch->hunk->pos.file _
-                          ch->hunk->last.file - ch->hunk->pos.file);
-#endif
-
-            if (sent >= ch->hunk->last.file - ch->hunk->pos.file) {
-                sent -= ch->hunk->last.file - ch->hunk->pos.file;
-                ch->hunk->pos.file = ch->hunk->last.file;
-
-#if (NGX_DEBUG_EVENT_WRITE)
-                ngx_log_debug(c->log, "event write: " QX_FMT " 0 " OFF_FMT _
-                              ch->hunk->pos.file _ sent);
-#endif
-
-/*
-                if (ch->hunk->type & NGX_HUNK_LAST)
-                   break;
-*/
-
-                continue;
-            }
-
-            ch->hunk->pos.file += sent;
-
-#if (NGX_DEBUG_EVENT_WRITE)
-            ngx_log_debug(c->log, "event write: " QX_FMT " " OFF_FMT _
-                          ch->hunk->pos.file _
-                          ch->hunk->last.file - ch->hunk->pos.file);
-#endif
-
-            break;
-        }
-
-    /* flush hunks if threaded state */
-    } while (c->write->context && flush > 0);
-
-    ngx_destroy_array(trailer);
-    ngx_destroy_array(header);
-
-    return ch;
-}
deleted file mode 100644
--- a/src/event/ngx_event_write.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef _NGX_EVENT_WRITE_H_INCLUDED_
-#define _NGX_EVENT_WRITE_H_INCLUDED_
-
-
-#include <ngx_types.h>
-#include <ngx_hunk.h>
-#include <ngx_connection.h>
-
-ngx_chain_t *ngx_event_write(ngx_connection_t *cn, ngx_chain_t *in,
-                             off_t flush);
-
-
-#endif /* _NGX_EVENT_WRITE_H_INCLUDED_ */
--- a/src/event/ngx_event_wsarecv.c
+++ b/src/event/ngx_event_wsarecv.c
@@ -32,7 +32,7 @@ ssize_t ngx_event_wsarecv(ngx_connection
     if (ev->ready) {
         ev->ready = 0;
 
-#if (HAVE_IOCP_EVENT) /* iocp */
+#if (HAVE_IOCP) /* iocp */
 
         if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
             if (ev->ovlp.error) {
@@ -85,7 +85,7 @@ ssize_t ngx_event_wsarecv(ngx_connection
         }
     }
 
-#if (HAVE_IOCP_EVENT) /* iocp */
+#if (HAVE_IOCP) /* iocp */
 
     if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
         return NGX_AGAIN;
--- a/src/http/modules/ngx_http_chunked_filter.c
+++ b/src/http/modules/ngx_http_chunked_filter.c
@@ -87,7 +87,7 @@ static int ngx_http_chunked_body_filter(
     }
 
     ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR);
-    len = ngx_snprintf(chunk, 11, SIZEX_FMT CRLF, size);
+    len = ngx_snprintf(chunk, 11, SIZE_T_X_FMT CRLF, size);
 
     ngx_test_null(h, ngx_calloc_hunk(r->pool), NGX_ERROR);
     h->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
--- a/src/http/modules/ngx_http_not_modified_filter.c
+++ b/src/http/modules/ngx_http_not_modified_filter.c
@@ -58,11 +58,13 @@ static int ngx_http_not_modified_header_
 
     if (ims != NGX_ERROR && ims == r->headers_out.last_modified_time) {
         r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
+        r->headers_out.content_type->key.len = 0;
+        r->headers_out.content_type = NULL;
         r->headers_out.content_length_n = -1;
         r->headers_out.content_length = NULL;
-        r->headers_out.content_type->key.len = 0;
-        r->headers_out.content_type = NULL;
+#if 0
         r->headers_out.accept_ranges->key.len = 0;
+#endif
     }
 
     return ngx_http_next_header_filter(r);
--- a/src/http/modules/ngx_http_range_filter.c
+++ b/src/http/modules/ngx_http_range_filter.c
@@ -215,7 +215,7 @@ static int ngx_http_range_header_filter(
 
         r->headers_out.content_range->value.len =
                         ngx_snprintf(r->headers_out.content_range->value.data,
-                                     8 + 20 + 1, "bytes */" OFF_FMT,
+                                     8 + 20 + 1, "bytes */" OFF_T_FMT,
                                      r->headers_out.content_length_n);
 
         r->headers_out.content_length_n = -1;
@@ -247,11 +247,11 @@ static int ngx_http_range_header_filter(
             /* "Content-Range: bytes SSSS-EEEE/TTTT" header */
 
             r->headers_out.content_range->value.len =
-                         ngx_snprintf(r->headers_out.content_range->value.data,
-                                      6 + 20 + 1 + 20 + 1 + 20 + 1,
-                                      "bytes " OFF_FMT "-" OFF_FMT "/" OFF_FMT,
-                                      range->start, range->end - 1,
-                                      r->headers_out.content_length_n);
+                   ngx_snprintf(r->headers_out.content_range->value.data,
+                                6 + 20 + 1 + 20 + 1 + 20 + 1,
+                                "bytes " OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT,
+                                range->start, range->end - 1,
+                                r->headers_out.content_length_n);
 
             r->headers_out.content_length_n = range->end - range->start;
 
@@ -336,11 +336,11 @@ static int ngx_http_range_header_filter(
                 /* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */
 
                 range[i].content_range.len =
-                        ngx_snprintf(range[i].content_range.data,
-                                     20 + 1 + 20 + 1 + 20 + 5,
-                                     OFF_FMT "-" OFF_FMT "/" OFF_FMT CRLF CRLF,
-                                     range[i].start, range[i].end - 1,
-                                     r->headers_out.content_length_n);
+                  ngx_snprintf(range[i].content_range.data,
+                               20 + 1 + 20 + 1 + 20 + 5,
+                               OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT CRLF CRLF,
+                               range[i].start, range[i].end - 1,
+                               r->headers_out.content_length_n);
 
                 len += ctx->boundary_header.len + range[i].content_range.len
                                     + (size_t) (range[i].end - range[i].start);
--- a/src/http/modules/ngx_http_static_handler.c
+++ b/src/http/modules/ngx_http_static_handler.c
@@ -44,6 +44,8 @@ int ngx_http_static_translate_handler(ng
     int                        rc, level;
     char                      *location, *last;
     ngx_err_t                  err;
+    ngx_http_cache_ctx_t       ctx;
+    ngx_http_cache_conf_t     *ccf;
     ngx_http_core_loc_conf_t  *clcf;
 
     if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
@@ -73,7 +75,7 @@ int ngx_http_static_translate_handler(ng
         return NGX_HTTP_FORBIDDEN;
     }
 
-    /* "+ 2" is for trailing '/' in redirect and '\0' */
+    /* "+ 2" is for trailing '/' in possible redirect and '\0' */
     ngx_test_null(r->file.name.data,
                   ngx_palloc(r->pool, clcf->doc_root.len + r->uri.len + 2),
                   NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -85,6 +87,38 @@ int ngx_http_static_translate_handler(ng
 
 ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->file.name.data);
 
+
+    /* STUB */
+    ccf = NULL;
+    ctx.key.len = 0;
+
+#if 0
+    ccf = ngx_http_get_module_loc_conf(r, ngx_http_cache_module);
+
+    if (ccf->open_files) {
+        ctx->hash = ccf->open_files;
+        ctx->key = r->file.name;
+
+        cache = ngx_http_cache_get_data(r, ctx);
+
+        if (cache
+            && ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
+                || ccf->hash->life_time >= ngx_time() - cache->updated))
+        {
+            cache->refs++;
+            r->file.fd = cache->fd;
+            r->file.name = cache->key;
+            r->content_handler = ngx_http_static_handler;
+
+            return NGX_OK;
+        }
+
+    } else {
+        cache = NULL;
+    }
+
+#endif
+
 #if (WIN9X)
 
     if (ngx_win32_version < NGX_WIN_NT) {
--- a/src/http/modules/proxy/ngx_http_proxy_cache.c
+++ b/src/http/modules/proxy/ngx_http_proxy_cache.c
@@ -86,6 +86,7 @@ static int ngx_http_proxy_process_cached
     }
 
     if (rc == NGX_HTTP_CACHE_STALE || rc == NGX_HTTP_CACHE_AGED) {
+        p->state->expired = ngx_time() - p->cache->ctx.expires;
         p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
 
         if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) {
@@ -487,6 +488,8 @@ int ngx_http_proxy_send_cached_response(
         out[i].hunk->type |= NGX_HUNK_LAST;
     }
 
+    r->file.fd = p->cache->ctx.file.fd;
+
     return ngx_http_output_filter(r, out);
 }
 
@@ -600,7 +603,7 @@ int ngx_http_proxy_update_cache(ngx_http
 
     ep = p->upstream->event_pipe;
 
-ngx_log_debug(p->request->connection->log, "LEN: " OFF_FMT ", " OFF_FMT _
+ngx_log_debug(p->request->connection->log, "LEN: " OFF_T_FMT ", " OFF_T_FMT _
               p->cache->ctx.length _ ep->read_length);
 
     if (p->cache->ctx.length == -1) {
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -485,6 +485,10 @@ ngx_log_debug(r->connection->log, "CACHE
         r->file.fd = p->cache->ctx.file.fd;
     }
 
+    if (rc == 0 && r->main == NULL) {
+        rc = ngx_http_send_last(r);
+    }
+
     ngx_http_finalize_request(r, rc);
 }
 
@@ -586,15 +590,25 @@ static char *ngx_http_proxy_log_proxy_st
 
     *buf++ = '/';
 
-    *buf++ = '_';
+    if (p->state->expired == 0) {
+        *buf++ = '-';
+
+    } else {
+        buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expired);
+    }
 
     *buf++ = '/';
 
-    *buf++ = '_';
+    if (p->state->bl_time == 0) {
+        *buf++ = '-';
+
+    } else {
+        buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->bl_time);
+    }
 
     *buf++ = '/';
 
-    *buf++ = '_';
+    *buf++ = '*';
 
     *buf++ = ' ';
 
@@ -617,15 +631,15 @@ static char *ngx_http_proxy_log_proxy_st
 
     *buf++ = '/';
 
-    if (p->state->reason >= NGX_HTTP_PROXY_CACHE_XAE) {
+    if (p->state->reason < NGX_HTTP_PROXY_CACHE_XAE) {
         *buf++ = '-';
 
     } else {
-        buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_FMT, p->state->expires);
+        buf += ngx_snprintf(buf, NGX_TIME_LEN, TIME_T_FMT, p->state->expires);
     }
 
     *buf++ = ' ';
-    *buf++ = '_';
+    *buf++ = '*';
 
     return buf;
 }
@@ -833,9 +847,9 @@ static char *ngx_http_proxy_set_pass(ngx
 
     int                        i, len;
     char                      *err, *host;
+    in_addr_t                  addr;
     ngx_str_t                 *value;
     struct hostent            *h;
-    u_int32_t                  addr;
     ngx_http_conf_ctx_t       *ctx;
     ngx_http_core_loc_conf_t  *clcf;
 
@@ -869,6 +883,8 @@ static char *ngx_http_proxy_set_pass(ngx
                   NGX_CONF_ERROR);
     ngx_cpystrn(host, lcf->upstream->host.data, lcf->upstream->host.len + 1);
 
+    /* AF_INET only */
+
     addr = inet_addr(host);
 
     if (addr == INADDR_NONE) {
@@ -894,7 +910,7 @@ static char *ngx_http_proxy_set_pass(ngx
         for (i = 0; h->h_addr_list[i] != NULL; i++) {
             lcf->peers->peers[i].host.data = host;
             lcf->peers->peers[i].host.len = lcf->upstream->host.len;
-            lcf->peers->peers[i].addr = *(u_int32_t *)(h->h_addr_list[i]);
+            lcf->peers->peers[i].addr = *(in_addr_t *)(h->h_addr_list[i]);
             lcf->peers->peers[i].port = lcf->upstream->port;
 
             len = INET_ADDRSTRLEN + lcf->upstream->port_text.len + 1;
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -1017,8 +1017,7 @@ static void ngx_http_proxy_send_response
     ep->hunk_to_file->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
 
     if (ngx_event_flags & NGX_USE_AIO_EVENT) {
-
-        /* the posted aio operation can currupt shadow buf */
+        /* the posted aio operation can currupt a shadow buffer */
         ep->single_buf = 1;
     }
 
@@ -1126,26 +1125,38 @@ static void ngx_http_proxy_process_body(
         }
 
         if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) {
+            ngx_log_debug(ev->log, "http proxy upstream exit");
             ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock);
-            ngx_http_proxy_close_connection(p);
+            ngx_http_proxy_finalize_request(p, 0);
+            return;
         }
     }
 
+    if (ep->downstream_error) {
+        ngx_log_debug(ev->log, "http proxy downstream error");
+        if (!p->cachable && p->upstream->peer.connection) {
+            ngx_http_proxy_finalize_request(p, 0);
+        }
+    }
+
+#if 0
     if (ep->downstream_done) {
         ngx_log_debug(ev->log, "http proxy downstream done");
-        ngx_http_proxy_finalize_request(p, r->main ? 0 : ngx_http_send_last(r));
+        ngx_http_proxy_finalize_request(p, 0);
         return;
     }
 
     if (ep->downstream_error) {
+        ngx_log_debug(ev->log, "http proxy downstream error");
         if (!p->cachable && p->upstream->peer.connection) {
             ngx_http_proxy_close_connection(p);
         }
  
         if (p->upstream->peer.connection == NULL) {
-            ngx_http_close_connection(r->connection);
+            ngx_http_close_request(r);
         }
     }
+#endif
 }
 
 
--- a/src/http/ngx_http_busy_lock.c
+++ b/src/http/ngx_http_busy_lock.c
@@ -205,7 +205,7 @@ char *ngx_http_set_busy_lock_slot(ngx_co
 
     dup = 0;
     invalid = 0;
-    value = (ngx_str_t *) cf->args->elts;
+    value = cf->args->elts;
 
     for (i = 1; i < cf->args->nelts; i++) {
 
--- a/src/http/ngx_http_cache.c
+++ b/src/http/ngx_http_cache.c
@@ -13,11 +13,45 @@
 #endif
 
 
+static int ngx_crc(char *data, size_t len);
+
+static void *ngx_http_cache_create_conf(ngx_conf_t *cf);
+static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
+                                          void *parent, void *child);
+
+
+static ngx_http_module_t  ngx_http_cache_module_ctx = {
+    NULL,                                  /* pre conf */
+
+    NULL,                                  /* create main configuration */
+    NULL,                                  /* init main configuration */
+
+    NULL,                                  /* create server configuration */
+    NULL,                                  /* merge server configuration */
+
+    ngx_http_cache_create_conf,            /* create location configuration */
+    ngx_http_core_merge_loc_conf           /* merge location configuration */
+};
+
+
+ngx_module_t  ngx_http_cache_module = {
+    NGX_MODULE,
+    &ngx_http_cache_module_ctx,            /* module context */
+    NULL,                                  /* module directives */
+    NGX_HTTP_MODULE,                       /* module type */
+    NULL,                                  /* init module */
+    NULL                                   /* init child */
+};
+
+
+
 int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
 {
     MD5_CTX  md5;
 
-    ctx->header_size = sizeof(ngx_http_cache_header_t) + ctx->key.len + 1;
+    /* we use offsetof() because sizeof() pads struct size to int size */
+    ctx->header_size = offsetof(ngx_http_cache_header_t, key)
+                                                            + ctx->key.len + 1;
 
     ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32;
     if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) {
@@ -46,7 +80,83 @@ ngx_log_debug(r->connection->log, "FILE:
 }
 
 
-/* TODO: Win32 inode analogy */
+int ngx_http_cache_get_data(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx)
+{
+    ngx_uint_t  n, i;
+
+    ctx->crc = ngx_crc(ctx->key.data, ctx->key.len);
+
+    n = ctx->crc % ctx->hash->hash;
+    for (i = 0; i < ctx->hash->nelts; i++) {
+        if (ctx->hash->cache[n][i].crc == ctx->crc
+            && ctx->hash->cache[n][i].key.len == ctx->key.len
+            && ngx_rstrncmp(ctx->hash->cache[n][i].key.data, ctx->key.data,
+                                                            ctx->key.len) == 0)
+        {
+            ctx->cache = ctx->hash->cache[n][i].data;
+            ctx->hash->cache[n][i].refs++;
+            return NGX_OK;
+        }
+    }
+
+    return NGX_DECLINED;
+}
+
+
+ngx_http_cache_entry_t *ngx_http_cache_get_entry(ngx_http_request_t *r,
+                                                 ngx_http_cache_ctx_t *ctx)
+{
+    time_t                   old;
+    ngx_uint_t               n, i;
+    ngx_http_cache_entry_t  *ce;
+
+    old = ngx_time() + 1;
+    ce = NULL;
+
+    n = ctx->crc % ctx->hash->hash;
+    for (i = 0; i < ctx->hash->nelts; i++) {
+        if (ctx->hash->cache[n][i].key.data == NULL) {
+
+            /* a free entry is found */
+
+            ce = &ctx->hash->cache[n][i];
+            break;
+        }
+
+        if (ctx->hash->cache[n][i].refs == 0
+            && old > ctx->hash->cache[n][i].accessed)
+        {
+            /* looking for the oldest cache entry that is not used right now */
+
+            old = ctx->hash->cache[n][i].accessed;
+            ce = &ctx->hash->cache[n][i];
+        }
+    }
+
+    if (ce) {
+        if (ce->key.data) {
+            if (ctx->key.len > ce->key.len) {
+                ngx_free(ce->key.data);
+                ce->key.data = NULL;
+            }
+        }
+
+        if (ce->key.data) {
+            ce->key.data = ngx_alloc(ctx->key.len, r->connection->log);
+            if (ce->key.data == NULL) {
+                return NULL;
+            }
+        }
+
+        ngx_memcpy(ce->key.data, ctx->key.data, ctx->key.len);
+
+        ce->key.len = ctx->key.len;
+        ce->crc = ctx->crc;
+    }
+
+    return ce;
+}
+
 
 int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq)
 {
@@ -138,6 +248,48 @@ ngx_log_debug(ctx->log, "EXPIRED");
 }
 
 
+int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
+                               ngx_str_t *temp_file)
+{
+    int        retry;
+    ngx_err_t  err;
+
+    retry = 0;
+
+    for ( ;; ) {
+        if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) {
+            return NGX_OK;
+        }
+
+        err = ngx_errno;
+
+#if (WIN32)
+        if (err == NGX_EEXIST) {
+            if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool)
+                                                                  == NGX_ERROR)
+            {
+                return NGX_ERROR;
+            }
+        }
+#endif
+
+        if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) {
+            ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
+                          ngx_rename_file_n "(\"%s\", \"%s\") failed",
+                          temp_file->data, ctx->file.name.data);
+
+            return NGX_ERROR;
+        }
+
+        if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) {
+            return NGX_ERROR;
+        }
+
+        retry = 1;
+    }
+}
+
+
 int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name,
                                              ngx_dir_t *dir)
 {
@@ -182,45 +334,69 @@ int ngx_garbage_collector_http_cache_han
 }
 
 
-int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx,
-                               ngx_str_t *temp_file)
+/* 32-bit crc16 */
+
+static int ngx_crc(char *data, size_t len)
 {
-    int        retry;
-    ngx_err_t  err;
+    uint32_t  sum;
+
+    for (sum = 0; len; len--) {
+        /*
+         * gcc 2.95.2 x86 and icc 7.1.006 compile that operator
+         *                                into the single rol opcode.
+         * msvc 6.0sp2 compiles it into four opcodes.
+         */
+        sum = sum >> 1 | sum << 31;
 
-    retry = 0;
+        sum += *data++;
+    }
+
+    return sum;
+}
+
+
+static void *ngx_http_cache_create_conf(ngx_conf_t *cf)
+{
+    ngx_http_cache_conf_t  *conf;
+
+    if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_conf_t)))) {
+        return NGX_CONF_ERROR;
+    }
 
-    for ( ;; ) {
-        if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) {
-            return NGX_OK;
-        }
+    return conf;
+}
+
 
-        err = ngx_errno;
+static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
+                                          void *parent, void *child)
+{
+    ngx_http_cache_conf_t *prev = parent;
+    ngx_http_cache_conf_t *conf = child;
+
+    if (conf->hash == NULL) {
+        if (prev->hash) {
+            conf->hash = prev->hash;
 
-#if (WIN32)
-        if (err == NGX_EEXIST) {
-            if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool)
-                                                                  == NGX_ERROR)
-            {
-                return NGX_ERROR;
+        } else {
+            conf->hash = ngx_pcalloc(cf->pool, sizeof(ngx_http_cache_hash_t));
+            if (conf->hash == NULL) {
+                return NGX_CONF_ERROR;
+            }
+
+            conf->hash->hash = NGX_HTTP_CACHE_HASH;
+            conf->hash->nelts = NGX_HTTP_CACHE_NELTS;
+
+            conf->hash->cache = ngx_pcalloc(cf->pool,
+                                            NGX_HTTP_CACHE_HASH
+                                            * NGX_HTTP_CACHE_NELTS
+                                            * sizeof(ngx_http_cache_entry_t));
+            if (conf->hash->cache == NULL) {
+                return NGX_CONF_ERROR;
             }
         }
-#endif
-
-        if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) {
-            ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
-                          ngx_rename_file_n "(\"%s\", \"%s\") failed",
-                          temp_file->data, ctx->file.name.data);
+    }
 
-            return NGX_ERROR;
-        }
-
-        if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) {
-            return NGX_ERROR;
-        }
-
-        retry = 1;
-    }
+    return NGX_CONF_OK;
 }
 
 
@@ -261,7 +437,7 @@ typedef struct {
 
 
 typedef struct {
-    u_int32_t          crc;
+    uint32_t           crc;
     ngx_str_t          uri;
     ngx_http_cache_t  *cache;
 } ngx_http_cache_hash_entry_t;
@@ -269,7 +445,7 @@ typedef struct {
 
 typedef struct {
     ngx_http_cache_t  *cache;
-    u_int32_t          crc;
+    uint32_t           crc;
     int                n;
 } ngx_http_cache_handle_t; 
 
@@ -305,7 +481,7 @@ int ngx_http_cache_get(ngx_http_cache_ha
 
 int ngx_crc(char *data, size_t len)
 {
-    u_int32_t  sum;
+    uint32_t  sum;
 
     for (sum = 0; len; len--) {
         /*
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -18,32 +18,52 @@ typedef struct {
 
 
 typedef struct {
-    u_int32_t    crc;
+    uint32_t     crc;
     ngx_str_t    key;
     ngx_fd_t     fd;
     off_t        size;
     void        *data;          /* mmap, memory */
     time_t       accessed;
     time_t       last_modified;
-    time_t       updated;      /* no needed with kqueue */
+    time_t       updated;       /* no needed with kqueue */
     int          refs;
     int          flags;
 } ngx_http_cache_entry_t;
 
+#define NGX_HTTP_CACHE_HASH   1021
+#define NGX_HTTP_CACHE_NELTS  4
+
+typedef struct {
+    ngx_http_cache_entry_t  **cache;
+    size_t                    hash;
+    size_t                    nelts;
+    time_t                    life_time;
+    time_t                    check_time;
+    ngx_pool_t               *pool;
+} ngx_http_cache_hash_t;
+
 
 typedef struct {
-    ngx_file_t   file;
-    ngx_str_t    key;
-    u_char       md5[16];
-    ngx_path_t  *path;
-    ngx_hunk_t  *buf;
-    time_t       expires;
-    time_t       last_modified;
-    time_t       date;
-    off_t        length;
-    ssize_t      header_size;
-    size_t       file_start;
-    ngx_log_t   *log;
+    ngx_http_cache_hash_t    *hash;
+} ngx_http_cache_conf_t;
+
+
+typedef struct {
+    ngx_http_cache_hash_t    *hash;
+    ngx_http_cache_entry_t   *cache;
+    ngx_file_t                file;
+    ngx_str_t                 key;
+    uint32_t                  crc;
+    u_char                    md5[16];
+    ngx_path_t               *path;
+    ngx_hunk_t               *buf;
+    time_t                    expires;
+    time_t                    last_modified;
+    time_t                    date;
+    off_t                     length;
+    ssize_t                   header_size;
+    size_t                    file_start;
+    ngx_log_t                *log;
 } ngx_http_cache_ctx_t;
 
 
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -88,7 +88,7 @@ static ngx_command_t  ngx_http_core_comm
      NULL},
 
     {ngx_string("location"),
-     NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
+     NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
      ngx_location_block,
      NGX_HTTP_SRV_CONF_OFFSET,
      0,
@@ -368,19 +368,27 @@ static void ngx_http_run_phases(ngx_http
 
 int ngx_http_find_location_config(ngx_http_request_t *r)
 {
-    int                            i, rc;
+    ngx_int_t                      i, rc, exact;
     ngx_str_t                     *auto_redirect;
     ngx_http_core_loc_conf_t      *clcf, **clcfp;
     ngx_http_core_srv_conf_t      *cscf;
 
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
     auto_redirect = NULL;
+    exact = 0;
 
     clcfp = cscf->locations.elts;
     for (i = 0; i < cscf->locations.nelts; i++) {
-#if 0
-ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data);
+
+#if 1
+ngx_log_debug(r->connection->log, "trans: %s: %d" _
+              clcfp[i]->name.data _ clcfp[i]->exact_match);
 #endif
+
+        if (clcfp[i]->regex) {
+            break;
+        }
+
         if (clcfp[i]->auto_redirect
             && r->uri.len == clcfp[i]->name.len - 1
             && ngx_strncmp(r->uri.data, clcfp[i]->name.data,
@@ -406,6 +414,50 @@ ngx_log_debug(r->connection->log, "trans
             clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
             r->connection->log->file = clcf->err_log->file;
             r->connection->log->log_level = clcf->err_log->log_level;
+
+            if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) {
+                exact = 1;
+                break;
+            }
+        }
+    }
+
+    if (!exact && !auto_redirect) {
+        /* regex matches */
+
+        for (/* void */; i < cscf->locations.nelts; i++) {
+
+#if 1
+ngx_log_debug(r->connection->log, "trans: %s: %d" _
+              clcfp[i]->name.data _ clcfp[i]->exact_match);
+#endif
+
+            if (!clcfp[i]->regex) {
+                continue;
+            }
+
+            rc = ngx_regex_exec(clcfp[i]->regex, &r->uri);
+
+            if (rc == NGX_DECLINED) {
+                continue;
+            }
+
+            if (rc < 0) {
+                ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                              ngx_regex_exec_n
+                              " failed: %d on \"%s\" using \"%s\"",
+                              rc, r->uri.data, clcfp[i]->name.data);
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+            /* match */
+
+            r->loc_conf = clcfp[i]->loc_conf;
+            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+            r->connection->log->file = clcf->err_log->file;
+            r->connection->log->log_level = clcf->err_log->log_level;
+
+            break;
         }
     }
 
@@ -669,37 +721,58 @@ static char *ngx_server_block(ngx_conf_t
 }
 
 
-static int ngx_cmp_locations(const void *first, const void *second)
+static int ngx_cmp_locations(const void *one, const void *two)
 {
-    ngx_http_core_loc_conf_t *one = *(ngx_http_core_loc_conf_t **) first;
-    ngx_http_core_loc_conf_t *two = *(ngx_http_core_loc_conf_t **) second;
+    ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one;
+    ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two;
+
+    ngx_int_t  rc;
+
+    if (first->regex && !second->regex) {
+        /* shift regex matches to the end */
+        return 1;
+    }
 
-    return ngx_strcmp(one->name.data, two->name.data);
+    if (first->regex || second->regex) {
+        /* do not sort regex matches */
+        return 0;
+    }
+
+    rc = ngx_strcmp(first->name.data, second->name.data);
+
+    if (rc == 0 && second->exact_match) {
+        /* an exact match must be before the same inclusive one */
+        return 1;
+    }
+
+    return rc;
 }
 
 
 static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
 {
-    int                        m;
     char                      *rv;
-    ngx_str_t                 *location;
+    ngx_int_t                  m;
+    ngx_str_t                 *value, err;
     ngx_http_module_t         *module;
     ngx_conf_t                 pvcf;
     ngx_http_conf_ctx_t       *ctx, *pvctx;
     ngx_http_core_srv_conf_t  *cscf;
     ngx_http_core_loc_conf_t  *clcf, **clcfp;
+    char                       errstr[NGX_MAX_CONF_ERRSTR];
 
-    ngx_test_null(ctx,
-                  ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
-                  NGX_CONF_ERROR);
+    if (!(ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)))) {
+        return NGX_CONF_ERROR;
+    }
 
     pvctx = (ngx_http_conf_ctx_t *) cf->ctx;
     ctx->main_conf = pvctx->main_conf;
     ctx->srv_conf = pvctx->srv_conf;
 
-    ngx_test_null(ctx->loc_conf,
-                  ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module),
-                  NGX_CONF_ERROR);
+    ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
+    if (ctx->loc_conf == NULL) {
+        return NGX_CONF_ERROR;
+    }
 
     for (m = 0; ngx_modules[m]; m++) {
         if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
@@ -709,20 +782,61 @@ static char *ngx_location_block(ngx_conf
         module = ngx_modules[m]->ctx;
 
         if (module->create_loc_conf) {
-            ngx_test_null(ctx->loc_conf[ngx_modules[m]->ctx_index],
-                          module->create_loc_conf(cf),
-                          NGX_CONF_ERROR);
+            ctx->loc_conf[ngx_modules[m]->ctx_index] =
+                                                   module->create_loc_conf(cf);
+            if (ctx->loc_conf[ngx_modules[m]->ctx_index] == NULL) {
+                 return NGX_CONF_ERROR;
+            }
         }
     }
 
     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
-    location = (ngx_str_t *) cf->args->elts;
-    clcf->name.len = location[1].len;
-    clcf->name.data = location[1].data;
     clcf->loc_conf = ctx->loc_conf;
 
+    value = (ngx_str_t *) cf->args->elts;
+
+    if (cf->args->nelts == 3) {
+        if (value[1].len == 1 && value[1].data[0] == '=') {
+            clcf->name.len = value[2].len;
+            clcf->name.data = value[2].data;
+            clcf->exact_match = 1;
+
+        } else if ((value[1].len == 1 && value[1].data[0] == '~')
+                   || (value[1].len == 2
+                       && value[1].data[0] == '~'
+                       && value[1].data[1] == '*'))
+        {
+            err.len = NGX_MAX_CONF_ERRSTR;
+            err.data = errstr;
+
+            clcf->regex = ngx_regex_compile(&value[2],
+                                     value[1].len == 2 ? NGX_REGEX_CASELESS: 0,
+                                     cf->pool, &err);
+
+            if (clcf->regex == NULL) {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
+                return NGX_CONF_ERROR;
+            }
+
+            clcf->name.len = value[2].len;
+            clcf->name.data = value[2].data;
+
+        } else {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "invalid location modifier \"%s\"",
+                               value[1].data);
+            return NGX_CONF_ERROR;
+        }
+
+    } else {
+        clcf->name.len = value[1].len;
+        clcf->name.data = value[1].data;
+    }
+
     cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
-    ngx_test_null(clcfp, ngx_push_array(&cscf->locations), NGX_CONF_ERROR);
+    if (!(clcfp = ngx_push_array(&cscf->locations))) {
+        return NGX_CONF_ERROR;
+    }
     *clcfp = clcf;
 
     pvcf = *cf;
@@ -911,6 +1025,10 @@ static void *ngx_http_core_create_loc_co
     lcf->err_log = NULL;
     lcf->error_pages = NULL;
 
+    lcf->regex = NULL;
+    lcf->exact_match = 0;
+    lcf->auto_redirect = 0;
+
     */
 
     lcf->client_body_timeout = NGX_CONF_UNSET;
@@ -1079,7 +1197,7 @@ static char *ngx_set_listen(ngx_conf_t *
             return NGX_CONF_ERROR;
         }
 
-        ls->addr = *(u_int32_t *)(h->h_addr_list[0]);
+        ls->addr = *(in_addr_t *)(h->h_addr_list[0]);
     }
 
     return NGX_CONF_OK;
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -8,7 +8,7 @@
 
 
 typedef struct {
-    u_int32_t  addr;
+    in_addr_t  addr;
     int        port;
     int        family;
     int        flags;             /* 'default' */
@@ -65,7 +65,7 @@ typedef struct {
 
 
 typedef struct {
-    u_int32_t                  addr;
+    in_addr_t                  addr;
     ngx_array_t                names;     /* array of ngx_http_server_name_t */
     ngx_http_core_srv_conf_t  *core_srv_conf;  /* default server conf
                                                   for this address:port */
@@ -128,6 +128,10 @@ typedef struct {
     int           msie_padding;            /* msie_padding */
     ngx_array_t  *error_pages;             /* error_page */
 
+    ngx_regex_t  *regex;
+
+    unsigned      exact_match:1;
+
     unsigned      auto_redirect:1;
 
     ngx_log_t    *err_log;
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -266,7 +266,7 @@ static int ngx_http_header_filter(ngx_ht
 #endif
             h->last += ngx_snprintf(h->last,        /* 2^64 */
                             sizeof("Content-Length: 18446744073709551616" CRLF),
-                            "Content-Length: " OFF_FMT CRLF,
+                            "Content-Length: " OFF_T_FMT CRLF,
                             r->headers_out.content_length_n);
 
 #if (NGX_HTTP_LOG_ALL_HEADERS_OUT)
--- a/src/http/ngx_http_log_handler.c
+++ b/src/http/ngx_http_log_handler.c
@@ -250,7 +250,7 @@ static char *ngx_http_log_status(ngx_htt
 static char *ngx_http_log_length(ngx_http_request_t *r, char *buf,
                                  uintptr_t data)
 {
-    return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_FMT,
+    return buf + ngx_snprintf(buf, NGX_OFF_LEN + 1, OFF_T_FMT,
                               r->connection->sent);
 }
 
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -82,7 +82,7 @@ int ngx_open_dir(ngx_str_t *name, ngx_di
 #define ngx_read_dir_n           "readdir()"
 
 
-#define ngx_create_dir(name)     mkdir(name, (mode_t) 0700)
+#define ngx_create_dir(name)     mkdir(name, 0700)
 #define ngx_create_dir_n         "mkdir()"
 
 
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -3,7 +3,7 @@
 
 
 #include <unistd.h>
-#include <stddef.h>             /* offsetof */
+#include <stddef.h>             /* offsetof() */
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -27,35 +27,6 @@
 #include <osreldate.h>
 
 
-
-/* TODO: autoconf */
-#if (i386)
-
-#if 0
-#define OFF_FMT    "%lld"
-#endif
-
-#define SIZE_FMT   "%d"
-#define SIZEX_FMT  "%x"
-
-#else  /* amd64, alpha, sparc64, ia64 */
-
-#if 0
-#define OFF_FMT    "%ld"
-#endif
-
-#define SIZE_FMT   "%ld"
-#define SIZEX_FMT  "%lx"
-
-#endif
-
-#if 0
-#define TIME_FMT   "%ld"
-#endif
-#define PID_FMT    "%d"
-#define RLIM_FMT   "%lld"
-
-
 #ifndef HAVE_SELECT
 #define HAVE_SELECT  1
 #endif
@@ -89,58 +60,11 @@
 #endif
 
 
-/* STUB */
-#define HAVE_PREAD         1
-#define HAVE_PWRITE        1
-#define HAVE_LOCALTIME_R   1
-
-
-       /* FreeBSD sendfile */
-
-#if __FreeBSD_version >= 300007
-
-#ifndef HAVE_FREEBSD_SENDFILE
-#define HAVE_FREEBSD_SENDFILE    1
-#endif
-
-#endif
-
-
-#if (HAVE_FREEBSD_SENDFILE)
-#define HAVE_SENDFILE  1
-#endif
-
-
-       /* FreeBSD kqueue */
-
-#if (__FreeBSD__ == 4 && __FreeBSD_version >= 410000) \
-    || __FreeBSD_version >= 500011
-
-#ifndef HAVE_KQUEUE
-#define HAVE_KQUEUE  1
-#endif
-
-#endif
-
 #if (HAVE_KQUEUE)
 #include <sys/event.h>
 #endif
 
 
-       /* kqueue's NOTE_LOWAT */
-
-#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \
-    || __FreeBSD_version >= 500018
-
-#ifndef HAVE_LOWAT_EVENT
-#define HAVE_LOWAT_EVENT  1
-#endif
-
-#endif
-
-
-
-
 #ifndef HAVE_INHERITED_NONBLOCK
 #define HAVE_INHERITED_NONBLOCK  1
 #endif
--- a/src/os/unix/ngx_freebsd_init.c
+++ b/src/os/unix/ngx_freebsd_init.c
@@ -20,12 +20,12 @@ ngx_os_io_t ngx_os_io = {
     ngx_unix_recv,
     ngx_readv_chain,
     NULL,
-#if (HAVE_FREEBSD_SENDFILE)
+#if (HAVE_SENDFILE)
     ngx_freebsd_sendfile_chain,
-    NGX_HAVE_SENDFILE|NGX_HAVE_ZEROCOPY
+    NGX_HAVE_SENDFILE
 #else
     ngx_writev_chain,
-    NULL
+    0
 #endif
 };
 
@@ -97,7 +97,7 @@ int ngx_os_init(ngx_log_t *log)
                   version, __FreeBSD_version);
 
 
-#if (HAVE_FREEBSD_SENDFILE)
+#if (HAVE_SENDFILE)
 
     /*
      * The determination of the sendfile() nbytes bug is complex enough.
@@ -127,7 +127,7 @@ int ngx_os_init(ngx_log_t *log)
 
 #endif
 
-#endif /* HAVE_FREEBSD_SENDFILE */
+#endif /* HAVE_SENDFILE */
 
 
     if ((version < 500000 && version >= 440003) || version >= 500017) {
--- a/src/os/unix/ngx_freebsd_sendfile_chain.c
+++ b/src/os/unix/ngx_freebsd_sendfile_chain.c
@@ -22,16 +22,17 @@
 
 ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
 {
-    int              rc, eintr, eagain;
+    int              rc;
     char            *prev;
     off_t            sent, fprev;
     size_t           hsize, fsize, size;
+    ngx_int_t        eintr, eagain;
     struct iovec    *iov;
     struct sf_hdtr   hdtr;
     ngx_err_t        err;
+    ngx_hunk_t      *file;
     ngx_array_t      header, trailer;
     ngx_event_t     *wev;
-    ngx_hunk_t      *file;
     ngx_chain_t     *cl, *tail;
 
     wev = c->write;
@@ -53,7 +54,6 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
 #endif
 
     do {
-        cl = in;
         file = NULL;
         fsize = 0;
         hsize = 0;
@@ -156,7 +156,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(
 ngx_log_debug(c->log, "NOPUSH");
 
                 if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
-                    ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
+                    ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno,
                                   ngx_tcp_nopush_n " failed");
                     return NGX_CHAIN_ERROR;
                 }
new file mode 100644
--- /dev/null
+++ b/src/os/unix/ngx_linux.h
@@ -0,0 +1,8 @@
+#ifndef _NGX_LINUX_H_INCLUDED_
+#define _NGX_LINUX_H_INCLUDED_
+
+
+ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
+
+
+#endif /* _NGX_LINUX_H_INCLUDED_ */
--- a/src/os/unix/ngx_linux_config.h
+++ b/src/os/unix/ngx_linux_config.h
@@ -2,14 +2,14 @@
 #define _NGX_LINUX_CONFIG_H_INCLUDED_
 
 
-#define _GNU_SOURCE             /* pread, pwrite, gethostname, bzero */
+#define _GNU_SOURCE             /* pread(), pwrite(), gethostname() */
 
 #define _FILE_OFFSET_BITS  64
 #define _LARGEFILE_SOURCE
 
 
 #include <unistd.h>
-#include <stddef.h>             /* offsetof */
+#include <stddef.h>             /* offsetof() */
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -27,16 +27,17 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <dirent.h>
 #include <netdb.h>
 
 
 
-#define OFF_FMT    "%lld"
+#if 0
 #define SIZE_FMT   "%d"
 #define SIZEX_FMT  "%x"
-#define TIME_FMT   "%ld"
 #define PID_FMT    "%d"
 #define RLIM_FMT   "%lu"
+#endif
 
 
 
--- a/src/os/unix/ngx_linux_sendfile_chain.c
+++ b/src/os/unix/ngx_linux_sendfile_chain.c
@@ -1,183 +1,214 @@
 
 #include <ngx_config.h>
 #include <ngx_core.h>
-#include <ngx_linux_init.h>
+#include <ngx_event.h>
 
 
 ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
 {
-    int              rc, on, off;
+    int              rc;
     char            *prev;
-    size_t           hsize, size;
-    ssize_t          sent;
+    off_t            fprev;
+    size_t           size, fsize, sent;
+    ngx_int_t        use_cork, eintr;
     struct iovec    *iov;
-    struct sf_hdtr   hdtr;
     ngx_err_t        err;
-    ngx_array_t      header, trailer;
     ngx_hunk_t      *file;
-    ngx_chain_t     *ce;
+    ngx_array_t      header;
+    ngx_event_t     *wev;
+    ngx_chain_t     *cl;
+
+    wev = c->write;
 
-    ce = in;
-    file = NULL;
-    hsize = 0;
+    if (!wev->ready) {
+        return in;
+    }
+
+    cork = 0;
 
-    on = 1;
-    off = 0;
+    do {
+        file = NULL;
+        fsize = 0;
+        eintr = 0;
 
-    ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
-    ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
+        ngx_init_array(header, c->pool, 10, sizeof(struct iovec),
+                       NGX_CHAIN_ERROR);
 
-    /* create the header iovec */
-    if (ngx_hunk_in_memory_only(ce->hunk)) {
         prev = NULL;
         iov = NULL;
 
-        /* create the iovec and coalesce the neighbouring chain entries */
-        while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
+        /* create the iovec and coalesce the neighbouring hunks */
+
+        for (cl = in; cl; cl = cl->next) {
+            if (ngx_hunk_special(cl->hunk)) {
+                continue;
+            }
 
-            if (prev == ce->hunk->pos) {
-                iov->iov_len += ce->hunk->last - ce->hunk->pos;
-                prev = ce->hunk->last;
+            if (!ngx_hunk_in_memory_only(cl->hunk)) {
+                break;
+            }
+
+            if (prev == cl->hunk->pos) {
+                iov->iov_len += cl->hunk->last - cl->hunk->pos;
 
             } else {
                 ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR);
-                iov->iov_base = ce->hunk->pos;
-                iov->iov_len = ce->hunk->last - ce->hunk->pos;
-                prev = ce->hunk->last;
-            }
-
-            if (ngx_freebsd_sendfile_nbytes_bug) {
-                hsize += ce->hunk->last - ce->hunk->pos;
+                iov->iov_base = cl->hunk->pos;
+                iov->iov_len = cl->hunk->last - cl->hunk->pos;
             }
 
-            ce = ce->next;
-        }
-    }
-
-    /* TODO: coalesce the neighbouring file hunks */
-    if (ce && (ce->hunk->type & NGX_HUNK_FILE)) {
-        file = ce->hunk;
-        ce = ce->next;
-    }
-
-    /* create the trailer iovec */
-    if (ce && ngx_hunk_in_memory_only(ce->hunk)) {
-        prev = NULL;
-        iov = NULL;
-
-        /* create the iovec and coalesce the neighbouring chain entries */
-        while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
-
-            if (prev == ce->hunk->pos) {
-                iov->iov_len += ce->hunk->last - ce->hunk->pos;
-                prev = ce->hunk->last;
-
-            } else {
-                ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR);
-                iov->iov_base = ce->hunk->pos;
-                iov->iov_len = ce->hunk->last - ce->hunk->pos;
-                prev = ce->hunk->last;
-            }
-
-            ce = ce->next;
-        }
-    }
-
-    if (file) {
-        if (setsockopt(c->fd, IPPROTO_TCP, TCP_CORK,
-                       (const void *) &on, sizeof(int)) == -1) {
-            ngx_log_error(NGX_LOG_CRIT, c->log, err,
-                          "setsockopt(TCP_CORK, 1) failed");
-            return NGX_CHAIN_ERROR;
+            prev = cl->hunk->last;
         }
 
-
-        rc = sendfile(c->fd, file->file->fd, file->file_pos,
-                        (size_t) (file->file_last - file->file_pos));
+        /* set TCP_CORK if there is a header before a file */
 
-        if (rc == -1) {
-            err = ngx_errno;
-            if (err == NGX_EAGAIN) {
-                ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EAGAIN");
+        if (!c->tcp_nopush
+            && header.nelts != 0
+            && cl
+            && cl->hunk->type & NGX_HUNK_FILE)
+        {
+            c->tcp_nopush = 1;
 
-            } else if (err == NGX_EINTR) {
-                ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EINTR");
+ngx_log_debug(c->log, "CORK");
 
-            } else {
-                ngx_log_error(NGX_LOG_CRIT, c->log, err, "sendfile() failed");
+            if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
+                ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno,
+                              ngx_tcp_nopush_n " failed");
                 return NGX_CHAIN_ERROR;
             }
         }
 
-        sent = rc > 0 ? rc : 0;
+        if (header.nelts == 0 && cl && cl->hunk->type & NGX_HUNK_FILE) {
+
+            /* get the file hunk */
 
-#if (NGX_DEBUG_WRITE_CHAIN)
-        ngx_log_debug(c->log, "sendfile: %d, @%qd %d:%d" _
-                      rc _ file->file_pos _ sent _
-                      (size_t) (file->file_last - file->file_pos));
-#endif
+            file = cl->hunk;
+            fsize = (size_t) (file->file_last - file->file_pos);
+            fprev = file->file_last;
+            cl = cl->next; 
 
-    } else {
-        rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
+            /* coalesce the neighbouring file hunks */
 
-        if (rc == -1) {
-            err = ngx_errno;
-            if (err == NGX_EAGAIN) {
-                ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
+            while (cl && (cl->hunk->type & NGX_HUNK_FILE)) {
+                if (file->file->fd != cl->hunk->file->fd
+                    || fprev != cl->hunk->file_pos)
+                {
+                    break;
+                }
 
-            } else if (err == NGX_EINTR) {
-                ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
-
-            } else {
-                ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
-                return NGX_CHAIN_ERROR;
+                fsize += (size_t) (cl->hunk->file_last - cl->hunk->file_pos);
+                fprev = cl->hunk->file_last;
+                cl = cl->next;
             }
         }
 
-        sent = rc > 0 ? rc : 0;
+        /* 
+         * the tail is the rest of the chain that exceeded
+         * a single sendfile() capability
+         */
+
+        tail = cl;
+
+        if (fsize) {
+            rc = sendfile(c->fd, file->file->fd, file->file_pos, fsize);
+
+            if (rc == -1) {
+                err = ngx_errno;
+                if (err == NGX_EAGAIN) {
+                    ngx_log_error(NGX_LOG_INFO, c->log, err,
+                                  "sendfile() EAGAIN");
+
+                } else if (err == NGX_EINTR) {
+                    eintr = 1;
+                    ngx_log_error(NGX_LOG_INFO, c->log, err,
+                                  "sendfile() EINTR");
+
+                } else {
+                    ngx_log_error(NGX_LOG_CRIT, c->log, err,
+                                  "sendfile() failed");
+                    return NGX_CHAIN_ERROR;
+                }
+            }
+
+            sent = rc > 0 ? rc : 0;
 
 #if (NGX_DEBUG_WRITE_CHAIN)
-        ngx_log_debug(c->log, "writev: %d" _ sent);
+            ngx_log_debug(c->log, "sendfile: %d, @" OFF_T_FMT " %d:%d" _
+                          rc _ file->file_pos _ sent _ fsize);
 #endif
-    }
-
-    c->sent += sent;
-
-    for (ce = in; ce && sent > 0; ce = ce->next) {
+        } else {
+            rc = writev(c->fd, header.elts, header.nelts);
 
-        if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
-            size = ce->hunk->last - ce->hunk->pos;
-        } else {
-            size = ce->hunk->file_last - ce->hunk->file_pos;
-        }
+            if (rc == -1) {
+                err = ngx_errno;
+                if (err == NGX_EAGAIN) {
+                    ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
 
-        if (sent >= size) {
-            sent -= size;
+                } else if (err == NGX_EINTR) {
+                    eintr = 1;
+                    ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
 
-            if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
-                ce->hunk->pos = ce->hunk->last;
+                } else {
+                    ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
+                    return NGX_CHAIN_ERROR;
+                }
             }
 
-            if (ce->hunk->type & NGX_HUNK_FILE) {
-                ce->hunk->file_pos = ce->hunk->file_last;
-            }
+            sent = rc > 0 ? rc : 0;
 
-            continue;
-        }
-
-        if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
-            ce->hunk->pos += sent;
+#if (NGX_DEBUG_WRITE_CHAIN)
+            ngx_log_debug(c->log, "writev: %d" _ sent);
+#endif
         }
 
-        if (ce->hunk->type & NGX_HUNK_FILE) {
-            ce->hunk->file_pos += sent;
+        c->sent += sent;
+
+        for (cl = in; cl; cl = cl->next) {
+
+            if (ngx_hunk_special(cl->hunk)) {
+                continue;
+            }
+
+            if (sent == 0) {
+                break;
+            }
+
+            size = ngx_hunk_size(cl->hunk);
+
+            if (sent >= size) {
+                sent -= size;
+
+                if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+                    cl->hunk->pos = cl->hunk->last;
+                }
+
+                if (cl->hunk->type & NGX_HUNK_FILE) {
+                    cl->hunk->file_pos = cl->hunk->file_last;
+                }
+
+                continue;
+            }
+
+            if (cl->hunk->type & NGX_HUNK_IN_MEMORY) {
+                cl->hunk->pos += sent;
+            }
+
+            if (cl->hunk->type & NGX_HUNK_FILE) {
+                cl->hunk->file_pos += sent;
+            }
+
+            break;
         }
 
-        break;
+        in = cl;
+
+        /* "tail == in" means that a single sendfile() is complete */
+
+    } while ((tail && tail == in) || eintr);
+
+    if (in) {
+        wev->ready = 0;
     }
 
-    ngx_destroy_array(&trailer);
-    ngx_destroy_array(&header);
-
-    return ce;
+    return in;
 }
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -56,7 +56,7 @@ int ngx_posix_init(ngx_log_t *log)
     }
 
     ngx_log_error(NGX_LOG_INFO, log, 0,
-                  "getrlimit(RLIMIT_NOFILE): " RLIM_FMT ":" RLIM_FMT,
+                  "getrlimit(RLIMIT_NOFILE): " RLIM_T_FMT ":" RLIM_T_FMT,
                   rlmt.rlim_cur, rlmt.rlim_max);
 
     ngx_max_sockets = rlmt.rlim_cur;
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -41,9 +41,10 @@ int ngx_spawn_process(ngx_log_t *log)
         break;
 
     default:
+        break;
     }
 
-ngx_log_debug(log, "parent process, child: " PID_FMT _ pid);
+ngx_log_debug(log, "parent process, child: " PID_T_FMT _ pid);
 
     /* book keeping */
 
@@ -97,7 +98,7 @@ void ngx_sigchld_handler(int signo)
         one = 1;
 
         ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
-                      "process " PID_FMT " exited with code %d", pid, status);
+                      "process " PID_T_FMT " exited with code %d", pid, status);
 
         /* TODO: restart handler */
 
--- a/src/os/unix/ngx_socket.c
+++ b/src/os/unix/ngx_socket.c
@@ -55,6 +55,28 @@ int ngx_tcp_push(ngx_socket_t s)
                       (const void *) &tcp_nopush, sizeof(int));
 }
 
+#elif __linux__
+
+int ngx_tcp_nopush(ngx_socket_t s)
+{
+    int  cork;
+
+    cork = 1;
+
+    return setsockopt(s, IPPROTO_TCP, TCP_CORK,
+                      (const void *) &cork, sizeof(int));
+}
+
+int ngx_tcp_push(ngx_socket_t s)
+{
+    int  cork;
+
+    cork = 0;
+
+    return setsockopt(s, IPPROTO_TCP, TCP_CORK,
+                      (const void *) &cork, sizeof(int));
+}
+
 #else
 
 int ngx_tcp_nopush(ngx_socket_t s)
--- a/src/os/unix/ngx_socket.h
+++ b/src/os/unix/ngx_socket.h
@@ -29,11 +29,19 @@ int ngx_blocking(ngx_socket_t s);
 #endif
 
 int ngx_tcp_nopush(ngx_socket_t s);
-#define ngx_tcp_nopush_n   "setsockopt(TCP_NOPUSH)"
+int ngx_tcp_push(ngx_socket_t s);
+
+#ifdef __linux__
 
-int ngx_tcp_push(ngx_socket_t s);
+#define ngx_tcp_nopush_n   "setsockopt(TCP_CORK)"
+#define ngx_tcp_push_n     "setsockopt(!TCP_CORK)"
+
+#else
+
+#define ngx_tcp_nopush_n   "setsockopt(TCP_NOPUSH)"
 #define ngx_tcp_push_n     "setsockopt(!TCP_NOPUSH)"
 
+#endif
 
 
 #define ngx_shutdown_socket    shutdown
--- a/src/os/unix/ngx_solaris_config.h
+++ b/src/os/unix/ngx_solaris_config.h
@@ -10,7 +10,7 @@
 
 #include <unistd.h>
 #include <inttypes.h>
-#include <stddef.h>             /* offsetof */
+#include <stddef.h>             /* offsetof() */
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -28,14 +28,14 @@
 #include <netdb.h>
 
 
-typedef uint32_t  u_int32_t;
-
+#if 0
 #define OFF_FMT    "%lld"
 #define SIZE_FMT   "%d"
 #define SIZEX_FMT  "%x"
 #define TIME_FMT   "%ld"
 #define PID_FMT    "%ld"
 #define RLIM_FMT   "%lu"
+#endif
 
 
 #ifndef HAVE_SELECT
--- a/src/os/unix/ngx_writev_chain.c
+++ b/src/os/unix/ngx_writev_chain.c
@@ -58,7 +58,7 @@ ngx_chain_t *ngx_writev_chain(ngx_connec
     sent = n > 0 ? n : 0;
 
 #if (NGX_DEBUG_WRITE_CHAIN)
-    ngx_log_debug(c->log, "writev: " OFF_FMT  _ sent);
+    ngx_log_debug(c->log, "writev: " OFF_T_FMT  _ sent);
 #endif
 
     c->sent += sent;
--- a/src/os/win32/ngx_sendfile.c
+++ b/src/os/win32/ngx_sendfile.c
@@ -42,7 +42,7 @@ int ngx_sendfile(ngx_connection_t *c,
     if (ev->ready) {
         ev->ready = 0;
 
-#if (HAVE_IOCP_EVENT) /* iocp */
+#if (HAVE_IOCP) /* iocp */
 
         if (ngx_event_flags & NGX_HAVE_IOCP_EVENT) {
             if (ev->ovlp.error) {
--- a/src/os/win32/ngx_win32_config.h
+++ b/src/os/win32/ngx_win32_config.h
@@ -21,7 +21,7 @@
 
 #include <winsock2.h>
 #include <mswsock.h>
-#include <stddef.h>    /* offsetof */
+#include <stddef.h>    /* offsetof() */
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -41,6 +41,7 @@
 
 
 #if 0
+/* owc have not __int32 */
 typedef unsigned __int32  uint32_t;
 #else
 typedef unsigned int      uint32_t;
@@ -52,18 +53,16 @@ typedef u_int             uintptr_t;
 typedef int               ssize_t;
 typedef long              time_t;
 typedef __int64           off_t;
+typedef uint32_t          in_addr_t;
 
 
-#define OFF_FMT    "%I64d"
-#define SIZE_FMT   "%d"
-#define SIZEX_FMT  "%x"
-#define PID_FMT    "%d"
-#define TIME_FMT   "%lu"
+#define OFF_T_FMT         "%I64d"
+#define SIZE_T_FMT        "%d"
+#define SIZE_T_X_FMT      "%x"
+#define PID_T_FMT         "%d"
+#define TIME_T_FMT        "%lu"
 
 
-/* STUB */
-typedef uint32_t     u_int32_t;
-
 
 #ifndef HAVE_INHERITED_NONBLOCK
 #define HAVE_INHERITED_NONBLOCK  1