--- ../lighttpd-1.4.11/NEWS 2006-03-09 19:34:33.000000000 +0200 +++ lighttpd-1.4.12/NEWS 2006-07-16 00:26:05.000000000 +0300 @@ -3,6 +3,23 @@ NEWS ==== +- 1.4.12 - 2006-..-.. + + * added handling of Content-Range to PUT requests in mod_webdav + * added handling of ETag and If-Modified-Since to mod_compress if + cache-dir is not set + * added experimental LOCK support for mod_webdav + * added support for X-Sendfile as addition to X-LIGHTTPD-send-file. + This allows compatibility with mod_xsendfile for apache + (http://celebnamer.celebworld.ws/stuff/mod_xsendfile/) + * fixed handling of If-Modified-Since if Etag is not set + * fixed hanging fastcgi connections + * fixed stalling SSL POST requests + * fixed round-robin load-balancing in mod_proxy + * TODO: add fail-over to mod-proxy + * TODO: fix CACHE_HIT/MISS in mod_cml + * TODO: finish LOCK/UNLOCK in mod_webdav + - 1.4.11 - 2006-03-09 * added ability to specify which ip address spawn-fci listens on --- ../lighttpd-1.4.11/configure.in 2006-03-04 16:32:38.000000000 +0200 +++ lighttpd-1.4.12/configure.in 2006-07-16 00:26:05.000000000 +0300 @@ -1,7 +1,7 @@ # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) -AC_INIT(lighttpd, 1.4.11, jan@kneschke.de) +AC_INIT(lighttpd, 1.4.12, jan@kneschke.de) AC_CONFIG_SRCDIR([src/server.c]) AC_CANONICAL_TARGET @@ -66,7 +66,7 @@ AC_TYPE_PID_T AC_TYPE_SIZE_T -AC_CHECK_MEMBER(struct tm.tm_gmtoff,AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm]),,[#include ]) +AC_CHECK_MEMBER(struct tm.tm_gmtoff,[AC_DEFINE([HAVE_STRUCT_TM_GMTOFF],[1],[gmtoff in struct tm])],,[#include ]) AC_CHECK_TYPES(struct sockaddr_storage,,,[#include ]) AC_CHECK_TYPES(socklen_t,,,[#include #include ]) @@ -339,6 +339,22 @@ AC_DEFINE([HAVE_SQLITE3], [1], [libsqlite3]) AC_DEFINE([HAVE_SQLITE3_H], [1], [sqlite3.h]) ]) + + AC_MSG_CHECKING(for locks in mod_webdav) + AC_ARG_WITH(webdav-locks, AC_HELP_STRING([--with-webdav-locks],[locks in mod_webdav]), + [WITH_WEBDAV_LOCKS=$withval],[WITH_WEBDAV_LOCKS=no]) + AC_MSG_RESULT([$WITH_WEBDAV_LOCKS]) + + if test "$WITH_WEBDAV_LOCKS" != "no"; then + AC_CHECK_LIB(uuid, uuid_unparse, [ + AC_CHECK_HEADERS([uuid/uuid.h],[ + UUID_LIB=-luuid + AC_DEFINE([HAVE_UUID], [1], [libuuid]) + AC_DEFINE([HAVE_UUID_H], [1], [uuid/uuid.h is available]) + ]) + ]) + + fi fi dnl Check for gdbm @@ -381,30 +397,11 @@ AC_MSG_RESULT($WITH_LUA) if test "$WITH_LUA" != "no"; then - AC_PATH_PROG(LUACONFIG, lua-config) - - if test x"$LUACONFIG" != x; then - LUA_CFLAGS=`$LUACONFIG --include` - LUA_LIBS=`$LUACONFIG --libs --extralibs` + # try pkgconfig + PKG_CHECK_MODULES(LUA, lua >= 5.1, [ AC_DEFINE([HAVE_LUA], [1], [liblua]) AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) - else - AC_CHECK_LIB(lua, lua_open, [ - AC_CHECK_HEADERS([lua.h],[ - LUA_LIBS="-llua -llualib" - AC_DEFINE([HAVE_LUA], [1], [liblua]) - AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) - ]) - ]) - fi - - if test x"$LUA_LIBS" = x; then - # try pkgconfig - PKG_CHECK_MODULES(LUA, lua, [ - AC_DEFINE([HAVE_LUA], [1], [liblua]) - AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) - ]) - fi + ]) AC_SUBST(LUA_CFLAGS) AC_SUBST(LUA_LIBS) @@ -440,7 +437,7 @@ esac AC_CHECK_FUNCS([dup2 getcwd inet_ntoa inet_ntop memset mmap munmap strchr \ - strdup strerror strstr strtol sendfile getopt socket \ + strdup strerror strstr strtol sendfile getopt socket lstat \ gethostbyname poll sigtimedwait epoll_ctl getrlimit chroot \ getuid select signal pathconf madvise posix_fadvise posix_madvise \ writev sigaction sendfile64 send_file kqueue port_create localtime_r]) @@ -538,7 +535,7 @@ AC_OUTPUT -do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi" +do_build="mod_cgi mod_fastcgi mod_proxy mod_evhost mod_simple_vhost mod_access mod_alias mod_setenv mod_usertrack mod_auth mod_status mod_accesslog mod_rrdtool mod_secdownload mod_expire mod_compress mod_dirlisting mod_indexfiles mod_userdir mod_webdav mod_staticfile mod_scgi mod_flv_streaming" plugins="mod_rewrite mod_redirect mod_ssi mod_trigger_b4_dl" features="regex-conditionals" @@ -642,6 +639,14 @@ disable_feature="$disable_feature $features" fi +features="webdav-locks" +if test "x$UUID_LIB" \!= x; then + enable_feature="$enable_feature $features" +else + disable_feature="$disable_feature $features" +fi + + ## output $ECHO --- ../lighttpd-1.4.11/cygwin/lighttpd.README 2006-03-07 14:22:19.000000000 +0200 +++ lighttpd-1.4.12/cygwin/lighttpd.README 2006-07-17 22:02:18.000000000 +0300 @@ -1,114 +1,114 @@ -lighttpd ------------------------------------------- -A fast, secure and flexible webserver - -Runtime requirements: - cygwin-1.5.10 or newer - crypt-1.1 or newer - libbz2_1-1.0.2 or newer - libpcre0-4.5 or newer - openssl-0.9.7d or newer - zlib-1.2.1 or newer - -Build requirements: - cygwin-1.5.10 or newer - gcc-3.3.1-3 or newer - binutils-20030901-1 or newer - crypt - openssl-devel - openssl - openldap - openldap-devel - zlib - bzip2 - -Canonical homepage: - http://jan.kneschke.de/projects/lighttpd/ - -Canonical download: - http://jan.kneschke.de/projects/lighttpd/download - ------------------------------------- - -Build instructions: - unpack lighttpd-1.4.11--src.tar.bz2 - if you use setup to install this src package, it will be - unpacked under /usr/src automatically - cd /usr/src - ./lighttpd-1.4.11-.sh all - -This will create: - /usr/src/lighttpd-1.4.11-.tar.bz2 - /usr/src/lighttpd-1.4.11--src.tar.bz2 - -Or use './lighttpd-1.4.11-.sh prep' to get a patched source directory - -------------------------------------------- - -Files included in the binary distribution: - - /etc/lighttpd/lighttpd.conf.default - /usr/lib/cyglightcomp.dll - /usr/lib/lighttpd/mod_access.dll - /usr/lib/lighttpd/mod_accesslog.dll - /usr/lib/lighttpd/mod_auth.dll - /usr/lib/lighttpd/mod_cgi.dll - /usr/lib/lighttpd/mod_compress.dll - /usr/lib/lighttpd/mod_evhost.dll - /usr/lib/lighttpd/mod_expire.dll - /usr/lib/lighttpd/mod_fastcgi.dll - /usr/lib/lighttpd/mod_httptls.dll - /usr/lib/lighttpd/mod_maps.dll - /usr/lib/lighttpd/mod_proxy.dll - /usr/lib/lighttpd/mod_redirect.dll - /usr/lib/lighttpd/mod_rewrite.dll - /usr/lib/lighttpd/mod_rrdtool.dll - /usr/lib/lighttpd/mod_secdownload.dll - /usr/lib/lighttpd/mod_simple_vhost.dll - /usr/lib/lighttpd/mod_ssi.dll - /usr/lib/lighttpd/mod_status.dll - /usr/lib/lighttpd/mod_usertrack.dll - /usr/sbin/lighttpd.exe - /usr/share/doc/Cygwin/lighttpd-1.3.0.README - /usr/share/doc/lighttpd-1.3.0/accesslog.txt - /usr/share/doc/lighttpd-1.3.0/authentification.txt - /usr/share/doc/lighttpd-1.3.0/AUTHORS - /usr/share/doc/lighttpd-1.3.0/cgi.txt - /usr/share/doc/lighttpd-1.3.0/ChangeLog - /usr/share/doc/lighttpd-1.3.0/compress.txt - /usr/share/doc/lighttpd-1.3.0/configuration.txt - /usr/share/doc/lighttpd-1.3.0/COPYING - /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt - /usr/share/doc/lighttpd-1.3.0/fastcgi.txt - /usr/share/doc/lighttpd-1.3.0/features.txt - /usr/share/doc/lighttpd-1.3.0/INSTALL - /usr/share/doc/lighttpd-1.3.0/NEWS - /usr/share/doc/lighttpd-1.3.0/performance.txt - /usr/share/doc/lighttpd-1.3.0/plugins.txt - /usr/share/doc/lighttpd-1.3.0/proxy.txt - /usr/share/doc/lighttpd-1.3.0/README - /usr/share/doc/lighttpd-1.3.0/redirect.txt - /usr/share/doc/lighttpd-1.3.0/rewrite.txt - /usr/share/doc/lighttpd-1.3.0/rrdtool.txt - /usr/share/doc/lighttpd-1.3.0/secdownload.txt - /usr/share/doc/lighttpd-1.3.0/security.txt - /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt - /usr/share/doc/lighttpd-1.3.0/skeleton.txt - /usr/share/doc/lighttpd-1.3.0/ssi.txt - /usr/share/doc/lighttpd-1.3.0/state.txt - /usr/share/man/man1/lighttpd.1.gz - ------------------- - -Port Notes: - ----------- lighttpd-1.3.1-1 ----------- - -Updated to 1.3.1 - ----------- lighttpd-1.3.0-1 ----------- -Initial release - -Cygwin port maintained by: Jan Kneschke -Please address all questions to the Cygwin mailing list at - +lighttpd +------------------------------------------ +A fast, secure and flexible webserver + +Runtime requirements: + cygwin-1.5.10 or newer + crypt-1.1 or newer + libbz2_1-1.0.2 or newer + libpcre0-4.5 or newer + openssl-0.9.7d or newer + zlib-1.2.1 or newer + +Build requirements: + cygwin-1.5.10 or newer + gcc-3.3.1-3 or newer + binutils-20030901-1 or newer + crypt + openssl-devel + openssl + openldap + openldap-devel + zlib + bzip2 + +Canonical homepage: + http://jan.kneschke.de/projects/lighttpd/ + +Canonical download: + http://jan.kneschke.de/projects/lighttpd/download + +------------------------------------ + +Build instructions: + unpack lighttpd-1.4.12--src.tar.bz2 + if you use setup to install this src package, it will be + unpacked under /usr/src automatically + cd /usr/src + ./lighttpd-1.4.12-.sh all + +This will create: + /usr/src/lighttpd-1.4.12-.tar.bz2 + /usr/src/lighttpd-1.4.12--src.tar.bz2 + +Or use './lighttpd-1.4.12-.sh prep' to get a patched source directory + +------------------------------------------- + +Files included in the binary distribution: + + /etc/lighttpd/lighttpd.conf.default + /usr/lib/cyglightcomp.dll + /usr/lib/lighttpd/mod_access.dll + /usr/lib/lighttpd/mod_accesslog.dll + /usr/lib/lighttpd/mod_auth.dll + /usr/lib/lighttpd/mod_cgi.dll + /usr/lib/lighttpd/mod_compress.dll + /usr/lib/lighttpd/mod_evhost.dll + /usr/lib/lighttpd/mod_expire.dll + /usr/lib/lighttpd/mod_fastcgi.dll + /usr/lib/lighttpd/mod_httptls.dll + /usr/lib/lighttpd/mod_maps.dll + /usr/lib/lighttpd/mod_proxy.dll + /usr/lib/lighttpd/mod_redirect.dll + /usr/lib/lighttpd/mod_rewrite.dll + /usr/lib/lighttpd/mod_rrdtool.dll + /usr/lib/lighttpd/mod_secdownload.dll + /usr/lib/lighttpd/mod_simple_vhost.dll + /usr/lib/lighttpd/mod_ssi.dll + /usr/lib/lighttpd/mod_status.dll + /usr/lib/lighttpd/mod_usertrack.dll + /usr/sbin/lighttpd.exe + /usr/share/doc/Cygwin/lighttpd-1.3.0.README + /usr/share/doc/lighttpd-1.3.0/accesslog.txt + /usr/share/doc/lighttpd-1.3.0/authentification.txt + /usr/share/doc/lighttpd-1.3.0/AUTHORS + /usr/share/doc/lighttpd-1.3.0/cgi.txt + /usr/share/doc/lighttpd-1.3.0/ChangeLog + /usr/share/doc/lighttpd-1.3.0/compress.txt + /usr/share/doc/lighttpd-1.3.0/configuration.txt + /usr/share/doc/lighttpd-1.3.0/COPYING + /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt + /usr/share/doc/lighttpd-1.3.0/fastcgi.txt + /usr/share/doc/lighttpd-1.3.0/features.txt + /usr/share/doc/lighttpd-1.3.0/INSTALL + /usr/share/doc/lighttpd-1.3.0/NEWS + /usr/share/doc/lighttpd-1.3.0/performance.txt + /usr/share/doc/lighttpd-1.3.0/plugins.txt + /usr/share/doc/lighttpd-1.3.0/proxy.txt + /usr/share/doc/lighttpd-1.3.0/README + /usr/share/doc/lighttpd-1.3.0/redirect.txt + /usr/share/doc/lighttpd-1.3.0/rewrite.txt + /usr/share/doc/lighttpd-1.3.0/rrdtool.txt + /usr/share/doc/lighttpd-1.3.0/secdownload.txt + /usr/share/doc/lighttpd-1.3.0/security.txt + /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt + /usr/share/doc/lighttpd-1.3.0/skeleton.txt + /usr/share/doc/lighttpd-1.3.0/ssi.txt + /usr/share/doc/lighttpd-1.3.0/state.txt + /usr/share/man/man1/lighttpd.1.gz + +------------------ + +Port Notes: + +---------- lighttpd-1.3.1-1 ----------- + +Updated to 1.3.1 + +---------- lighttpd-1.3.0-1 ----------- +Initial release + +Cygwin port maintained by: Jan Kneschke +Please address all questions to the Cygwin mailing list at + --- ../lighttpd-1.4.11/cygwin/lighttpd.README.in 2005-08-11 01:26:59.000000000 +0300 +++ lighttpd-1.4.12/cygwin/lighttpd.README.in 2006-07-16 00:26:04.000000000 +0300 @@ -1,114 +1,114 @@ -lighttpd ------------------------------------------- -A fast, secure and flexible webserver - -Runtime requirements: - cygwin-1.5.10 or newer - crypt-1.1 or newer - libbz2_1-1.0.2 or newer - libpcre0-4.5 or newer - openssl-0.9.7d or newer - zlib-1.2.1 or newer - -Build requirements: - cygwin-1.5.10 or newer - gcc-3.3.1-3 or newer - binutils-20030901-1 or newer - crypt - openssl-devel - openssl - openldap - openldap-devel - zlib - bzip2 - -Canonical homepage: - http://jan.kneschke.de/projects/lighttpd/ - -Canonical download: - http://jan.kneschke.de/projects/lighttpd/download - ------------------------------------- - -Build instructions: - unpack lighttpd-@VERSION@--src.tar.bz2 - if you use setup to install this src package, it will be - unpacked under /usr/src automatically - cd /usr/src - ./lighttpd-@VERSION@-.sh all - -This will create: - /usr/src/lighttpd-@VERSION@-.tar.bz2 - /usr/src/lighttpd-@VERSION@--src.tar.bz2 - -Or use './lighttpd-@VERSION@-.sh prep' to get a patched source directory - -------------------------------------------- - -Files included in the binary distribution: - - /etc/lighttpd/lighttpd.conf.default - /usr/lib/cyglightcomp.dll - /usr/lib/lighttpd/mod_access.dll - /usr/lib/lighttpd/mod_accesslog.dll - /usr/lib/lighttpd/mod_auth.dll - /usr/lib/lighttpd/mod_cgi.dll - /usr/lib/lighttpd/mod_compress.dll - /usr/lib/lighttpd/mod_evhost.dll - /usr/lib/lighttpd/mod_expire.dll - /usr/lib/lighttpd/mod_fastcgi.dll - /usr/lib/lighttpd/mod_httptls.dll - /usr/lib/lighttpd/mod_maps.dll - /usr/lib/lighttpd/mod_proxy.dll - /usr/lib/lighttpd/mod_redirect.dll - /usr/lib/lighttpd/mod_rewrite.dll - /usr/lib/lighttpd/mod_rrdtool.dll - /usr/lib/lighttpd/mod_secdownload.dll - /usr/lib/lighttpd/mod_simple_vhost.dll - /usr/lib/lighttpd/mod_ssi.dll - /usr/lib/lighttpd/mod_status.dll - /usr/lib/lighttpd/mod_usertrack.dll - /usr/sbin/lighttpd.exe - /usr/share/doc/Cygwin/lighttpd-1.3.0.README - /usr/share/doc/lighttpd-1.3.0/accesslog.txt - /usr/share/doc/lighttpd-1.3.0/authentification.txt - /usr/share/doc/lighttpd-1.3.0/AUTHORS - /usr/share/doc/lighttpd-1.3.0/cgi.txt - /usr/share/doc/lighttpd-1.3.0/ChangeLog - /usr/share/doc/lighttpd-1.3.0/compress.txt - /usr/share/doc/lighttpd-1.3.0/configuration.txt - /usr/share/doc/lighttpd-1.3.0/COPYING - /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt - /usr/share/doc/lighttpd-1.3.0/fastcgi.txt - /usr/share/doc/lighttpd-1.3.0/features.txt - /usr/share/doc/lighttpd-1.3.0/INSTALL - /usr/share/doc/lighttpd-1.3.0/NEWS - /usr/share/doc/lighttpd-1.3.0/performance.txt - /usr/share/doc/lighttpd-1.3.0/plugins.txt - /usr/share/doc/lighttpd-1.3.0/proxy.txt - /usr/share/doc/lighttpd-1.3.0/README - /usr/share/doc/lighttpd-1.3.0/redirect.txt - /usr/share/doc/lighttpd-1.3.0/rewrite.txt - /usr/share/doc/lighttpd-1.3.0/rrdtool.txt - /usr/share/doc/lighttpd-1.3.0/secdownload.txt - /usr/share/doc/lighttpd-1.3.0/security.txt - /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt - /usr/share/doc/lighttpd-1.3.0/skeleton.txt - /usr/share/doc/lighttpd-1.3.0/ssi.txt - /usr/share/doc/lighttpd-1.3.0/state.txt - /usr/share/man/man1/lighttpd.1.gz - ------------------- - -Port Notes: - ----------- lighttpd-1.3.1-1 ----------- - -Updated to 1.3.1 - ----------- lighttpd-1.3.0-1 ----------- -Initial release - -Cygwin port maintained by: Jan Kneschke -Please address all questions to the Cygwin mailing list at - +lighttpd +------------------------------------------ +A fast, secure and flexible webserver + +Runtime requirements: + cygwin-1.5.10 or newer + crypt-1.1 or newer + libbz2_1-1.0.2 or newer + libpcre0-4.5 or newer + openssl-0.9.7d or newer + zlib-1.2.1 or newer + +Build requirements: + cygwin-1.5.10 or newer + gcc-3.3.1-3 or newer + binutils-20030901-1 or newer + crypt + openssl-devel + openssl + openldap + openldap-devel + zlib + bzip2 + +Canonical homepage: + http://jan.kneschke.de/projects/lighttpd/ + +Canonical download: + http://jan.kneschke.de/projects/lighttpd/download + +------------------------------------ + +Build instructions: + unpack lighttpd-@VERSION@--src.tar.bz2 + if you use setup to install this src package, it will be + unpacked under /usr/src automatically + cd /usr/src + ./lighttpd-@VERSION@-.sh all + +This will create: + /usr/src/lighttpd-@VERSION@-.tar.bz2 + /usr/src/lighttpd-@VERSION@--src.tar.bz2 + +Or use './lighttpd-@VERSION@-.sh prep' to get a patched source directory + +------------------------------------------- + +Files included in the binary distribution: + + /etc/lighttpd/lighttpd.conf.default + /usr/lib/cyglightcomp.dll + /usr/lib/lighttpd/mod_access.dll + /usr/lib/lighttpd/mod_accesslog.dll + /usr/lib/lighttpd/mod_auth.dll + /usr/lib/lighttpd/mod_cgi.dll + /usr/lib/lighttpd/mod_compress.dll + /usr/lib/lighttpd/mod_evhost.dll + /usr/lib/lighttpd/mod_expire.dll + /usr/lib/lighttpd/mod_fastcgi.dll + /usr/lib/lighttpd/mod_httptls.dll + /usr/lib/lighttpd/mod_maps.dll + /usr/lib/lighttpd/mod_proxy.dll + /usr/lib/lighttpd/mod_redirect.dll + /usr/lib/lighttpd/mod_rewrite.dll + /usr/lib/lighttpd/mod_rrdtool.dll + /usr/lib/lighttpd/mod_secdownload.dll + /usr/lib/lighttpd/mod_simple_vhost.dll + /usr/lib/lighttpd/mod_ssi.dll + /usr/lib/lighttpd/mod_status.dll + /usr/lib/lighttpd/mod_usertrack.dll + /usr/sbin/lighttpd.exe + /usr/share/doc/Cygwin/lighttpd-1.3.0.README + /usr/share/doc/lighttpd-1.3.0/accesslog.txt + /usr/share/doc/lighttpd-1.3.0/authentification.txt + /usr/share/doc/lighttpd-1.3.0/AUTHORS + /usr/share/doc/lighttpd-1.3.0/cgi.txt + /usr/share/doc/lighttpd-1.3.0/ChangeLog + /usr/share/doc/lighttpd-1.3.0/compress.txt + /usr/share/doc/lighttpd-1.3.0/configuration.txt + /usr/share/doc/lighttpd-1.3.0/COPYING + /usr/share/doc/lighttpd-1.3.0/fastcgi-state.txt + /usr/share/doc/lighttpd-1.3.0/fastcgi.txt + /usr/share/doc/lighttpd-1.3.0/features.txt + /usr/share/doc/lighttpd-1.3.0/INSTALL + /usr/share/doc/lighttpd-1.3.0/NEWS + /usr/share/doc/lighttpd-1.3.0/performance.txt + /usr/share/doc/lighttpd-1.3.0/plugins.txt + /usr/share/doc/lighttpd-1.3.0/proxy.txt + /usr/share/doc/lighttpd-1.3.0/README + /usr/share/doc/lighttpd-1.3.0/redirect.txt + /usr/share/doc/lighttpd-1.3.0/rewrite.txt + /usr/share/doc/lighttpd-1.3.0/rrdtool.txt + /usr/share/doc/lighttpd-1.3.0/secdownload.txt + /usr/share/doc/lighttpd-1.3.0/security.txt + /usr/share/doc/lighttpd-1.3.0/simple-vhost.txt + /usr/share/doc/lighttpd-1.3.0/skeleton.txt + /usr/share/doc/lighttpd-1.3.0/ssi.txt + /usr/share/doc/lighttpd-1.3.0/state.txt + /usr/share/man/man1/lighttpd.1.gz + +------------------ + +Port Notes: + +---------- lighttpd-1.3.1-1 ----------- + +Updated to 1.3.1 + +---------- lighttpd-1.3.0-1 ----------- +Initial release + +Cygwin port maintained by: Jan Kneschke +Please address all questions to the Cygwin mailing list at + --- ../lighttpd-1.4.11/doc/authentication.txt 2006-01-12 20:34:26.000000000 +0200 +++ lighttpd-1.4.12/doc/authentication.txt 2006-07-16 00:26:05.000000000 +0300 @@ -7,8 +7,8 @@ ---------------- :Author: Jan Kneschke -:Date: $Date$ -:Revision: $Revision$ +:Date: $Date$ +:Revision: $Revision$ :abstract: The auth module provides ... --- ../lighttpd-1.4.11/doc/compress.txt 2005-08-11 01:26:16.000000000 +0300 +++ lighttpd-1.4.12/doc/compress.txt 2006-07-16 00:26:05.000000000 +0300 @@ -22,12 +22,38 @@ =========== Output compression reduces the network load and can improve the overall -throughput of the webserver. +throughput of the webserver. All major http-clients support compression by +announcing it in the Accept-Encoding header. This is used to negotiate the +most suitable compression method. We support deflate, gzip and bzip2. -Only static content is supported up to now. +deflate (RFC1950, RFC1951) and gzip (RFC1952) depend on zlib while bzip2 +depends on libbzip2. bzip2 is only supported by lynx and some other console +text-browsers. -The server negotiates automaticly which compression method is used. -Supported are gzip, deflate, bzip. +Currently we limit to compression support to static files. + +Caching +------- + +mod_compress can stored compressed files on disk to optimized the compression +on a second request away. As soon as compress.cache-dir is set the files are +compressed. + +The names of the cache files are made of the filename, the compression method +and the etag associated to the file. + +Cleaning the cache is left to the user. A cron job deleting files older than +10 days should do fine. + +Limitations +----------- + +The module limits the compression of files to files larger than 128 Byte and +smaller than 128 MByte. + +The lower limit is set as small files tend to become larger by compressing due +to the compression headers, the upper limit is set to work sensable with +memory and cpu-time. Options ======= @@ -47,15 +73,28 @@ Default: not set, compress the file for every request compress.filetype - mimetypes where might get compressed + mimetypes which might get compressed e.g.: :: compress.filetype = ("text/plain", "text/html") + Keep in mind that compressed JavaScript and CSS files are broken in some + browsers. + Default: not set +compress.max-file-size + maximum size of the original file to be compressed kBytes. + + This is meant to protect the server against DoSing as compressing large + (let's say 1Gbyte) takes a lot of time and would delay the whole operation + of the server. + There is a hard upper limit of 128Mbyte. + + Default: unlimited (== hard-limit of 128MByte) + Compressing Dynamic Content =========================== --- ../lighttpd-1.4.11/doc/configuration.txt 2006-03-09 02:10:40.000000000 +0200 +++ lighttpd-1.4.12/doc/configuration.txt 2006-07-16 00:26:05.000000000 +0300 @@ -7,8 +7,8 @@ ------------ :Author: Jan Kneschke -:Date: $Date$ -:Revision: $Revision$ +:Date: $Date$ +:Revision: $Revision$ :abstract: the layout of the configuration file @@ -511,3 +511,10 @@ debug.log-request-handling default: disabled + +debug.log-condition-handling + default: disabled + +debug.log-condition-cache-handling + for developers only + default: disabled --- ../lighttpd-1.4.11/doc/fastcgi.txt 2006-02-16 17:03:52.000000000 +0200 +++ lighttpd-1.4.12/doc/fastcgi.txt 2006-07-16 00:26:05.000000000 +0300 @@ -144,8 +144,8 @@ PHP can extract PATH_INFO from it (default: disabled) :"disable-time": time to wait before a disabled backend is checked again - :"allow-x-send-file": controls if X-LIGHTTPD-send-file headers - are allowed + :"allow-x-send-file": controls if X-LIGHTTPD-send-file and X-Sendfile + headers are allowed If bin-path is set: --- ../lighttpd-1.4.11/doc/lighttpd.conf 2006-03-04 14:41:12.000000000 +0200 +++ lighttpd-1.4.12/doc/lighttpd.conf 2006-07-16 00:26:05.000000000 +0300 @@ -172,10 +172,11 @@ #dir-listing.activate = "enable" ## enable debugging -#debug.log-request-header = "enable" -#debug.log-response-header = "enable" -#debug.log-request-handling = "enable" -#debug.log-file-not-found = "enable" +#debug.log-request-header = "enable" +#debug.log-response-header = "enable" +#debug.log-request-handling = "enable" +#debug.log-file-not-found = "enable" +#debug.log-condition-handling = "enable" ### only root can use these options # --- ../lighttpd-1.4.11/doc/performance.txt 2006-02-02 13:01:08.000000000 +0200 +++ lighttpd-1.4.12/doc/performance.txt 2006-07-16 00:26:05.000000000 +0300 @@ -183,6 +183,8 @@ server.stat-cache-engine = "fam" # either fam, simple or disabled +See http://oss.sgi.com/projects/fam/faq.html for information about FAM. +See http://www.gnome.org/~veillard/gamin/overview.html for information about gamin. Platform-Specific Notes ======================= --- ../lighttpd-1.4.11/doc/secdownload.txt 2005-12-20 15:58:58.000000000 +0200 +++ lighttpd-1.4.12/doc/secdownload.txt 2006-07-16 00:26:05.000000000 +0300 @@ -118,7 +118,7 @@ $secret = "verysecret"; $uri_prefix = "/dl/"; - # filename + # filename, make sure it's started with a "/" or you'll get 404 in the browser $f = "/secret-file.txt"; # current timestamp --- ../lighttpd-1.4.11/lighttpd.spec 2006-03-07 14:22:18.000000000 +0200 +++ lighttpd-1.4.12/lighttpd.spec 2006-07-17 22:02:18.000000000 +0300 @@ -1,6 +1,6 @@ Summary: A fast webserver with minimal memory-footprint (lighttpd) Name: lighttpd -Version: 1.4.11 +Version: 1.4.12 Release: 1 Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-%version.tar.gz Packager: Jan Kneschke --- ../lighttpd-1.4.11/openwrt/control 2006-03-07 14:22:19.000000000 +0200 +++ lighttpd-1.4.12/openwrt/control 2006-07-17 22:02:18.000000000 +0300 @@ -1,8 +1,8 @@ Package: lighttpd -Version: 1.4.11 +Version: 1.4.12 Architecture: mipsel Maintainer: Jan Kneschke -Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.11.tar.gz +Source: http://jan.kneschke.de/projects/lighttpd/download/lighttpd-1.4.12.tar.gz Section: net Priority: optional Depends: --- ../lighttpd-1.4.11/openwrt/lighttpd.mk 2006-03-07 14:22:19.000000000 +0200 +++ lighttpd-1.4.12/openwrt/lighttpd.mk 2006-07-17 22:02:18.000000000 +0300 @@ -10,7 +10,7 @@ # For this example we'll use a fairly simple package that compiles easily # and has sources available for download at sourceforge -LIGHTTPD=lighttpd-1.4.11 +LIGHTTPD=lighttpd-1.4.12 LIGHTTPD_TARGET=.built LIGHTTPD_DIR=$(BUILD_DIR)/$(LIGHTTPD) LIGHTTPD_IPK=$(BUILD_DIR)/$(LIGHTTPD)_mipsel.ipk --- ../lighttpd-1.4.11/src/Makefile.am 2006-03-07 14:20:20.000000000 +0200 +++ lighttpd-1.4.12/src/Makefile.am 2006-07-18 13:03:40.000000000 +0300 @@ -16,18 +16,24 @@ else configparser.y: lemon mod_ssi_exprparser.y: lemon +http_resp_parser.y: lemon configparser.c configparser.h: configparser.y rm -f configparser.h - $(LEMON) -q $(srcdir)/configparser.y $(srcdir)/lempar.c + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c + +http_resp_parser.c http_resp_parser.h: http_resp_parser.y + rm -f http_resp_parser.h + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c mod_ssi_exprparser.c mod_ssi_exprparser.h: mod_ssi_exprparser.y rm -f mod_ssi_exprparser.h - $(LEMON) -q $(srcdir)/mod_ssi_exprparser.y $(srcdir)/lempar.c + $(LEMON) -q $(srcdir)/$< $(srcdir)/lempar.c endif configfile.c: configparser.h mod_ssi_expr.c: mod_ssi_exprparser.h +http_resp.c: http_resp_parser.h common_src=buffer.c log.c \ keyvalue.c chunk.c \ @@ -40,13 +46,13 @@ fdevent_solaris_devpoll.c fdevent_freebsd_kqueue.c \ data_config.c bitset.c \ inet_ntop_cache.c crc32.c \ - connections-glue.c \ + connections-glue.c iosocket.c \ configfile-glue.c \ http-header-glue.c \ network_write.c network_linux_sendfile.c \ network_freebsd_sendfile.c network_writev.c \ network_solaris_sendfilev.c network_openssl.c \ - splaytree.c + splaytree.c http_resp.c http_resp_parser.c src = server.c response.c connections.c network.c \ configfile.c configparser.c request.c proc_open.c @@ -82,9 +88,9 @@ lib_LTLIBRARIES += mod_webdav.la mod_webdav_la_SOURCES = mod_webdav.c -mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS) +mod_webdav_la_CFLAGS = $(AM_CFLAGS) $(XML_CFLAGS) $(SQLITE_CFLAGS) mod_webdav_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined -mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) +mod_webdav_la_LIBADD = $(common_libadd) $(XML_LIBS) $(SQLITE_LIBS) $(UUID_LIB) lib_LTLIBRARIES += mod_cml.la mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c @@ -103,6 +109,11 @@ mod_mysql_vhost_la_LIBADD = $(MYSQL_LIBS) $(common_libadd) mod_mysql_vhost_la_CPPFLAGS = $(MYSQL_INCLUDE) +lib_LTLIBRARIES += mod_sql_vhost_core.la +mod_sql_vhost_core_la_SOURCES = mod_sql_vhost_core.c +mod_sql_vhost_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined +mod_sql_vhost_core_la_LIBADD = $(common_libadd) + lib_LTLIBRARIES += mod_cgi.la mod_cgi_la_SOURCES = mod_cgi.c mod_cgi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined @@ -158,6 +169,13 @@ mod_proxy_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined mod_proxy_la_LIBADD = $(common_libadd) +lib_LTLIBRARIES += mod_proxy_core.la +mod_proxy_core_la_SOURCES = mod_proxy_core.c mod_proxy_core_pool.c \ + mod_proxy_core_backend.c mod_proxy_core_address.c mod_proxy_core_backlog.c +mod_proxy_core_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined +mod_proxy_core_la_LIBADD = $(common_libadd) + + lib_LTLIBRARIES += mod_ssi.la mod_ssi_la_SOURCES = mod_ssi_exprparser.c mod_ssi_expr.c mod_ssi.c mod_ssi_la_LDFLAGS = -module -export-dynamic -avoid-version -no-undefined @@ -240,7 +258,12 @@ mod_ssi.h mod_ssi_expr.h inet_ntop_cache.h \ configparser.h mod_ssi_exprparser.h \ sys-mmap.h sys-socket.h mod_cml.h mod_cml_funcs.h \ - splaytree.h proc_open.h + splaytree.h proc_open.h http_resp.h mod_sql_vhost_core.h \ + sys-files.h sys-process.h sys-strings.h http_resp_parser.h \ + iosocket.h array-static.h \ + mod_proxy_core_address.h mod_proxy_core_backend.h \ + mod_proxy_core_backlog.h mod_proxy_core.h \ + mod_proxy_core_pool.h DEFS= @DEFS@ -DLIBRARY_DIR="\"$(libdir)\"" @@ -267,4 +290,4 @@ #ajp_SOURCES = ajp.c noinst_HEADERS = $(hdr) -EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c +EXTRA_DIST = mod_skeleton.c configparser.y mod_ssi_exprparser.y lempar.c http_resp_parser.y --- ../lighttpd-1.4.11/src/array-static.h 1970-01-01 03:00:00.000000000 +0300 +++ lighttpd-1.4.12/src/array-static.h 2006-07-18 13:03:40.000000000 +0300 @@ -0,0 +1,33 @@ +#ifndef _ARRAY_STATIC_H_ +#define _ARRAY_STATIC_H_ + +/* define a generic array of + * */ + +#define ARRAY_STATIC_DEF(name, type, extra) \ +typedef struct { \ + type **ptr; \ + size_t used; \ + size_t size; \ + extra\ +} name + +/* all append operations need a 'resize' for the +1 */ + +#define ARRAY_STATIC_PREPARE_APPEND(a) \ + if (a->size == 0) { \ + a->size = 16; \ + a->ptr = malloc(a->size * sizeof(*(a->ptr))); \ + } else if (a->size == a->used) { \ + a->size += 16; \ + a->ptr = realloc(a->ptr, a->size * sizeof(*(a->ptr))); \ + } + +#define FOREACH(array, element, func) \ +do { size_t _i; for (_i = 0; _i < array->used; _i++) { void *element = array->ptr[_i]; func; } } while(0); + +#define STRUCT_INIT(type, var) \ + type *var;\ + var = calloc(1, sizeof(*var)) + +#endif --- ../lighttpd-1.4.11/src/array.c 2005-11-18 13:58:32.000000000 +0200 +++ lighttpd-1.4.12/src/array.c 2006-07-16 00:26:03.000000000 +0300 @@ -11,12 +11,12 @@ array *array_init(void) { array *a; - + a = calloc(1, sizeof(*a)); assert(a); - + a->next_power_of_2 = 1; - + return a; } @@ -43,29 +43,29 @@ void array_free(array *a) { size_t i; if (!a) return; - + if (!a->is_weakref) { for (i = 0; i < a->size; i++) { if (a->data[i]) a->data[i]->free(a->data[i]); } } - + if (a->data) free(a->data); if (a->sorted) free(a->sorted); - + free(a); } void array_reset(array *a) { size_t i; if (!a) return; - + if (!a->is_weakref) { for (i = 0; i < a->used; i++) { a->data[i]->reset(a->data[i]); } } - + a->used = 0; } @@ -84,20 +84,20 @@ static int array_get_index(array *a, const char *key, size_t keylen, int *rndx) { int ndx = -1; int i, pos = 0; - + if (key == NULL) return -1; - + /* try to find the string */ for (i = pos = a->next_power_of_2 / 2; ; i >>= 1) { int cmp; - + if (pos < 0) { pos += i; } else if (pos >= (int)a->used) { pos -= i; } else { cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used); - + if (cmp == 0) { /* found */ ndx = a->sorted[pos]; @@ -110,46 +110,46 @@ } if (i == 0) break; } - + if (rndx) *rndx = pos; - + return ndx; } data_unset *array_get_element(array *a, const char *key) { int ndx; - + if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) { /* found, leave here */ - + return a->data[ndx]; - } - + } + return NULL; } data_unset *array_get_unused_element(array *a, data_type_t t) { data_unset *ds = NULL; - + UNUSED(t); if (a->size == 0) return NULL; - + if (a->used == a->size) return NULL; if (a->data[a->used]) { ds = a->data[a->used]; - + a->data[a->used] = NULL; } - + return ds; } /* replace or insert data, return the old one with the same key */ data_unset *array_replace(array *a, data_unset *du) { int ndx; - + if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) { array_insert_unique(a, du); return NULL; @@ -164,13 +164,13 @@ int ndx = -1; int pos = 0; size_t j; - - /* generate unique index if neccesary */ + + /* generate unique index if necessary */ if (str->key->used == 0 || str->is_index_key) { buffer_copy_long(str->key, a->unique_ndx++); str->is_index_key = 1; } - + /* try to find the string */ if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) { /* found, leave here */ @@ -181,14 +181,14 @@ } return 0; } - + /* insert */ - + if (a->used+1 > INT_MAX) { /* we can't handle more then INT_MAX entries: see array_get_index() */ return -1; } - + if (a->size == 0) { a->size = 16; a->data = malloc(sizeof(*a->data) * a->size); @@ -204,27 +204,27 @@ assert(a->sorted); for (j = a->used; j < a->size; j++) a->data[j] = NULL; } - + ndx = (int) a->used; - + a->data[a->used++] = str; - + if (pos != ndx && - ((pos < 0) || + ((pos < 0) || buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) { pos++; - } - - /* move everything on step to the right */ + } + + /* move everything one step to the right */ if (pos != ndx) { memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted)); } - + /* insert */ a->sorted[pos] = ndx; - + if (a->next_power_of_2 == (size_t)ndx) a->next_power_of_2 <<= 1; - + return 0; } @@ -254,7 +254,7 @@ size_t i; size_t maxlen; int oneline = 1; - + if (a->used > 5) { oneline = 0; } @@ -314,7 +314,7 @@ } array_print_indent(depth); fprintf(stderr, ")"); - + return 0; } @@ -323,47 +323,47 @@ array *a; data_string *ds; data_count *dc; - + UNUSED(argc); UNUSED(argv); a = array_init(); - + ds = data_string_init(); buffer_copy_string(ds->key, "abc"); buffer_copy_string(ds->value, "alfrag"); - + array_insert_unique(a, (data_unset *)ds); - + ds = data_string_init(); buffer_copy_string(ds->key, "abc"); buffer_copy_string(ds->value, "hameplman"); - + array_insert_unique(a, (data_unset *)ds); - + ds = data_string_init(); buffer_copy_string(ds->key, "123"); buffer_copy_string(ds->value, "alfrag"); - + array_insert_unique(a, (data_unset *)ds); - + dc = data_count_init(); buffer_copy_string(dc->key, "def"); - + array_insert_unique(a, (data_unset *)dc); - + dc = data_count_init(); buffer_copy_string(dc->key, "def"); - + array_insert_unique(a, (data_unset *)dc); - + array_print(a, 0); - + array_free(a); - + fprintf(stderr, "%d\n", buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type"))); - + return 0; } #endif --- ../lighttpd-1.4.11/src/array.h 2005-09-23 21:24:18.000000000 +0300 +++ lighttpd-1.4.12/src/array.h 2006-07-16 00:26:03.000000000 +0300 @@ -16,7 +16,7 @@ #define DATA_UNSET \ data_type_t type; \ buffer *key; \ - int is_index_key; /* 1 if key is a array index (autogenerated keys) */ \ + int is_index_key; /* 1 if key is an array index (auto-generated keys) */ \ struct data_unset *(*copy)(const struct data_unset *src); \ void (* free)(struct data_unset *p); \ void (* reset)(struct data_unset *p); \ @@ -29,21 +29,21 @@ typedef struct { data_unset **data; - + size_t *sorted; - + size_t used; size_t size; - + size_t unique_ndx; - + size_t next_power_of_2; int is_weakref; /* data is weakref, don't bother the data */ } array; typedef struct { DATA_UNSET; - + int count; } data_count; @@ -51,7 +51,7 @@ typedef struct { DATA_UNSET; - + buffer *value; } data_string; @@ -60,7 +60,7 @@ typedef struct { DATA_UNSET; - + array *value; } data_array; @@ -74,7 +74,7 @@ COMP_SERVER_SOCKET, COMP_HTTP_URL, COMP_HTTP_HOST, COMP_HTTP_REFERER, COMP_HTTP_USERAGENT, COMP_HTTP_COOKIE, COMP_HTTP_REMOTEIP } comp_key_t; -/* $HTTP["host"] == "incremental.home.kneschke.de" { ... } +/* $HTTP["host"] == "incremental.home.kneschke.de" { ... } * for print: comp_key op string * for compare: comp cond string/regex */ @@ -82,15 +82,15 @@ typedef struct _data_config data_config; struct _data_config { DATA_UNSET; - + array *value; - + buffer *comp_key; comp_key_t comp; - + config_cond_t cond; buffer *op; - + int context_ndx; /* more or less like an id */ array *childs; /* nested */ @@ -98,7 +98,7 @@ /* for chaining only */ data_config *prev; data_config *next; - + buffer *string; #ifdef HAVE_PCRE_H pcre *regex; @@ -110,7 +110,7 @@ typedef struct { DATA_UNSET; - + int value; } data_integer; @@ -120,13 +120,13 @@ DATA_UNSET; buffer *host; - + unsigned short port; time_t disable_ts; int is_disabled; size_t balance; - + int usage; /* fair-balancing needs the no. of connections active on this host */ int last_used_ndx; /* round robin */ } data_fastcgi; --- ../lighttpd-1.4.11/src/base.h 2006-01-11 16:51:04.000000000 +0200 +++ lighttpd-1.4.12/src/base.h 2006-07-18 13:03:40.000000000 +0300 @@ -2,7 +2,6 @@ #define _BASE_H_ #include -#include #include #ifdef HAVE_CONFIG_H @@ -26,10 +25,9 @@ #include "sys-socket.h" #include "splaytree.h" - #if defined HAVE_LIBSSL && defined HAVE_OPENSSL_SSL_H # define USE_OPENSSL -# include +# include #endif #ifdef HAVE_FAM_H @@ -40,10 +38,6 @@ # define O_BINARY 0 #endif -#ifndef O_LARGEFILE -# define O_LARGEFILE 0 -#endif - #ifndef SIZE_MAX # ifdef SIZE_T_MAX # define SIZE_MAX SIZE_T_MAX @@ -70,7 +64,8 @@ /* solaris and NetBSD 1.3.x again */ #if (!defined(HAVE_STDINT_H)) && (!defined(HAVE_INTTYPES_H)) && (!defined(uint32_t)) -# define uint32_t u_int32_t +/* # define uint32_t u_int32_t */ +typedef unsigned __int32 uint32_t; #endif @@ -80,24 +75,24 @@ #include "settings.h" -typedef enum { T_CONFIG_UNSET, - T_CONFIG_STRING, - T_CONFIG_SHORT, - T_CONFIG_BOOLEAN, - T_CONFIG_ARRAY, - T_CONFIG_LOCAL, +typedef enum { T_CONFIG_UNSET, + T_CONFIG_STRING, + T_CONFIG_SHORT, + T_CONFIG_BOOLEAN, + T_CONFIG_ARRAY, + T_CONFIG_LOCAL, T_CONFIG_DEPRECATED } config_values_type_t; -typedef enum { T_CONFIG_SCOPE_UNSET, - T_CONFIG_SCOPE_SERVER, +typedef enum { T_CONFIG_SCOPE_UNSET, + T_CONFIG_SCOPE_SERVER, T_CONFIG_SCOPE_CONNECTION } config_scope_type_t; typedef struct { const char *key; void *destination; - + config_values_type_t type; config_scope_type_t scope; } config_values_t; @@ -118,18 +113,6 @@ short factor; } fcgi_connections; - -typedef union { -#ifdef HAVE_IPV6 - struct sockaddr_in6 ipv6; -#endif - struct sockaddr_in ipv4; -#ifdef HAVE_SYS_UN_H - struct sockaddr_un un; -#endif - struct sockaddr plain; -} sock_addr; - /* fcgi_response_header contains ... */ #define HTTP_STATUS BV(0) #define HTTP_CONNECTION BV(1) @@ -142,40 +125,40 @@ /* the request-line */ buffer *request; buffer *uri; - + buffer *orig_uri; - + http_method_t http_method; http_version_t http_version; - + buffer *request_line; - + /* strings to the header */ buffer *http_host; /* not alloced */ const char *http_range; const char *http_content_type; const char *http_if_modified_since; const char *http_if_none_match; - + array *headers; - + /* CONTENT */ size_t content_length; /* returned by strtoul() */ - + /* internal representation */ int accept_encoding; - + /* internal */ buffer *pathinfo; } request; typedef struct { off_t content_length; - int keep_alive; /* used by the subrequests in proxy, cgi and fcgi to say the subrequest was keep-alive or not */ - + int keep_alive; /* used by the subrequests in proxy, cgi and fcgi to say whether the subrequest was keep-alive or not */ + array *headers; - - enum { + + enum { HTTP_TRANSFER_ENCODING_IDENTITY, HTTP_TRANSFER_ENCODING_CHUNKED } transfer_encoding; } response; @@ -191,21 +174,21 @@ typedef struct { buffer *path; buffer *basedir; /* path = "(basedir)(.*)" */ - + buffer *doc_root; /* path = doc_root + rel_path */ buffer *rel_path; - + buffer *etag; } physical; typedef struct { buffer *name; buffer *etag; - + struct stat st; - + time_t stat_ts; - + #ifdef HAVE_FAM_H int dir_version; int dir_ndx; @@ -215,20 +198,20 @@ } stat_cache_entry; typedef struct { - splay_tree *files; /* the nodes of the tree are stat_cache_entry's */ - + splay_tree *files; /* the nodes of the tree are stat_cache_entries */ + buffer *dir_name; /* for building the dirname from the filename */ #ifdef HAVE_FAM_H splay_tree *dirs; /* the nodes of the tree are fam_dir_entry */ FAMConnection *fam; - int fam_fcce_ndx; + iosocket *sock; #endif } stat_cache; typedef struct { array *mimetypes; - + /* virtual-servers */ buffer *document_root; buffer *server_name; @@ -236,7 +219,7 @@ buffer *server_tag; buffer *dirlist_encoding; buffer *errorfile_prefix; - + unsigned short max_keep_alive_requests; unsigned short max_keep_alive_idle; unsigned short max_read_idle; @@ -244,16 +227,17 @@ unsigned short use_xattr; unsigned short follow_symlink; unsigned short range_requests; - + /* debug */ - + unsigned short log_file_not_found; unsigned short log_request_header; unsigned short log_request_handling; unsigned short log_response_header; unsigned short log_condition_handling; - - + unsigned short log_condition_cache_handling; + + /* server wide */ buffer *ssl_pemfile; buffer *ssl_ca_file; @@ -268,22 +252,22 @@ /* configside */ unsigned short global_kbytes_per_second; /* */ - off_t global_bytes_per_second_cnt; + off_t global_bytes_per_second_cnt; /* server-wide traffic-shaper - * + * * each context has the counter which is inited once - * a second by the global_kbytes_per_second config-var + * per second by the global_kbytes_per_second config-var * * as soon as global_kbytes_per_second gets below 0 * the connected conns are "offline" a little bit * * the problem: - * we somehow have to loose our "we are writable" signal + * we somehow have to lose our "we are writable" signal * on the way. - * + * */ off_t *global_bytes_per_second_cnt_ptr; /* */ - + #ifdef USE_OPENSSL SSL_CTX *ssl_ctx; #endif @@ -291,18 +275,18 @@ /* the order of the items should be the same as they are processed * read before write as we use this later */ -typedef enum { - CON_STATE_CONNECT, - CON_STATE_REQUEST_START, - CON_STATE_READ, - CON_STATE_REQUEST_END, - CON_STATE_READ_POST, - CON_STATE_HANDLE_REQUEST, - CON_STATE_RESPONSE_START, - CON_STATE_WRITE, - CON_STATE_RESPONSE_END, - CON_STATE_ERROR, - CON_STATE_CLOSE +typedef enum { + CON_STATE_CONNECT, + CON_STATE_REQUEST_START, + CON_STATE_READ, + CON_STATE_REQUEST_END, + CON_STATE_READ_POST, + CON_STATE_HANDLE_REQUEST, + CON_STATE_RESPONSE_START, + CON_STATE_WRITE, + CON_STATE_RESPONSE_END, + CON_STATE_ERROR, + CON_STATE_CLOSE } connection_state_t; typedef enum { COND_RESULT_UNSET, COND_RESULT_FALSE, COND_RESULT_TRUE } cond_result_t; @@ -315,91 +299,86 @@ typedef struct { connection_state_t state; - + /* timestamps */ time_t read_idle_ts; time_t close_timeout_ts; time_t write_request_ts; - + time_t connection_start; time_t request_start; - + struct timeval start_tv; - + size_t request_count; /* number of requests handled in this connection */ size_t loops_per_request; /* to catch endless loops in a single request - * + * * used by mod_rewrite, mod_fastcgi, ... and others * this is self-protection */ - - int fd; /* the FD for this connection */ - int fde_ndx; /* index for the fdevent-handler */ + + iosocket *sock; int ndx; /* reverse mapping to server->connection[ndx] */ - + /* fd states */ int is_readable; int is_writable; - - int keep_alive; /* only request.c can enable it, all other just disable */ - + + int keep_alive; /* only request.c can enable it, all others just disable */ + int file_started; int file_finished; - + chunkqueue *write_queue; /* a large queue for low-level write ( HTTP response ) [ file, mem ] */ chunkqueue *read_queue; /* a small queue for low-level read ( HTTP request ) [ mem ] */ chunkqueue *request_content_queue; /* takes request-content into tempfile if necessary [ tempfile, mem ]*/ - + int traffic_limit_reached; - + off_t bytes_written; /* used by mod_accesslog, mod_rrd */ off_t bytes_written_cur_second; /* used by mod_accesslog, mod_rrd */ off_t bytes_read; /* used by mod_accesslog, mod_rrd */ off_t bytes_header; - + int http_status; - + sock_addr dst_addr; buffer *dst_addr_buf; /* request */ buffer *parse_request; unsigned int parsed_response; /* bitfield which contains the important header-fields of the parsed response header */ - + request request; request_uri uri; - physical physical; + physical physical; response response; - + size_t header_len; - + buffer *authed_user; array *environment; /* used to pass lighttpd internal stuff to the FastCGI/CGI apps, setenv does that */ - + /* response */ int got_response; - + int in_joblist; - + connection_type mode; - + void **plugin_ctx; /* plugin connection specific config */ - + specific_config conf; /* global connection specific config */ cond_cache_t *cond_cache; - + buffer *server_name; - + /* error-handler */ buffer *error_handler; int error_handler_saved_status; int in_error_handler; - + void *srv_socket; /* reference to the server-socket (typecast to server_socket) */ - -#ifdef USE_OPENSSL - SSL *ssl; -#endif } connection; typedef struct { @@ -439,55 +418,63 @@ size_t size; } buffer_plugin; +typedef enum { + NETWORK_STATUS_UNSET, + NETWORK_STATUS_SUCCESS, + NETWORK_STATUS_FATAL_ERROR, + NETWORK_STATUS_CONNECTION_CLOSE, + NETWORK_STATUS_WAIT_FOR_EVENT, + NETWORK_STATUS_INTERRUPTED +} network_status_t; + typedef struct { unsigned short port; buffer *bindhost; - - buffer *errorlog_file; - unsigned short errorlog_use_syslog; - + unsigned short dont_daemonize; buffer *changeroot; buffer *username; buffer *groupname; - + buffer *pid_file; - + buffer *event_handler; - + buffer *modules_dir; buffer *network_backend; array *modules; array *upload_tempdirs; - + unsigned short max_worker; unsigned short max_fds; unsigned short max_conns; unsigned short max_request_size; - + unsigned short log_request_header_on_error; unsigned short log_state_handling; - - enum { STAT_CACHE_ENGINE_UNSET, - STAT_CACHE_ENGINE_NONE, - STAT_CACHE_ENGINE_SIMPLE, - STAT_CACHE_ENGINE_FAM + + enum { STAT_CACHE_ENGINE_UNSET, + STAT_CACHE_ENGINE_NONE, + STAT_CACHE_ENGINE_SIMPLE, + STAT_CACHE_ENGINE_FAM } stat_cache_engine; unsigned short enable_cores; + + buffer *errorlog_file; + unsigned short errorlog_use_syslog; } server_config; typedef struct { sock_addr addr; - int fd; - int fde_ndx; - + iosocket *sock; + buffer *ssl_pemfile; buffer *ssl_ca_file; unsigned short use_ipv6; unsigned short is_ssl; - + buffer *srv_token; - + #ifdef USE_OPENSSL SSL_CTX *ssl_ctx; #endif @@ -495,37 +482,32 @@ typedef struct { server_socket **ptr; - + size_t size; size_t used; } server_socket_array; typedef struct server { server_socket_array srv_sockets; - - /* the errorlog */ - int errorlog_fd; - enum { ERRORLOG_STDERR, ERRORLOG_FILE, ERRORLOG_SYSLOG } errorlog_mode; - buffer *errorlog_buf; - + fdevents *ev, *ev_ins; - + buffer_plugin plugins; void *plugin_slots; - + /* counters */ int con_opened; int con_read; int con_written; int con_closed; - + int ssl_is_init; - + int max_fds; /* max possible fds */ int cur_fds; /* currently used fds */ int want_fds; /* waiting fds */ int sockets_disabled; - + size_t max_conns; /* buffers */ @@ -533,13 +515,13 @@ buffer *response_header; buffer *response_range; buffer *tmp_buf; - + buffer *tmp_chunk_len; - + buffer *empty_string; /* is necessary for cond_match */ buffer *cond_check_buf; - + /* caches */ #ifdef HAVE_IPV6 inet_ntop_cache_type inet_ntop_cache[INET_NTOP_CACHE_MAX]; @@ -547,31 +529,31 @@ mtime_cache_type mtime_cache[FILE_CACHE_MAX]; array *split_vals; - + /* Timestamps */ time_t cur_ts; time_t last_generated_date_ts; time_t last_generated_debug_ts; time_t startup_ts; - + buffer *ts_debug_str; buffer *ts_date_str; - + /* config-file */ array *config; array *config_touched; - + array *config_context; specific_config **config_storage; - + server_config srvconf; - + int config_deprecated; - + connections *conns; connections *joblist; connections *fdwaitqueue; - + stat_cache *stat_cache; /** @@ -588,18 +570,20 @@ * fastcgi.backend..disconnects = ... */ array *status; - + fdevent_handler_t event_handler; - int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq); - int (* network_backend_read)(struct server *srv, connection *con, int fd, chunkqueue *cq); + network_status_t (* network_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq); + network_status_t (* network_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq); #ifdef USE_OPENSSL - int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); - int (* network_ssl_backend_read)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq); + network_status_t (* network_ssl_backend_write)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq); + network_status_t (* network_ssl_backend_read)(struct server *srv, connection *con, iosocket *sock, chunkqueue *cq); #endif +#ifdef HAVE_PWD_H uid_t uid; gid_t gid; +#endif } server; --- ../lighttpd-1.4.11/src/bitset.c 2005-08-22 01:54:12.000000000 +0300 +++ lighttpd-1.4.12/src/bitset.c 2006-07-18 13:03:40.000000000 +0300 @@ -6,6 +6,7 @@ #include "bitset.h" #include "buffer.h" +#include "log.h" #define BITSET_BITS \ ( CHAR_BIT * sizeof(size_t) ) --- ../lighttpd-1.4.11/src/buffer.c 2006-01-13 00:00:45.000000000 +0200 +++ lighttpd-1.4.12/src/buffer.c 2006-07-18 13:03:40.000000000 +0300 @@ -12,20 +12,20 @@ /** - * init the buffer - * + * init the buffer + * */ buffer* buffer_init(void) { buffer *b; - + b = malloc(sizeof(*b)); assert(b); - + b->ptr = NULL; b->size = 0; b->used = 0; - + return b; } @@ -36,8 +36,8 @@ } /** - * free the buffer - * + * free the buffer + * */ void buffer_free(buffer *b) { @@ -49,39 +49,39 @@ void buffer_reset(buffer *b) { if (!b) return; - + /* limit don't reuse buffer larger than ... bytes */ if (b->size > BUFFER_MAX_REUSE_SIZE) { free(b->ptr); b->ptr = NULL; b->size = 0; } - + b->used = 0; } /** - * - * allocate (if neccessary) enough space for 'size' bytes and + * + * allocate (if necessary) enough space for 'size' bytes and * set the 'used' counter to 0 - * + * */ #define BUFFER_PIECE_SIZE 64 int buffer_prepare_copy(buffer *b, size_t size) { if (!b) return -1; - - if ((0 == b->size) || + + if ((0 == b->size) || (size > b->size)) { if (b->size) free(b->ptr); - + b->size = size; - - /* always allocate a multiply of BUFFER_PIECE_SIZE */ + + /* always allocate a multiple of BUFFER_PIECE_SIZE */ b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE); - + b->ptr = malloc(b->size); assert(b->ptr); } @@ -90,30 +90,30 @@ } /** - * - * increase the internal buffer (if neccessary) to append another 'size' byte + * + * increase the internal buffer (if necessary) to append another 'size' byte * ->used isn't changed - * + * */ int buffer_prepare_append(buffer *b, size_t size) { if (!b) return -1; - + if (0 == b->size) { b->size = size; - - /* always allocate a multiply of BUFFER_PIECE_SIZE */ + + /* always allocate a multiple of BUFFER_PIECE_SIZE */ b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE); - + b->ptr = malloc(b->size); b->used = 0; assert(b->ptr); } else if (b->used + size > b->size) { b->size += size; - - /* always allocate a multiply of BUFFER_PIECE_SIZE */ + + /* always allocate a multiple of BUFFER_PIECE_SIZE */ b->size += BUFFER_PIECE_SIZE - (b->size % BUFFER_PIECE_SIZE); - + b->ptr = realloc(b->ptr, b->size); assert(b->ptr); } @@ -122,7 +122,7 @@ int buffer_copy_string(buffer *b, const char *s) { size_t s_len; - + if (!s || !b) return -1; s_len = strlen(s) + 1; @@ -136,26 +136,26 @@ int buffer_copy_string_len(buffer *b, const char *s, size_t s_len) { if (!s || !b) return -1; -#if 0 - /* removed optimization as we have to keep the empty string +#if 0 + /* removed optimization as we have to keep the empty string * in some cases for the config handling - * + * * url.access-deny = ( "" ) */ if (s_len == 0) return 0; -#endif +#endif buffer_prepare_copy(b, s_len + 1); - + memcpy(b->ptr, s, s_len); b->ptr[s_len] = '\0'; b->used = s_len + 1; - + return 0; } int buffer_copy_string_buffer(buffer *b, const buffer *src) { if (!src) return -1; - + if (src->used == 0) { b->used = 0; return 0; @@ -201,10 +201,10 @@ /** * append a string to the end of the buffer - * - * the resulting buffer is terminated with a '\0' - * s is treated as a un-terminated string (a \0 is handled a normal character) - * + * + * the resulting buffer is terminated with a '\0' + * s is treated as an un-terminated string (a \0 is handled as a normal character) + * * @param b a buffer * @param s the string * @param s_len size of the string (without the terminating \0) @@ -228,7 +228,7 @@ int buffer_append_string_buffer(buffer *b, const buffer *src) { if (!src) return -1; if (src->used == 0) return 0; - + return buffer_append_string_len(b, src->ptr, src->used - 1); } @@ -245,9 +245,9 @@ int buffer_copy_memory(buffer *b, const char *s, size_t s_len) { if (!s || !b) return -1; - + b->used = 0; - + return buffer_append_memory(b, s, s_len); } @@ -402,46 +402,115 @@ /** - * init the buffer - * + * init the ptr buffer + * + */ +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer) +{ + buffer_ptr *l = calloc(1, sizeof(buffer_ptr)); + l->free = freer; + + return l; +} + +/** + * free the buffer_array + * + */ +void buffer_ptr_free(buffer_ptr *l) +{ + if (NULL != l) { + buffer_ptr_clear(l); + free(l); + } +} + +void buffer_ptr_clear(buffer_ptr *l) +{ + assert(NULL != l); + + if (l->free && l->used) { + size_t i; + for (i = 0; i < l->used; i ++) { + l->free(l->ptr[i]); + } + } + + if (l->ptr) { + free(l->ptr); + l->ptr = NULL; + } + l->used = 0; + l->size = 0; +} + +void buffer_ptr_append(buffer_ptr* l, void *item) +{ + assert(NULL != l); + if (l->ptr == NULL) { + l->size = 16; + l->ptr = (void **)malloc(sizeof(void *) * l->size); + } + else if (l->used == l->size) { + l->size += 16; + l->ptr = realloc(l->ptr, sizeof(void *) * l->size); + } + l->ptr[l->used++] = item; +} + +void *buffer_ptr_pop(buffer_ptr* l) +{ + assert(NULL != l && l->used > 0); + return l->ptr[--l->used]; +} + +void *buffer_ptr_top(buffer_ptr* l) +{ + assert(NULL != l && l->used > 0); + return l->ptr[l->used-1]; +} + +/** + * init the buffer + * */ buffer_array* buffer_array_init(void) { buffer_array *b; - + b = malloc(sizeof(*b)); - + assert(b); b->ptr = NULL; b->size = 0; b->used = 0; - + return b; } void buffer_array_reset(buffer_array *b) { size_t i; - + if (!b) return; - + /* if they are too large, reduce them */ for (i = 0; i < b->used; i++) { buffer_reset(b->ptr[i]); } - + b->used = 0; } /** - * free the buffer_array - * + * free the buffer_array + * */ void buffer_array_free(buffer_array *b) { size_t i; if (!b) return; - + for (i = 0; i < b->size; i++) { if (b->ptr[i]) buffer_free(b->ptr[i]); } @@ -451,7 +520,7 @@ buffer *buffer_array_append_get_buffer(buffer_array *b) { size_t i; - + if (b->size == 0) { b->size = 16; b->ptr = malloc(sizeof(*b->ptr) * b->size); @@ -467,13 +536,13 @@ b->ptr[i] = NULL; } } - + if (b->ptr[b->used] == NULL) { b->ptr[b->used] = buffer_init(); } - + b->ptr[b->used]->used = 0; - + return b->ptr[b->used++]; } @@ -482,23 +551,23 @@ size_t i; if (len == 0) return NULL; if (needle == NULL) return NULL; - + if (b->used < len) return NULL; - + for(i = 0; i < b->used - len; i++) { if (0 == memcmp(b->ptr + i, needle, len)) { return b->ptr + i; } } - + return NULL; } buffer *buffer_init_string(const char *str) { buffer *b = buffer_init(); - + buffer_copy_string(b, str); - + return b; } @@ -507,8 +576,8 @@ } /** - * check if two buffer contain the same data - * + * check if two buffers contain the same data + * * HISTORY: this function was pretty much optimized, but didn't handled * alignment properly. */ @@ -517,105 +586,105 @@ if (a->used != b->used) return 0; if (a->used == 0) return 1; - return (0 == strcmp(a->ptr, b->ptr)); + return (0 == strncmp(a->ptr, b->ptr, a->used - 1)); } int buffer_is_equal_string(buffer *a, const char *s, size_t b_len) { buffer b; - + b.ptr = (char *)s; b.used = b_len + 1; - + return buffer_is_equal(a, &b); } /* simple-assumption: - * - * most parts are equal and doing a case conversion needs time - * + * + * most parts are equal and doing a case conversion takes time + * */ int buffer_caseless_compare(const char *a, size_t a_len, const char *b, size_t b_len) { size_t ndx = 0, max_ndx; size_t *al, *bl; size_t mask = sizeof(*al) - 1; - + al = (size_t *)a; bl = (size_t *)b; - - /* is the alignment correct ? */ + + /* is the alignment correct? */ if ( ((size_t)al & mask) == 0 && ((size_t)bl & mask) == 0 ) { - + max_ndx = ((a_len < b_len) ? a_len : b_len) & ~mask; - + for (; ndx < max_ndx; ndx += sizeof(*al)) { if (*al != *bl) break; al++; bl++; - + } - + } - + a = (char *)al; b = (char *)bl; - + max_ndx = ((a_len < b_len) ? a_len : b_len); - + for (; ndx < max_ndx; ndx++) { char a1 = *a++, b1 = *b++; - + if (a1 != b1) { if ((a1 >= 'A' && a1 <= 'Z') && (b1 >= 'a' && b1 <= 'z')) a1 |= 32; else if ((a1 >= 'a' && a1 <= 'z') && (b1 >= 'A' && b1 <= 'Z')) b1 |= 32; if ((a1 - b1) != 0) return (a1 - b1); - + } } - + return 0; } /** * check if the rightmost bytes of the string are equal. - * - * + * + * */ int buffer_is_equal_right_len(buffer *b1, buffer *b2, size_t len) { /* no, len -> equal */ if (len == 0) return 1; - + /* len > 0, but empty buffers -> not equal */ if (b1->used == 0 || b2->used == 0) return 0; - + /* buffers too small -> not equal */ - if (b1->used - 1 < len || b1->used - 1 < len) return 0; - - if (0 == strncmp(b1->ptr + b1->used - 1 - len, + if (b1->used - 1 < len || b2->used - 1 < len) return 0; + + if (0 == strncmp(b1->ptr + b1->used - 1 - len, b2->ptr + b2->used - 1 - len, len)) { return 1; } - + return 0; } int buffer_copy_string_hex(buffer *b, const char *in, size_t in_len) { size_t i; - + /* BO protection */ if (in_len * 2 < in_len) return -1; - + buffer_prepare_copy(b, in_len * 2 + 1); - + for (i = 0; i < in_len; i++) { b->ptr[b->used++] = hex_chars[(in[i] >> 4) & 0x0F]; b->ptr[b->used++] = hex_chars[in[i] & 0x0F]; } b->ptr[b->used++] = '\0'; - + return 0; } @@ -624,7 +693,7 @@ 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, /* 20 - 2F space " # $ % & ' + , / */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ @@ -646,7 +715,7 @@ 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, /* 20 - 2F space " # $ % & ' + , / */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 30 - 3F : ; = ? @ < > */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ @@ -668,7 +737,7 @@ 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ @@ -690,7 +759,7 @@ 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 2F & */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 30 - 3F < > */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 - 4F */ @@ -712,12 +781,12 @@ 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00 - 0F control chars */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 - 1F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 - 3F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 70 - 7F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80 - 8F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 90 - 9F */ @@ -734,13 +803,12 @@ unsigned char *ds, *d; size_t d_len, ndx; const char *map = NULL; - + if (!s || !b) return -1; - - if (b->ptr[b->used - 1] != '\0') { - SEGFAULT(); - } - + if (b->used == 0) return -1; + + if (b->ptr[b->used - 1] != '\0') return -1; + if (s_len == 0) return 0; switch(encoding) { @@ -760,12 +828,12 @@ map = encoded_chars_hex; break; case ENCODING_UNSET: - break; + return buffer_append_string_len(b, s, s_len); } assert(map != NULL); - - /* count to-be-encoded-characters */ + + /* count to-be-encoded characters */ for (ds = (unsigned char *)s, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) { if (map[*ds]) { switch(encoding) { @@ -787,9 +855,9 @@ d_len ++; } } - + buffer_prepare_append(b, d_len); - + for (ds = (unsigned char *)s, d = (unsigned char *)b->ptr + b->used - 1, d_len = 0, ndx = 0; ndx < s_len; ds++, ndx++) { if (map[*ds]) { switch(encoding) { @@ -820,16 +888,16 @@ } } - /* terminate buffer and calculate new length */ + /* terminate buffer and calculate new length */ b->ptr[b->used + d_len - 1] = '\0'; - + b->used += d_len; return 0; } -/* decodes url-special-chars inplace. +/* decodes url-special chars in-place. * replaces non-printable characters with '_' */ @@ -854,10 +922,10 @@ low = hex2int(*(src + 2)); if (low != 0xFF) { high = (high << 4) | low; - - /* map control-characters out */ + + /* map out control characters */ if (high < 32 || high == 127) high = '_'; - + *dst = high; src += 2; } @@ -891,7 +959,7 @@ * /abc/./xyz gets /abc/xyz * /abc//xyz gets /abc/xyz * - * NOTE: src and dest can point to the same buffer, in which case, + * NOTE: src and dest can point to the same buffer, in which case * the operation is performed in-place. */ @@ -979,7 +1047,7 @@ int light_isxdigit(int c) { if (light_isdigit(c)) return 1; - + c |= 32; return (c >= 'a' && c <= 'f'); } @@ -993,31 +1061,56 @@ return light_isdigit(c) || light_isalpha(c); } +#undef BUFFER_CTYPE_FUNC +#define BUFFER_CTYPE_FUNC(type) \ + int buffer_is##type(buffer *b) { \ + size_t i, len; \ + if (b->used < 2) return 0; \ + /* strlen */ \ + len = b->used - 1; \ + /* c-string only */ \ + if (b->ptr[len] != '\0') { \ + return 0; \ + } \ + /* check on the whole string */ \ + for (i = 0; i < len; i ++) { \ + if (!light_is##type(b->ptr[i])) { \ + return 0; \ + } \ + } \ + return 1; \ + } + +BUFFER_CTYPE_FUNC(digit) +BUFFER_CTYPE_FUNC(xdigit) +BUFFER_CTYPE_FUNC(alpha) +BUFFER_CTYPE_FUNC(alnum) + int buffer_to_lower(buffer *b) { char *c; - + if (b->used == 0) return 0; - + for (c = b->ptr; *c; c++) { if (*c >= 'A' && *c <= 'Z') { *c |= 32; } } - + return 0; } int buffer_to_upper(buffer *b) { char *c; - + if (b->used == 0) return 0; - + for (c = b->ptr; *c; c++) { if (*c >= 'a' && *c <= 'z') { *c &= ~32; } } - + return 0; } --- ../lighttpd-1.4.11/src/buffer.h 2006-01-13 00:00:45.000000000 +0200 +++ lighttpd-1.4.12/src/buffer.h 2006-07-18 13:03:40.000000000 +0300 @@ -12,27 +12,43 @@ typedef struct { char *ptr; - + size_t used; size_t size; } buffer; +typedef void (*buffer_ptr_free_t)(void *p); + +typedef struct { + void **ptr; + size_t size; + size_t used; + buffer_ptr_free_t free; +} buffer_ptr; + typedef struct { buffer **ptr; - + size_t used; size_t size; } buffer_array; typedef struct { char *ptr; - - size_t offset; /* input-pointer */ - - size_t used; /* output-pointer */ + + size_t offset; /* input pointer */ + + size_t used; /* output pointer */ size_t size; } read_buffer; +buffer_ptr *buffer_ptr_init(buffer_ptr_free_t freer); +void buffer_ptr_free(buffer_ptr *b); +void buffer_ptr_clear(buffer_ptr *b); +void buffer_ptr_append(buffer_ptr *b, void *item); +void *buffer_ptr_pop(buffer_ptr *b); +void *buffer_ptr_top(buffer_ptr *b); + buffer_array* buffer_array_init(void); void buffer_array_free(buffer_array *b); void buffer_array_reset(buffer_array *b); @@ -43,7 +59,7 @@ buffer* buffer_init_string(const char *str); void buffer_free(buffer *b); void buffer_reset(buffer *b); - + int buffer_prepare_copy(buffer *b, size_t size); int buffer_prepare_append(buffer *b, size_t size); @@ -85,9 +101,9 @@ typedef enum { ENCODING_UNSET, - ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of a href */ - ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus coding / too as %2F */ - ENCODING_HTML, /* & becomes & and so on */ + ENCODING_REL_URI, /* for coding a rel-uri (/with space/and%percent) nicely as part of an href */ + ENCODING_REL_URI_PART, /* same as ENC_REL_URL plus encoding "/" as "%2F" */ + ENCODING_HTML, /* "&" becomes "&" and so on */ ENCODING_MINIMAL_XML, /* minimal encoding for xml */ ENCODING_HEX /* encode string as hex */ } buffer_encoding_t; @@ -111,20 +127,23 @@ int light_isalpha(int c); int light_isalnum(int c); +#define BUFFER_CTYPE_FUNC(type) int buffer_is##type(buffer *b); +BUFFER_CTYPE_FUNC(digit) +BUFFER_CTYPE_FUNC(xdigit) +BUFFER_CTYPE_FUNC(alpha) +BUFFER_CTYPE_FUNC(alnum) + +#define BUF_STR(x) x->ptr #define BUFFER_APPEND_STRING_CONST(x, y) \ buffer_append_string_len(x, y, sizeof(y) - 1) #define BUFFER_COPY_STRING_CONST(x, y) \ buffer_copy_string_len(x, y, sizeof(y) - 1) -#define BUFFER_APPEND_SLASH(x) \ - if (x->used > 1 && x->ptr[x->used - 2] != '/') { BUFFER_APPEND_STRING_CONST(x, "/"); } - #define CONST_STR_LEN(x) x, x ? sizeof(x) - 1 : 0 -#define CONST_BUF_LEN(x) x->ptr, x->used ? x->used - 1 : 0 +#define CONST_BUF_LEN(x) BUF_STR(x), x->used ? x->used - 1 : 0 - -#define SEGFAULT() do { fprintf(stderr, "%s.%d: aborted\n", __FILE__, __LINE__); abort(); } while(0) + #define UNUSED(x) ( (void)(x) ) #endif --- ../lighttpd-1.4.11/src/chunk.c 2005-11-18 15:18:19.000000000 +0200 +++ lighttpd-1.4.12/src/chunk.c 2006-07-18 13:03:40.000000000 +0300 @@ -1,16 +1,14 @@ /** * the network chunk-API - * - * + * + * */ #include #include -#include #include #include -#include #include #include @@ -18,36 +16,39 @@ #include "chunk.h" +#include "sys-mmap.h" +#include "sys-files.h" + chunkqueue *chunkqueue_init(void) { chunkqueue *cq; - + cq = calloc(1, sizeof(*cq)); - + cq->first = NULL; cq->last = NULL; - + cq->unused = NULL; - + return cq; } static chunk *chunk_init(void) { chunk *c; - + c = calloc(1, sizeof(*c)); - + c->mem = buffer_init(); c->file.name = buffer_init(); c->file.fd = -1; c->file.mmap.start = MAP_FAILED; c->next = NULL; - + return c; } static void chunk_free(chunk *c) { if (!c) return; - + buffer_free(c->mem); buffer_free(c->file.name); @@ -56,13 +57,13 @@ static void chunk_reset(chunk *c) { if (!c) return; - + buffer_reset(c->mem); if (c->file.is_temp && !buffer_is_empty(c->file.name)) { unlink(c->file.name->ptr); } - + buffer_reset(c->file.name); if (c->file.fd != -1) { @@ -78,28 +79,28 @@ void chunkqueue_free(chunkqueue *cq) { chunk *c, *pc; - + if (!cq) return; - + for (c = cq->first; c; ) { pc = c; c = c->next; chunk_free(pc); } - + for (c = cq->unused; c; ) { pc = c; c = c->next; chunk_free(pc); } - + free(cq); } static chunk *chunkqueue_get_unused_chunk(chunkqueue *cq) { chunk *c; - - /* check if we have a unused chunk */ + + /* check if we have an unused chunk */ if (!cq->unused) { c = chunk_init(); } else { @@ -109,18 +110,18 @@ c->next = NULL; cq->unused_chunks--; } - + return c; } static int chunkqueue_prepend_chunk(chunkqueue *cq, chunk *c) { c->next = cq->first; cq->first = c; - + if (cq->last == NULL) { cq->last = c; } - + return 0; } @@ -129,19 +130,19 @@ cq->last->next = c; } cq->last = c; - + if (cq->first == NULL) { cq->first = c; } - + return 0; } void chunkqueue_reset(chunkqueue *cq) { chunk *c; /* move everything to the unused queue */ - - /* mark all read written */ + + /* mark all read written */ for (c = cq->first; c; c = c->next) { switch(c->type) { case MEM_CHUNK: @@ -150,7 +151,7 @@ case FILE_CHUNK: c->offset = c->file.length; break; - default: + default: break; } } @@ -162,93 +163,93 @@ int chunkqueue_append_file(chunkqueue *cq, buffer *fn, off_t offset, off_t len) { chunk *c; - + if (len == 0) return 0; - + c = chunkqueue_get_unused_chunk(cq); - + c->type = FILE_CHUNK; - + buffer_copy_string_buffer(c->file.name, fn); c->file.start = offset; c->file.length = len; c->offset = 0; - + chunkqueue_append_chunk(cq, c); - + return 0; } int chunkqueue_append_buffer(chunkqueue *cq, buffer *mem) { chunk *c; - + if (mem->used == 0) return 0; - + c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; c->offset = 0; buffer_copy_string_buffer(c->mem, mem); - + chunkqueue_append_chunk(cq, c); - + return 0; } int chunkqueue_prepend_buffer(chunkqueue *cq, buffer *mem) { chunk *c; - + if (mem->used == 0) return 0; - + c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; c->offset = 0; buffer_copy_string_buffer(c->mem, mem); - + chunkqueue_prepend_chunk(cq, c); - + return 0; } int chunkqueue_append_mem(chunkqueue *cq, const char * mem, size_t len) { chunk *c; - + if (len == 0) return 0; - + c = chunkqueue_get_unused_chunk(cq); c->type = MEM_CHUNK; c->offset = 0; buffer_copy_string_len(c->mem, mem, len - 1); - + chunkqueue_append_chunk(cq, c); - + return 0; } buffer * chunkqueue_get_prepend_buffer(chunkqueue *cq) { chunk *c; - + c = chunkqueue_get_unused_chunk(cq); - + c->type = MEM_CHUNK; c->offset = 0; buffer_reset(c->mem); - + chunkqueue_prepend_chunk(cq, c); - + return c->mem; } buffer *chunkqueue_get_append_buffer(chunkqueue *cq) { chunk *c; - + c = chunkqueue_get_unused_chunk(cq); - + c->type = MEM_CHUNK; c->offset = 0; buffer_reset(c->mem); - + chunkqueue_append_chunk(cq, c); - + return c->mem; } @@ -263,7 +264,7 @@ chunk *chunkqueue_get_append_tempfile(chunkqueue *cq) { chunk *c; buffer *template = buffer_init_string("/var/tmp/lighttpd-upload-XXXXXX"); - + c = chunkqueue_get_unused_chunk(cq); c->type = FILE_CHUNK; @@ -273,12 +274,12 @@ size_t i; /* we have several tempdirs, only if all of them fail we jump out */ - + for (i = 0; i < cq->tempdirs->used; i++) { data_string *ds = (data_string *)cq->tempdirs->data[i]; buffer_copy_string_buffer(template, ds->value); - BUFFER_APPEND_SLASH(template); + PATHNAME_APPEND_SLASH(template); BUFFER_APPEND_STRING_CONST(template, "lighttpd-upload-XXXXXX"); if (-1 != (c->file.fd = mkstemp(template->ptr))) { @@ -300,7 +301,7 @@ chunkqueue_append_chunk(cq, c); buffer_free(template); - + return c; } @@ -308,7 +309,7 @@ off_t chunkqueue_length(chunkqueue *cq) { off_t len = 0; chunk *c; - + for (c = cq->first; c; c = c->next) { switch (c->type) { case MEM_CHUNK: @@ -321,14 +322,14 @@ break; } } - + return len; } off_t chunkqueue_written(chunkqueue *cq) { off_t len = 0; chunk *c; - + for (c = cq->first; c; c = c->next) { switch (c->type) { case MEM_CHUNK: @@ -339,7 +340,7 @@ break; } } - + return len; } @@ -355,12 +356,13 @@ switch (c->type) { case MEM_CHUNK: + if (c->mem->used == 0) is_finished = 1; if (c->offset == (off_t)c->mem->used - 1) is_finished = 1; break; case FILE_CHUNK: - if (c->offset == c->file.length) is_finished = 1; + if (c->offset == c->file.length) is_finished = 1; break; - default: + default: break; } @@ -383,3 +385,50 @@ return 0; } + +void chunkqueue_print(chunkqueue *cq) { + chunk *c; + + for (c = cq->first; c; c = c->next) { + fprintf(stderr, "(mem) %s", c->mem->ptr + c->offset); + } + fprintf(stderr, "\r\n"); +} + + +/** + * remove the last chunk if it is empty + */ + +void chunkqueue_remove_empty_last_chunk(chunkqueue *cq) { + chunk *c; + if (!cq->last) return; + if (!cq->first) return; + + if (cq->first == cq->last) { + c = cq->first; + + if (c->type != MEM_CHUNK) return; + if (c->mem->used == 0) { + chunk_free(c); + cq->first = cq->last = NULL; + } + return; + } + + for (c = cq->first; c->next; c = c->next) { + if (c->type != MEM_CHUNK) continue; + if (c->mem->used != 0) continue; + + if (c->next == cq->last) { + cq->last = c; + + chunk_free(c->next); + c->next = NULL; + + return; + } + } +} + + --- ../lighttpd-1.4.11/src/chunk.h 2005-11-01 09:32:21.000000000 +0200 +++ lighttpd-1.4.12/src/chunk.h 2006-07-18 13:03:40.000000000 +0300 @@ -6,7 +6,7 @@ typedef struct chunk { enum { UNUSED_CHUNK, MEM_CHUNK, FILE_CHUNK } type; - + buffer *mem; /* either the storage of the mem-chunk or the read-ahead buffer */ struct { @@ -16,28 +16,28 @@ off_t length; /* octets to send from the starting offset */ int fd; - struct { + struct { char *start; /* the start pointer of the mmap'ed area */ size_t length; /* size of the mmap'ed area */ - off_t offset; /* start is octet away from the start of the file */ + off_t offset; /* start is octets away from the start of the file */ } mmap; - int is_temp; /* file is temporary and will be deleted if on cleanup */ + int is_temp; /* file is temporary and will be deleted on cleanup */ } file; - - off_t offset; /* octets sent from this chunk - the size of the chunk is either + + off_t offset; /* octets sent from this chunk + the size of the chunk is either - mem-chunk: mem->used - 1 - file-chunk: file.length */ - + struct chunk *next; } chunk; typedef struct { chunk *first; chunk *last; - + chunk *unused; size_t unused_chunks; @@ -56,6 +56,7 @@ buffer * chunkqueue_get_append_buffer(chunkqueue *c); buffer * chunkqueue_get_prepend_buffer(chunkqueue *c); chunk * chunkqueue_get_append_tempfile(chunkqueue *cq); +void chunkqueue_remove_empty_last_chunk(chunkqueue *cq); int chunkqueue_remove_finished_chunks(chunkqueue *cq); @@ -66,4 +67,6 @@ int chunkqueue_is_empty(chunkqueue *c); +void chunkqueue_print(chunkqueue *cq); + #endif --- ../lighttpd-1.4.11/src/configfile-glue.c 2006-03-03 20:14:56.000000000 +0200 +++ lighttpd-1.4.12/src/configfile-glue.c 2006-07-16 00:26:03.000000000 +0300 @@ -1,4 +1,5 @@ #include +#include #include "base.h" #include "buffer.h" @@ -11,10 +12,10 @@ * are the external interface of lighttpd. The functions * are used by the server itself and the plugins. * - * The main-goal is to have a small library in the end - * which is linked against both and which will define + * The main-goal is to have a small library in the end + * which is linked against both and which will define * the interface itself in the end. - * + * */ @@ -24,56 +25,60 @@ int config_insert_values_internal(server *srv, array *ca, const config_values_t cv[]) { size_t i; data_unset *du; - + for (i = 0; cv[i].key; i++) { - + if (NULL == (du = array_get_element(ca, cv[i].key))) { /* no found */ - + continue; } - + switch (cv[i].type) { case T_CONFIG_ARRAY: if (du->type == TYPE_ARRAY) { size_t j; data_array *da = (data_array *)du; - + for (j = 0; j < da->value->used; j++) { if (da->value->data[j]->type == TYPE_STRING) { data_string *ds = data_string_init(); - + buffer_copy_string_buffer(ds->value, ((data_string *)(da->value->data[j]))->value); if (!da->is_index_key) { /* the id's were generated automaticly, as we copy now we might have to renumber them - * this is used to prepend server.modules by mod_indexfiles as it has to be loaded + * this is used to prepend server.modules by mod_indexfiles as it has to be loaded * before mod_fastcgi and friends */ buffer_copy_string_buffer(ds->key, ((data_string *)(da->value->data[j]))->key); } - + array_insert_unique(cv[i].destination, (data_unset *)ds); } else { - log_error_write(srv, __FILE__, __LINE__, "sssd", - "the key of and array can only be a string or a integer, variable:", - cv[i].key, "type:", da->value->data[j]->type); - + log_error_write(srv, __FILE__, __LINE__, "sssd", + "the key of and array can only be a string or a integer, variable:", + cv[i].key, "type:", da->value->data[j]->type); + return -1; } } } else { log_error_write(srv, __FILE__, __LINE__, "sss", "unexpected type for key: ", cv[i].key, "array of strings"); - + return -1; } break; case T_CONFIG_STRING: if (du->type == TYPE_STRING) { data_string *ds = (data_string *)du; - + buffer_copy_string_buffer(cv[i].destination, ds->value); + } else if (du->type == TYPE_INTEGER) { + data_integer *di = (data_integer *)du; + + buffer_copy_long(cv[i].destination, di->value); } else { log_error_write(srv, __FILE__, __LINE__, "ssss", "unexpected type for key: ", cv[i].key, "(string)", "\"...\""); - + return -1; } break; @@ -81,15 +86,20 @@ switch(du->type) { case TYPE_INTEGER: { data_integer *di = (data_integer *)du; - + *((unsigned short *)(cv[i].destination)) = di->value; break; } case TYPE_STRING: { data_string *ds = (data_string *)du; - + + if (buffer_isdigit(ds->value)) { + *((unsigned short *)(cv[i].destination)) = strtol(ds->value->ptr, NULL, 10); + break; + } + log_error_write(srv, __FILE__, __LINE__, "ssb", "get a string but expected a short:", cv[i].key, ds->value); - + return -1; } default: @@ -100,19 +110,19 @@ case T_CONFIG_BOOLEAN: if (du->type == TYPE_STRING) { data_string *ds = (data_string *)du; - + if (buffer_is_equal_string(ds->value, CONST_STR_LEN("enable"))) { *((unsigned short *)(cv[i].destination)) = 1; } else if (buffer_is_equal_string(ds->value, CONST_STR_LEN("disable"))) { *((unsigned short *)(cv[i].destination)) = 0; } else { log_error_write(srv, __FILE__, __LINE__, "ssbs", "ERROR: unexpected value for key:", cv[i].key, ds->value, "(enable|disable)"); - + return -1; } } else { log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: unexpected type for key:", cv[i].key, "(string)", "\"(enable|disable)\""); - + return -1; } break; @@ -121,9 +131,9 @@ break; case T_CONFIG_DEPRECATED: log_error_write(srv, __FILE__, __LINE__, "ssss", "ERROR: found deprecated key:", cv[i].key, "-", (char *)(cv[i].destination)); - + srv->config_deprecated = 1; - + break; } } @@ -133,25 +143,25 @@ int config_insert_values_global(server *srv, array *ca, const config_values_t cv[]) { size_t i; data_unset *du; - + for (i = 0; cv[i].key; i++) { data_string *touched; - + if (NULL == (du = array_get_element(ca, cv[i].key))) { /* no found */ - + continue; } - + /* touched */ touched = data_string_init(); - + buffer_copy_string(touched->value, ""); buffer_copy_string_buffer(touched->key, du->key); - + array_insert_unique(srv->config_touched, (data_unset *)touched); } - + return config_insert_values_internal(srv, ca, cv); } @@ -191,25 +201,25 @@ } /* pass the rules */ - + switch (dc->comp) { case COMP_HTTP_HOST: { char *ck_colon = NULL, *val_colon = NULL; - + if (!buffer_is_empty(con->uri.authority)) { - - /* + + /* * append server-port to the HTTP_POST if necessary */ - + l = con->uri.authority; - + switch(dc->cond) { case CONFIG_COND_NE: case CONFIG_COND_EQ: ck_colon = strchr(dc->string->ptr, ':'); val_colon = strchr(l->ptr, ':'); - + if (ck_colon == val_colon) { /* nothing to do with it */ break; @@ -230,21 +240,21 @@ break; } } else { - l = NULL; + l = srv->empty_string; } break; } case COMP_HTTP_REMOTEIP: { char *nm_slash; - /* handle remoteip limitations - * + /* handle remoteip limitations + * * "10.0.0.1" is provided for all comparisions - * + * * only for == and != we support - * + * * "10.0.0.1/24" */ - + if ((dc->cond == CONFIG_COND_EQ || dc->cond == CONFIG_COND_NE) && (con->dst_addr.plain.sa_family == AF_INET) && @@ -253,41 +263,48 @@ long nm; char *err; struct in_addr val_inp; - + + if (con->conf.log_condition_handling) { + l = srv->empty_string; + + log_error_write(srv, __FILE__, __LINE__, "bsbsb", dc->comp_key, + "(", l, ") compare to", dc->string); + } + if (*(nm_slash+1) == '\0') { log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: no number after / ", dc->string); - + return COND_RESULT_FALSE; } - + nm_bits = strtol(nm_slash + 1, &err, 10); - + if (*err) { log_error_write(srv, __FILE__, __LINE__, "sbs", "ERROR: non-digit found in netmask:", dc->string, *err); - + return COND_RESULT_FALSE; } - + /* take IP convert to the native */ buffer_copy_string_len(srv->cond_check_buf, dc->string->ptr, nm_slash - dc->string->ptr); -#ifdef __WIN32 +#ifdef _WIN32 if (INADDR_NONE == (val_inp.s_addr = inet_addr(srv->cond_check_buf->ptr))) { log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); - + return COND_RESULT_FALSE; } #else if (0 == inet_aton(srv->cond_check_buf->ptr, &val_inp)) { log_error_write(srv, __FILE__, __LINE__, "sb", "ERROR: ip addr is invalid:", srv->cond_check_buf); - + return COND_RESULT_FALSE; } #endif - + /* build netmask */ nm = htonl(~((1 << (32 - nm_bits)) - 1)); - + if ((val_inp.s_addr & nm) == (con->dst_addr.ipv4.sin_addr.s_addr & nm)) { return (dc->cond == CONFIG_COND_EQ) ? COND_RESULT_TRUE : COND_RESULT_FALSE; } else { @@ -308,7 +325,7 @@ case COMP_HTTP_REFERER: { data_string *ds; - + if (NULL != (ds = (data_string *)array_get_element(con->request.headers, "Referer"))) { l = ds->value; } else { @@ -338,7 +355,7 @@ default: return COND_RESULT_FALSE; } - + if (NULL == l) { if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "bsbs", dc->comp_key, @@ -346,10 +363,10 @@ } return COND_RESULT_FALSE; } - + if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "bsbsb", dc->comp_key, - "(", l, ") compare to ", dc->string); + "(", l, ") compare to", dc->string); } switch(dc->cond) { case CONFIG_COND_NE: @@ -365,13 +382,13 @@ case CONFIG_COND_MATCH: { cond_cache_t *cache = &con->cond_cache[dc->context_ndx]; int n; - + #ifndef elementsof #define elementsof(x) (sizeof(x) / sizeof(x[0])) #endif n = pcre_exec(dc->regex, dc->regex_study, l->ptr, l->used - 1, 0, 0, cache->matches, elementsof(cache->matches)); - + cache->patterncount = n; if (n > 0) { cache->comp_value = l; @@ -387,7 +404,7 @@ /* no way */ break; } - + return COND_RESULT_FALSE; } @@ -395,6 +412,9 @@ cond_cache_t *caches = con->cond_cache; if (COND_RESULT_UNSET == caches[dc->context_ndx].result) { + if (con->conf.log_condition_handling) { + log_error_write(srv, __FILE__, __LINE__, "sds", "=== start of", dc->context_ndx, "condition block ==="); + } if (COND_RESULT_TRUE == (caches[dc->context_ndx].result = config_check_cond_nocache(srv, con, dc))) { if (dc->next) { data_config *c; @@ -409,11 +429,11 @@ } if (con->conf.log_condition_handling) { log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx, - "(uncached) result:", + "result:", caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false"); } } else { - if (con->conf.log_condition_handling) { + if (con->conf.log_condition_cache_handling) { log_error_write(srv, __FILE__, __LINE__, "dss", dc->context_ndx, "(cached) result:", caches[dc->context_ndx].result == COND_RESULT_TRUE ? "true" : "false"); @@ -423,9 +443,6 @@ } int config_check_cond(server *srv, connection *con, data_config *dc) { - if (con->conf.log_condition_handling) { - log_error_write(srv, __FILE__, __LINE__, "s", "=== start of condition block ==="); - } return (config_check_cond_cached(srv, con, dc) == COND_RESULT_TRUE); } @@ -443,3 +460,85 @@ return 1; } +/* return <0 on error + * return 0-x if matched (and replaced) + */ +int config_exec_pcre_keyvalue_buffer(connection *con, pcre_keyvalue_buffer *kvb, data_config *context, buffer *match_buf, buffer *result) +{ +#ifdef HAVE_PCRE_H + pcre *match; + pcre_extra *extra; + const char *pattern; + size_t pattern_len; + int n; + size_t i; + pcre_keyvalue *kv; +# define N 10 + int ovec[N * 3]; + + for (i = 0; i < kvb->used; i++) { + kv = kvb->kv[i]; + + match = kv->key; + extra = kv->key_extra; + pattern = kv->value->ptr; + pattern_len = kv->value->used - 1; + + if ((n = pcre_exec(match, extra, match_buf->ptr, match_buf->used - 1, 0, 0, ovec, 3 * N)) < 0) { + if (n != PCRE_ERROR_NOMATCH) { + return n; + } + } else { + const char **list; + size_t start, end; + size_t k; + + /* it matched */ + pcre_get_substring_list(match_buf->ptr, ovec, n, &list); + + /* search for $[0-9] */ + + buffer_reset(result); + + start = 0; end = pattern_len; + for (k = 0; k < pattern_len; k++) { + if ((pattern[k] == '$' || pattern[k] == '%') && + isdigit((unsigned char)pattern[k + 1])) { + /* got one */ + + size_t num = pattern[k + 1] - '0'; + + end = k; + + buffer_append_string_len(result, pattern + start, end - start); + + if (pattern[k] == '$') { + /* n is always > 0 */ + if (num < (size_t)n) { + buffer_append_string(result, list[num]); + } + } else { + config_append_cond_match_buffer(con, context, result, num); + } + + k++; + start = k + 1; + } + } + + buffer_append_string_len(result, pattern + start, pattern_len - start); + + pcre_free(list); + + return i; + } + } + + return PCRE_ERROR_NOMATCH; +#undef N +#else + UNUSED(kvb); + return -2; +#endif +} + --- ../lighttpd-1.4.11/src/configfile.c 2006-02-15 14:26:42.000000000 +0200 +++ lighttpd-1.4.12/src/configfile.c 2006-07-18 13:03:40.000000000 +0300 @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -13,21 +12,24 @@ #include "log.h" #include "stream.h" #include "plugin.h" -#ifdef USE_LICENSE -#include "license.h" -#endif - #include "configparser.h" #include "configfile.h" #include "proc_open.h" +#include "sys-files.h" +#include "sys-process.h" + +#ifndef PATH_MAX +/* win32 */ +#define PATH_MAX 64 +#endif static int config_insert(server *srv) { size_t i; int ret = 0; buffer *stat_cache_string; - - config_values_t cv[] = { + + config_values_t cv[] = { { "server.bind", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 0 */ { "server.errorlog", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 1 */ { "server.errorfile-prefix", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 2 */ @@ -38,7 +40,7 @@ { "server.tag", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 7 */ { "server.use-ipv6", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */ { "server.modules", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER }, /* 9 */ - + { "server.event-handler", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 10 */ { "server.pid-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 11 */ { "server.max-request-size", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 12 */ @@ -49,7 +51,7 @@ { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */ { "server.name", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 18 */ { "server.max-keep-alive-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 19 */ - + { "server.max-read-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 20 */ { "server.max-write-idle", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 21 */ { "server.error-handler-404", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 22 */ @@ -60,19 +62,19 @@ { "mimetype.use-xattr", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */ { "mimetype.assign", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 28 */ { "ssl.pemfile", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 29 */ - + { "ssl.engine", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 30 */ - + { "debug.log-file-not-found", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 31 */ { "debug.log-request-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 32 */ { "debug.log-response-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 33 */ { "debug.log-request-header", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 34 */ - + { "server.protocol-http11", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 35 */ { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 36 */ { "debug.log-state-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */ { "ssl.ca-file", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER }, /* 38 */ - + { "server.errorlog-use-syslog", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 39 */ { "server.range-requests", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 40 */ { "server.stat-cache-engine", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 41 */ @@ -80,7 +82,8 @@ { "server.network-backend", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 43 */ { "server.upload-dirs", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 44 */ { "server.core-files", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 45 */ - + { "debug.log-condition-cache-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 46 */ + { "server.host", "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.docroot", "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.virtual-root", "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, @@ -90,11 +93,11 @@ { "server.groupid", "use server.groupname instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.use-keep-alive", "use server.max-keep-alive-requests = 0 instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, { "server.force-lower-case-files", "use server.force-lowercase-filenames instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, - + { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; - + /* 0 */ cv[0].destination = srv->srvconf.bindhost; cv[1].destination = srv->srvconf.errorlog_file; @@ -102,33 +105,33 @@ cv[4].destination = srv->srvconf.username; cv[5].destination = srv->srvconf.groupname; cv[6].destination = &(srv->srvconf.port); - + cv[9].destination = srv->srvconf.modules; cv[10].destination = srv->srvconf.event_handler; cv[11].destination = srv->srvconf.pid_file; - + cv[13].destination = &(srv->srvconf.max_worker); cv[23].destination = &(srv->srvconf.max_fds); cv[36].destination = &(srv->srvconf.log_request_header_on_error); cv[37].destination = &(srv->srvconf.log_state_handling); - + cv[39].destination = &(srv->srvconf.errorlog_use_syslog); - + stat_cache_string = buffer_init(); cv[41].destination = stat_cache_string; cv[43].destination = srv->srvconf.network_backend; cv[44].destination = srv->srvconf.upload_tempdirs; cv[45].destination = &(srv->srvconf.enable_cores); - + cv[42].destination = &(srv->srvconf.max_conns); cv[12].destination = &(srv->srvconf.max_request_size); srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *)); assert(srv->config_storage); - + for (i = 0; i < srv->config_context->used; i++) { specific_config *s; - + s = calloc(1, sizeof(specific_config)); assert(s); s->document_root = buffer_init(); @@ -154,17 +157,18 @@ s->global_kbytes_per_second = 0; s->global_bytes_per_second_cnt = 0; s->global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt; - + cv[2].destination = s->errorfile_prefix; - + cv[7].destination = s->server_tag; cv[8].destination = &(s->use_ipv6); - - + + /* 13 max-worker */ cv[14].destination = s->document_root; cv[15].destination = &(s->force_lowercase_filenames); cv[16].destination = &(s->log_condition_handling); + cv[46].destination = &(s->log_condition_cache_handling); cv[17].destination = &(s->max_keep_alive_requests); cv[18].destination = s->server_name; cv[19].destination = &(s->max_keep_alive_idle); @@ -179,23 +183,23 @@ cv[28].destination = s->mimetypes; cv[29].destination = s->ssl_pemfile; cv[30].destination = &(s->is_ssl); - + cv[31].destination = &(s->log_file_not_found); cv[32].destination = &(s->log_request_handling); cv[33].destination = &(s->log_response_header); cv[34].destination = &(s->log_request_header); - + cv[35].destination = &(s->allow_http11); cv[38].destination = s->ssl_ca_file; cv[40].destination = &(s->range_requests); - + srv->config_storage[i] = s; - + if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) { break; } } - + if (buffer_is_empty(stat_cache_string)) { srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE; } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) { @@ -205,22 +209,22 @@ } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("disable"))) { srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_NONE; } else { - log_error_write(srv, __FILE__, __LINE__, "sb", + log_error_write(srv, __FILE__, __LINE__, "sb", "server.stat-cache-engine can be one of \"disable\", \"simple\", \"fam\", but not:", stat_cache_string); ret = HANDLER_ERROR; } - + buffer_free(stat_cache_string); - + return ret; - -} +} -#define PATCH(x) con->conf.x = s->x +#define PATCH(x) \ + con->conf.x = s->x int config_setup_connection(server *srv, connection *con) { specific_config *s = srv->config_storage[0]; - + PATCH(allow_http11); PATCH(mimetypes); PATCH(document_root); @@ -236,20 +240,21 @@ PATCH(kbytes_per_second); PATCH(global_kbytes_per_second); PATCH(global_bytes_per_second_cnt); - + con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt; buffer_copy_string_buffer(con->server_name, s->server_name); - + PATCH(log_request_header); PATCH(log_response_header); PATCH(log_request_handling); PATCH(log_condition_handling); + PATCH(log_condition_cache_handling); PATCH(log_file_not_found); - + PATCH(range_requests); PATCH(force_lowercase_filenames); PATCH(is_ssl); - + PATCH(ssl_pemfile); PATCH(ssl_ca_file); return 0; @@ -257,22 +262,22 @@ int config_patch_connection(server *srv, connection *con, comp_key_t comp) { size_t i, j; - + /* skip the first, the global context */ for (i = 1; i < srv->config_context->used; i++) { data_config *dc = (data_config *)srv->config_context->data[i]; specific_config *s = srv->config_storage[i]; - + /* not our stage */ if (comp != dc->comp) continue; - + /* condition didn't match */ if (!config_check_cond(srv, con, dc)) continue; - + /* merge config */ for (j = 0; j < dc->value->used; j++) { data_unset *du = dc->value->data[j]; - + if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.document-root"))) { PATCH(document_root); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.range-requests"))) { @@ -315,11 +320,13 @@ PATCH(log_response_header); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-handling"))) { PATCH(log_condition_handling); + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-condition-cache-handling"))) { + PATCH(log_condition_cache_handling); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-file-not-found"))) { PATCH(log_file_not_found); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.protocol-http11"))) { PATCH(allow_http11); - } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) { + } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) { PATCH(force_lowercase_filenames); } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.kbytes-per-second"))) { PATCH(global_kbytes_per_second); @@ -328,7 +335,7 @@ } } } - + return 0; } #undef PATCH @@ -336,15 +343,15 @@ typedef struct { int foo; int bar; - + const buffer *source; const char *input; size_t offset; size_t size; - + int line_pos; int line; - + int in_key; int in_brace; int in_cond; @@ -362,7 +369,7 @@ } if (0 != stream_open(&(t->s), t->file)) { - log_error_write(srv, __FILE__, __LINE__, "sbss", + log_error_write(srv, __FILE__, __LINE__, "sbss", "opening configfile ", t->file, "failed:", strerror(errno)); buffer_free(t->file); return -1; @@ -373,7 +380,7 @@ t->size = t->s.size; t->line = 1; t->line_pos = 1; - + t->in_key = 1; t->in_brace = 0; t->in_cond = 0; @@ -401,7 +408,7 @@ static int config_skip_comment(tokenizer_t *t) { int i; assert(t->input[t->offset] == '#'); - for (i = 1; t->input[t->offset + i] && + for (i = 1; t->input[t->offset + i] && (t->input[t->offset + i] != '\n' && t->input[t->offset + i] != '\r'); i++); t->offset += i; @@ -411,44 +418,44 @@ static int config_tokenizer(server *srv, tokenizer_t *t, int *token_id, buffer *token) { int tid = 0; size_t i; - + for (tid = 0; tid == 0 && t->offset < t->size && t->input[t->offset] ; ) { char c = t->input[t->offset]; const char *start = NULL; - + switch (c) { - case '=': + case '=': if (t->in_brace) { if (t->input[t->offset + 1] == '>') { t->offset += 2; - + buffer_copy_string(token, "=>"); - + tid = TK_ARRAY_ASSIGN; } else { - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "use => for assignments in arrays"); return -1; } } else if (t->in_cond) { if (t->input[t->offset + 1] == '=') { t->offset += 2; - + buffer_copy_string(token, "=="); - + tid = TK_EQ; } else if (t->input[t->offset + 1] == '~') { t->offset += 2; - + buffer_copy_string(token, "=~"); - + tid = TK_MATCH; } else { - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "only =~ and == are allowed in the condition"); return -1; } @@ -456,51 +463,51 @@ t->in_cond = 0; } else if (t->in_key) { tid = TK_ASSIGN; - + buffer_copy_string_len(token, t->input + t->offset, 1); - + t->offset++; t->line_pos++; } else { - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "unexpected equal-sign: ="); return -1; } - + break; - case '!': + case '!': if (t->in_cond) { if (t->input[t->offset + 1] == '=') { t->offset += 2; - + buffer_copy_string(token, "!="); - + tid = TK_NE; } else if (t->input[t->offset + 1] == '~') { t->offset += 2; - + buffer_copy_string(token, "!~"); - + tid = TK_NOMATCH; } else { - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "only !~ and != are allowed in the condition"); return -1; } t->in_key = 1; t->in_cond = 0; } else { - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "unexpected exclamation-marks: !"); return -1; } - + break; case '\t': case ' ': @@ -546,10 +553,10 @@ case ',': if (t->in_brace > 0) { tid = TK_COMMA; - + buffer_copy_string(token, "(COMMA)"); } - + t->offset++; t->line_pos++; break; @@ -557,70 +564,70 @@ /* search for the terminating " */ start = t->input + t->offset + 1; buffer_copy_string(token, ""); - + for (i = 1; t->input[t->offset + i]; i++) { if (t->input[t->offset + i] == '\\' && t->input[t->offset + i + 1] == '"') { - + buffer_append_string_len(token, start, t->input + t->offset + i - start); - + start = t->input + t->offset + i + 1; - + /* skip the " */ i++; continue; } - - + + if (t->input[t->offset + i] == '"') { tid = TK_STRING; - + buffer_append_string_len(token, start, t->input + t->offset + i - start); - + break; } } if (t->input[t->offset + i] == '\0') { /* ERROR */ - - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "missing closing quote"); - + return -1; } - + t->offset += i + 1; t->line_pos += i + 1; - + break; case '(': t->offset++; t->in_brace++; - + tid = TK_LPARAN; - + buffer_copy_string(token, "("); break; case ')': t->offset++; t->in_brace--; - + tid = TK_RPARAN; - + buffer_copy_string(token, ")"); break; case '$': t->offset++; - + tid = TK_DOLLAR; t->in_cond = 1; t->in_key = 0; - + buffer_copy_string(token, "$"); - + break; case '+': @@ -637,115 +644,107 @@ case '{': t->offset++; - + tid = TK_LCURLY; - + buffer_copy_string(token, "{"); - + break; - + case '}': t->offset++; - + tid = TK_RCURLY; - + buffer_copy_string(token, "}"); - + break; case '[': t->offset++; - + tid = TK_LBRACKET; - + buffer_copy_string(token, "["); - + break; - + case ']': t->offset++; - + tid = TK_RBRACKET; - + buffer_copy_string(token, "]"); - + break; case '#': t->line_pos += config_skip_comment(t); - + break; default: if (t->in_cond) { - for (i = 0; t->input[t->offset + i] && + for (i = 0; t->input[t->offset + i] && (isalpha((unsigned char)t->input[t->offset + i]) ); i++); - + if (i && t->input[t->offset + i]) { tid = TK_SRVVARNAME; buffer_copy_string_len(token, t->input + t->offset, i); - + t->offset += i; t->line_pos += i; } else { /* ERROR */ - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "invalid character in condition"); return -1; } } else if (isdigit((unsigned char)c)) { /* take all digits */ for (i = 0; t->input[t->offset + i] && isdigit((unsigned char)t->input[t->offset + i]); i++); - + /* was there it least a digit ? */ - if (i && t->input[t->offset + i]) { + if (i) { tid = TK_INTEGER; - + buffer_copy_string_len(token, t->input + t->offset, i); - + t->offset += i; t->line_pos += i; - } else { - /* ERROR */ - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", - "source:", t->source, - "line:", t->line, "pos:", t->line_pos, - "unexpected EOF"); - - return -1; } } else { /* the key might consist of [-.0-9a-z] */ - for (i = 0; t->input[t->offset + i] && - (isalnum((unsigned char)t->input[t->offset + i]) || + for (i = 0; t->input[t->offset + i] && + (isalnum((unsigned char)t->input[t->offset + i]) || t->input[t->offset + i] == '.' || t->input[t->offset + i] == '_' || /* for env.* */ t->input[t->offset + i] == '-' ); i++); - + if (i && t->input[t->offset + i]) { buffer_copy_string_len(token, t->input + t->offset, i); - - if (strcmp(token->ptr, "include") == 0) { + + if (buffer_is_equal_string(token, CONST_STR_LEN("include"))) { tid = TK_INCLUDE; - } else if (strcmp(token->ptr, "include_shell") == 0) { + } else if (buffer_is_equal_string(token, CONST_STR_LEN("include_shell"))) { tid = TK_INCLUDE_SHELL; - } else if (strcmp(token->ptr, "global") == 0) { + } else if (buffer_is_equal_string(token, CONST_STR_LEN("global"))) { tid = TK_GLOBAL; - } else if (strcmp(token->ptr, "else") == 0) { + } else if (buffer_is_equal_string(token, CONST_STR_LEN("else"))) { tid = TK_ELSE; } else { tid = TK_LKEY; } - + t->offset += i; t->line_pos += i; } else { /* ERROR */ - log_error_write(srv, __FILE__, __LINE__, "sbsdsds", + log_error_write(srv, __FILE__, __LINE__, "sbsdsds", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "invalid character in variable name"); return -1; } @@ -753,16 +752,16 @@ break; } } - + if (tid) { *token_id = tid; #if 0 - log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", + log_error_write(srv, __FILE__, __LINE__, "sbsdsdbdd", "source:", t->source, "line:", t->line, "pos:", t->line_pos, token, token->used - 1, tid); #endif - + return 1; } else if (t->offset < t->size) { fprintf(stderr, "%s.%d: %d, %s\n", @@ -781,10 +780,11 @@ pParser = configparserAlloc( malloc ); lasttoken = buffer_init(); token = buffer_init(); + while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) { buffer_copy_string_buffer(lasttoken, token); configparser(pParser, token_id, token, context); - + token = buffer_init(); } buffer_free(token); @@ -797,14 +797,14 @@ } } configparserFree(pParser, free); - + if (ret == -1) { - log_error_write(srv, __FILE__, __LINE__, "sb", + log_error_write(srv, __FILE__, __LINE__, "sb", "configfile parser failed:", lasttoken); } else if (context->ok == 0) { - log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", + log_error_write(srv, __FILE__, __LINE__, "sbsdsdsb", "source:", t->source, - "line:", t->line, "pos:", t->line_pos, + "line:", t->line, "pos:", t->line_pos, "parser failed somehow near here:", lasttoken); ret = -1; } @@ -821,7 +821,7 @@ t->offset = 0; t->line = 1; t->line_pos = 1; - + t->in_key = 1; t->in_brace = 0; t->in_cond = 0; @@ -844,7 +844,7 @@ } if (0 != stream_open(&s, filename)) { - log_error_write(srv, __FILE__, __LINE__, "sbss", + log_error_write(srv, __FILE__, __LINE__, "sbss", "opening configfile ", filename, "failed:", strerror(errno)); ret = -1; } else { @@ -866,7 +866,7 @@ char oldpwd[PATH_MAX]; if (NULL == getcwd(oldpwd, sizeof(oldpwd))) { - log_error_write(srv, __FILE__, __LINE__, "s", + log_error_write(srv, __FILE__, __LINE__, "s", "cannot get cwd", strerror(errno)); return -1; } @@ -879,7 +879,7 @@ } if (0 != proc_open_buffer(&proc, cmd, NULL, out, NULL)) { - log_error_write(srv, __FILE__, __LINE__, "sbss", + log_error_write(srv, __FILE__, __LINE__, "sbss", "opening", source, "failed:", strerror(errno)); ret = -1; } else { @@ -896,13 +896,12 @@ static void context_init(server *srv, config_t *context) { context->srv = srv; context->ok = 1; - context->configs_stack = array_init(); - context->configs_stack->is_weakref = 1; + context->configs_stack = buffer_ptr_init(NULL); context->basedir = buffer_init(); } static void context_free(config_t *context) { - array_free(context->configs_stack); + buffer_ptr_free(context->configs_stack); buffer_free(context->basedir); } @@ -918,18 +917,15 @@ context_init(srv, &context); context.all_configs = srv->config_context; - pos = strrchr(fn, -#ifdef __WIN32 - '\\' -#else - '/' -#endif - ); + /* use the current dir as basedir for all other includes + */ + pos = strrchr(fn, DIR_SEPERATOR); + if (pos) { buffer_copy_string_len(context.basedir, fn, pos - fn + 1); fn = pos + 1; } - + dc = data_config_init(); buffer_copy_string(dc->key, "global"); @@ -944,7 +940,7 @@ dpid->value = getpid(); buffer_copy_string(dpid->key, "var.PID"); array_insert_unique(srv->config, (data_unset *)dpid); - + dcwd = data_string_init(); buffer_prepare_copy(dcwd->value, 1024); if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) { @@ -968,7 +964,7 @@ } else { return -1; } - + if (NULL != (modules = (data_array *)array_get_element(srv->config, "server.modules"))) { data_string *ds; data_array *prepends; @@ -1026,22 +1022,23 @@ buffer_copy_string(modules->key, "server.modules"); array_insert_unique(srv->config, (data_unset *)modules); } - + if (0 != config_insert(srv)) { return -1; } - + return 0; } + int config_set_defaults(server *srv) { size_t i; specific_config *s = srv->config_storage[0]; struct stat st1, st2; - - struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = - { + + struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] = + { /* - poll is most reliable * - select works everywhere * - linux-* are experimental @@ -1067,20 +1064,21 @@ #endif { FDEVENT_HANDLER_UNSET, NULL } }; - - if (buffer_is_empty(s->document_root)) { - log_error_write(srv, __FILE__, __LINE__, "s", - "a default document-root has to be set"); - - return -1; - } - + + if (buffer_is_empty(s->document_root)) { + log_error_write(srv, __FILE__, __LINE__, "s", + "a default document-root has to be set"); + + return -1; + } + if (buffer_is_empty(srv->srvconf.changeroot)) { - if (-1 == stat(s->document_root->ptr, &st1)) { - log_error_write(srv, __FILE__, __LINE__, "sb", + pathname_unix2local(s->document_root); + if (-1 == stat(s->document_root->ptr, &st1)) { + log_error_write(srv, __FILE__, __LINE__, "sbs", "base-docroot doesn't exist:", - s->document_root); + s->document_root, strerror(errno)); return -1; } @@ -1088,18 +1086,18 @@ buffer_copy_string_buffer(srv->tmp_buf, srv->srvconf.changeroot); buffer_append_string_buffer(srv->tmp_buf, s->document_root); - if (-1 == stat(srv->tmp_buf->ptr, &st1)) { - log_error_write(srv, __FILE__, __LINE__, "sb", + if (-1 == stat(srv->tmp_buf->ptr, &st1)) { + log_error_write(srv, __FILE__, __LINE__, "sb", "base-docroot doesn't exist:", - srv->tmp_buf); + srv->tmp_buf); return -1; } - + } - - buffer_copy_string_buffer(srv->tmp_buf, s->document_root); - buffer_to_lower(srv->tmp_buf); + buffer_copy_string_buffer(srv->tmp_buf, s->document_root); + + buffer_to_lower(srv->tmp_buf); if (0 == stat(srv->tmp_buf->ptr, &st1)) { int is_lower = 0; @@ -1107,68 +1105,68 @@ is_lower = buffer_is_equal(srv->tmp_buf, s->document_root); /* lower-case existed, check upper-case */ - buffer_copy_string_buffer(srv->tmp_buf, s->document_root); + buffer_copy_string_buffer(srv->tmp_buf, s->document_root); - buffer_to_upper(srv->tmp_buf); + buffer_to_upper(srv->tmp_buf); /* we have to handle the special case that upper and lower-casing results in the same filename * as in server.document-root = "/" or "/12345/" */ if (is_lower && buffer_is_equal(srv->tmp_buf, s->document_root)) { - /* lower-casing and upper-casing didn't result in - * an other filename, no need to stat(), + /* lower-casing and upper-casing didn't result in + * an other filename, no need to stat(), * just assume it is case-sensitive. */ s->force_lowercase_filenames = 0; - } else if (0 == stat(srv->tmp_buf->ptr, &st2)) { + } else if (0 == stat(srv->tmp_buf->ptr, &st2)) { + + /* upper case exists too, doesn't the FS handle this ? */ + + /* upper and lower have the same inode -> case-insensitve FS */ + + if (st1.st_ino == st2.st_ino) { + /* upper and lower have the same inode -> case-insensitve FS */ + + s->force_lowercase_filenames = 1; + } + } + } - /* upper case exists too, doesn't the FS handle this ? */ - - /* upper and lower have the same inode -> case-insensitve FS */ - - if (st1.st_ino == st2.st_ino) { - /* upper and lower have the same inode -> case-insensitve FS */ - - s->force_lowercase_filenames = 1; - } - } - } - if (srv->srvconf.port == 0) { srv->srvconf.port = s->is_ssl ? 443 : 80; } - + if (srv->srvconf.event_handler->used == 0) { /* choose a good default - * - * the event_handler list is sorted by 'goodness' + * + * the event_handler list is sorted by 'goodness' * taking the first available should be the best solution */ srv->event_handler = event_handlers[0].et; - + if (FDEVENT_HANDLER_UNSET == srv->event_handler) { - log_error_write(srv, __FILE__, __LINE__, "s", + log_error_write(srv, __FILE__, __LINE__, "s", "sorry, there is no event handler for this system"); - + return -1; } } else { /* * User override */ - + for (i = 0; event_handlers[i].name; i++) { if (0 == strcmp(event_handlers[i].name, srv->srvconf.event_handler->ptr)) { srv->event_handler = event_handlers[i].et; break; } } - + if (FDEVENT_HANDLER_UNSET == srv->event_handler) { - log_error_write(srv, __FILE__, __LINE__, "sb", - "the selected event-handler in unknown or not supported:", + log_error_write(srv, __FILE__, __LINE__, "sb", + "the selected event-handler in unknown or not supported:", srv->srvconf.event_handler ); - + return -1; } } @@ -1176,19 +1174,19 @@ if (s->is_ssl) { if (buffer_is_empty(s->ssl_pemfile)) { /* PEM file is require */ - - log_error_write(srv, __FILE__, __LINE__, "s", + + log_error_write(srv, __FILE__, __LINE__, "s", "ssl.pemfile has to be set"); return -1; } - + #ifndef USE_OPENSSL - log_error_write(srv, __FILE__, __LINE__, "s", + log_error_write(srv, __FILE__, __LINE__, "s", "ssl support is missing, recompile with --with-openssl"); - + return -1; #endif } - + return 0; } --- ../lighttpd-1.4.11/src/configfile.h 2005-08-23 17:36:12.000000000 +0300 +++ lighttpd-1.4.12/src/configfile.h 2006-07-16 00:26:03.000000000 +0300 @@ -9,7 +9,7 @@ server *srv; int ok; array *all_configs; - array *configs_stack; /* to parse nested block */ + buffer_ptr *configs_stack; /* to parse nested block */ data_config *current; /* current started with { */ buffer *basedir; } config_t; --- ../lighttpd-1.4.11/src/configparser.c 2006-02-01 19:51:15.000000000 +0200 +++ lighttpd-1.4.12/src/configparser.c 2006-07-17 22:02:23.000000000 +0300 @@ -24,52 +24,34 @@ dc->parent = ctx->current; array_insert_unique(dc->parent->childs, (data_unset *)dc); } - array_insert_unique(ctx->configs_stack, (data_unset *)ctx->current); + buffer_ptr_append(ctx->configs_stack, (void *)ctx->current); ctx->current = dc; } static data_config *configparser_pop(config_t *ctx) { data_config *old = ctx->current; - ctx->current = (data_config *) array_pop(ctx->configs_stack); + ctx->current = (data_config *) buffer_ptr_pop(ctx->configs_stack); return old; } /* return a copied variable */ static data_unset *configparser_get_variable(config_t *ctx, const buffer *key) { - if (strncmp(key->ptr, "env.", sizeof("env.") - 1) == 0) { - char *env; - - if (NULL != (env = getenv(key->ptr + 4))) { - data_string *ds; - ds = data_string_init(); - buffer_append_string(ds->value, env); - return (data_unset *)ds; - } - - fprintf(stderr, "Undefined env variable: %s\n", key->ptr + 4); - ctx->ok = 0; - - return NULL; - } else { - data_unset *du; - data_config *dc; + data_unset *du; + data_config *dc; #if 0 - fprintf(stderr, "get var %s\n", key->ptr); + fprintf(stderr, "get var %s\n", key->ptr); #endif - for (dc = ctx->current; dc; dc = dc->parent) { + for (dc = ctx->current; dc; dc = dc->parent) { #if 0 - fprintf(stderr, "get var on block: %s\n", dc->key->ptr); - array_print(dc->value, 0); + fprintf(stderr, "get var on block: %s\n", dc->key->ptr); + array_print(dc->value, 0); #endif - if (NULL != (du = array_get_element(dc->value, key->ptr))) { - return du->copy(du); - } + if (NULL != (du = array_get_element(dc->value, key->ptr))) { + return du->copy(du); } - fprintf(stderr, "Undefined config variable: %s\n", key->ptr); - ctx->ok = 0; - return NULL; } + return NULL; } /* op1 is to be eat/return by this function, op1->key is not cared @@ -124,14 +106,14 @@ } -#line 128 "configparser.c" +#line 110 "configparser.c" /* Next is all token values, in a form suitable for use by makeheaders. ** This section will be null unless lemon is run with the -m switch. */ -/* +/* ** These constants (all generated automatically by the parser generator) ** specify the various kinds of tokens (terminals) that the parser -** understands. +** understands. ** ** Each symbol here is a terminal symbol in the grammar. */ @@ -148,7 +130,7 @@ ** and nonterminals. "int" is used otherwise. ** YYNOCODE is a number of type YYCODETYPE which corresponds ** to no legal terminal or nonterminal number. This -** number is used to fill in empty slots of the hash +** number is used to fill in empty slots of the hash ** table. ** YYFALLBACK If defined, this indicates that one or more tokens ** have fall-back values which should be used if the @@ -157,7 +139,7 @@ ** and nonterminal numbers. "unsigned char" is ** used if there are fewer than 250 rules and ** states combined. "int" is used otherwise. -** configparserTOKENTYPE is the data type used for minor tokens given +** configparserTOKENTYPE is the data type used for minor tokens given ** directly to the parser from the tokenizer. ** YYMINORTYPE is the data type used for all minor tokens. ** This is typically a union of many types, one of @@ -192,8 +174,8 @@ #define configparserARG_PDECL ,config_t *ctx #define configparserARG_FETCH config_t *ctx = yypParser->ctx #define configparserARG_STORE yypParser->ctx = ctx -#define YYNSTATE 62 -#define YYNRULE 39 +#define YYNSTATE 63 +#define YYNRULE 40 #define YYERRORSYMBOL 26 #define YYERRSYMDT yy95 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) @@ -203,7 +185,7 @@ /* Next are that tables used to determine what action to take based on the ** current state and lookahead token. These tables are used to implement ** functions that take a state number and lookahead value and return an -** action integer. +** action integer. ** ** Suppose the action integer is N. Then the action is determined as ** follows @@ -228,7 +210,7 @@ ** If the index value yy_shift_ofst[S]+X is out of range or if the value ** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] ** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table -** and that yy_default[S] should be used instead. +** and that yy_default[S] should be used instead. ** ** The formula above is for computing the action when the lookahead is ** a terminal symbol. If the lookahead is a non-terminal (as occurs after @@ -248,67 +230,69 @@ ** yy_default[] Default action for each state. */ static YYACTIONTYPE yy_action[] = { - /* 0 */ 2, 3, 4, 5, 13, 14, 62, 15, 7, 44, - /* 10 */ 20, 86, 16, 45, 28, 48, 40, 10, 39, 25, - /* 20 */ 22, 49, 45, 8, 15, 102, 1, 20, 28, 18, - /* 30 */ 57, 59, 19, 25, 22, 39, 19, 61, 98, 45, - /* 40 */ 20, 6, 23, 24, 26, 28, 35, 57, 59, 12, - /* 50 */ 25, 22, 28, 27, 36, 87, 29, 25, 22, 33, - /* 60 */ 15, 30, 31, 20, 28, 38, 9, 17, 37, 25, - /* 70 */ 22, 39, 42, 43, 10, 45, 11, 53, 54, 55, - /* 80 */ 56, 28, 52, 57, 59, 34, 25, 22, 28, 27, - /* 90 */ 32, 88, 41, 25, 22, 33, 28, 48, 46, 28, - /* 100 */ 48, 25, 22, 58, 25, 22, 60, 21, 19, 47, - /* 110 */ 51, 50, 25, 22, 88, 88, 93, + /* 0 */ 2, 3, 4, 5, 13, 14, 63, 15, 7, 45, + /* 10 */ 20, 88, 16, 46, 28, 49, 41, 10, 40, 25, + /* 20 */ 22, 50, 46, 8, 15, 104, 1, 20, 28, 18, + /* 30 */ 58, 60, 6, 25, 22, 40, 47, 62, 11, 46, + /* 40 */ 20, 9, 23, 24, 26, 29, 89, 58, 60, 10, + /* 50 */ 17, 38, 28, 27, 37, 19, 30, 25, 22, 34, + /* 60 */ 15, 100, 20, 20, 23, 24, 26, 12, 19, 31, + /* 70 */ 32, 40, 19, 44, 43, 46, 95, 35, 90, 89, + /* 80 */ 28, 49, 42, 58, 60, 25, 22, 59, 28, 27, + /* 90 */ 33, 48, 52, 25, 22, 34, 28, 49, 51, 28, + /* 100 */ 36, 25, 22, 61, 25, 22, 89, 28, 39, 89, + /* 110 */ 89, 89, 25, 22, 54, 55, 56, 57, 89, 28, + /* 120 */ 53, 21, 89, 89, 25, 22, 25, 22, }; static YYCODETYPE yy_lookahead[] = { /* 0 */ 29, 30, 31, 32, 33, 34, 0, 1, 44, 38, /* 10 */ 4, 15, 41, 16, 35, 36, 45, 46, 12, 40, /* 20 */ 41, 42, 16, 15, 1, 27, 28, 4, 35, 36, - /* 30 */ 24, 25, 5, 40, 41, 12, 5, 14, 11, 16, - /* 40 */ 4, 1, 6, 7, 8, 35, 36, 24, 25, 28, - /* 50 */ 40, 41, 35, 36, 37, 15, 39, 40, 41, 42, - /* 60 */ 1, 9, 10, 4, 35, 36, 38, 2, 3, 40, - /* 70 */ 41, 12, 28, 14, 46, 16, 13, 20, 21, 22, - /* 80 */ 23, 35, 36, 24, 25, 11, 40, 41, 35, 36, - /* 90 */ 37, 13, 13, 40, 41, 42, 35, 36, 17, 35, - /* 100 */ 36, 40, 41, 42, 40, 41, 42, 35, 5, 18, - /* 110 */ 43, 19, 40, 41, 47, 47, 13, + /* 30 */ 24, 25, 1, 40, 41, 12, 17, 14, 13, 16, + /* 40 */ 4, 38, 6, 7, 8, 9, 15, 24, 25, 46, + /* 50 */ 2, 3, 35, 36, 37, 5, 39, 40, 41, 42, + /* 60 */ 1, 11, 4, 4, 6, 7, 8, 28, 5, 9, + /* 70 */ 10, 12, 5, 14, 28, 16, 13, 11, 13, 47, + /* 80 */ 35, 36, 13, 24, 25, 40, 41, 42, 35, 36, + /* 90 */ 37, 18, 43, 40, 41, 42, 35, 36, 19, 35, + /* 100 */ 36, 40, 41, 42, 40, 41, 47, 35, 36, 47, + /* 110 */ 47, 47, 40, 41, 20, 21, 22, 23, 47, 35, + /* 120 */ 36, 35, 47, 47, 40, 41, 40, 41, }; #define YY_SHIFT_USE_DFLT (-5) static signed char yy_shift_ofst[] = { - /* 0 */ -5, 6, -5, -5, -5, 40, -4, 8, -3, -5, - /* 10 */ 63, -5, 23, -5, -5, -5, 65, 36, 31, 36, - /* 20 */ -5, -5, -5, -5, -5, -5, 36, 27, -5, 52, - /* 30 */ -5, 36, -5, 74, 36, 31, -5, 36, 31, 78, - /* 40 */ 79, -5, 59, -5, -5, 81, 91, 36, 31, 92, - /* 50 */ 57, 36, 103, -5, -5, -5, -5, 36, -5, 36, - /* 60 */ -5, -5, + /* 0 */ -5, 6, -5, -5, -5, 31, -4, 8, -3, -5, + /* 10 */ 25, -5, 23, -5, -5, -5, 48, 58, 67, 58, + /* 20 */ -5, -5, -5, -5, -5, -5, 36, 50, -5, -5, + /* 30 */ 60, -5, 58, -5, 66, 58, 67, -5, 58, 67, + /* 40 */ 65, 69, -5, 59, -5, -5, 19, 73, 58, 67, + /* 50 */ 79, 94, 58, 63, -5, -5, -5, -5, 58, -5, + /* 60 */ 58, -5, -5, }; #define YY_REDUCE_USE_DFLT (-37) static signed char yy_reduce_ofst[] = { - /* 0 */ -2, -29, -37, -37, -37, -36, -37, -37, 28, -37, - /* 10 */ -37, 21, -29, -37, -37, -37, -37, -7, -37, 72, + /* 0 */ -2, -29, -37, -37, -37, -36, -37, -37, 3, -37, + /* 10 */ -37, 39, -29, -37, -37, -37, -37, -7, -37, 86, /* 20 */ -37, -37, -37, -37, -37, -37, 17, -37, -37, -37, - /* 30 */ -37, 53, -37, -37, 10, -37, -37, 29, -37, -37, - /* 40 */ -37, 44, -29, -37, -37, -37, -37, -21, -37, -37, - /* 50 */ 67, 46, -37, -37, -37, -37, -37, 61, -37, 64, - /* 60 */ -37, -37, + /* 30 */ -37, -37, 53, -37, -37, 64, -37, -37, 72, -37, + /* 40 */ -37, -37, 46, -29, -37, -37, -37, -37, -21, -37, + /* 50 */ -37, 49, 84, -37, -37, -37, -37, -37, 45, -37, + /* 60 */ 61, -37, -37, }; static YYACTIONTYPE yy_default[] = { - /* 0 */ 64, 101, 63, 65, 66, 101, 67, 101, 101, 90, - /* 10 */ 101, 64, 101, 68, 69, 70, 101, 101, 71, 101, - /* 20 */ 73, 74, 76, 77, 78, 79, 101, 84, 75, 101, - /* 30 */ 80, 82, 81, 101, 101, 85, 83, 101, 72, 101, - /* 40 */ 101, 64, 101, 89, 91, 101, 101, 101, 98, 101, - /* 50 */ 101, 101, 101, 94, 95, 96, 97, 101, 99, 101, - /* 60 */ 100, 92, + /* 0 */ 65, 103, 64, 66, 67, 103, 68, 103, 103, 92, + /* 10 */ 103, 65, 103, 69, 70, 71, 103, 103, 72, 103, + /* 20 */ 74, 75, 77, 78, 79, 80, 103, 86, 76, 81, + /* 30 */ 103, 82, 84, 83, 103, 103, 87, 85, 103, 73, + /* 40 */ 103, 103, 65, 103, 91, 93, 103, 103, 103, 100, + /* 50 */ 103, 103, 103, 103, 96, 97, 98, 99, 103, 101, + /* 60 */ 103, 102, 94, }; #define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0])) /* The next table maps tokens into fallback tokens. If a construct ** like the following: -** +** ** %fallback ID X Y Z. ** ** appears in the grammer, then ID becomes a fallback token for X, Y, @@ -359,10 +343,10 @@ #endif /* NDEBUG */ #ifndef NDEBUG -/* +/* ** Turn parser tracing on by giving a stream to which to write the trace ** and a prompt to preface each trace message. Tracing is turned off -** by making either argument NULL +** by making either argument NULL ** ** Inputs: **