]> git.pld-linux.org Git - packages/syslog-ng.git/commitdiff
- up from git
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Thu, 19 Feb 2009 20:08:58 +0000 (20:08 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    syslog-ng-fixes.patch -> 1.5

syslog-ng-fixes.patch

index 819c3e4841af23f433bced7394ddf4e71d5a6fa8..e5ab1fadd662a02ffcf05b551a92d232b531c566 100644 (file)
---- syslog-ng-3.0.1/src/misc.c~        2008-11-05 20:57:42.000000000 +0100
-+++ syslog-ng-3.0.1/src/misc.c 2009-01-16 11:43:30.896633603 +0100
-@@ -274,7 +274,7 @@
-   struct passwd *pw;
+diff --git a/configure.in b/configure.in
+index d5f0769..1605bff 100644
+--- a/configure.in
++++ b/configure.in
+@@ -49,10 +49,8 @@ fi
  
-   *uid = 0;
--  if (*user)
-+  if (!*user)
-     return FALSE;
+ if test "x$prefix" = "xNONE"; then
+         prefix=$ac_default_prefix
+-        pidfiledir="/var/run"
+-else
+-        pidfiledir="${prefix}/var/run"
+ fi
++pidfiledir="${localstatedir}"
+ AM_CONFIG_HEADER(config.h)
+@@ -70,7 +68,7 @@ AC_ARG_WITH(pidfile-dir,
+       
+ AC_ARG_WITH(timezone-dir,
+    [  --with-timezone-dir=path   Use path as the directory to get the timezone files],
+-   timezone_dir=$with_timezone_dir)
++   timezonedir=$with_timezone_dir)
+ AC_ARG_WITH(ld-library-path,
+    [  --with-ld-library-path=path  Set LD_LIBRARY_PATH during runtime to the value given],
+@@ -92,10 +90,13 @@ AC_ARG_ENABLE(ssl,
+               [  --enable-ssl        Enable SSL support.],,enable_ssl="auto")
+ AC_ARG_ENABLE(dynamic-linking,
+-              [  --enable-dynamic-linking        Link glib and eventlog dynamically instead of statically.])
++              [  --enable-dynamic-linking        Link glib and eventlog dynamically instead of statically.],,enable_dynamic_linking="auto")
+ AC_ARG_ENABLE(static-linking,
+-              [  --enable-static-linking         Link everything statically.])
++              [  --enable-static-linking         Link everything statically.],,enable_static_linking="auto")
++
++AC_ARG_ENABLE(mixed-linking,
++              [  --enable-mixed-linking          Link 3rd party libraries statically, system libraries dynamically],,enable_mixed_linking="auto")
+ AC_ARG_ENABLE(ipv6,
+               [  --enable-ipv6           Enable support for IPv6.],,enable_ipv6="auto")
+@@ -319,9 +320,6 @@ dnl ***************************************************************************
+ dnl OpenSSL headers/libraries
+ dnl ***************************************************************************
+-OPENSSL_LIBS=""
+-OPENSSL_CPPFLAGS=""
+-
+ # openssl is needed for:
+ #  * TLS support
+@@ -360,7 +358,13 @@ dnl libdbi headers/libraries
+ dnl ***************************************************************************
+ AC_CHECK_LIB(dl, dlsym, DL_LIBS="-ldl")
+-PKG_CHECK_MODULES(LIBDBI, dbi >= $LIBDBI_MIN_VERSION,, LIBDBI_LIBS="")
++PKG_CHECK_MODULES(LIBDBI, dbi >= $LIBDBI_MIN_VERSION,, libdbi_pkgconfig_not_found="1")
++
++if test "$libdbi_pkgconfig_not_found" -eq 1; then
++      dnl if libdbi has no .pc file, try it without one
++      AC_CHECK_LIB(dbi, dbi_initialize, LIBDBI_LIBS="-ldbi"; LIBDBI_CFLAGS="-I/usr/include")
++fi
++
+ dnl ***************************************************************************
+ dnl Some more checks based on the detected settings above
+@@ -606,8 +610,42 @@ int main()
+       fi
+ fi
+-if test "x$enable_dynamic_linking" = "xyes" -a "x$enable_static_linking" = "xyes"; then
+-      AC_MSG_ERROR([You cannot specify dynamic and static linking at the same time.])
++if test "$enable_dynamic_linking" = "auto" -a "$enable_static_linking" = "auto" -a "$enable_mixed_linking" = "auto"; then
++      enable_dynamic_linking="yes"
++      enable_static_linking="no"
++      enable_mixed_linking="no"
++fi
++
++linkopts=0
++if test "x$enable_dynamic_linking" = "xyes"; then
++       linkopts=`expr $linkopts + 1`
++fi
++if test "x$enable_static_linking" = "xyes"; then
++       linkopts=`expr $linkopts + 1`
++fi
++if test "x$enable_mixed_linking" = "xyes"; then
++       linkopts=`expr $linkopts + 1`
++fi
++
++if test "$linkopts" -gt 1; then
++       AC_MSG_ERROR([You cannot specify multiple linking options at the same time (--enable-dynamic-linking, --enable-static-linking, --enable-mixed-linking).])
++fi
++
++if test "x$enable_dynamic_linking" = "xyes"; then
++      enable_dynamic_linking="yes"
++      enable_static_linking="no"
++      enable_mixed_linking="no"
++      linking_mode="dynamic"
++elif test "x$enable_static_linking" = "xyes"; then
++      enable_dynamic_linking="no"
++      enable_static_linking="yes"
++      enable_mixed_linking="no"
++      linking_mode="static"
++elif test "x$enable_mixed_linking" = "xyes"; then
++      enable_dynamic_linking="no"
++      enable_static_linking="no"
++      enable_mixed_linking="yes"
++      linking_mode="mixed"
+ fi
+ if test "x$enable_dynamic_linking" != "xyes" -a "x$blb_cv_static_glib" = "xno"; then
+@@ -615,7 +653,7 @@ if test "x$enable_dynamic_linking" != "xyes" -a "x$blb_cv_static_glib" = "xno";
+ fi
+ if test "x$enable_dynamic_linking" != "xyes" -a "x$blb_cv_static_openssl" = "xno"; then
+-      AC_MSG_ERROR([static OpenSSL libraries not found (libssl.a and libcrypto.a), either link OpenSSL statically using the --enable-dynamic-linking, or install a static OpenSSL])
++      AC_MSG_ERROR([static OpenSSL libraries not found (libssl.a, libcrypto.a and their external dependencies like libz.a), either link OpenSSL statically using the --enable-dynamic-linking, or install a static OpenSSL])
+ fi
+@@ -672,8 +710,8 @@ AC_DEFINE_UNQUOTED(PATH_PREFIX, "`patheval $prefix`", [prefix directory])
+ AC_DEFINE_UNQUOTED(PATH_SYSCONFDIR, "`patheval $sysconfdir`", [sysconfdir])
+ AC_DEFINE_UNQUOTED(PATH_LOCALSTATEDIR, "`patheval $localstatedir`", [local state directory])
+ AC_DEFINE_UNQUOTED(PATH_PIDFILEDIR, "`patheval $pidfiledir`", [local state directory])
+-if test -n "$timezone_dir"; then
+-        AC_DEFINE_UNQUOTED(PATH_TIMEZONEDIR, "`patheval $timezone_dir`", [timezone base directory])
++if test -n "$timezonedir"; then
++        AC_DEFINE_UNQUOTED(PATH_TIMEZONEDIR, "`patheval $timezonedir`", [timezone base directory])
+ fi
+ if test -n "$env_ld_library_path"; then
+         AC_DEFINE_UNQUOTED(ENV_LD_LIBRARY_PATH, "$env_ld_library_path", [set LD_LIBRARY_PATH to this value])
+@@ -695,6 +733,8 @@ AC_DEFINE_UNQUOTED(ENABLE_ENV_WRAPPER, `enable_value $enable_env_wrapper`, [Enab
+ AM_CONDITIONAL(ENABLE_ENV_WRAPPER, [test "$enable_env_wrapper" = "yes"])
++AC_SUBST(timezonedir)
++AC_SUBST(pidfiledir)
+ AC_SUBST(DEPS_CPPFLAGS)
+ AC_SUBST(DEPS_LIBS)
+ AC_SUBST(BASE_LIBS)
+@@ -729,6 +769,7 @@ echo "  compiler                    : $CC"
+ echo "  compiler options            : $CFLAGS $CPPFLAGS"
+ echo "  linker flags                : $LDFLAGS $LIBS"
+ echo "  prefix                      : $prefix"
++echo "  linking mode                : $linking_mode"
+ echo " Features:"
+ echo "  Sun STREAMS support         : ${enable_sun_streams:=no}"
+ echo "  Sun Door support            : ${enable_sun_door:=no}"
+diff --git a/contrib/balabit-initscripts/init-functions b/contrib/balabit-initscripts/init-functions
+index e1898a8..c3b18ef 100644
+--- a/contrib/balabit-initscripts/init-functions
++++ b/contrib/balabit-initscripts/init-functions
+@@ -6,12 +6,35 @@ NORMAL=
+ FANCYTTY=
+ PSOPTS=
+-case `uname -s` in
++ECHO=echo
++
++OS=`uname -s`
++
++disable_xpg_echo() {
++  # \X chars only passed to echo under bash, if xpg_echo enabled or echo -e
++  # used on Linux.
++  if [ -n "$BASH_VERSION" ];then
++    shopt -s xpg_echo
++  fi
++}
++
++case $OS in
+   # default ps -e cuts the process' name at 8 characters, so we have to list it
+   # in a long form
+-  SunOS) PSOPTS=" -o pid -o tty -o time -o comm" ;;
++  SunOS)
++        PSOPTS=" -o pid -o tty -o time -o comm"
++        disable_xpg_echo
++        ;;
++  Linux)
++        if [ -z "$BASH_VERSION" ]; then
++          # beware of dash's builtin echo ...
++          ECHO="/bin/echo -e"
++        fi
++        ;;
++  *)    disable_xpg_echo ;;
+ esac
++
+ _checkpid() {
+   _pid=$1
+   _proc=$2
+@@ -30,7 +53,7 @@ _pid_from_pidfile() {
+   pid=
+   if [ -f "$pidfile" ];then
+-    pid=`head -1 $pidfile`
++    pid=`head -1 $pidfile 2> /dev/null`
+     if [ $? -ne 0 ]; then
+       # on slow machines (or ones under high load) the pidfile could be
+       # erased between -f and `head` ...
+@@ -195,17 +218,17 @@ log_use_fancy_output() {
+ log_success_msg() {
+-  echo "$@"
++  $ECHO "$@"
+ }
+ log_failure_msg() {
+   log_use_fancy_output
+-  echo "${RED}$@${NORMAL}"   
++  $ECHO "${RED}$@${NORMAL}"
+ }
+ log_warning_msg() {
+   log_use_fancy_output
+-  echo "${YELLOW}$@${NORMAL}"   
++  $ECHO "${YELLOW}$@${NORMAL}"
+ }
+ # NON-LSB Functions
+@@ -215,7 +238,7 @@ log_begin_msg() {
+     return 1
+   fi
+-  echo "$@\c " 
++  $ECHO "$@\c "
+ }
+ log_daemon_msg() {
+@@ -224,11 +247,11 @@ log_daemon_msg() {
+   fi
+   if [ -z "$2" ]; then
+-    echo "$1:\c "
++    $ECHO "$1:\c "
+     return
+   fi
+-  echo "$1: $2\c "
++  $ECHO "$1: $2\c "
+ }
+ log_progress_msg() {
+@@ -237,9 +260,9 @@ log_progress_msg() {
+   fi
+   if [ $1 -eq 0 ]; then
+-    echo "."
++    $ECHO "."
+   else
+-    echo " failed"
++    $ECHO " failed"
+   fi
+ }
+@@ -250,23 +273,23 @@ log_end_msg() {
+   log_fancy_output
+   if [ $1 -eq 0 ];then
+-    echo "."
++    $ECHO "."
+   else
+-    echo "${RED}failed!${NORMAL}"
++    $ECHO "${RED}failed!${NORMAL}"
+   fi
+   return $1
+ }
+ log_action_msg() {
+-  echo "$@."
++  $ECHO "$@."
+ }
+ log_action_begin_msg() {
+-  echo "$@...\c "
++  $ECHO "$@...\c "
+ }
+ log_action_cont_msg() {
+-  echo "$@...\c "
++  $ECHO "$@...\c "
+ }
+ log_action_end_msg() {
+@@ -278,15 +301,12 @@ log_action_end_msg() {
+   log_fancy_output
+   if [ $1 -eq 0 ]; then
+-    echo "done${end}"
++    $ECHO "done${end}"
+   else
+-    echo "${RED}failed${end}${NORMAL}"
++    $ECHO "${RED}failed${end}${NORMAL}"
+   fi
+ }
+-# \X chars only passed to echo under bash, if xpg_echo enabled....
+-if [ -n "$BASH_VERSION" ];then
+-  shopt -s xpg_echo
+-fi
+ # vim: ft=sh ts=2 expandtab
++
+diff --git a/contrib/balabit-initscripts/init.d b/contrib/balabit-initscripts/init.d
+index ff2e249..589da86 100644
+--- a/contrib/balabit-initscripts/init.d
++++ b/contrib/balabit-initscripts/init.d
+@@ -25,6 +25,7 @@ SYSLOGNG_PREFIX=/opt/syslog-ng
+ SYSLOGNG="$SYSLOGNG_PREFIX/sbin/syslog-ng"
+ CONFFILE=$SYSLOGNG_PREFIX/etc/syslog-ng.conf
+ PIDFILE=$SYSLOGNG_PREFIX/var/run/syslog-ng.pid
++SYSLOGPIDFILE="/var/run/syslog.pid"
+ INIT_FUNCTIONS=/lib/lsb/init-functions
+ SLNG_INIT_FUNCTIONS=$SYSLOGNG_PREFIX/lib/init-functions
+@@ -64,6 +65,17 @@ if [ -f /etc/lsb-release ]; then
+       . /etc/lsb-release
+ fi
++if [ -f "/etc/redhat-release" ];then
++      # redhat uses a different syslogd pidfile...
++      SYSLOGPIDFILE="/var/run/syslogd.pid"
++fi
++
++if [ "$OS" = "SunOS" ] || [ "$OS" = "Solaris" ];then
++      if [ "`uname -r`" = "5.8" ];then
++              SYSLOGPIDFILE="/etc/syslog.pid"
++      fi
++fi
++
+ if [ -f /lib/lsb/init-functions ];then
+       # long list of exclusions... 
+       if [ -f "/etc/redhat-release" ] || [ -f "/etc/SuSE-release" ];then
+@@ -117,7 +129,7 @@ check_syntax() {
+ slng_waitforpid() {
+       _pid=$1
+-  _process=$2
++      _process=$2
+       _cnt=$MAXWAIT
+       # no pid, return...
+@@ -147,6 +159,11 @@ returnmessage() {
+ syslogng_start() {
+       echo_n "Starting syslog-ng: "
++      PID=`pidofproc -p ${PIDFILE} ${SYSLOGNG} | head -1`
++      if [ -n "$PID" ] && [ $PID -gt 0 ] ;then
++              log_success_msg "already running: $PID"
++              return $retval
++      fi
+       start_daemon -p ${PIDFILE} ${SYSLOGNG} ${SYSLOGNG_OPTIONS}
+       retval=$?
+       returnmessage $retval
+@@ -154,6 +171,13 @@ syslogng_start() {
+               if [ "$OS" = "Linux" ] && [ -d $SUBSYSDIR ];then
+                       touch $SUBSYSDIR/syslog-ng
+               fi
++              # remove symlinks
++              if [ -h $SYSLOGPIDFILE ];then
++                      rm -f $SYSLOGPIDFILE
++              fi
++              if [ ! -f $SYSLOGPIDFILE ];then
++                      ln -s $PIDFILE $SYSLOGPIDFILE
++              fi
+       fi
+       return $retval
+ }
+@@ -180,6 +204,9 @@ syslogng_stop() {
+       fi
+       if [ $retval -eq 0 ];then
+               rm -f $SUBSYSDIR/syslog-ng ${PIDFILE}
++              if [ -h $SYSLOGPIDFILE ];then
++                      rm -f $SYSLOGPIDFILE
++              fi
+       fi
+       return $retval
+ }
+@@ -270,6 +297,14 @@ case "$1" in
+       force-reload)
+               syslogng_restart
+               ;;
++      reload-or-restart)
++              PID=`pidofproc -p ${PIDFILE} ${SYSLOGNG} | head -1`
++              if [ -n "$PID" ] && [ $PID -gt 0 ] ;then
++                      syslogng_reload
++              else
++                      syslogng_start
++              fi
++              ;;
+       status)
+               syslogng_status 
+               ;;
+@@ -284,4 +319,4 @@ esac
+ exit $retval
+-# vim: ts=2 ft=sh
++# vim: ts=2 ft=sh noexpandtab
+diff --git a/contrib/balabit-initscripts/init.d.freebsd b/contrib/balabit-initscripts/init.d.freebsd
+index 997b4db..de04473 100644
+--- a/contrib/balabit-initscripts/init.d.freebsd
++++ b/contrib/balabit-initscripts/init.d.freebsd
+@@ -33,9 +33,13 @@ command="$SYSLOGNG_PREFIX/sbin/syslog-ng"
+ required_files="$SYSLOGNG_PREFIX/etc/syslog-ng.conf"
+ start_precmd="syslog_ng_start_precmd"
++start_postcmd="syslog_ng_start_postcmd"
++stop_postcmd="syslog_ng_stop_postcmd"
+ reload_precmd="syslog_ng_reload_precmd"
+ extra_commands="reload"
++# get original syslog pidfile from initscript.
++_syslogd_pidfile=`sed -n -e 's/^pidfile="\([^"]*\)"/\1/p' /etc/rc.d/syslogd 2> /dev/null`
+ syslog_ng_start_precmd() {
+       if [ ! -L /dev/log ]; then
+               ln -s /var/run/log /dev/log
+@@ -50,6 +54,26 @@ syslog_ng_reload_precmd() {
+       fi
+ }
++syslog_ng_start_postcmd() {
++      if [ -n "$_syslogd_pidfile" ]; then
++              # remove symlinks
++              if [ -h $_syslogd_pidfile ]; then
++                      rm -f $_syslogd_pidfile
++              fi
++              if [ ! -f $_syslogd_pidfile ]; then
++                      ln -s "$pidfile" "$_syslogd_pidfile"
++              fi
++      fi
++}
++
++syslog_ng_stop_postcmd() {
++      if [ -n "$_syslogd_pidfile" ]; then
++              if [ -h $_syslogd_pidfile ]; then
++                      rm -f "$_syslogd_pidfile"
++              fi
++      fi
++}
++
+ load_rc_config "$name"
+ case $1 in
+diff --git a/contrib/cygwin-packaging/cygwin-postinstall b/contrib/cygwin-packaging/cygwin-postinstall
+index 4b7bf7d..e812ead 100755
+--- a/contrib/cygwin-packaging/cygwin-postinstall
++++ b/contrib/cygwin-packaging/cygwin-postinstall
+@@ -21,11 +21,11 @@ then
+   exit 3
+ fi
+ mkdir -p "${DESTDIR}/usr/bin"
+-mkdir -p "${DESTDIR}/usr/share/doc/syslog-ng"
++#mkdir -p "${DESTDIR}/usr/share/doc/syslog-ng"
+ mkdir -p "${DESTDIR}/usr/share/doc/Cygwin"
+ cp contrib/cygwin-packaging/syslog-ng-config "${DESTDIR}/usr/bin"
+-cp -rp doc/examples/syslog-ng.conf.s* doc/reference/syslog-ng.[tx]* "${DESTDIR}/usr/share/doc/syslog-ng"
+-tar xzfC doc/reference/syslog-ng.html.tar.gz "${DESTDIR}/usr/share/doc/syslog-ng"
++#cp -rp doc/examples/syslog-ng.conf.s* doc/reference/syslog-ng.[tx]* "${DESTDIR}/usr/share/doc/syslog-ng"
++#tar xzfC doc/reference/syslog-ng.html.tar.gz "${DESTDIR}/usr/share/doc/syslog-ng"
+ cat > "${DESTDIR}/usr/share/doc/Cygwin/syslog-ng.README" <<'EOF'
+ If you want to use syslog-ng, just run the /usr/bin/syslog-ng-config
+ script.  This script will create a default configuration file
+@@ -42,15 +42,15 @@ The syslog-ng package has been built using the following command
+ sequence from the top level source dir:
+ ./configure \
+-       --disable-ipv6 \
+-       --disable-tcp-wrapper \
+         --prefix=/usr \
+         --sysconfdir=/etc \
+         --libexecdir='$(prefix)/sbin' \
+         --localstatedir=/var \
+         --datadir='$(prefix)/share' \
+         --mandir='$(prefix)/share/man' \
+-        --infodir='$(prefix)/share/info'
++        --infodir='$(prefix)/share/info' \
++      --enable-dynamic-linking \
++      --with-pidfile-dir=/var
+ make
+ make install-strip
+ contrib/cygwin-packaging/cygwin-postinstall
+diff --git a/contrib/cygwin-packaging/syslog-ng-config b/contrib/cygwin-packaging/syslog-ng-config
+index 790f0cc..7ae5fec 100755
+--- a/contrib/cygwin-packaging/syslog-ng-config
++++ b/contrib/cygwin-packaging/syslog-ng-config
+@@ -205,13 +205,13 @@ if [ ! -f "${SYSCONFDIR}/syslog-ng.conf" ]
+ then
+   echo "Creating default ${SYSCONFDIR}/syslog-ng.conf file"
+   cat > ${SYSCONFDIR}/syslog-ng.conf << EOF
++@version 3.0
+ options {
+   keep_hostname(yes);
+-  chain_hostnames(no);
+   owner("system");
+   group("root");
+   perm(0664);
+-  sync(0);
++  flush_lines(0);
+ };
+ source applications {
+@@ -220,7 +220,7 @@ source applications {
+ };
+ source kernel {
+-  file("/dev/kmsg", log_prefix("kernel: "));
++  file("/dev/kmsg", program_override("kernel: "));
+ };
+ destination messages {
+@@ -240,42 +240,35 @@ EOF
+ fi
+ setfacl -m u:system:rw- "${SYSCONFDIR}/syslog-ng.conf"
+-# Check if running on NT
+-_sys="`uname`"
+-_nt=`expr "${_sys}" : "CYGWIN_NT"`
+-# On NT ask if syslog-ng should be installed as service
+-if [ ${_nt} -gt 0 ]
++# Check if syslogd is installed and remove on user request.
++if cygrunsrv -Q syslogd > /dev/null 2>&1
+ then
+-  # Check if syslogd is installed and remove on user request.
+-  if cygrunsrv -Q syslogd > /dev/null 2>&1
++  echo "Warning: The syslogd service is already installed.  You can not"
++  echo "run both, syslogd and syslog-ng in parallel."
++  echo
++  if request "Do you want to deinstall the syslogd service in favor of syslog-ng?"
+   then
+-    echo "Warning: The syslogd service is already installed.  You can not"
+-    echo "run both, syslogd and syslog-ng in parallel."
+-    echo
+-    if request "Do you want to deinstall the syslogd service in favor of syslog-ng?"
+-    then
+-      cygrunsrv -E syslogd
+-      cygrunsrv -R syslogd
+-    fi
++    cygrunsrv -E syslogd
++    cygrunsrv -R syslogd
+   fi
+-  # Install syslog-ng service if it is not already installed
+-  if ! cygrunsrv -Q syslog-ng > /dev/null 2>&1
++fi
++# Install syslog-ng service if it is not already installed
++if ! cygrunsrv -Q syslog-ng > /dev/null 2>&1
++then
++  echo
++  echo
++  echo "Warning: The following function requires administrator privileges!"
++  echo
++  echo "Do you want to install syslog-ng as service?"
++  if request "(Say \"no\" if it's already installed as service)"
+   then
+-    echo
+-    echo
+-    echo "Warning: The following function requires administrator privileges!"
+-    echo
+-    echo "Do you want to install syslog-ng as service?"
+-    if request "(Say \"no\" if it's already installed as service)"
++    if cygrunsrv -I syslog-ng -d "CYGWIN syslog-ng" -p /usr/sbin/syslog-ng -a "-F --fd-limit 256"
+     then
+-      if cygrunsrv -I syslog-ng -d "CYGWIN syslog-ng" -p /usr/sbin/syslog-ng -a -F
+-      then
+-       echo
+-       echo "The service has been installed under LocalSystem account."
+-       echo "To start the service, call \`net start syslog-ng' or \`cygrunsrv -S syslog-ng'."
+-       echo
+-       echo "Check ${SYSCONFDIR}/syslog-ng.conf first, if it suits your needs."
+-      fi
++     echo
++     echo "The service has been installed under LocalSystem account."
++     echo "To start the service, call \`net start syslog-ng' or \`cygrunsrv -S syslog-ng'."
++     echo
++     echo "Check ${SYSCONFDIR}/syslog-ng.conf first, if it suits your needs."
+     fi
+   fi
+ fi
+diff --git a/contrib/solaris-packaging/syslog-ng.method b/contrib/solaris-packaging/syslog-ng.method
+index f0fee58..d819a3c 100755
+--- a/contrib/solaris-packaging/syslog-ng.method
++++ b/contrib/solaris-packaging/syslog-ng.method
+@@ -13,6 +13,7 @@ SYSLOGNG_PREFIX=/opt/syslog-ng
+ SYSLOGNG="$SYSLOGNG_PREFIX/sbin/syslog-ng"
+ CONFFILE=$SYSLOGNG_PREFIX/etc/syslog-ng.conf
+ PIDFILE=$SYSLOGNG_PREFIX/var/run/syslog-ng.pid
++SYSLOGPIDFILE=/var/run/syslog.pid
+ OPTIONS=
+ MAXWAIT=30
+@@ -56,7 +57,7 @@ slng_stop() {
+         _process=`basename $SYSLOGNG`
+         slng_waitforpid "$_process" $syspid
+-      _ret=$?
++        _ret=$?
+         if [ $_ret -eq 0 ]; then
+                 kill -KILL $syspid
+                 $_ret=$?
+@@ -68,6 +69,9 @@ slng_stop() {
+                         [ $? -ne 0 ] && exit $SMF_EXIT_ERR_FATAL
+                 fi
+                 rm -f $PIDFILE
++                if [ -h $SYSLOGPIDFILE ];then
++                        rm -f $SYSLOGPIDFILE
++                fi
+                 return $SMF_EXIT_OK
+         fi
+         return $SMF_EXIT_ERR_FATAL
+@@ -93,6 +97,13 @@ slng_start () {
+                 fi
+                 check_syntax
+                 $SYSLOGNG $OPTIONS
++                # remove symlinks
++                if [ -h $SYSLOGPIDFILE ];then
++                        rm -f $SYSLOGPIDFILE
++                fi
++                if [ ! -f $SYSLOGPIDFILE ];then
++                        ln -s $PIDFILE $SYSLOGPIDFILE
++                fi
+                 return $SMF_EXIT_OK
+         fi
+         return $SMF_EXIT_ERR_FATAL
+diff --git a/src/affile.c b/src/affile.c
+index 6d48915..5721a1a 100644
+--- a/src/affile.c
++++ b/src/affile.c
+@@ -40,11 +40,12 @@
+ static gboolean
+ affile_open_file(gchar *name, gint flags,
+-           uid_t uid, gid_t gid, mode_t mode,
+-           uid_t dir_uid, gid_t dir_gid, mode_t dir_mode,
+-           gboolean create_dirs, gboolean privileged, gint *fd)
++                 uid_t uid, gid_t gid, mode_t mode,
++                 uid_t dir_uid, gid_t dir_gid, mode_t dir_mode,
++                 gboolean create_dirs, gboolean privileged, gboolean is_pipe, gint *fd)
+ {
+   cap_t saved_caps;
++  struct stat st;
+   if (strstr(name, "../") || strstr(name, "/..")) 
+     {
+@@ -63,20 +64,43 @@ affile_open_file(gchar *name, gint flags,
+       g_process_cap_modify(CAP_DAC_READ_SEARCH, TRUE);
+       g_process_cap_modify(CAP_SYS_ADMIN, TRUE);
+     }
++  if (stat(name, &st) >= 0)
++    {
++      if (is_pipe && !S_ISFIFO(st.st_mode))
++        {
++          msg_error("Error opening pipe, underlying file is not a FIFO, it should be used by file()",
++                    evt_tag_str("filename", name),
++                    NULL);
++          goto exit;
++        }
++      else if (!is_pipe && S_ISFIFO(st.st_mode))
++        {
++          msg_error("Error opening file, underlying file is a FIFO, it should be used by pipe()",
++                    evt_tag_str("filename", name),
++                    NULL);
++          goto exit;
++        }
++    }
+   *fd = open(name, flags, mode);
++  if (is_pipe && *fd < 0 && errno == ENOENT)
++    {
++      if (mkfifo(name, 0666) >= 0)
++        *fd = open(name, flags, 0666);
++    }
+   if (*fd != -1)
+     {
+       g_fd_set_cloexec(*fd, TRUE);
+       
+       g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);
+-      if (uid != -1)
++      if (uid != (uid_t) -1)
+         fchown(*fd, uid, -1);
+-      if (gid != -1)
++      if (gid != (gid_t) -1)
+         fchown(*fd, -1, gid);
+-      if (mode != -1)
++      if (mode != (mode_t) -1)
+         fchmod(*fd, mode);
+     }
++ exit:
+   if (privileged)
+     {
+       g_process_cap_restore(saved_caps);
+@@ -99,7 +123,7 @@ affile_sd_open_file(AFFileSourceDriver *self, gchar *name, gint *fd)
+   else
+     flags = O_RDONLY | O_NOCTTY | O_NONBLOCK | O_LARGEFILE;
+-  if (affile_open_file(name, flags, -1, -1, -1, 0, 0, 0, 0, !!(self->flags & AFFILE_PRIVILEGED), fd))
++  if (affile_open_file(name, flags, -1, -1, -1, 0, 0, 0, 0, !!(self->flags & AFFILE_PRIVILEGED), !!(self->flags & AFFILE_PIPE), fd))
+     return TRUE;
+   return FALSE;
+ }
+@@ -196,9 +220,15 @@ affile_sd_notify(LogPipe *s, LogPipe *sender, gint notify_code, gpointer user_da
+             transport = log_transport_plain_new(fd, 0);
+             transport->timeout = 10;
+-            self->reader = log_reader_new(log_proto_plain_new_server(transport, self->reader_options.padding, self->reader_options.msg_size, LPPF_NOMREAD | ((self->reader_options.follow_freq > 0) ? LPPF_IGNORE_EOF : 0)), 
+-                                          LR_LOCAL);
+-                                          
++            self->reader = log_reader_new(
++                                  log_proto_plain_new_server(transport, self->reader_options.padding,
++                                                             self->reader_options.msg_size,
++                                                             ((self->reader_options.follow_freq > 0)
++                                                                    ? LPPF_IGNORE_EOF
++                                                                    : LPPF_NOMREAD)
++                                                            ),
++                                  LR_LOCAL);
++
+             log_reader_set_options(self->reader, s, &self->reader_options, 1, SCS_FILE, self->super.id, self->filename->str);
+             log_reader_set_follow_filename(self->reader, self->filename->str);
+@@ -290,10 +320,16 @@ affile_sd_init(LogPipe *s)
+       transport->timeout = 10;
+       /* FIXME: we shouldn't use reader_options to store log protocol parameters */
+-      self->reader = log_reader_new(log_proto_plain_new_server(transport, self->reader_options.padding, self->reader_options.msg_size, LPPF_NOMREAD | ((self->reader_options.follow_freq > 0) ? LPPF_IGNORE_EOF : 0)), 
+-                                    LR_LOCAL);
++      self->reader = log_reader_new(
++                            log_proto_plain_new_server(transport, self->reader_options.padding,
++                                                       self->reader_options.msg_size,
++                                                       ((self->reader_options.follow_freq > 0)
++                                                            ? LPPF_IGNORE_EOF
++                                                            : LPPF_NOMREAD)
++                                                      ),
++                            LR_LOCAL);
+       log_reader_set_options(self->reader, s, &self->reader_options, 1, SCS_FILE, self->super.id, self->filename->str);
+-      
++
+       log_reader_set_follow_filename(self->reader, self->filename->str);
+       /* NOTE: if the file could not be opened, we ignore the last
+@@ -458,7 +494,7 @@ affile_dw_init(LogPipe *s)
+   if (affile_open_file(self->filename->str, flags, 
+                        self->owner->file_uid, self->owner->file_gid, self->owner->file_perm, 
+                        self->owner->dir_uid, self->owner->dir_gid, self->owner->dir_perm, 
+-                       !!(self->owner->flags & AFFILE_CREATE_DIRS), FALSE, &fd))
++                       !!(self->owner->flags & AFFILE_CREATE_DIRS), FALSE, !!(self->owner->flags & AFFILE_PIPE), &fd))
+     {
+       guint write_flags;
+       
+diff --git a/src/afsocket.c b/src/afsocket.c
+index ad8e198..af788f6 100644
+--- a/src/afsocket.c
++++ b/src/afsocket.c
+@@ -90,12 +90,12 @@ afsocket_open_socket(GSockAddr *bind_addr, int stream_or_dgram, int *fd)
+   else
+     sock = socket(bind_addr->sa.sa_family, SOCK_DGRAM, 0);
      
-   pw = getpwnam(user);
-commit 11f8d45b016107a686dbfa29497960ae3f6145ac
-Author: Balazs Scheidler <bazsi@balabit.hu>
-Date:   Fri Jan 16 14:44:53 2009 +0100
-
-    [config parser] "syslog" became a reserved word, make it possible to use that as a facility name
-    
-       In syslog-ng 3.0, "syslog" became a reserved word, thus the facility()
-       filter couldn't use it as name for the facility named syslog.
-    
-       To avoid having to quote this word, I added a kludge to the
-       config grammar, to make it recognize syslog as a facility name
-       based on context.
-
+-  g_fd_set_nonblock(sock, TRUE);
+-  g_fd_set_cloexec(sock, TRUE);
+   if (sock != -1)
+     {
+       cap_t saved_caps;
++      g_fd_set_nonblock(sock, TRUE);
++      g_fd_set_cloexec(sock, TRUE);
+       saved_caps = g_process_cap_save();
+       g_process_cap_modify(CAP_NET_BIND_SERVICE, TRUE);
+       g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);
+@@ -208,7 +208,9 @@ afsocket_sc_init(LogPipe *s)
+   if ((self->owner->flags & AFSOCKET_SYSLOG_PROTOCOL) == 0)
+     {
+       /* plain protocol */
+-      proto = log_proto_plain_new_server(transport, self->owner->reader_options.padding, self->owner->reader_options.msg_size, (self->owner->flags & AFSOCKET_DGRAM) ? LPPF_PKTTERM : 0);
++      proto = log_proto_plain_new_server(transport, self->owner->reader_options.padding,
++                   self->owner->reader_options.msg_size,
++                   (self->owner->flags & AFSOCKET_DGRAM) ? (LPPF_PKTTERM + LPPF_IGNORE_EOF) : 0);
+     }
+   else
+     {
+diff --git a/src/afsql.c b/src/afsql.c
+index 96c5b22..dcbc02e 100644
+--- a/src/afsql.c
++++ b/src/afsql.c
+@@ -940,6 +940,7 @@ afsql_dd_new()
+   self->frac_digits = -1;
+   self->validated_tables = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
++  g_static_mutex_init(&self->queue_lock);
+   
+   init_sequence_number(&self->seq_num);
+   return &self->super;  
 diff --git a/src/cfg-grammar.y b/src/cfg-grammar.y
-index c40b7fb..d54ba8f 100644
+index 9902d84..2ad453a 100644
 --- a/src/cfg-grammar.y
 +++ b/src/cfg-grammar.y
-@@ -277,6 +277,7 @@ cfg_check_template(LogTemplate *template)
+@@ -52,6 +52,7 @@ LogParser *last_parser;
+ FilterRE *last_re_filter;
+ LogRewrite *last_rewrite;
+ gint last_addr_family = AF_INET;
++gchar *last_include_file;
+ #if ENABLE_SSL
+ TLSContext *last_tls_context;
+@@ -92,17 +93,20 @@ cfg_check_template(LogTemplate *template)
+   return TRUE;
+ }
++
+ %}
+ %union {
++        gint token;
+       gint64 num;
++      double fnum;
+       char *cptr;
+       void *ptr;
+       FilterExprNode *node;
+ }
+ /* statements */
+-%token        KW_SOURCE KW_FILTER KW_PARSER KW_DESTINATION KW_LOG KW_OPTIONS 
++%token        KW_SOURCE KW_FILTER KW_PARSER KW_DESTINATION KW_LOG KW_OPTIONS KW_INCLUDE
+ /* source & destination items */
+ %token        KW_INTERNAL KW_FILE KW_PIPE KW_UNIX_STREAM KW_UNIX_DGRAM
+@@ -154,7 +158,7 @@ cfg_check_template(LogTemplate *template)
+ /* socket related options */
+ %token KW_KEEP_ALIVE KW_MAX_CONNECTIONS
+-%token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT KW_FRAMED
++%token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT
+ %token KW_IP_TTL KW_SO_BROADCAST KW_IP_TOS KW_SO_SNDBUF KW_SO_RCVBUF KW_SO_KEEPALIVE KW_SPOOF_SOURCE
+ /* misc options */
+@@ -182,6 +186,7 @@ cfg_check_template(LogTemplate *template)
+ %token  DOTDOT
+ %token        <cptr> IDENTIFIER
+ %token        <num>  NUMBER
++%token        <fnum> FLOAT
+ %token        <cptr> STRING
  
- %type <cptr> string
- %type <cptr> string_or_number
-+%type <cptr> facility_string
+ %left KW_OR
+@@ -276,6 +281,32 @@ cfg_check_template(LogTemplate *template)
  %type   <ptr> string_list
  %type   <ptr> string_list_build
  
-@@ -464,7 +465,7 @@ source_affile_option
++%type   <token> reserved_words_as_strings
++
++%type <token> KW_PARSER
++%type <token> KW_REWRITE
++%type <token> KW_INCLUDE
++%type <token> KW_SYSLOG
++%type <token> KW_COLUMNS
++%type <token> KW_DELIMITERS
++%type <token> KW_QUOTES
++%type <token> KW_QUOTE_PAIRS
++%type <token> KW_NULL
++%type <token> KW_CSV_PARSER
++%type <token> KW_DB_PARSER
++%type <token> KW_ENCODING
++%type <token> KW_SET
++%type <token> KW_SUBST
++%type <token> KW_VALUE
++%type <token> KW_PROGRAM_OVERRIDE
++%type <token> KW_HOST_OVERRIDE
++%type <token> KW_TRANSPORT
++%type <token> KW_TRUSTED_KEYS
++%type <token> KW_TRUSTED_DN
++%type <token> KW_MESSAGE
++%type <token> KW_TYPE
++%type <token> KW_SQL
++
+ %%
+ start   
+@@ -283,7 +314,21 @@ start
+       ;
+ stmts   
+-        : stmt ';' stmts
++        : stmt ';' 
++          { 
++            if (last_include_file && !cfg_lex_process_include(last_include_file)) 
++              { 
++                free(last_include_file);
++                last_include_file = NULL;
++                YYERROR; 
++              } 
++            if (last_include_file)
++              {
++                free(last_include_file);
++                last_include_file = NULL;
++              }
++          }
++          stmts
+       |       
+       ;
+@@ -296,6 +341,7 @@ stmt
+         | KW_REWRITE rewrite_stmt               { cfg_add_rewrite(configuration, $2); }
+       | KW_TEMPLATE template_stmt             { cfg_add_template(configuration, $2); }
+       | KW_OPTIONS options_stmt               {  }
++      | KW_INCLUDE include_stmt               {  }
+       ;
+ source_stmt
+@@ -319,6 +365,9 @@ dest_stmt
+ log_stmt
+         : '{' log_items log_forks log_flags '}'               { LogPipeItem *pi = log_pipe_item_append_tail($2, $3); $$ = log_connection_new(pi, $4); }
+       ;
++      
++include_stmt
++        : string                                { last_include_file = $1; }
+ log_items
+       : log_item ';' log_items                { log_pipe_item_append($1, $3); $$ = $1; }
+@@ -442,7 +491,7 @@ source_affile_option
                affile_sd_set_pri_level(last_driver, level); 
              free($3);
            }
 -        | KW_FACILITY '(' string ')'    
-+        | KW_FACILITY '(' facility_string ')'
++        | KW_FACILITY '(' string ')'
  
            {
              int facility = -1;
-@@ -1305,7 +1306,7 @@ filter_fac_list
+@@ -708,7 +757,8 @@ source_reader_option
+       | KW_LOG_MSG_SIZE '(' NUMBER ')'        { last_reader_options->msg_size = $3; }
+       | KW_LOG_FETCH_LIMIT '(' NUMBER ')'     { last_reader_options->fetch_limit = $3; }
+       | KW_PAD_SIZE '(' NUMBER ')'            { last_reader_options->padding = $3; }
+-      | KW_FOLLOW_FREQ '(' NUMBER ')'         { last_reader_options->follow_freq = $3; }
++      | KW_FOLLOW_FREQ '(' FLOAT ')'          { last_reader_options->follow_freq = (long) ($3 * 1000); }
++      | KW_FOLLOW_FREQ '(' NUMBER ')'         { last_reader_options->follow_freq = ($3 * 1000); }
+       | KW_KEEP_TIMESTAMP '(' yesno ')'       { last_reader_options->super.keep_timestamp = $3; }
+         | KW_ENCODING '(' string ')'          { last_reader_options->text_encoding = g_strdup($3); free($3); }
+       ;
+@@ -777,7 +827,7 @@ dest_afpipe
+ dest_afpipe_params
+       : string 
+         { 
+-          last_driver = affile_dd_new($1, AFFILE_NO_EXPAND | AFFILE_PIPE);
++          last_driver = affile_dd_new($1, AFFILE_PIPE);
+           free($1); 
+           last_writer_options = &((AFFileDestDriver *) last_driver)->writer_options;
+           last_writer_options->flush_lines = 0;
+@@ -1282,7 +1332,7 @@ filter_fac_list
        ;
  
  filter_fac
 -      : string                                
-+      : facility_string
++      : string
          { 
            int n = syslog_name_lookup_facility_by_name($1);
            if (n == -1)
-@@ -1499,6 +1500,11 @@ string_list_build
-         |                                     { $$ = NULL; }
-         ;
+@@ -1461,6 +1511,34 @@ dnsmode
+ string
+       : IDENTIFIER
+       | STRING
++      | reserved_words_as_strings             { $$ = cfg_lex_get_keyword_string($1); }
++      ;
++
++reserved_words_as_strings
++        /* these keywords were introduced in syslog-ng 3.0 */
++        : KW_PARSER
++        | KW_REWRITE
++        | KW_INCLUDE
++        | KW_SYSLOG
++        | KW_COLUMNS
++        | KW_DELIMITERS
++        | KW_QUOTES
++        | KW_QUOTE_PAIRS
++        | KW_NULL
++        | KW_CSV_PARSER
++        | KW_DB_PARSER
++        | KW_ENCODING
++        | KW_SET
++        | KW_SUBST
++        | KW_VALUE
++        | KW_PROGRAM_OVERRIDE
++        | KW_HOST_OVERRIDE
++        | KW_TRANSPORT
++        | KW_TRUSTED_KEYS
++        | KW_TRUSTED_DN
++        | KW_MESSAGE
++        | KW_TYPE
++        | KW_SQL
+       ;
+ string_or_number
+@@ -1483,14 +1561,8 @@ extern int linenum;
+ void 
+ yyerror(char *msg)
+ {
+-  fprintf(stderr, "%s in %s at line %d.\n", msg, configuration->filename, linenum);
++  fprintf(stderr, "%s in %s at line %d.\n\n"
++                  "syslog-ng documentation: http://www.balabit.com/support/documentation/?product=syslog-ng\n"
++                  "mailing list: https://lists.balabit.hu/mailman/listinfo/syslog-ng\n", msg, cfg_lex_get_current_file(), cfg_lex_get_current_lineno());
+ }
+-void
+-yyparser_reset(void)
+-{
+-  last_driver = NULL;
+-  last_reader_options = NULL;
+-  last_writer_options = NULL;
+-  last_template = NULL;
+-}
+diff --git a/src/cfg-lex.l b/src/cfg-lex.l
+index c9db716..dba726a 100644
+--- a/src/cfg-lex.l
++++ b/src/cfg-lex.l
+@@ -31,6 +31,7 @@
+ #include <string.h>
+ #include <strings.h>
++#include <sys/stat.h>
+ struct keyword 
+ {
+@@ -52,6 +53,7 @@ static struct keyword keywords[] = {
+       { "destination",        KW_DESTINATION },
+       { "log",                KW_LOG },
+       { "options",            KW_OPTIONS },
++      { "include",            KW_INCLUDE },
+       /* source or destination items */
+       { "file",               KW_FILE },
+@@ -162,7 +164,6 @@ static struct keyword keywords[] = {
+       { "localport",          KW_LOCALPORT },
+       { "port",               KW_PORT },
+       { "destport",           KW_DESTPORT },
+-        { "framed",             KW_FRAMED },
+         { "ip_ttl",             KW_IP_TTL },
+         { "ip_tos",             KW_IP_TOS },
+         { "so_broadcast",       KW_SO_BROADCAST },
+@@ -229,7 +230,20 @@ static struct keyword keywords[] = {
+ #define MAX_REGEXP_LEN        1024
+-int linenum = 1;
++typedef struct _CfgIncludeLevel
++{
++  GSList *files;
++  gchar *current_file;
++  gint linenum;
++  struct yy_buffer_state *yybuf;
++} CfgIncludeLevel;
++
++#define MAX_INCLUDE_DEPTH 16
++
++static CfgIncludeLevel include_stack[MAX_INCLUDE_DEPTH];
++static gint include_depth = 0;
++
++
+ int lex_filter_params = 0;
+ char buf[MAX_REGEXP_LEN];
+ char *str;
+@@ -237,6 +251,7 @@ char *str;
+ static int check_reserved_words(char *token);
+ static void append_string(int length, char *str);
+ static void append_char(char c);
++static gboolean cfg_start_next_include(gboolean first_on_this_level);
+ %}
+@@ -254,9 +269,10 @@ word      [^ \#'"\(\)\{\}\\;\n\t,|\.]
+ %%
  
-+facility_string
-+        : string                                { $$ = $1; };
-+        | KW_SYSLOG                             { $$ = strdup("syslog"); }
-+        ;
+ \#.*$                      ;
+-\r?\n                    { linenum++; }
++\r?\n                    { include_stack[include_depth].linenum++; }
+ {white}+                 ;
+ \.\.                       { return DOTDOT; }
++(-|\+)?{digit}+\.{digit}+  { yylval.fnum = strtod(yytext, NULL); return FLOAT; }
+ 0x{digit}+               { yylval.num = strtoll(yytext, NULL, 16); return NUMBER; }
+ 0{digit}+                { yylval.num = strtoll(yytext, NULL, 8); return NUMBER; }
+ (-|\+)?{digit}+            { yylval.num = strtoll(yytext, NULL, 10); return NUMBER; }
+@@ -298,16 +314,13 @@ word     [^ \#'"\(\)\{\}\\;\n\t,|\.]
+                               return STRING;
+                          }
++
++<INITIAL><<EOF>>           { if (!cfg_start_next_include(FALSE)) yyterminate(); }
 +
  %%
+-int 
+-lex_init(FILE *file, gint init_line_num)
+-{
+-  yyrestart(file);
+-  linenum = init_line_num;
+-  return 0;
+-}
+-int 
++
++static int 
+ check_reserved_words(char *token)
+ {
+   int i, j;
+@@ -339,6 +352,7 @@ check_reserved_words(char *token)
+               break;
+             }
+           keywords[i].kw_status = KWS_NORMAL;
++          yylval.token = keywords[i].kw_token;
+           return keywords[i].kw_token;
+         }
+     }
+@@ -364,3 +378,246 @@ append_char(char c)
+   str++;
+   *str = 0;
+ }
++
++const gchar *
++cfg_lex_get_current_file(void)
++{
++  CfgIncludeLevel *level = &include_stack[include_depth];
++
++  return level->current_file;
++}
++
++gint
++cfg_lex_get_current_lineno(void)
++{
++  CfgIncludeLevel *level = &include_stack[include_depth];
++
++  return level->linenum;
++}
++
++char *
++cfg_lex_get_keyword_string(int kw)
++{
++  int i;
++  for (i = 0; i < (sizeof(keywords) / sizeof(struct keyword)); i++)
++    {
++      if (keywords[i].kw_token == kw)
++        {
++          msg_warning("WARNING: Your configuration uses a newly introduced reserved word as identifier, please use a different name",
++                      evt_tag_str("keyword", keywords[i].kw_name),
++                      evt_tag_str("filename", cfg_lex_get_current_file()),
++                      evt_tag_int("line", cfg_lex_get_current_lineno()),
++                      NULL);
++          return strdup(keywords[i].kw_name);
++        }
++    }
++  g_assert_not_reached();
++}
++
++
++
++static gboolean
++cfg_start_next_include(gboolean first_on_this_level)
++{
++  FILE *include_file;
++  CfgIncludeLevel *level = &include_stack[include_depth];
++  gchar *filename;
++  struct yy_buffer_state *yybuf;
++  
++  g_assert(level->yybuf == NULL);
++  
++  if (include_depth == 0)
++    {
++      return FALSE;
++    }
++
++  if (!first_on_this_level)
++    {
++      msg_debug("Finishing include file",
++                evt_tag_str("filename", level->current_file),
++                evt_tag_int("depth", include_depth),
++                NULL);
++    }
++  
++  if (!level->files)
++    {
++      yybuf = YY_CURRENT_BUFFER;
++      g_free(level->current_file);
++      level->current_file = NULL;
++      include_depth--;
++      yy_switch_to_buffer(include_stack[include_depth].yybuf);
++      include_stack[include_depth].yybuf = NULL;
++      if (!first_on_this_level)
++        yy_delete_buffer(yybuf);
++        
++      return TRUE;
++    }
++    
++  filename = (gchar *) level->files->data;
++  level->files = g_slist_delete_link(level->files, level->files);
++  
++  include_file = fopen(filename, "r");
++  if (!include_file)
++    {
++      msg_error("Error opening include file",
++                evt_tag_str("filename", filename),
++                evt_tag_int("depth", include_depth),
++                NULL);
++      g_free(filename);
++      return FALSE;
++    }
++  msg_debug("Starting to read include file",
++            evt_tag_str("filename", filename),
++            evt_tag_int("depth", include_depth),
++            NULL);
++  if (level->current_file)
++    g_free(level->current_file);
++  level->current_file = filename;
++  level->linenum = 1;
++  
++  yybuf = YY_CURRENT_BUFFER;
++  yy_switch_to_buffer(yy_create_buffer(include_file, YY_BUF_SIZE));
++  if (!first_on_this_level)
++    yy_delete_buffer(yybuf);
++  return TRUE;
++}
++
++gboolean
++cfg_lex_process_include(const gchar *filename)
++{
++  struct stat st;
++  gchar buf[1024];
++  CfgIncludeLevel *level;
++  
++  if (include_depth >= MAX_INCLUDE_DEPTH - 1)
++    {
++      msg_error("Include file depth is too deep, increase MAX_INCLUDE_DEPTH and recompile",
++                evt_tag_str("filename", filename),
++                evt_tag_int("depth", include_depth),
++                NULL);
++      return FALSE;
++    }
++  
++  if (filename[0] != '/')
++    {
++      g_snprintf(buf, sizeof(buf), "%s/%s", PATH_SYSCONFDIR, filename);
++      filename = buf;
++    }
++  
++  if (stat(filename, &st) < 0)
++    {
++      msg_error("Include file/directory not found", 
++                evt_tag_str("filename", filename),
++                evt_tag_errno("error", errno),
++                NULL);
++      return FALSE;
++    }
++  include_stack[include_depth].yybuf = YY_CURRENT_BUFFER;
++  include_depth++;
++  level = &include_stack[include_depth];
++  if (S_ISDIR(st.st_mode))
++    {
++      GDir *dir;
++      GError *error = NULL;
++      const gchar *entry;
++      
++      dir = g_dir_open(filename, 0, &error);
++      if (!dir)
++        {
++          msg_error("Error opening directory for reading",
++                evt_tag_str("filename", filename),
++                evt_tag_str("error", error->message),
++                NULL);
++          goto drop_level;
++        }
++      while ((entry = g_dir_read_name(dir)))
++        {
++          const gchar *p;
++          
++          for (p = entry; *p; p++)
++            {
++              if (!((*p >= 'a' && *p <= 'z') ||
++                   (*p >= 'A' && *p <= 'Z') ||
++                   (*p >= '0' && *p <= '9') ||
++                   (*p == '_') || (*p == '-') || (*p == '.')))
++                {
++                  msg_debug("Skipping include file, does not match pattern [\\-_a-zA-Z0-9]+",
++                            evt_tag_str("filename", entry),
++                            NULL);
++                  p = NULL;
++                  break;
++                }
++            }
++          if (p)
++            {
++              gchar *full_filename = g_build_filename(filename, entry, NULL);
++              if (stat(full_filename, &st) < 0 || S_ISDIR(st.st_mode))
++                {
++                  msg_debug("Skipping include file as it is a directory",
++                            evt_tag_str("filename", entry),
++                            NULL);
++                  g_free(full_filename);
++                  continue;
++                }
++              level->files = g_slist_insert_sorted(level->files, full_filename, (GCompareFunc) strcmp);
++              msg_debug("Adding include file",
++                        evt_tag_str("filename", entry),
++                        NULL);
++            }
++        }
++      g_dir_close(dir);
++      if (!level->files)
++        {
++          /* no include files in the specified directory */
++          msg_debug("No files in this include directory",
++                    evt_tag_str("dir", filename),
++                    NULL);
++          include_depth--;
++          include_stack[include_depth].yybuf = NULL;
++          return TRUE;
++        }
++    }
++  else
++    {
++      g_assert(level->files == NULL);
++      level->files = g_slist_prepend(level->files, g_strdup(filename));
++    }
++  return cfg_start_next_include(TRUE);
++ drop_level:
++  g_slist_foreach(level->files, (GFunc) g_free, NULL);
++  g_slist_free(level->files);
++  level->files = NULL;
++  return FALSE;
++}
++
++int 
++cfg_lex_init(FILE *file, gint init_line_num)
++{
++  CfgIncludeLevel *level;
++  
++  yyrestart(file);
++  level = &include_stack[0];
++  level->current_file = g_strdup(configuration->filename);
++  level->linenum = init_line_num;
++  return 0;
++}
++
++void
++cfg_lex_deinit(void)
++{
++  gint i;
++  
++  for (i = 0; i < include_depth; i++)
++    {
++      CfgIncludeLevel *level = &include_stack[i];
++
++      if (level->current_file)
++        g_free(level->current_file);
++      
++      g_slist_foreach(level->files, (GFunc) g_free, NULL);
++      g_slist_free(level->files);
++      level->files = NULL;
++      if (level->yybuf)
++        yy_delete_buffer(level->yybuf);
++    }
++}
+diff --git a/src/cfg.c b/src/cfg.c
+index 23d93b6..45e5119 100644
+--- a/src/cfg.c
++++ b/src/cfg.c
+@@ -34,6 +34,8 @@
+ #include "logparser.h"
+ #include "serialize.h"
++#include <sys/types.h>
++#include <signal.h>
+ #include <stdio.h>
+ #include <string.h>
  
- extern int linenum;
-commit ef5eb95d26fcfe3746b78bba8d39cfa2cdb9eeeb
-Author: Balazs Scheidler <bazsi@balabit.hu>
-Date:   Tue Dec 30 15:22:00 2008 +0100
-
-    [LogReader] only assume that a file was moved if the size of the file is non-zero
-    
-    If an external logrotate program is used to rotate a logfile, a
-    small race still exists when using syslog-ng to read that logfile,
-    as described by Evan Rempel:
-    
-    "
-    1. Application is writing to log file named "A".
-    2. External log rotation renames "A" to "A.1"
-    3. External log rotation touches/creates file named "A" and sets appropriate
-        permissions.
-    4. Internal timer of syslog-ng is triggered by follow_freq() setting. Syslog-ng will
-        switch to the new file "A" because it exists, even though it was created only
-        milliseconds earlier.
-    5. log rotation signals the application to switch log files (reload or restart).
-    6. Application flushes log buffers to current file which is now A.1, but syslog-ng
-        is no longer reading this file.
-    7. Application closes current log file "A.1" and opens new log file "A".
-    
-    This sequence will result in the last buffer flush (step 6) from the application to
-    be missed by syslog-ng.
-    "
-    
-    This patch makes syslog-ng to switch to the new log file if it already
-    received some data.
-
+@@ -203,15 +205,6 @@ cfg_deinit(GlobalConfig *cfg)
+   return log_center_deinit(cfg->center);
+ }
+-/* extern declarations in the generated parser & lexer */
+-extern FILE *yyin;
+-extern int yyparse();
+-extern void lex_init(FILE *, gint lineno);
+-extern int yydebug;
+-extern int linenum;
+-
+-extern void yyparser_reset(void);
+-
+ gboolean
+ cfg_read_pragmas(GlobalConfig *self, FILE *cfg, gint *lineno)
+ {
+@@ -358,8 +351,9 @@ cfg_new(gchar *fname)
+           self->chain_hostnames = TRUE;
+         }
+-      lex_init(cfg, lineno);
++      cfg_lex_init(cfg, lineno);
+       res = yyparse();
++      cfg_lex_deinit();
+       fclose(cfg);
+       if (!res)
+       {
+@@ -481,7 +475,15 @@ cfg_reload_config(gchar *fname, GlobalConfig *cfg)
+     {
+       msg_error("Error initializing new configuration, reverting to old config", NULL);
+       cfg_persist_config_move(new_cfg, cfg);
+-      cfg_init(cfg);
++      if (!cfg_init(cfg))
++        {
++          /* hmm. hmmm, error reinitializing old configuration, we're hosed.
++           * Best is to kill ourselves in the hope that the supervisor
++           * restarts us.
++           */
++          kill(getpid(), SIGQUIT);
++          g_assert_not_reached();
++        }
+       return cfg;
+     }
+ }
+diff --git a/src/cfg.h b/src/cfg.h
+index d7b4edc..91f3060 100644
+--- a/src/cfg.h
++++ b/src/cfg.h
+@@ -28,6 +28,7 @@
+ #include <sys/types.h>
+ #include <regex.h>
++#include <stdio.h>
+ struct _LogSourceGroup;
+ struct _LogDestGroup;
+@@ -148,6 +149,19 @@ void cfg_persist_set_version(GlobalConfig *cfg, const gint version);
+ void persist_config_free(PersistentConfig *persist);
++/* defined in the lexer */
++void yyerror(char *msg);
++int yylex();
++int cfg_lex_init(FILE *file, gint init_line_num);
++void cfg_lex_deinit(void);
++gboolean cfg_lex_process_include(const gchar *filename);
++const gchar *cfg_lex_get_current_file(void);
++gint cfg_lex_get_current_lineno(void);
++char *cfg_lex_get_keyword_string(int kw);
++
++/* defined in the parser */
++int yyparse(void);
++
+ static inline gboolean 
+ cfg_check_current_config_version(gint req)
+ {
+diff --git a/src/filter.c b/src/filter.c
+index 0d1fe57..3a14fdd 100644
+--- a/src/filter.c
++++ b/src/filter.c
+@@ -375,6 +375,11 @@ filter_netmask_eval(FilterExprNode *s, LogMessage *msg)
+     {
+       addr.s_addr = htonl(INADDR_LOOPBACK);
+     }
++  else
++    {
++      /* no address information, return FALSE */
++      return s->comp;
++    }
+   return ((addr.s_addr & self->netmask.s_addr) == (self->address.s_addr)) ^ s->comp;
+ }
+diff --git a/src/gprocess.c b/src/gprocess.c
+index 5a4a76f..004f57c 100644
+--- a/src/gprocess.c
++++ b/src/gprocess.c
+@@ -87,7 +87,9 @@ static struct
+   GProcessMode mode;
+   const gchar *name;
+   const gchar *user;
++  uid_t uid;
+   const gchar *group;
++  gid_t gid;
+   const gchar *chroot_dir;
+   const gchar *pidfile;
+   const gchar *pidfile_dir;
+@@ -109,9 +111,15 @@ static struct
+   .argv = NULL,
+   .argv_start = NULL,
+   .argv_env_len = 0,
++#ifdef __CYGWIN__
++  .fd_limit_min = 256,
++#else
+   .fd_limit_min = 4096,
++#endif
+   .check_period = -1,
+   .check_fn = NULL,
++  .uid = -1,
++  .gid = -1
+ };
+ #if ENABLE_LINUX_CAPS
+@@ -255,6 +263,8 @@ g_process_set_user(const gchar *user)
+ {
+   if (!process_opts.user)
+     process_opts.user = user;
++
++
+ }
+ /**
+@@ -268,6 +278,7 @@ g_process_set_group(const gchar *group)
+ {
+   if (!process_opts.group)
+     process_opts.group = group;
++
+ }
+ /**
+@@ -666,35 +677,20 @@ g_process_change_root(void)
+ static gboolean
+ g_process_change_user(void)
+ {
+-  uid_t uid = -1;
+-  gid_t gid = -1;
+-  
+ #if ENABLE_LINUX_CAPS
+   if (process_opts.caps)
+     prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+ #endif
+-  if (process_opts.user && !resolve_user(process_opts.user, &uid))
+-    {
+-      g_process_message("Error resolving user; user='%s'", process_opts.user);
+-      return FALSE;
+-    }
+-
+-  if (process_opts.group && !resolve_group(process_opts.group, &gid))
+-    {
+-      g_process_message("Error resolving group; group='%s'", process_opts.group);
+-      return FALSE;
+-    }
+-
+-  if ((gint) gid != -1)
++  if ((gint) process_opts.gid != -1)
+     {
+-      if (setgid(gid) < 0)
++      if (setgid(process_opts.gid) < 0)
+         {
+-          g_process_message("Error in setgid(); group='%s', error='%s'", process_opts.group, g_strerror(errno));
++          g_process_message("Error in setgid(); group='%s', gid='%d', error='%s'", process_opts.group, (gint) process_opts.gid, g_strerror(errno));
+           if (getuid() == 0)
+             return FALSE;
+         }
+-      if (process_opts.user && initgroups(process_opts.user, gid) < 0)
++      if (process_opts.user && initgroups(process_opts.user, process_opts.gid) < 0)
+         {
+           g_process_message("Error in initgroups(); user='%s', error='%s'", process_opts.user, g_strerror(errno));
+           if (getuid() == 0)
+@@ -702,11 +698,11 @@ g_process_change_user(void)
+         }
+     }
+-  if ((gint) uid != -1)
++  if ((gint) process_opts.uid != -1)
+     {
+-      if (setuid(uid) < 0)
++      if (setuid(process_opts.uid) < 0)
+         {
+-          g_process_message("Error in setuid(); user='%s', error='%s'", process_opts.user, g_strerror(errno));
++          g_process_message("Error in setuid(); user='%s', uid='%d', error='%s'", process_opts.user, (gint) process_opts.uid, g_strerror(errno));
+           if (getuid() == 0)
+             return FALSE;
+         }
+@@ -763,6 +759,21 @@ g_process_change_caps(void)
+ #endif
++static void
++g_process_resolve_names(void)
++{
++  if (process_opts.user && !resolve_user(process_opts.user, &process_opts.uid))
++    {
++      g_process_message("Error resolving user; user='%s'", process_opts.user);
++      process_opts.uid = (uid_t) -1;
++    }
++  if (process_opts.group && !resolve_group(process_opts.group, &process_opts.gid))
++    {
++      g_process_message("Error resolving group; group='%s'", process_opts.group);
++      process_opts.gid = (gid_t) -1;
++    }
++}
++
+ /**
+  * g_process_change_dir:
+  *
+@@ -1116,6 +1127,7 @@ g_process_start(void)
+   
+   g_process_detach_tty();
+   g_process_change_limits();
++  g_process_resolve_names();
+   
+   if (process_opts.mode == G_PM_BACKGROUND)
+     {
+diff --git a/src/logmsg.c b/src/logmsg.c
+index 9bad35f..d7f7558 100644
+--- a/src/logmsg.c
++++ b/src/logmsg.c
+@@ -264,6 +264,10 @@ log_msg_get_value(LogMessage *self, const gchar *value_name, gssize *length)
+   return value;
+ }
++/**
++ * NOTE: the new_value is taken as a reference, e.g. it'll be assigned to
++ * the LogMessage and freed later on.
++ **/
+ void
+ log_msg_set_value(LogMessage *self, const gchar *value_name, gchar *new_value, gssize length)
+ {
+@@ -1065,7 +1069,7 @@ log_msg_parse_version(LogMessage *self, const guchar **data, gint *length)
+ }
+ static void
+-log_msg_parse_legacy_program_name(LogMessage *self, const guchar **data, gint *length)
++log_msg_parse_legacy_program_name(LogMessage *self, const guchar **data, gint *length, guint flags)
+ { 
+   /* the data pointer will not change */ 
+   const guchar *src, *prog_start;
+@@ -1110,6 +1114,11 @@ log_msg_parse_legacy_program_name(LogMessage *self, const guchar **data, gint *l
+       src++;
+       left--;
+     }
++  if (flags & LP_STORE_LEGACY_MSGHDR)
++    {
++      log_msg_set_value(self, "LEGACY_MSGHDR", g_strndup((gchar *) *data, *length - left), *length - left);
++      self->flags |= LF_LEGACY_MSGHDR;
++    }
+   *data = src;
+   *length = left;
+ }
+@@ -1573,7 +1582,7 @@ log_msg_parse_legacy(LogMessage *self, const guchar *data, gint length, guint fl
+           log_msg_parse_skip_chars(self, &src, &left, " ", -1);
+           /* Try to extract a program name */
+-          log_msg_parse_legacy_program_name(self, &src, &left);
++          log_msg_parse_legacy_program_name(self, &src, &left, flags);
+         }
+       /* If we did manage to find a hostname, store it. */
+@@ -1598,7 +1607,7 @@ log_msg_parse_legacy(LogMessage *self, const guchar *data, gint length, guint fl
+       else
+         {
+           /* Capture the program name */
+-          log_msg_parse_legacy_program_name(self, &src, &left);
++          log_msg_parse_legacy_program_name(self, &src, &left, flags);
+         }
+       self->timestamps[LM_TS_STAMP] = self->timestamps[LM_TS_RECVD];
+     }
+@@ -1607,7 +1616,7 @@ log_msg_parse_legacy(LogMessage *self, const guchar *data, gint length, guint fl
+   self->message_len = left;
+   if ((flags & LP_VALIDATE_UTF8) && g_utf8_validate((gchar *) src, left, NULL))
+     self->flags |= LF_UTF8;
+-    
++
+   return TRUE;
+ }
+diff --git a/src/logmsg.h b/src/logmsg.h
+index 17d4b5c..6e0a9be 100644
+--- a/src/logmsg.h
++++ b/src/logmsg.h
+@@ -47,6 +47,7 @@
+ #define LP_ASSUME_UTF8     0x0080
+ #define LP_VALIDATE_UTF8   0x0100
+ #define LP_NO_MULTI_LINE   0x0200
++#define LP_STORE_LEGACY_MSGHDR 0x0400
+ typedef struct _LogPathOptions LogPathOptions;
+@@ -97,6 +98,13 @@ enum
+   LF_OWN_MATCHES      = 0x4000,
+   LF_OWN_ALL          = 0x7FF0,
+   LF_CHAINED_HOSTNAME = 0x8000,
++
++  /* originally parsed from RFC 3164 format and the legacy message header
++   * was saved in $LEGACY_MSGHDR. This flag is a hack to avoid a hash lookup
++   * in the fast path and indicates that the parser has saved the legacy
++   * message header intact in a value named LEGACY_MSGHDR.
++   */
++  LF_LEGACY_MSGHDR    = 0x00010000,
+ };
+ typedef struct _LogMessageSDParam  LogMessageSDParam;
+@@ -129,12 +137,25 @@ typedef struct _LogMessageMatch
+       guint16 ofs;
+       guint16 len;
+ #else
++
++#if GLIB_SIZEOF_VOID_P == 4
++      guint16 ofs;
++      guint8 __pad;
++      guint8 flags;
++      guint16 len;
++      guint8 builtin_value;
++      guint8 type;
++#elif GLIB_SIZEOF_VOID_P == 8
+       guint16 ofs;
+       guint16 len;
+       guint8 builtin_value;
+       guint8 type;
+       guint8 __pad;
+       guint8 flags;
++#else
++#error "Unknown pointer size"
++#endif
++
+ #endif
+     };
+   };
+@@ -156,9 +177,10 @@ struct _LogMessage
+    */
+   struct
+   {
+-    guint16 flags;
+-    guint16 pri;
++    guint32 flags;
+     guint32 message_len;
++    guint16 pri;
++    /* 6 bytes hole */
+     
+     LogStamp timestamps[LM_TS_MAX];
+     gchar * const host;
+diff --git a/src/logproto.c b/src/logproto.c
+index b2c30ee..9d7187b 100644
+--- a/src/logproto.c
++++ b/src/logproto.c
+@@ -8,11 +8,22 @@
+ gboolean
+ log_proto_set_encoding(LogProto *self, const gchar *encoding)
+ {
+-  self->convert = g_iconv_open("utf-8", encoding);
+   if (self->convert != (GIConv) -1)
+     {
+-      return FALSE;
++      g_iconv_close(self->convert);
++      self->convert = (GIConv) -1;
++    }
++  if (self->encoding)
++    {
++      g_free(self->encoding);
++      self->encoding = NULL;
+     }
++
++  self->convert = g_iconv_open("utf-8", encoding);
++  if (self->convert == (GIConv) -1)
++    return FALSE;
++
++  self->encoding = g_strdup(encoding);
+   return TRUE;
+ }
+@@ -23,6 +34,8 @@ log_proto_free(LogProto *s)
+     s->free_fn(s);
+   if (s->convert != (GIConv) -1)
+     g_iconv_close(s->convert);
++  if (s->encoding)
++    g_free(s->encoding);
+   log_transport_free(s->transport);
+   g_free(s);
+ }
+@@ -159,6 +172,8 @@ struct _LogProtoPlainServer
+   gsize buffer_size, buffer_end, buffer_pos;
+   gsize padding_size, max_msg_size;
+   GSockAddr *prev_saddr;
++  gchar raw_buffer_leftover[8];
++  gint raw_buffer_leftover_size;
+   LogProtoStatus status;
+ };
+@@ -487,7 +502,8 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
+           /* if conversion is needed, we first read into an on-stack
+            * buffer, and then convert it into our internal buffer */
+-          raw_buffer = g_alloca(self->max_msg_size);
++          raw_buffer = g_alloca(self->max_msg_size + self->raw_buffer_leftover_size);
++          memcpy(raw_buffer, self->raw_buffer_leftover, self->raw_buffer_leftover_size);
+           if (!self->padding_size)
+             {
+               avail = self->max_msg_size;
+@@ -499,7 +515,7 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
+             }
+         }
+-      rc = log_transport_read(self->super.transport, raw_buffer, avail, sa);
++      rc = log_transport_read(self->super.transport, raw_buffer + self->raw_buffer_leftover_size, avail, sa);
+       if (sa && *sa)
+         self->prev_saddr = *sa;
+       if (rc < 0)
+@@ -534,6 +550,13 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
+               msg_verbose("EOF occurred while reading", 
+                           evt_tag_int(EVT_TAG_FD, self->super.transport->fd),
+                           NULL);
++              if (self->raw_buffer_leftover_size > 0)
++                {
++                  msg_error("EOF read on a channel with leftovers from previous character conversion, dropping input",
++                            NULL);
++                  self->status = LPS_EOF;
++                  return self->status;
++                }
+               self->status = LPS_EOF;
+               if (log_proto_plain_server_fetch_from_buf(self, msg, msg_len, TRUE))
+                 {
+@@ -562,6 +585,9 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
+         }
+       else
+         {
++          rc += self->raw_buffer_leftover_size;
++          self->raw_buffer_leftover_size = 0;
++
+           /* some data was read */
+           if (self->super.convert != (GIConv) -1)
+             {
+@@ -581,22 +607,62 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
+                       switch (errno)
+                         {
+                         case EINVAL:
+-                          /* Incomplete text, do not report an error */
++                          /* Incomplete text, do not report an error, rather try to read again */
++                          self->buffer_end = self->buffer_size - avail_out;
++
++                          if (avail_in > 0)
++                            {
++                              if (avail_in > sizeof(self->raw_buffer_leftover))
++                                {
++                                  msg_error("Invalid byte sequence, the remaining raw buffer is larger than the supported leftover size",
++                                            evt_tag_str("encoding", self->super.encoding),
++                                            evt_tag_int("avail_in", avail_in),
++                                            evt_tag_int("leftover_size", sizeof(self->raw_buffer_leftover)),
++                                            NULL);
++                                  self->status = LPS_ERROR;
++                                  return self->status;
++                                }
++                              memcpy(self->raw_buffer_leftover, raw_buffer, avail_in);
++                              self->raw_buffer_leftover_size = avail_in;
++                              msg_debug("Leftover characters remained after conversion, delaying message until another chunk arrives",
++                                        evt_tag_str("encoding", self->super.encoding),
++                                        evt_tag_int("avail_in", avail_in),
++                                        NULL);
++                              return LPS_SUCCESS;
++                            }
+                           break;
+                         case E2BIG:
+                           
+                           self->buffer_end = self->buffer_size - avail_out;
+                           /* extend the buffer */
+-                          self->buffer_size *= 2; 
+-                          self->buffer = g_realloc(self->buffer, self->buffer_size);
+                           
+-                          /* recalculate the out pointer, and add what we have now */
+-                          ret = -1;
++                          if (self->buffer_size < self->max_msg_size * 6)
++                            {
++                              self->buffer_size *= 2;
++                              self->buffer = g_realloc(self->buffer, self->buffer_size);
++
++                              /* recalculate the out pointer, and add what we have now */
++                              ret = -1;
++                            }
++                          else
++                            {
++                              msg_error("Incoming byte stream requires a too large conversion buffer, probably invalid character sequence",
++                                        evt_tag_str("encoding", self->super.encoding),
++                                        evt_tag_printf("buffer", "%.*s", self->buffer_end, self->buffer),
++                                        NULL);
++                              self->status = LPS_ERROR;
++                              return self->status;
++                            }
+                           break;
+                         case EILSEQ:
+                         default:
+-                          msg_error("Invalid byte sequence or other error while converting input", 
+-                                    NULL);
++                          msg_notice("Invalid byte sequence or other error while converting input, skipping character",
++                                     evt_tag_str("encoding", self->super.encoding),
++                                     evt_tag_printf("char", "0x%02x", *(guchar *) raw_buffer),
++                                     NULL);
++                          self->buffer_end = self->buffer_size - avail_out;
++                          raw_buffer++;
++                          avail_in--;
+                           break;
+                         }
+                     }
+diff --git a/src/logproto.h b/src/logproto.h
+index 8a03d75..f94e5df 100644
+--- a/src/logproto.h
++++ b/src/logproto.h
+@@ -18,6 +18,7 @@ struct _LogProto
+ {
+   LogTransport *transport;
+   GIConv convert;
++  gchar *encoding;
+   guint flags;
+   gboolean (*read_state)(LogProto *s, SerializeArchive *archive);
+   gboolean (*write_state)(LogProto *s, SerializeArchive *archive);
 diff --git a/src/logreader.c b/src/logreader.c
-index f9567ff..40e2ae7 100644
+index f9567ff..ca800d0 100644
 --- a/src/logreader.c
 +++ b/src/logreader.c
+@@ -103,7 +103,7 @@ log_reader_fd_prepare(GSource *source,
+   if (self->reader->flags & LR_FOLLOW)
+     {
+-      *timeout = self->reader->options->follow_freq * 1000;
++      *timeout = self->reader->options->follow_freq;
+       return FALSE;
+     }
+   
 @@ -167,7 +167,7 @@ log_reader_fd_check(GSource *source)
          
        if (self->reader->follow_filename && stat(self->reader->follow_filename, &followed_st) != -1)
          {
 -          if (fd < 0 || st.st_ino != followed_st.st_ino)
-+          if (fd < 0 || (st.st_ino != followed_st.st_ino && st.st_size > 0))
++          if (fd < 0 || (st.st_ino != followed_st.st_ino && followed_st.st_size > 0))
              {
                msg_trace("log_reader_fd_check file moved eof",
                          evt_tag_int("pos", pos),
-commit 8ad0edb1e4198bbf657708d07360bbac8b30b55a
-Author: Balazs Scheidler <bazsi@balabit.hu>
-Date:   Thu Feb 5 11:26:18 2009 +0100
-
-    [affile] validate file type before opening
-    
-    report an error if a file is opened using the pipe() driver, OR a
-    fifo is opened using the file() driver. named pipes should really be
-    driven by the pipe() driver.
-
-diff --git a/src/affile.c b/src/affile.c
-index f9264a7..e582a5d 100644
---- a/src/affile.c
-+++ b/src/affile.c
-@@ -45,6 +45,7 @@ affile_open_file(gchar *name, gint flags,
-                  gboolean create_dirs, gboolean privileged, gboolean is_pipe, gint *fd)
- {
-   cap_t saved_caps;
-+  struct stat st;
+@@ -278,6 +278,8 @@ log_reader_fetch_log(LogReader *self, LogProto *proto)
+     parse_flags |= LP_VALIDATE_UTF8;
+   if (self->options->options & LRO_NO_MULTI_LINE)
+     parse_flags |= LP_NO_MULTI_LINE;
++  if (self->options->options & LRO_STORE_LEGACY_MSGHDR)
++    parse_flags |= LP_STORE_LEGACY_MSGHDR;
+     
+   if (self->waiting_for_preemption)
+     may_read = FALSE;
+@@ -321,7 +323,7 @@ log_reader_fetch_log(LogReader *self, LogProto *proto)
+           /* no more messages for now */
+           break;
+         }
+-      if (msg_len > 0)
++      if (msg_len > 0 || (self->options->options & LRO_EMPTY_LINES))
+         {
+           msg_count++;
  
-   if (strstr(name, "../") || strstr(name, "/..")) 
+@@ -772,6 +774,10 @@ log_reader_options_lookup_flag(const gchar *flag)
+     return LRO_VALIDATE_UTF8;
+   if (strcmp(flag, "no-multi-line") == 0 || strcmp(flag, "no_multi_line") == 0)
+     return LRO_NO_MULTI_LINE;
++  if (strcmp(flag, "store-legacy-msghdr") == 0 || strcmp(flag, "store_legacy_msghdr") == 0)
++    return LRO_STORE_LEGACY_MSGHDR;
++  if (strcmp(flag, "empty-lines") == 0 || strcmp(flag, "empty_lines") == 0)
++    return LRO_EMPTY_LINES;
+   msg_error("Unknown parse flag", evt_tag_str("flag", flag), NULL);
+   return 0;
+ }
+diff --git a/src/logreader.h b/src/logreader.h
+index 8e5bc7c..11ff0da 100644
+--- a/src/logreader.h
++++ b/src/logreader.h
+@@ -43,6 +43,8 @@
+ #define LRO_SYSLOG_PROTOCOL  0x0004
+ #define LRO_VALIDATE_UTF8    0x0008
+ #define LRO_NO_MULTI_LINE    0x0010
++#define LRO_STORE_LEGACY_MSGHDR 0x0020
++#define LRO_EMPTY_LINES      0x0040
+ typedef struct _LogReaderWatch LogReaderWatch;
+@@ -77,7 +79,7 @@ typedef struct _LogReader
+   GSockAddr *peer_addr;
+   gchar *follow_filename;
+   ino_t inode;
+-  off_t size;
++  gint64 size;
+   
+ } LogReader;
+@@ -86,7 +88,7 @@ void log_reader_set_follow_filename(LogPipe *self, const gchar *follow_filename)
+ void log_reader_set_peer_addr(LogPipe *s, GSockAddr *peer_addr);
+ void log_reader_set_immediate_check(LogPipe *s);
+-void log_reader_update_pos(LogReader *self, off_t ofs);
++void log_reader_update_pos(LogReader *self, gint64 ofs);
+ void log_reader_save_state(LogReader *self, SerializeArchive *archive);
+ void log_reader_restore_state(LogReader *self, SerializeArchive *archive);
+diff --git a/src/logwriter.c b/src/logwriter.c
+index bb01148..5f77293 100644
+--- a/src/logwriter.c
++++ b/src/logwriter.c
+@@ -595,9 +595,20 @@ log_writer_format_log(LogWriter *self, LogMessage *lm, GString *result)
+           g_string_append_len(result, lm->host, lm->host_len);
+           g_string_append_c(result, ' ');
+-          g_string_append_len(result, lm->program, lm->program_len);
+-          if (lm->program_len > 0)
++          if ((lm->flags & LF_LEGACY_MSGHDR))
+             {
++              gssize length;
++              const gchar *msghdr;
++
++              msghdr = log_msg_get_value(lm, "LEGACY_MSGHDR", &length);
++              if (msghdr)
++                {
++                  g_string_append_len(result, msghdr, length);
++                }
++            }
++          else if (lm->program_len > 0)
++            {
++              g_string_append_len(result, lm->program, lm->program_len);
+               if (lm->pid_len > 0)
+                 {
+                   g_string_append_c(result, '[');
+diff --git a/src/main.c b/src/main.c
+index ba97f0c..f78dcc1 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -366,8 +366,6 @@ main(int argc, char *argv[])
+   g_process_set_name("syslog-ng");
+   
+-#if ENABLE_LINUX_CAPS
+-  
+   /* in this case we switch users early while retaining a limited set of
+    * credentials in order to initialize/reinitialize the configuration.
+    */
+@@ -381,27 +379,11 @@ main(int argc, char *argv[])
+     }
+   else
      {
-@@ -63,6 +64,23 @@ affile_open_file(gchar *name, gint flags,
-       g_process_cap_modify(CAP_DAC_READ_SEARCH, TRUE);
-       g_process_cap_modify(CAP_SYS_ADMIN, TRUE);
+-      g_process_startup_ok();
++      if (syntax_only)
++        g_process_startup_failed(0, TRUE);
++      else
++        g_process_startup_ok();
      }
-+  if (stat(name, &st) >= 0)
+-#else
+-
+-  /* if Linux capabilities are not compiled in, the initial setup is
+-   * performed as the root user, and then the switch to a limited user
+-   * account is made. This is compatible how syslog-ng behaved before
+-   * capability support.
+-   */
+-   
+-  rc = initial_init(&cfg);
+-  if (rc)
+-    {
+-      return rc;
+-    }
+-  g_process_start();
+-  g_process_startup_ok();
+-#endif
+-
+-  if (syntax_only)
+-    return 0;
+   /* we are running as a non-root user from this point */
+   
+@@ -424,6 +406,7 @@ main(int argc, char *argv[])
+   app_shutdown();
+   tls_deinit();
+   z_mem_trace_dump();
++  g_process_finish();
+   return rc;
+ }
+diff --git a/src/memtrace.c b/src/memtrace.c
+index ef4729a..eb33f4f 100644
+--- a/src/memtrace.c
++++ b/src/memtrace.c
+@@ -121,7 +121,7 @@ z_mem_trace_init(gchar *tracefile)
+       for (i = 0; i < MEMTRACE_HASH_SIZE; i++) 
+         {
+           mem_trace_hash[i].list = -1;
+-          memset(&mem_trace_hash[i].lock, 0, sizeof(GStaticMutex));
++          g_static_mutex_init(&mem_trace_hash[i].lock);
+         }
+       old_malloc = dlsym(RTLD_NEXT, "malloc");
+       old_free = dlsym(RTLD_NEXT, "free");
+diff --git a/src/misc.c b/src/misc.c
+index 96fcdd2..364ead6 100644
+--- a/src/misc.c
++++ b/src/misc.c
+@@ -274,7 +274,7 @@ resolve_user(const char *user, uid_t *uid)
+   struct passwd *pw;
+   *uid = 0;
+-  if (*user)
++  if (!(*user))
+     return FALSE;
+     
+   pw = getpwnam(user);
+@@ -299,7 +299,7 @@ resolve_group(const char *group, gid_t *gid)
+   struct group *gr;
+   *gid = 0;
+-  if (!*group)
++  if (!(*group))
+     return FALSE;
+     
+   gr = getgrnam(group);
+diff --git a/src/sgroup.c b/src/sgroup.c
+index add7ac9..27e863f 100644
+--- a/src/sgroup.c
++++ b/src/sgroup.c
+@@ -25,8 +25,10 @@
+ #include "misc.h"
+ #include "messages.h"
+ #include "stats.h"
++#include "afinter.h"
+ #include <time.h>
++#include <string.h>
+ static gboolean
+ log_source_group_init(LogPipe *s)
+diff --git a/src/templates.c b/src/templates.c
+index aee1f34..67b8217 100644
+--- a/src/templates.c
++++ b/src/templates.c
+@@ -339,17 +339,33 @@ log_macro_expand(GString *result, gint id, guint32 flags, gint ts_format, TimeZo
+         }
+       break;
+     case M_MSGHDR:
+-      /* message, complete with program name and pid */
+-      result_append(result, msg->program, msg->program_len, !!(flags & LT_ESCAPE));
+-      if (msg->program_len > 0)
++      if ((msg->flags & LF_LEGACY_MSGHDR))
+         {
+-          if (msg->pid_len > 0)
++          gssize length;
++          const gchar *msghdr;
++
++          /* fast path for now, as most messages come from legacy devices */
++
++          msghdr = log_msg_get_value(msg, "LEGACY_MSGHDR", &length);
++          if (msghdr)
+             {
+-              result_append(result, "[", 1, !!(flags & LT_ESCAPE));
+-              result_append(result, msg->pid, msg->pid_len, !!(flags & LT_ESCAPE));
+-              result_append(result, "]", 1, !!(flags & LT_ESCAPE));
++              result_append(result, msghdr, length, !!(flags & LT_ESCAPE));
++            }
++        }
++      else
++        {
++          /* message, complete with program name and pid */
++          result_append(result, msg->program, msg->program_len, !!(flags & LT_ESCAPE));
++          if (msg->program_len > 0)
++            {
++              if (msg->pid_len > 0)
++                {
++                  result_append(result, "[", 1, !!(flags & LT_ESCAPE));
++                  result_append(result, msg->pid, msg->pid_len, !!(flags & LT_ESCAPE));
++                  result_append(result, "]", 1, !!(flags & LT_ESCAPE));
++                }
++              result_append(result, ": ", 2, !!(flags & LT_ESCAPE));
+             }
+-          result_append(result, ": ", 2, !!(flags & LT_ESCAPE));
+         }
+       break;
+     case M_MESSAGE:
+@@ -433,6 +449,9 @@ log_macro_expand(GString *result, gint id, guint32 flags, gint ts_format, TimeZo
+          *   local timezone
+          */
+         zone_ofs = (zone_info != NULL ? time_zone_info_get_offset(zone_info, stamp->time.tv_sec) : stamp->zone_offset);
++        if (zone_ofs == -1)
++          zone_ofs = stamp->zone_offset;
++
+         t = stamp->time.tv_sec + zone_ofs;
+         tm = gmtime_r(&t, &tm_storage);
+@@ -506,9 +525,6 @@ log_macro_expand(GString *result, gint id, guint32 flags, gint ts_format, TimeZo
+           }
+         break;
+       }
+-
+-
+-
+       g_assert_not_reached();
+       break;
+     }
+@@ -634,6 +650,9 @@ log_template_compile(LogTemplate *self, GError **error)
+   
+   g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+   
++  if (self->compiled_template)
++    return TRUE;
++
+   p = self->template;
+   
+   while (*p)
+@@ -754,7 +773,7 @@ log_template_append_format(LogTemplate *self, LogMessage *lm, guint flags, gint
+   
+   flags |= self->flags;
+   
+-  if (self->compiled_template == NULL && !log_template_compile(self, NULL))
++  if (!log_template_compile(self, NULL))
+     return;
+   for (p = self->compiled_template; p; p = g_list_next(p))
+diff --git a/src/tlscontext.c b/src/tlscontext.c
+index b22b546..c06ec88 100644
+--- a/src/tlscontext.c
++++ b/src/tlscontext.c
+@@ -102,28 +102,41 @@ tls_session_verify_dn(X509_STORE_CTX *ctx)
+ }
+ int
+-tls_session_verify(int ok, X509_STORE_CTX *ctx)
++tls_session_verify(TLSSession *self, int ok, X509_STORE_CTX *ctx)
+ {
++  /* untrusted means that we have to accept the certificate even if it is untrusted */
++  if (self->ctx->verify_mode & TVM_UNTRUSTED)
++    return 1;
++
++  /* accept certificate if its fingerprint matches, again regardless whether x509 certificate validation was successful */
+   if (tls_session_verify_fingerprint(ctx))
+-    return 1; /* success */
 +    {
-+      if (is_pipe && !S_ISFIFO(st.st_mode))
++      msg_debug("Certificate accepted because its fingerprint is listed", NULL);
++      return 1;
++    }
++
++  if (ok && ctx->error_depth != 0 && (ctx->current_cert->ex_flags & EXFLAG_CA) == 0)
++    {
++      msg_debug("Invalid certificate found in chain, basicConstraints.ca is unset in non-leaf certificate", NULL);
++      ctx->error = X509_V_ERR_INVALID_CA;
++      return 0;
++    }
+  
++  /* reject certificate if it is valid, but its DN is not trusted */
+   if (ok && ctx->error_depth == 0 && !tls_session_verify_dn(ctx))
+     {
++      msg_debug("Certificate valid, but DN constraints were not met, rejecting", NULL);
+       ctx->error = X509_V_ERR_CERT_UNTRUSTED;
+-      return 0; /* fail */
++      return 0;
+     }
+-  
+-  return ok; 
+-}
+-
+-int
+-tls_session_ignore_errors(int ok, X509_STORE_CTX *ctx)
+-{
+   /* if the crl_dir is set in the configuration file but the directory is empty ignore this error */
+-  if (ok == 0 && ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
+-    return 1;
+-  else
+-    return ok;
++  if (!ok && ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
++    {
++      msg_notice("CRL directory is set but no CRLs found", NULL);
++      return 1;
++    }
++
++  return ok;
+ }
+ int
+@@ -132,10 +145,8 @@ tls_session_verify_callback(int ok, X509_STORE_CTX *ctx)
+   SSL *ssl = X509_STORE_CTX_get_app_data(ctx);
+   TLSSession *self = SSL_get_app_data(ssl);
+-  ok = tls_session_verify(ok, ctx);
++  ok = tls_session_verify(self, ok, ctx);
+     
+-  ok = tls_session_ignore_errors(ok, ctx);
+-
+   tls_log_certificate_validation_progress(ok, ctx);
+   
+   if (self->verify_func)
+@@ -165,9 +176,6 @@ tls_session_set_verify(TLSSession *self, TLSSessionVerifyFunc verify_func, gpoin
+   self->verify_func = verify_func;
+   self->verify_data = verify_data;
+   self->verify_data_destroy = verify_destroy;
+-
+-  SSL_set_app_data(self->ssl, self);
+-  SSL_set_verify(self->ssl, SSL_get_verify_mode(self->ssl), tls_session_verify_callback);
+ }
+ static TLSSession *
+@@ -212,11 +220,13 @@ TLSSession *
+ tls_context_setup_session(TLSContext *self)
+ {
+   SSL *ssl;
++  TLSSession *session;
+   gint ssl_error;
+   if (!self->ssl_ctx)
+     {  
+       gint verify_mode = 0;
++      gint verify_flags = X509_V_FLAG_POLICY_CHECK;
+       
+       if (self->mode == TM_CLIENT)
+         self->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
+@@ -240,7 +250,9 @@ tls_context_setup_session(TLSContext *self)
+         goto error;
+       
+       if (self->crl_dir)
+-        X509_VERIFY_PARAM_set_flags(self->ssl_ctx->param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
++        verify_flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
++
++      X509_VERIFY_PARAM_set_flags(self->ssl_ctx->param, verify_flags);
+         
+       switch (self->verify_mode)
+         {
+@@ -254,7 +266,7 @@ tls_context_setup_session(TLSContext *self)
+           verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+           break;
+         case TVM_REQUIRED | TVM_UNTRUSTED:
+-          verify_mode = SSL_VERIFY_NONE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
++          verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+           break;
+         case TVM_REQUIRED | TVM_TRUSTED:
+           verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+@@ -263,7 +275,7 @@ tls_context_setup_session(TLSContext *self)
+           g_assert_not_reached();
+         }  
+       
+-      SSL_CTX_set_verify(self->ssl_ctx, verify_mode, NULL);
++      SSL_CTX_set_verify(self->ssl_ctx, verify_mode, tls_session_verify_callback);
+       SSL_CTX_set_options(self->ssl_ctx, SSL_OP_NO_SSLv2);
+     }
+@@ -273,7 +285,10 @@ tls_context_setup_session(TLSContext *self)
+     SSL_set_connect_state(ssl);
+   else
+     SSL_set_accept_state(ssl);
+-  return tls_session_new(ssl, self);
++
++  session = tls_session_new(ssl, self);
++  SSL_set_app_data(ssl, session);
++  return session;
+  error:
+   ssl_error = ERR_get_error();
+diff --git a/src/tlscontext.h b/src/tlscontext.h
+index ada8e18..568682d 100644
+--- a/src/tlscontext.h
++++ b/src/tlscontext.h
+@@ -7,7 +7,7 @@
+ #include "syslog-ng.h"
+-#ifdef ENABLE_SSL
++#if ENABLE_SSL
+ #include <openssl/ssl.h>
+@@ -69,6 +69,9 @@ gboolean tls_verify_certificate_name(X509 *cert, const gchar *hostname);
+ #else
++typedef struct _TLSContext TLSContext;
++typedef struct _TLSSession TLSSession;
++
+ #define tls_context_new(m)
+ #endif
+diff --git a/src/tlstransport.c b/src/tlstransport.c
+index 608a427..2f07625 100644
+--- a/src/tlstransport.c
++++ b/src/tlstransport.c
+@@ -1,5 +1,7 @@
+ #include "tlstransport.h"
++#if ENABLE_SSL
++
+ #include "messages.h"
+ #include <openssl/ssl.h>
+@@ -149,4 +151,4 @@ log_transport_tls_free_method(LogTransport *s)
+   log_transport_free_method(s);
+ }
+-
++#endif
+diff --git a/tests/functional/func_test.py b/tests/functional/func_test.py
+index d7af8ff..ffd0fae 100755
+--- a/tests/functional/func_test.py
++++ b/tests/functional/func_test.py
+@@ -2,6 +2,7 @@
+ import os, sys, signal, traceback, time, errno
+ from socket import *
++import struct
+ padding = 'x' * 250
+ session_counter = 0
+@@ -39,12 +40,24 @@ class SocketSender(MessageSender):
+             self.sock = socket(self.family, SOCK_STREAM)
+         
+         self.sock.connect(self.sock_name)
++        self.sock.setsockopt(SOL_SOCKET, SO_SNDTIMEO, struct.pack('ll', 3, 0))
++        if self.dgram:
++                self.sock.send('')
+     
+     def sendMessage(self, msg):
+         line = '%s%s' % (msg, self.terminate_seq)
+         if self.send_by_bytes:
+             for c in line:
+-                self.sock.send(c)
++                try:
++                    self.sock.send(c)
++                except error, e:
++                    if e[0] == errno.ENOBUFS:
++                        print 'got ENOBUFS, sleeping...'
++                        time.sleep(0.5)
++                        repeat = True
++                    else:
++                        print "hmm... got an error to the 'send' call, maybe syslog-ng is not accepting messages?"
++                        raise
+         else:
+             repeat = True
+             while repeat:
+@@ -59,6 +72,9 @@ class SocketSender(MessageSender):
+                         print 'got ENOBUFS, sleeping...'
+                         time.sleep(0.5)
+                         repeat = True
++                    else:
++                        print "hmm... got an error to the 'send' call, maybe syslog-ng is not accepting messages?"
++                        raise
+     def __str__(self):
+         if self.family == AF_UNIX:
+diff --git a/tests/unit/test_logqueue.c b/tests/unit/test_logqueue.c
+index 6e9dd00..b27f08e 100644
+--- a/tests/unit/test_logqueue.c
++++ b/tests/unit/test_logqueue.c
+@@ -115,6 +115,91 @@ testcase_zero_diskbuf_alternating_send_acks()
+   log_queue_free(q);
+ }
++#if 0
++
++/* no synchronization between the feed/consume threads, therefore it does
++ * not succeed reliably. commented out for now, will fix at the next
++ * logqueue related threaded issue */
++
++GStaticMutex threaded_lock = G_STATIC_MUTEX_INIT;
++
++gpointer
++threaded_feed(gpointer st)
++{
++  LogQueue *q = (LogQueue *) st;
++  char *msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép";
++  gint i;
++  LogPathOptions path_options = LOG_PATH_OPTIONS_INIT;
++  LogMessage *msg;
++
++  for (i = 0; i < 100000; i++)
++    {
++      msg = log_msg_new(msg_str, strlen(msg_str), g_sockaddr_inet_new("10.10.10.10", 1010), 0, NULL, -1);
++      log_msg_add_ack(msg, &path_options);
++      msg->ack_func = test_ack;
++
++      g_static_mutex_lock(&threaded_lock);
++      if (!log_queue_push_tail(q, msg, &path_options))
 +        {
-+          msg_error("Error opening pipe, underlying file is not a FIFO, it should be used by file()",
-+                    evt_tag_str("filename", name),
-+                    NULL);
-+          goto exit;
++          fprintf(stderr, "Queue unable to consume enough messages: %d\n", fed_messages);
++          return GUINT_TO_POINTER(1);
 +        }
-+      else if (!is_pipe && S_ISFIFO(st.st_mode))
++      g_static_mutex_unlock(&threaded_lock);
++    }
++  return NULL;
++}
++
++gpointer
++threaded_consume(gpointer st)
++{
++  LogQueue *q = (LogQueue *) st;
++  LogMessage *msg;
++  LogPathOptions path_options = LOG_PATH_OPTIONS_INIT;
++  gboolean success;
++  gint i;
++
++  for (i = 0; i < 100000; i++)
++    {
++      g_static_mutex_lock(&threaded_lock);
++      msg = NULL;
++      success = log_queue_pop_head(q, &msg, &path_options, FALSE);
++      g_static_mutex_unlock(&threaded_lock);
++
++      g_assert(!success || (success && msg != NULL));
++      if (!success)
 +        {
-+          msg_error("Error opening file, underlying file is a FIFO, it should be used by pipe()",
-+                    evt_tag_str("filename", name),
-+                    NULL);
-+          goto exit;
++          fprintf(stderr, "Queue didn't return enough messages: i=%d\n", i);
++          return GUINT_TO_POINTER(1);
 +        }
++
++      log_msg_ack(msg, &path_options);
++      log_msg_unref(msg);
 +    }
-   *fd = open(name, flags, mode);
-   if (is_pipe && *fd < 0 && errno == ENOENT)
-     {
-@@ -82,6 +100,7 @@ affile_open_file(gchar *name, gint flags,
-       if (mode != -1)
-         fchmod(*fd, mode);
-     }
-+ exit:
-   if (privileged)
++
++  return NULL;
++}
++
++void
++testcase_with_threads()
++{
++  LogQueue *q;
++  GThread *thread_feed, *thread_consume;
++  gint i;
++
++  for (i = 0; i < 100; i++)
++    {
++      q = log_queue_new(100000, 0, 64);
++      thread_feed = g_thread_create(threaded_feed, q, TRUE, NULL);
++
++      thread_consume = g_thread_create(threaded_consume, q, TRUE, NULL);
++      g_thread_join(thread_feed);
++      g_thread_join(thread_consume);
++
++      log_queue_free(q);
++    }
++}
++#endif
++
+ int 
+ main()
+ {
+diff --git a/tests/unit/test_template.c b/tests/unit/test_template.c
+index 675b9d6..c499d8d 100644
+--- a/tests/unit/test_template.c
++++ b/tests/unit/test_template.c
+@@ -18,9 +18,13 @@ testcase(LogMessage *msg, gchar *template, gchar *expected)
+ {
+   LogTemplate *templ;
+   GString *res = g_string_sized_new(128);
++  static TimeZoneInfo *tzinfo = NULL;
++
++  if (!tzinfo)
++    tzinfo = time_zone_info_new(NULL);
+   
+   templ = log_template_new("dummy", template);
+-  log_template_format(templ, msg, LT_ESCAPE, TS_FMT_BSD, NULL, 3, 0, res);
++  log_template_format(templ, msg, LT_ESCAPE, TS_FMT_BSD, tzinfo, 3, 0, res);
+   
+   if (strcmp(res->str, expected) != 0)
      {
-       g_process_cap_restore(saved_caps);
+@@ -39,7 +43,7 @@ int
+ main(int argc G_GNUC_UNUSED, char *argv[] G_GNUC_UNUSED)
+ {
+   LogMessage *msg;
+-  char *msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép";
++  char *msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]:árvíztűrőtükörfúrógép";
+   GlobalConfig dummy;
+   
+   if (argc > 1)
+@@ -172,6 +176,14 @@ main(int argc G_GNUC_UNUSED, char *argv[] G_GNUC_UNUSED)
+   testcase(msg, "$PID", "");
+   log_msg_unref(msg);
++  msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]:árvíztűrőtükörfúrógép";
++
++  msg = log_msg_new(msg_str, strlen(msg_str), g_sockaddr_inet_new("10.10.10.10", 1010), LP_STORE_LEGACY_MSGHDR, NULL, -1);
++
++  testcase(msg, "$LEGACY_MSGHDR", "syslog-ng[23323]:");
++  testcase(msg, "$MSGHDR", "syslog-ng[23323]:");
++  log_msg_unref(msg);
++
+   msg_str = "<132>1 2006-10-29T01:59:59.156+01:00 mymachine evntslog 3535 ID47 [exampleSDID@0 iut=\"3\" eventSource=\"Application\" eventID=\"1011\"][examplePriority@0 class=\"high\"] BOMAn application event log entry..."; 
+   msg = log_msg_new(msg_str, strlen(msg_str), g_sockaddr_inet_new("10.10.10.10", 1010), LP_SYSLOG_PROTOCOL, NULL, -1);
+diff --git a/tgz2build/rules b/tgz2build/rules
+index 57eb338..7f2c776 100644
+--- a/tgz2build/rules
++++ b/tgz2build/rules
+@@ -3,7 +3,7 @@ STAMPDIR=tgz2build/stamps
+ DOCDIR=$(PREFIX)/doc
+-CONFIGURE_OPTS := --prefix $(ZBS_PREFIX) --enable-ssl --enable-dynamic-linking --enable-sql --enable-spoof-source --disable-tcp-wrapper --disable-pcre --with-ld-library-path=$(ZBS_PREFIX)/lib
++CONFIGURE_OPTS := --prefix $(ZBS_PREFIX) --enable-ssl --enable-dynamic-linking --enable-sql --enable-spoof-source --disable-tcp-wrapper --disable-pcre --with-ld-library-path=$(ZBS_PREFIX)/lib --with-pidfile-dir=$(ZBS_PREFIX)/var/run
+ INSTALL:=./install-sh
+ RPATH=-Wl,-R/opt/syslog-ng/lib
This page took 0.250497 seconds and 4 git commands to generate.