]> git.pld-linux.org Git - packages/syslog-ng.git/blob - syslog-ng-fixes.patch
- does not require logrotate; rel 13
[packages/syslog-ng.git] / syslog-ng-fixes.patch
1 diff --git a/configure.in b/configure.in
2 index d5f0769..1605bff 100644
3 --- a/configure.in
4 +++ b/configure.in
5 @@ -49,10 +49,8 @@ fi
6  
7  if test "x$prefix" = "xNONE"; then
8          prefix=$ac_default_prefix
9 -        pidfiledir="/var/run"
10 -else
11 -        pidfiledir="${prefix}/var/run"
12  fi
13 +pidfiledir="${localstatedir}"
14  
15  AM_CONFIG_HEADER(config.h)
16  
17 @@ -70,7 +68,7 @@ AC_ARG_WITH(pidfile-dir,
18         
19  AC_ARG_WITH(timezone-dir,
20     [  --with-timezone-dir=path   Use path as the directory to get the timezone files],
21 -   timezone_dir=$with_timezone_dir)
22 +   timezonedir=$with_timezone_dir)
23  
24  AC_ARG_WITH(ld-library-path,
25     [  --with-ld-library-path=path  Set LD_LIBRARY_PATH during runtime to the value given],
26 @@ -92,10 +90,13 @@ AC_ARG_ENABLE(ssl,
27                [  --enable-ssl        Enable SSL support.],,enable_ssl="auto")
28  
29  AC_ARG_ENABLE(dynamic-linking,
30 -              [  --enable-dynamic-linking        Link glib and eventlog dynamically instead of statically.])
31 +              [  --enable-dynamic-linking        Link glib and eventlog dynamically instead of statically.],,enable_dynamic_linking="auto")
32  
33  AC_ARG_ENABLE(static-linking,
34 -              [  --enable-static-linking         Link everything statically.])
35 +              [  --enable-static-linking         Link everything statically.],,enable_static_linking="auto")
36 +
37 +AC_ARG_ENABLE(mixed-linking,
38 +              [  --enable-mixed-linking          Link 3rd party libraries statically, system libraries dynamically],,enable_mixed_linking="auto")
39  
40  AC_ARG_ENABLE(ipv6,
41                [  --enable-ipv6           Enable support for IPv6.],,enable_ipv6="auto")
42 @@ -319,9 +320,6 @@ dnl ***************************************************************************
43  dnl OpenSSL headers/libraries
44  dnl ***************************************************************************
45  
46 -OPENSSL_LIBS=""
47 -OPENSSL_CPPFLAGS=""
48 -
49  # openssl is needed for:
50  #  * TLS support
51  
52 @@ -360,7 +358,13 @@ dnl libdbi headers/libraries
53  dnl ***************************************************************************
54  
55  AC_CHECK_LIB(dl, dlsym, DL_LIBS="-ldl")
56 -PKG_CHECK_MODULES(LIBDBI, dbi >= $LIBDBI_MIN_VERSION,, LIBDBI_LIBS="")
57 +PKG_CHECK_MODULES(LIBDBI, dbi >= $LIBDBI_MIN_VERSION,, libdbi_pkgconfig_not_found="1")
58 +
59 +if test "$libdbi_pkgconfig_not_found" -eq 1; then
60 +       dnl if libdbi has no .pc file, try it without one
61 +       AC_CHECK_LIB(dbi, dbi_initialize, LIBDBI_LIBS="-ldbi"; LIBDBI_CFLAGS="-I/usr/include")
62 +fi
63 +
64  
65  dnl ***************************************************************************
66  dnl Some more checks based on the detected settings above
67 @@ -606,8 +610,42 @@ int main()
68         fi
69  fi
70  
71 -if test "x$enable_dynamic_linking" = "xyes" -a "x$enable_static_linking" = "xyes"; then
72 -       AC_MSG_ERROR([You cannot specify dynamic and static linking at the same time.])
73 +if test "$enable_dynamic_linking" = "auto" -a "$enable_static_linking" = "auto" -a "$enable_mixed_linking" = "auto"; then
74 +       enable_dynamic_linking="yes"
75 +       enable_static_linking="no"
76 +       enable_mixed_linking="no"
77 +fi
78 +
79 +linkopts=0
80 +if test "x$enable_dynamic_linking" = "xyes"; then
81 +       linkopts=`expr $linkopts + 1`
82 +fi
83 +if test "x$enable_static_linking" = "xyes"; then
84 +       linkopts=`expr $linkopts + 1`
85 +fi
86 +if test "x$enable_mixed_linking" = "xyes"; then
87 +       linkopts=`expr $linkopts + 1`
88 +fi
89 +
90 +if test "$linkopts" -gt 1; then
91 +       AC_MSG_ERROR([You cannot specify multiple linking options at the same time (--enable-dynamic-linking, --enable-static-linking, --enable-mixed-linking).])
92 +fi
93 +
94 +if test "x$enable_dynamic_linking" = "xyes"; then
95 +       enable_dynamic_linking="yes"
96 +       enable_static_linking="no"
97 +       enable_mixed_linking="no"
98 +       linking_mode="dynamic"
99 +elif test "x$enable_static_linking" = "xyes"; then
100 +       enable_dynamic_linking="no"
101 +       enable_static_linking="yes"
102 +       enable_mixed_linking="no"
103 +       linking_mode="static"
104 +elif test "x$enable_mixed_linking" = "xyes"; then
105 +       enable_dynamic_linking="no"
106 +       enable_static_linking="no"
107 +       enable_mixed_linking="yes"
108 +       linking_mode="mixed"
109  fi
110  
111  if test "x$enable_dynamic_linking" != "xyes" -a "x$blb_cv_static_glib" = "xno"; then
112 @@ -615,7 +653,7 @@ if test "x$enable_dynamic_linking" != "xyes" -a "x$blb_cv_static_glib" = "xno";
113  fi
114  
115  if test "x$enable_dynamic_linking" != "xyes" -a "x$blb_cv_static_openssl" = "xno"; then
116 -       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])
117 +       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])
118  fi
119  
120  
121 @@ -672,8 +710,8 @@ AC_DEFINE_UNQUOTED(PATH_PREFIX, "`patheval $prefix`", [prefix directory])
122  AC_DEFINE_UNQUOTED(PATH_SYSCONFDIR, "`patheval $sysconfdir`", [sysconfdir])
123  AC_DEFINE_UNQUOTED(PATH_LOCALSTATEDIR, "`patheval $localstatedir`", [local state directory])
124  AC_DEFINE_UNQUOTED(PATH_PIDFILEDIR, "`patheval $pidfiledir`", [local state directory])
125 -if test -n "$timezone_dir"; then
126 -        AC_DEFINE_UNQUOTED(PATH_TIMEZONEDIR, "`patheval $timezone_dir`", [timezone base directory])
127 +if test -n "$timezonedir"; then
128 +        AC_DEFINE_UNQUOTED(PATH_TIMEZONEDIR, "`patheval $timezonedir`", [timezone base directory])
129  fi
130  if test -n "$env_ld_library_path"; then
131          AC_DEFINE_UNQUOTED(ENV_LD_LIBRARY_PATH, "$env_ld_library_path", [set LD_LIBRARY_PATH to this value])
132 @@ -695,6 +733,8 @@ AC_DEFINE_UNQUOTED(ENABLE_ENV_WRAPPER, `enable_value $enable_env_wrapper`, [Enab
133  
134  AM_CONDITIONAL(ENABLE_ENV_WRAPPER, [test "$enable_env_wrapper" = "yes"])
135  
136 +AC_SUBST(timezonedir)
137 +AC_SUBST(pidfiledir)
138  AC_SUBST(DEPS_CPPFLAGS)
139  AC_SUBST(DEPS_LIBS)
140  AC_SUBST(BASE_LIBS)
141 @@ -729,6 +769,7 @@ echo "  compiler                    : $CC"
142  echo "  compiler options            : $CFLAGS $CPPFLAGS"
143  echo "  linker flags                : $LDFLAGS $LIBS"
144  echo "  prefix                      : $prefix"
145 +echo "  linking mode                : $linking_mode"
146  echo " Features:"
147  echo "  Sun STREAMS support         : ${enable_sun_streams:=no}"
148  echo "  Sun Door support            : ${enable_sun_door:=no}"
149 diff --git a/contrib/balabit-initscripts/init-functions b/contrib/balabit-initscripts/init-functions
150 index e1898a8..c3b18ef 100644
151 --- a/contrib/balabit-initscripts/init-functions
152 +++ b/contrib/balabit-initscripts/init-functions
153 @@ -6,12 +6,35 @@ NORMAL=
154  FANCYTTY=
155  PSOPTS=
156  
157 -case `uname -s` in
158 +ECHO=echo
159 +
160 +OS=`uname -s`
161 +
162 +disable_xpg_echo() {
163 +  # \X chars only passed to echo under bash, if xpg_echo enabled or echo -e
164 +  # used on Linux.
165 +  if [ -n "$BASH_VERSION" ];then
166 +    shopt -s xpg_echo
167 +  fi
168 +}
169 +
170 +case $OS in
171    # default ps -e cuts the process' name at 8 characters, so we have to list it
172    # in a long form
173 -  SunOS) PSOPTS=" -o pid -o tty -o time -o comm" ;;
174 +  SunOS)
175 +        PSOPTS=" -o pid -o tty -o time -o comm"
176 +        disable_xpg_echo
177 +        ;;
178 +  Linux)
179 +        if [ -z "$BASH_VERSION" ]; then
180 +          # beware of dash's builtin echo ...
181 +          ECHO="/bin/echo -e"
182 +        fi
183 +        ;;
184 +  *)    disable_xpg_echo ;;
185  esac
186  
187 +
188  _checkpid() {
189    _pid=$1
190    _proc=$2
191 @@ -30,7 +53,7 @@ _pid_from_pidfile() {
192    pid=
193  
194    if [ -f "$pidfile" ];then
195 -    pid=`head -1 $pidfile`
196 +    pid=`head -1 $pidfile 2> /dev/null`
197      if [ $? -ne 0 ]; then
198        # on slow machines (or ones under high load) the pidfile could be
199        # erased between -f and `head` ...
200 @@ -195,17 +218,17 @@ log_use_fancy_output() {
201  
202  
203  log_success_msg() {
204 -  echo "$@"
205 +  $ECHO "$@"
206  }
207  
208  log_failure_msg() {
209    log_use_fancy_output
210 -  echo "${RED}$@${NORMAL}"   
211 +  $ECHO "${RED}$@${NORMAL}"
212  }
213  
214  log_warning_msg() {
215    log_use_fancy_output
216 -  echo "${YELLOW}$@${NORMAL}"   
217 +  $ECHO "${YELLOW}$@${NORMAL}"
218  }
219  
220  # NON-LSB Functions
221 @@ -215,7 +238,7 @@ log_begin_msg() {
222      return 1
223    fi
224  
225 -  echo "$@\c " 
226 +  $ECHO "$@\c "
227  }
228  
229  log_daemon_msg() {
230 @@ -224,11 +247,11 @@ log_daemon_msg() {
231    fi
232  
233    if [ -z "$2" ]; then
234 -    echo "$1:\c "
235 +    $ECHO "$1:\c "
236      return
237    fi
238  
239 -  echo "$1: $2\c "
240 +  $ECHO "$1: $2\c "
241  }
242  
243  log_progress_msg() {
244 @@ -237,9 +260,9 @@ log_progress_msg() {
245    fi
246  
247    if [ $1 -eq 0 ]; then
248 -    echo "."
249 +    $ECHO "."
250    else
251 -    echo " failed"
252 +    $ECHO " failed"
253    fi
254  }
255  
256 @@ -250,23 +273,23 @@ log_end_msg() {
257  
258    log_fancy_output
259    if [ $1 -eq 0 ];then
260 -    echo "."
261 +    $ECHO "."
262    else
263 -    echo "${RED}failed!${NORMAL}"
264 +    $ECHO "${RED}failed!${NORMAL}"
265    fi
266    return $1
267  }
268  
269  log_action_msg() {
270 -  echo "$@."
271 +  $ECHO "$@."
272  }
273  
274  log_action_begin_msg() {
275 -  echo "$@...\c "
276 +  $ECHO "$@...\c "
277  }
278  
279  log_action_cont_msg() {
280 -  echo "$@...\c "
281 +  $ECHO "$@...\c "
282  }
283  
284  log_action_end_msg() {
285 @@ -278,15 +301,12 @@ log_action_end_msg() {
286  
287    log_fancy_output
288    if [ $1 -eq 0 ]; then
289 -    echo "done${end}"
290 +    $ECHO "done${end}"
291    else
292 -    echo "${RED}failed${end}${NORMAL}"
293 +    $ECHO "${RED}failed${end}${NORMAL}"
294    fi
295  }
296  
297 -# \X chars only passed to echo under bash, if xpg_echo enabled....
298 -if [ -n "$BASH_VERSION" ];then
299 -  shopt -s xpg_echo
300 -fi
301  
302  # vim: ft=sh ts=2 expandtab
303 +
304 diff --git a/contrib/balabit-initscripts/init.d b/contrib/balabit-initscripts/init.d
305 index ff2e249..589da86 100644
306 --- a/contrib/balabit-initscripts/init.d
307 +++ b/contrib/balabit-initscripts/init.d
308 @@ -25,6 +25,7 @@ SYSLOGNG_PREFIX=/opt/syslog-ng
309  SYSLOGNG="$SYSLOGNG_PREFIX/sbin/syslog-ng"
310  CONFFILE=$SYSLOGNG_PREFIX/etc/syslog-ng.conf
311  PIDFILE=$SYSLOGNG_PREFIX/var/run/syslog-ng.pid
312 +SYSLOGPIDFILE="/var/run/syslog.pid"
313  
314  INIT_FUNCTIONS=/lib/lsb/init-functions
315  SLNG_INIT_FUNCTIONS=$SYSLOGNG_PREFIX/lib/init-functions
316 @@ -64,6 +65,17 @@ if [ -f /etc/lsb-release ]; then
317         . /etc/lsb-release
318  fi
319  
320 +if [ -f "/etc/redhat-release" ];then
321 +       # redhat uses a different syslogd pidfile...
322 +       SYSLOGPIDFILE="/var/run/syslogd.pid"
323 +fi
324 +
325 +if [ "$OS" = "SunOS" ] || [ "$OS" = "Solaris" ];then
326 +       if [ "`uname -r`" = "5.8" ];then
327 +               SYSLOGPIDFILE="/etc/syslog.pid"
328 +       fi
329 +fi
330 +
331  if [ -f /lib/lsb/init-functions ];then
332         # long list of exclusions... 
333         if [ -f "/etc/redhat-release" ] || [ -f "/etc/SuSE-release" ];then
334 @@ -117,7 +129,7 @@ check_syntax() {
335  
336  slng_waitforpid() {
337         _pid=$1
338 -  _process=$2
339 +       _process=$2
340         _cnt=$MAXWAIT
341  
342         # no pid, return...
343 @@ -147,6 +159,11 @@ returnmessage() {
344  
345  syslogng_start() {
346         echo_n "Starting syslog-ng: "
347 +       PID=`pidofproc -p ${PIDFILE} ${SYSLOGNG} | head -1`
348 +       if [ -n "$PID" ] && [ $PID -gt 0 ] ;then
349 +               log_success_msg "already running: $PID"
350 +               return $retval
351 +       fi
352         start_daemon -p ${PIDFILE} ${SYSLOGNG} ${SYSLOGNG_OPTIONS}
353         retval=$?
354         returnmessage $retval
355 @@ -154,6 +171,13 @@ syslogng_start() {
356                 if [ "$OS" = "Linux" ] && [ -d $SUBSYSDIR ];then
357                         touch $SUBSYSDIR/syslog-ng
358                 fi
359 +               # remove symlinks
360 +               if [ -h $SYSLOGPIDFILE ];then
361 +                       rm -f $SYSLOGPIDFILE
362 +               fi
363 +               if [ ! -f $SYSLOGPIDFILE ];then
364 +                       ln -s $PIDFILE $SYSLOGPIDFILE
365 +               fi
366         fi
367         return $retval
368  }
369 @@ -180,6 +204,9 @@ syslogng_stop() {
370         fi
371         if [ $retval -eq 0 ];then
372                 rm -f $SUBSYSDIR/syslog-ng ${PIDFILE}
373 +               if [ -h $SYSLOGPIDFILE ];then
374 +                       rm -f $SYSLOGPIDFILE
375 +               fi
376         fi
377         return $retval
378  }
379 @@ -270,6 +297,14 @@ case "$1" in
380         force-reload)
381                 syslogng_restart
382                 ;;
383 +       reload-or-restart)
384 +               PID=`pidofproc -p ${PIDFILE} ${SYSLOGNG} | head -1`
385 +               if [ -n "$PID" ] && [ $PID -gt 0 ] ;then
386 +                       syslogng_reload
387 +               else
388 +                       syslogng_start
389 +               fi
390 +               ;;
391         status)
392                 syslogng_status 
393                 ;;
394 @@ -284,4 +319,4 @@ esac
395  
396  exit $retval
397  
398 -# vim: ts=2 ft=sh
399 +# vim: ts=2 ft=sh noexpandtab
400 diff --git a/contrib/balabit-initscripts/init.d.freebsd b/contrib/balabit-initscripts/init.d.freebsd
401 index 997b4db..de04473 100644
402 --- a/contrib/balabit-initscripts/init.d.freebsd
403 +++ b/contrib/balabit-initscripts/init.d.freebsd
404 @@ -33,9 +33,13 @@ command="$SYSLOGNG_PREFIX/sbin/syslog-ng"
405  required_files="$SYSLOGNG_PREFIX/etc/syslog-ng.conf"
406  
407  start_precmd="syslog_ng_start_precmd"
408 +start_postcmd="syslog_ng_start_postcmd"
409 +stop_postcmd="syslog_ng_stop_postcmd"
410  reload_precmd="syslog_ng_reload_precmd"
411  extra_commands="reload"
412  
413 +# get original syslog pidfile from initscript.
414 +_syslogd_pidfile=`sed -n -e 's/^pidfile="\([^"]*\)"/\1/p' /etc/rc.d/syslogd 2> /dev/null`
415  syslog_ng_start_precmd() {
416         if [ ! -L /dev/log ]; then
417                 ln -s /var/run/log /dev/log
418 @@ -50,6 +54,26 @@ syslog_ng_reload_precmd() {
419         fi
420  }
421  
422 +syslog_ng_start_postcmd() {
423 +       if [ -n "$_syslogd_pidfile" ]; then
424 +               # remove symlinks
425 +               if [ -h $_syslogd_pidfile ]; then
426 +                       rm -f $_syslogd_pidfile
427 +               fi
428 +               if [ ! -f $_syslogd_pidfile ]; then
429 +                       ln -s "$pidfile" "$_syslogd_pidfile"
430 +               fi
431 +       fi
432 +}
433 +
434 +syslog_ng_stop_postcmd() {
435 +       if [ -n "$_syslogd_pidfile" ]; then
436 +               if [ -h $_syslogd_pidfile ]; then
437 +                       rm -f "$_syslogd_pidfile"
438 +               fi
439 +       fi
440 +}
441 +
442  load_rc_config "$name"
443  
444  case $1 in
445 diff --git a/contrib/cygwin-packaging/cygwin-postinstall b/contrib/cygwin-packaging/cygwin-postinstall
446 index 4b7bf7d..e812ead 100755
447 --- a/contrib/cygwin-packaging/cygwin-postinstall
448 +++ b/contrib/cygwin-packaging/cygwin-postinstall
449 @@ -21,11 +21,11 @@ then
450    exit 3
451  fi
452  mkdir -p "${DESTDIR}/usr/bin"
453 -mkdir -p "${DESTDIR}/usr/share/doc/syslog-ng"
454 +#mkdir -p "${DESTDIR}/usr/share/doc/syslog-ng"
455  mkdir -p "${DESTDIR}/usr/share/doc/Cygwin"
456  cp contrib/cygwin-packaging/syslog-ng-config "${DESTDIR}/usr/bin"
457 -cp -rp doc/examples/syslog-ng.conf.s* doc/reference/syslog-ng.[tx]* "${DESTDIR}/usr/share/doc/syslog-ng"
458 -tar xzfC doc/reference/syslog-ng.html.tar.gz "${DESTDIR}/usr/share/doc/syslog-ng"
459 +#cp -rp doc/examples/syslog-ng.conf.s* doc/reference/syslog-ng.[tx]* "${DESTDIR}/usr/share/doc/syslog-ng"
460 +#tar xzfC doc/reference/syslog-ng.html.tar.gz "${DESTDIR}/usr/share/doc/syslog-ng"
461  cat > "${DESTDIR}/usr/share/doc/Cygwin/syslog-ng.README" <<'EOF'
462  If you want to use syslog-ng, just run the /usr/bin/syslog-ng-config
463  script.  This script will create a default configuration file
464 @@ -42,15 +42,15 @@ The syslog-ng package has been built using the following command
465  sequence from the top level source dir:
466  
467  ./configure \
468 -       --disable-ipv6 \
469 -       --disable-tcp-wrapper \
470          --prefix=/usr \
471          --sysconfdir=/etc \
472          --libexecdir='$(prefix)/sbin' \
473          --localstatedir=/var \
474          --datadir='$(prefix)/share' \
475          --mandir='$(prefix)/share/man' \
476 -        --infodir='$(prefix)/share/info'
477 +        --infodir='$(prefix)/share/info' \
478 +       --enable-dynamic-linking \
479 +       --with-pidfile-dir=/var
480  make
481  make install-strip
482  contrib/cygwin-packaging/cygwin-postinstall
483 diff --git a/contrib/cygwin-packaging/syslog-ng-config b/contrib/cygwin-packaging/syslog-ng-config
484 index 790f0cc..7ae5fec 100755
485 --- a/contrib/cygwin-packaging/syslog-ng-config
486 +++ b/contrib/cygwin-packaging/syslog-ng-config
487 @@ -205,13 +205,13 @@ if [ ! -f "${SYSCONFDIR}/syslog-ng.conf" ]
488  then
489    echo "Creating default ${SYSCONFDIR}/syslog-ng.conf file"
490    cat > ${SYSCONFDIR}/syslog-ng.conf << EOF
491 +@version 3.0
492  options {
493    keep_hostname(yes);
494 -  chain_hostnames(no);
495    owner("system");
496    group("root");
497    perm(0664);
498 -  sync(0);
499 +  flush_lines(0);
500  };
501  
502  source applications {
503 @@ -220,7 +220,7 @@ source applications {
504  };
505  
506  source kernel {
507 -  file("/dev/kmsg", log_prefix("kernel: "));
508 +  file("/dev/kmsg", program_override("kernel: "));
509  };
510  
511  destination messages {
512 @@ -240,42 +240,35 @@ EOF
513  fi
514  setfacl -m u:system:rw- "${SYSCONFDIR}/syslog-ng.conf"
515  
516 -# Check if running on NT
517 -_sys="`uname`"
518 -_nt=`expr "${_sys}" : "CYGWIN_NT"`
519 -# On NT ask if syslog-ng should be installed as service
520 -if [ ${_nt} -gt 0 ]
521 +# Check if syslogd is installed and remove on user request.
522 +if cygrunsrv -Q syslogd > /dev/null 2>&1
523  then
524 -  # Check if syslogd is installed and remove on user request.
525 -  if cygrunsrv -Q syslogd > /dev/null 2>&1
526 +  echo "Warning: The syslogd service is already installed.  You can not"
527 +  echo "run both, syslogd and syslog-ng in parallel."
528 +  echo
529 +  if request "Do you want to deinstall the syslogd service in favor of syslog-ng?"
530    then
531 -    echo "Warning: The syslogd service is already installed.  You can not"
532 -    echo "run both, syslogd and syslog-ng in parallel."
533 -    echo
534 -    if request "Do you want to deinstall the syslogd service in favor of syslog-ng?"
535 -    then
536 -      cygrunsrv -E syslogd
537 -      cygrunsrv -R syslogd
538 -    fi
539 +    cygrunsrv -E syslogd
540 +    cygrunsrv -R syslogd
541    fi
542 -  # Install syslog-ng service if it is not already installed
543 -  if ! cygrunsrv -Q syslog-ng > /dev/null 2>&1
544 +fi
545 +# Install syslog-ng service if it is not already installed
546 +if ! cygrunsrv -Q syslog-ng > /dev/null 2>&1
547 +then
548 +  echo
549 +  echo
550 +  echo "Warning: The following function requires administrator privileges!"
551 +  echo
552 +  echo "Do you want to install syslog-ng as service?"
553 +  if request "(Say \"no\" if it's already installed as service)"
554    then
555 -    echo
556 -    echo
557 -    echo "Warning: The following function requires administrator privileges!"
558 -    echo
559 -    echo "Do you want to install syslog-ng as service?"
560 -    if request "(Say \"no\" if it's already installed as service)"
561 +    if cygrunsrv -I syslog-ng -d "CYGWIN syslog-ng" -p /usr/sbin/syslog-ng -a "-F --fd-limit 256"
562      then
563 -      if cygrunsrv -I syslog-ng -d "CYGWIN syslog-ng" -p /usr/sbin/syslog-ng -a -F
564 -      then
565 -       echo
566 -       echo "The service has been installed under LocalSystem account."
567 -       echo "To start the service, call \`net start syslog-ng' or \`cygrunsrv -S syslog-ng'."
568 -       echo
569 -       echo "Check ${SYSCONFDIR}/syslog-ng.conf first, if it suits your needs."
570 -      fi
571 +     echo
572 +     echo "The service has been installed under LocalSystem account."
573 +     echo "To start the service, call \`net start syslog-ng' or \`cygrunsrv -S syslog-ng'."
574 +     echo
575 +     echo "Check ${SYSCONFDIR}/syslog-ng.conf first, if it suits your needs."
576      fi
577    fi
578  fi
579 diff --git a/contrib/solaris-packaging/syslog-ng.method b/contrib/solaris-packaging/syslog-ng.method
580 index f0fee58..d819a3c 100755
581 --- a/contrib/solaris-packaging/syslog-ng.method
582 +++ b/contrib/solaris-packaging/syslog-ng.method
583 @@ -13,6 +13,7 @@ SYSLOGNG_PREFIX=/opt/syslog-ng
584  SYSLOGNG="$SYSLOGNG_PREFIX/sbin/syslog-ng"
585  CONFFILE=$SYSLOGNG_PREFIX/etc/syslog-ng.conf
586  PIDFILE=$SYSLOGNG_PREFIX/var/run/syslog-ng.pid
587 +SYSLOGPIDFILE=/var/run/syslog.pid
588  
589  OPTIONS=
590  MAXWAIT=30
591 @@ -56,7 +57,7 @@ slng_stop() {
592  
593          _process=`basename $SYSLOGNG`
594          slng_waitforpid "$_process" $syspid
595 -       _ret=$?
596 +        _ret=$?
597          if [ $_ret -eq 0 ]; then
598                  kill -KILL $syspid
599                  $_ret=$?
600 @@ -68,6 +69,9 @@ slng_stop() {
601                          [ $? -ne 0 ] && exit $SMF_EXIT_ERR_FATAL
602                  fi
603                  rm -f $PIDFILE
604 +                if [ -h $SYSLOGPIDFILE ];then
605 +                        rm -f $SYSLOGPIDFILE
606 +                fi
607                  return $SMF_EXIT_OK
608          fi
609          return $SMF_EXIT_ERR_FATAL
610 @@ -93,6 +97,13 @@ slng_start () {
611                  fi
612                  check_syntax
613                  $SYSLOGNG $OPTIONS
614 +                # remove symlinks
615 +                if [ -h $SYSLOGPIDFILE ];then
616 +                        rm -f $SYSLOGPIDFILE
617 +                fi
618 +                if [ ! -f $SYSLOGPIDFILE ];then
619 +                        ln -s $PIDFILE $SYSLOGPIDFILE
620 +                fi
621                  return $SMF_EXIT_OK
622          fi
623          return $SMF_EXIT_ERR_FATAL
624 diff --git a/debian/control b/debian/control
625 index c0689a5..0dcc8b3 100644
626 --- a/debian/control
627 +++ b/debian/control
628 @@ -2,7 +2,7 @@ Source: syslog-ng
629  Section: admin
630  Priority: extra
631  Maintainer: SZALAY Attila <sasa@debian.org>
632 -Build-depends: debhelper (>=3.0.0), libevtlog-dev, libnet1-dev, libglib2.0-dev (>= 2.4), pkg-config, libdbi-dev
633 +Build-depends: debhelper (>=3.0.0), libevtlog-dev, libnet1-dev, libglib2.0-dev (>= 2.4), pkg-config, libdbi0-dev, libssl-dev
634  Standards-Version: 3.6.1
635  
636  Package: syslog-ng
637 diff --git a/src/affile.c b/src/affile.c
638 index 6d48915..5721a1a 100644
639 --- a/src/affile.c
640 +++ b/src/affile.c
641 @@ -40,11 +40,12 @@
642  
643  static gboolean
644  affile_open_file(gchar *name, gint flags,
645 -            uid_t uid, gid_t gid, mode_t mode,
646 -            uid_t dir_uid, gid_t dir_gid, mode_t dir_mode,
647 -            gboolean create_dirs, gboolean privileged, gint *fd)
648 +                 uid_t uid, gid_t gid, mode_t mode,
649 +                 uid_t dir_uid, gid_t dir_gid, mode_t dir_mode,
650 +                 gboolean create_dirs, gboolean privileged, gboolean is_pipe, gint *fd)
651  {
652    cap_t saved_caps;
653 +  struct stat st;
654  
655    if (strstr(name, "../") || strstr(name, "/..")) 
656      {
657 @@ -63,20 +64,43 @@ affile_open_file(gchar *name, gint flags,
658        g_process_cap_modify(CAP_DAC_READ_SEARCH, TRUE);
659        g_process_cap_modify(CAP_SYS_ADMIN, TRUE);
660      }
661 +  if (stat(name, &st) >= 0)
662 +    {
663 +      if (is_pipe && !S_ISFIFO(st.st_mode))
664 +        {
665 +          msg_error("Error opening pipe, underlying file is not a FIFO, it should be used by file()",
666 +                    evt_tag_str("filename", name),
667 +                    NULL);
668 +          goto exit;
669 +        }
670 +      else if (!is_pipe && S_ISFIFO(st.st_mode))
671 +        {
672 +          msg_error("Error opening file, underlying file is a FIFO, it should be used by pipe()",
673 +                    evt_tag_str("filename", name),
674 +                    NULL);
675 +          goto exit;
676 +        }
677 +    }
678    *fd = open(name, flags, mode);
679 +  if (is_pipe && *fd < 0 && errno == ENOENT)
680 +    {
681 +      if (mkfifo(name, 0666) >= 0)
682 +        *fd = open(name, flags, 0666);
683 +    }
684  
685    if (*fd != -1)
686      {
687        g_fd_set_cloexec(*fd, TRUE);
688        
689        g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);
690 -      if (uid != -1)
691 +      if (uid != (uid_t) -1)
692          fchown(*fd, uid, -1);
693 -      if (gid != -1)
694 +      if (gid != (gid_t) -1)
695          fchown(*fd, -1, gid);
696 -      if (mode != -1)
697 +      if (mode != (mode_t) -1)
698          fchmod(*fd, mode);
699      }
700 + exit:
701    if (privileged)
702      {
703        g_process_cap_restore(saved_caps);
704 @@ -99,7 +123,7 @@ affile_sd_open_file(AFFileSourceDriver *self, gchar *name, gint *fd)
705    else
706      flags = O_RDONLY | O_NOCTTY | O_NONBLOCK | O_LARGEFILE;
707  
708 -  if (affile_open_file(name, flags, -1, -1, -1, 0, 0, 0, 0, !!(self->flags & AFFILE_PRIVILEGED), fd))
709 +  if (affile_open_file(name, flags, -1, -1, -1, 0, 0, 0, 0, !!(self->flags & AFFILE_PRIVILEGED), !!(self->flags & AFFILE_PIPE), fd))
710      return TRUE;
711    return FALSE;
712  }
713 @@ -196,9 +220,15 @@ affile_sd_notify(LogPipe *s, LogPipe *sender, gint notify_code, gpointer user_da
714              transport = log_transport_plain_new(fd, 0);
715              transport->timeout = 10;
716  
717 -            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)), 
718 -                                          LR_LOCAL);
719 -                                          
720 +            self->reader = log_reader_new(
721 +                                  log_proto_plain_new_server(transport, self->reader_options.padding,
722 +                                                             self->reader_options.msg_size,
723 +                                                             ((self->reader_options.follow_freq > 0)
724 +                                                                    ? LPPF_IGNORE_EOF
725 +                                                                    : LPPF_NOMREAD)
726 +                                                            ),
727 +                                  LR_LOCAL);
728 +
729              log_reader_set_options(self->reader, s, &self->reader_options, 1, SCS_FILE, self->super.id, self->filename->str);
730  
731              log_reader_set_follow_filename(self->reader, self->filename->str);
732 @@ -290,10 +320,16 @@ affile_sd_init(LogPipe *s)
733        transport->timeout = 10;
734  
735        /* FIXME: we shouldn't use reader_options to store log protocol parameters */
736 -      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)), 
737 -                                    LR_LOCAL);
738 +      self->reader = log_reader_new(
739 +                            log_proto_plain_new_server(transport, self->reader_options.padding,
740 +                                                       self->reader_options.msg_size,
741 +                                                       ((self->reader_options.follow_freq > 0)
742 +                                                            ? LPPF_IGNORE_EOF
743 +                                                            : LPPF_NOMREAD)
744 +                                                      ),
745 +                            LR_LOCAL);
746        log_reader_set_options(self->reader, s, &self->reader_options, 1, SCS_FILE, self->super.id, self->filename->str);
747 -      
748 +
749        log_reader_set_follow_filename(self->reader, self->filename->str);
750  
751        /* NOTE: if the file could not be opened, we ignore the last
752 @@ -458,7 +494,7 @@ affile_dw_init(LogPipe *s)
753    if (affile_open_file(self->filename->str, flags, 
754                         self->owner->file_uid, self->owner->file_gid, self->owner->file_perm, 
755                         self->owner->dir_uid, self->owner->dir_gid, self->owner->dir_perm, 
756 -                       !!(self->owner->flags & AFFILE_CREATE_DIRS), FALSE, &fd))
757 +                       !!(self->owner->flags & AFFILE_CREATE_DIRS), FALSE, !!(self->owner->flags & AFFILE_PIPE), &fd))
758      {
759        guint write_flags;
760        
761 diff --git a/src/afsocket.c b/src/afsocket.c
762 index ad8e198..af788f6 100644
763 --- a/src/afsocket.c
764 +++ b/src/afsocket.c
765 @@ -90,12 +90,12 @@ afsocket_open_socket(GSockAddr *bind_addr, int stream_or_dgram, int *fd)
766    else
767      sock = socket(bind_addr->sa.sa_family, SOCK_DGRAM, 0);
768      
769 -  g_fd_set_nonblock(sock, TRUE);
770 -  g_fd_set_cloexec(sock, TRUE);
771    if (sock != -1)
772      {
773        cap_t saved_caps;
774  
775 +      g_fd_set_nonblock(sock, TRUE);
776 +      g_fd_set_cloexec(sock, TRUE);
777        saved_caps = g_process_cap_save();
778        g_process_cap_modify(CAP_NET_BIND_SERVICE, TRUE);
779        g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);
780 @@ -208,7 +208,9 @@ afsocket_sc_init(LogPipe *s)
781    if ((self->owner->flags & AFSOCKET_SYSLOG_PROTOCOL) == 0)
782      {
783        /* plain protocol */
784 -      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);
785 +      proto = log_proto_plain_new_server(transport, self->owner->reader_options.padding,
786 +                   self->owner->reader_options.msg_size,
787 +                   (self->owner->flags & AFSOCKET_DGRAM) ? (LPPF_PKTTERM + LPPF_IGNORE_EOF) : 0);
788      }
789    else
790      {
791 diff --git a/src/afsql.c b/src/afsql.c
792 index 96c5b22..dcbc02e 100644
793 --- a/src/afsql.c
794 +++ b/src/afsql.c
795 @@ -940,6 +940,7 @@ afsql_dd_new()
796    self->frac_digits = -1;
797  
798    self->validated_tables = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
799 +  g_static_mutex_init(&self->queue_lock);
800    
801    init_sequence_number(&self->seq_num);
802    return &self->super;  
803 diff --git a/src/apphook.c b/src/apphook.c
804 index ab9cb02..6115b27 100644
805 --- a/src/apphook.c
806 +++ b/src/apphook.c
807 @@ -54,10 +54,10 @@ run_application_hook(gint type)
808        
809        if (e->type == type)
810          {
811 +          l_next = l->next;
812            application_hooks = g_list_remove_link(application_hooks, l);
813            e->func(type, e->user_data);
814            g_free(e);
815 -          l_next = l->next;
816            g_list_free_1(l);
817          }
818        else
819 diff --git a/src/cfg-grammar.y b/src/cfg-grammar.y
820 index 9902d84..056783d 100644
821 --- a/src/cfg-grammar.y
822 +++ b/src/cfg-grammar.y
823 @@ -52,6 +52,7 @@ LogParser *last_parser;
824  FilterRE *last_re_filter;
825  LogRewrite *last_rewrite;
826  gint last_addr_family = AF_INET;
827 +gchar *last_include_file;
828  
829  #if ENABLE_SSL
830  TLSContext *last_tls_context;
831 @@ -92,17 +93,20 @@ cfg_check_template(LogTemplate *template)
832    return TRUE;
833  }
834  
835 +
836  %}
837  
838  %union {
839 +        gint token;
840         gint64 num;
841 +       double fnum;
842         char *cptr;
843         void *ptr;
844         FilterExprNode *node;
845  }
846  
847  /* statements */
848 -%token KW_SOURCE KW_FILTER KW_PARSER KW_DESTINATION KW_LOG KW_OPTIONS 
849 +%token KW_SOURCE KW_FILTER KW_PARSER KW_DESTINATION KW_LOG KW_OPTIONS KW_INCLUDE
850  
851  /* source & destination items */
852  %token KW_INTERNAL KW_FILE KW_PIPE KW_UNIX_STREAM KW_UNIX_DGRAM
853 @@ -154,7 +158,7 @@ cfg_check_template(LogTemplate *template)
854  
855  /* socket related options */
856  %token KW_KEEP_ALIVE KW_MAX_CONNECTIONS
857 -%token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT KW_FRAMED
858 +%token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT
859  %token KW_IP_TTL KW_SO_BROADCAST KW_IP_TOS KW_SO_SNDBUF KW_SO_RCVBUF KW_SO_KEEPALIVE KW_SPOOF_SOURCE
860  
861  /* misc options */
862 @@ -182,6 +186,7 @@ cfg_check_template(LogTemplate *template)
863  %token  DOTDOT
864  %token <cptr> IDENTIFIER
865  %token <num>  NUMBER
866 +%token <fnum> FLOAT
867  %token <cptr> STRING
868  
869  %left  KW_OR
870 @@ -276,6 +281,32 @@ cfg_check_template(LogTemplate *template)
871  %type   <ptr> string_list
872  %type   <ptr> string_list_build
873  
874 +%type   <token> reserved_words_as_strings
875 +
876 +%type <token> KW_PARSER
877 +%type <token> KW_REWRITE
878 +%type <token> KW_INCLUDE
879 +%type <token> KW_SYSLOG
880 +%type <token> KW_COLUMNS
881 +%type <token> KW_DELIMITERS
882 +%type <token> KW_QUOTES
883 +%type <token> KW_QUOTE_PAIRS
884 +%type <token> KW_NULL
885 +%type <token> KW_CSV_PARSER
886 +%type <token> KW_DB_PARSER
887 +%type <token> KW_ENCODING
888 +%type <token> KW_SET
889 +%type <token> KW_SUBST
890 +%type <token> KW_VALUE
891 +%type <token> KW_PROGRAM_OVERRIDE
892 +%type <token> KW_HOST_OVERRIDE
893 +%type <token> KW_TRANSPORT
894 +%type <token> KW_TRUSTED_KEYS
895 +%type <token> KW_TRUSTED_DN
896 +%type <token> KW_MESSAGE
897 +%type <token> KW_TYPE
898 +%type <token> KW_SQL
899 +
900  %%
901  
902  start   
903 @@ -283,7 +314,21 @@ start
904         ;
905  
906  stmts   
907 -        : stmt ';' stmts
908 +        : stmt ';' 
909 +          { 
910 +            if (last_include_file && !cfg_lex_process_include(last_include_file)) 
911 +              { 
912 +                free(last_include_file);
913 +                last_include_file = NULL;
914 +                YYERROR; 
915 +              } 
916 +            if (last_include_file)
917 +              {
918 +                free(last_include_file);
919 +                last_include_file = NULL;
920 +              }
921 +          }
922 +          stmts
923         |       
924         ;
925  
926 @@ -296,6 +341,7 @@ stmt
927          | KW_REWRITE rewrite_stmt               { cfg_add_rewrite(configuration, $2); }
928         | KW_TEMPLATE template_stmt             { cfg_add_template(configuration, $2); }
929         | KW_OPTIONS options_stmt               {  }
930 +       | KW_INCLUDE include_stmt               {  }
931         ;
932  
933  source_stmt
934 @@ -319,6 +365,9 @@ dest_stmt
935  log_stmt
936          : '{' log_items log_forks log_flags '}'                { LogPipeItem *pi = log_pipe_item_append_tail($2, $3); $$ = log_connection_new(pi, $4); }
937         ;
938 +       
939 +include_stmt
940 +        : string                                { last_include_file = $1; }
941  
942  log_items
943         : log_item ';' log_items                { log_pipe_item_append($1, $3); $$ = $1; }
944 @@ -442,7 +491,7 @@ source_affile_option
945                affile_sd_set_pri_level(last_driver, level); 
946              free($3);
947            }
948 -        | KW_FACILITY '(' string ')'    
949 +        | KW_FACILITY '(' string ')'
950  
951            {
952              int facility = -1;
953 @@ -708,7 +757,8 @@ source_reader_option
954         | KW_LOG_MSG_SIZE '(' NUMBER ')'        { last_reader_options->msg_size = $3; }
955         | KW_LOG_FETCH_LIMIT '(' NUMBER ')'     { last_reader_options->fetch_limit = $3; }
956         | KW_PAD_SIZE '(' NUMBER ')'            { last_reader_options->padding = $3; }
957 -       | KW_FOLLOW_FREQ '(' NUMBER ')'         { last_reader_options->follow_freq = $3; }
958 +       | KW_FOLLOW_FREQ '(' FLOAT ')'          { last_reader_options->follow_freq = (long) ($3 * 1000); }
959 +       | KW_FOLLOW_FREQ '(' NUMBER ')'         { last_reader_options->follow_freq = ($3 * 1000); }
960         | KW_KEEP_TIMESTAMP '(' yesno ')'       { last_reader_options->super.keep_timestamp = $3; }
961          | KW_ENCODING '(' string ')'           { last_reader_options->text_encoding = g_strdup($3); free($3); }
962         ;
963 @@ -777,7 +827,7 @@ dest_afpipe
964  dest_afpipe_params
965         : string 
966           { 
967 -           last_driver = affile_dd_new($1, AFFILE_NO_EXPAND | AFFILE_PIPE);
968 +           last_driver = affile_dd_new($1, AFFILE_PIPE);
969             free($1); 
970             last_writer_options = &((AFFileDestDriver *) last_driver)->writer_options;
971             last_writer_options->flush_lines = 0;
972 @@ -895,7 +945,7 @@ dest_afinet_tcp_option
973         : dest_afinet_option
974         | KW_TLS 
975           {
976 -#if ENABLE_TLS
977 +#if ENABLE_SSL
978             last_tls_context = tls_context_new(TM_CLIENT);
979  #endif
980           }
981 @@ -1282,7 +1332,7 @@ filter_fac_list
982         ;
983  
984  filter_fac
985 -       : string                                
986 +       : string
987           { 
988             int n = syslog_name_lookup_facility_by_name($1);
989             if (n == -1)
990 @@ -1461,6 +1511,34 @@ dnsmode
991  string
992         : IDENTIFIER
993         | STRING
994 +       | reserved_words_as_strings             { $$ = cfg_lex_get_keyword_string($1); }
995 +       ;
996 +
997 +reserved_words_as_strings
998 +        /* these keywords were introduced in syslog-ng 3.0 */
999 +        : KW_PARSER
1000 +        | KW_REWRITE
1001 +        | KW_INCLUDE
1002 +        | KW_SYSLOG
1003 +        | KW_COLUMNS
1004 +        | KW_DELIMITERS
1005 +        | KW_QUOTES
1006 +        | KW_QUOTE_PAIRS
1007 +        | KW_NULL
1008 +        | KW_CSV_PARSER
1009 +        | KW_DB_PARSER
1010 +        | KW_ENCODING
1011 +        | KW_SET
1012 +        | KW_SUBST
1013 +        | KW_VALUE
1014 +        | KW_PROGRAM_OVERRIDE
1015 +        | KW_HOST_OVERRIDE
1016 +        | KW_TRANSPORT
1017 +        | KW_TRUSTED_KEYS
1018 +        | KW_TRUSTED_DN
1019 +        | KW_MESSAGE
1020 +        | KW_TYPE
1021 +        | KW_SQL
1022         ;
1023  
1024  string_or_number
1025 @@ -1483,14 +1561,8 @@ extern int linenum;
1026  void 
1027  yyerror(char *msg)
1028  {
1029 -  fprintf(stderr, "%s in %s at line %d.\n", msg, configuration->filename, linenum);
1030 +  fprintf(stderr, "%s in %s at line %d.\n\n"
1031 +                  "syslog-ng documentation: http://www.balabit.com/support/documentation/?product=syslog-ng\n"
1032 +                  "mailing list: https://lists.balabit.hu/mailman/listinfo/syslog-ng\n", msg, cfg_lex_get_current_file(), cfg_lex_get_current_lineno());
1033  }
1034  
1035 -void
1036 -yyparser_reset(void)
1037 -{
1038 -  last_driver = NULL;
1039 -  last_reader_options = NULL;
1040 -  last_writer_options = NULL;
1041 -  last_template = NULL;
1042 -}
1043 diff --git a/src/cfg-lex.l b/src/cfg-lex.l
1044 index c9db716..b3c893c 100644
1045 --- a/src/cfg-lex.l
1046 +++ b/src/cfg-lex.l
1047 @@ -31,6 +31,7 @@
1048  
1049  #include <string.h>
1050  #include <strings.h>
1051 +#include <sys/stat.h>
1052  
1053  struct keyword 
1054  {
1055 @@ -52,6 +53,7 @@ static struct keyword keywords[] = {
1056         { "destination",        KW_DESTINATION },
1057         { "log",                KW_LOG },
1058         { "options",            KW_OPTIONS },
1059 +       { "include",            KW_INCLUDE },
1060  
1061         /* source or destination items */
1062         { "file",               KW_FILE },
1063 @@ -162,7 +164,6 @@ static struct keyword keywords[] = {
1064         { "localport",          KW_LOCALPORT },
1065         { "port",               KW_PORT },
1066         { "destport",           KW_DESTPORT },
1067 -        { "framed",             KW_FRAMED },
1068          { "ip_ttl",             KW_IP_TTL },
1069          { "ip_tos",             KW_IP_TOS },
1070          { "so_broadcast",       KW_SO_BROADCAST },
1071 @@ -229,7 +230,20 @@ static struct keyword keywords[] = {
1072  
1073  #define MAX_REGEXP_LEN 1024
1074  
1075 -int linenum = 1;
1076 +typedef struct _CfgIncludeLevel
1077 +{
1078 +  GSList *files;
1079 +  gchar *current_file;
1080 +  gint linenum;
1081 +  struct yy_buffer_state *yybuf;
1082 +} CfgIncludeLevel;
1083 +
1084 +#define MAX_INCLUDE_DEPTH 16
1085 +
1086 +static CfgIncludeLevel include_stack[MAX_INCLUDE_DEPTH];
1087 +static gint include_depth = 0;
1088 +
1089 +
1090  int lex_filter_params = 0;
1091  char buf[MAX_REGEXP_LEN];
1092  char *str;
1093 @@ -237,6 +251,7 @@ char *str;
1094  static int check_reserved_words(char *token);
1095  static void append_string(int length, char *str);
1096  static void append_char(char c);
1097 +static gboolean cfg_start_next_include(gboolean first_on_this_level);
1098  
1099  %}
1100  
1101 @@ -254,9 +269,10 @@ word       [^ \#'"\(\)\{\}\\;\n\t,|\.]
1102  %%
1103  
1104  \#.*$                      ;
1105 -\r?\n                     { linenum++; }
1106 +\r?\n                     { include_stack[include_depth].linenum++; }
1107  {white}+                  ;
1108  \.\.                       { return DOTDOT; }
1109 +(-|\+)?{digit}+\.{digit}+  { yylval.fnum = strtod(yytext, NULL); return FLOAT; }
1110  0x{digit}+                { yylval.num = strtoll(yytext, NULL, 16); return NUMBER; }
1111  0{digit}+                 { yylval.num = strtoll(yytext, NULL, 8); return NUMBER; }
1112  (-|\+)?{digit}+            { yylval.num = strtoll(yytext, NULL, 10); return NUMBER; }
1113 @@ -298,16 +314,13 @@ word      [^ \#'"\(\)\{\}\\;\n\t,|\.]
1114                                 return STRING;
1115                            }
1116  
1117 +
1118 +<INITIAL><<EOF>>           { if (!cfg_start_next_include(FALSE)) yyterminate(); }
1119 +
1120  %%
1121 -int 
1122 -lex_init(FILE *file, gint init_line_num)
1123 -{
1124 -  yyrestart(file);
1125 -  linenum = init_line_num;
1126 -  return 0;
1127 -}
1128  
1129 -int 
1130 +
1131 +static int 
1132  check_reserved_words(char *token)
1133  {
1134    int i, j;
1135 @@ -339,6 +352,7 @@ check_reserved_words(char *token)
1136                break;
1137              }
1138            keywords[i].kw_status = KWS_NORMAL;
1139 +          yylval.token = keywords[i].kw_token;
1140            return keywords[i].kw_token;
1141          }
1142      }
1143 @@ -364,3 +378,251 @@ append_char(char c)
1144    str++;
1145    *str = 0;
1146  }
1147 +
1148 +const gchar *
1149 +cfg_lex_get_current_file(void)
1150 +{
1151 +  CfgIncludeLevel *level = &include_stack[include_depth];
1152 +
1153 +  return level->current_file;
1154 +}
1155 +
1156 +gint
1157 +cfg_lex_get_current_lineno(void)
1158 +{
1159 +  CfgIncludeLevel *level = &include_stack[include_depth];
1160 +
1161 +  return level->linenum;
1162 +}
1163 +
1164 +char *
1165 +cfg_lex_get_keyword_string(int kw)
1166 +{
1167 +  int i;
1168 +  for (i = 0; i < (sizeof(keywords) / sizeof(struct keyword)); i++)
1169 +    {
1170 +      if (keywords[i].kw_token == kw)
1171 +        {
1172 +          msg_warning("WARNING: Your configuration uses a newly introduced reserved word as identifier, please use a different name",
1173 +                      evt_tag_str("keyword", keywords[i].kw_name),
1174 +                      evt_tag_str("filename", cfg_lex_get_current_file()),
1175 +                      evt_tag_int("line", cfg_lex_get_current_lineno()),
1176 +                      NULL);
1177 +          return strdup(keywords[i].kw_name);
1178 +        }
1179 +    }
1180 +  g_assert_not_reached();
1181 +}
1182 +
1183 +
1184 +
1185 +static gboolean
1186 +cfg_start_next_include(gboolean first_on_this_level)
1187 +{
1188 +  FILE *include_file;
1189 +  CfgIncludeLevel *level = &include_stack[include_depth];
1190 +  gchar *filename;
1191 +  struct yy_buffer_state *yybuf;
1192 +  
1193 +  g_assert(level->yybuf == NULL);
1194 +  
1195 +  if (include_depth == 0)
1196 +    {
1197 +      return FALSE;
1198 +    }
1199 +
1200 +  if (!first_on_this_level)
1201 +    {
1202 +      msg_debug("Finishing include file",
1203 +                evt_tag_str("filename", level->current_file),
1204 +                evt_tag_int("depth", include_depth),
1205 +                NULL);
1206 +    }
1207 +  
1208 +  if (!level->files)
1209 +    {
1210 +      yybuf = YY_CURRENT_BUFFER;
1211 +      g_free(level->current_file);
1212 +      fclose(yybuf->yy_input_file);
1213 +      level->current_file = NULL;
1214 +      include_depth--;
1215 +      yy_switch_to_buffer(include_stack[include_depth].yybuf);
1216 +      include_stack[include_depth].yybuf = NULL;
1217 +      if (!first_on_this_level)
1218 +        yy_delete_buffer(yybuf);
1219 +        
1220 +      return TRUE;
1221 +    }
1222 +    
1223 +  filename = (gchar *) level->files->data;
1224 +  level->files = g_slist_delete_link(level->files, level->files);
1225 +  
1226 +  include_file = fopen(filename, "r");
1227 +  if (!include_file)
1228 +    {
1229 +      msg_error("Error opening include file",
1230 +                evt_tag_str("filename", filename),
1231 +                evt_tag_int("depth", include_depth),
1232 +                NULL);
1233 +      g_free(filename);
1234 +      return FALSE;
1235 +    }
1236 +  msg_debug("Starting to read include file",
1237 +            evt_tag_str("filename", filename),
1238 +            evt_tag_int("depth", include_depth),
1239 +            NULL);
1240 +  yybuf = YY_CURRENT_BUFFER;
1241 +  if (level->current_file)
1242 +    {
1243 +      g_free(level->current_file);
1244 +      if (yybuf)
1245 +        fclose(yybuf->yy_input_file);
1246 +    }
1247 +  level->current_file = filename;
1248 +  level->linenum = 1;
1249 +  
1250 +  yy_switch_to_buffer(yy_create_buffer(include_file, YY_BUF_SIZE));
1251 +  if (!first_on_this_level)
1252 +    yy_delete_buffer(yybuf);
1253 +  return TRUE;
1254 +}
1255 +
1256 +gboolean
1257 +cfg_lex_process_include(const gchar *filename)
1258 +{
1259 +  struct stat st;
1260 +  gchar buf[1024];
1261 +  CfgIncludeLevel *level;
1262 +  
1263 +  if (include_depth >= MAX_INCLUDE_DEPTH - 1)
1264 +    {
1265 +      msg_error("Include file depth is too deep, increase MAX_INCLUDE_DEPTH and recompile",
1266 +                evt_tag_str("filename", filename),
1267 +                evt_tag_int("depth", include_depth),
1268 +                NULL);
1269 +      return FALSE;
1270 +    }
1271 +  
1272 +  if (filename[0] != '/')
1273 +    {
1274 +      g_snprintf(buf, sizeof(buf), "%s/%s", PATH_SYSCONFDIR, filename);
1275 +      filename = buf;
1276 +    }
1277 +  
1278 +  if (stat(filename, &st) < 0)
1279 +    {
1280 +      msg_error("Include file/directory not found", 
1281 +                evt_tag_str("filename", filename),
1282 +                evt_tag_errno("error", errno),
1283 +                NULL);
1284 +      return FALSE;
1285 +    }
1286 +  include_stack[include_depth].yybuf = YY_CURRENT_BUFFER;
1287 +  include_depth++;
1288 +  level = &include_stack[include_depth];
1289 +  if (S_ISDIR(st.st_mode))
1290 +    {
1291 +      GDir *dir;
1292 +      GError *error = NULL;
1293 +      const gchar *entry;
1294 +      
1295 +      dir = g_dir_open(filename, 0, &error);
1296 +      if (!dir)
1297 +        {
1298 +          msg_error("Error opening directory for reading",
1299 +                evt_tag_str("filename", filename),
1300 +                evt_tag_str("error", error->message),
1301 +                NULL);
1302 +          goto drop_level;
1303 +        }
1304 +      while ((entry = g_dir_read_name(dir)))
1305 +        {
1306 +          const gchar *p;
1307 +          
1308 +          for (p = entry; *p; p++)
1309 +            {
1310 +              if (!((*p >= 'a' && *p <= 'z') ||
1311 +                   (*p >= 'A' && *p <= 'Z') ||
1312 +                   (*p >= '0' && *p <= '9') ||
1313 +                   (*p == '_') || (*p == '-') || (*p == '.')))
1314 +                {
1315 +                  msg_debug("Skipping include file, does not match pattern [\\-_a-zA-Z0-9]+",
1316 +                            evt_tag_str("filename", entry),
1317 +                            NULL);
1318 +                  p = NULL;
1319 +                  break;
1320 +                }
1321 +            }
1322 +          if (p)
1323 +            {
1324 +              gchar *full_filename = g_build_filename(filename, entry, NULL);
1325 +              if (stat(full_filename, &st) < 0 || S_ISDIR(st.st_mode))
1326 +                {
1327 +                  msg_debug("Skipping include file as it is a directory",
1328 +                            evt_tag_str("filename", entry),
1329 +                            NULL);
1330 +                  g_free(full_filename);
1331 +                  continue;
1332 +                }
1333 +              level->files = g_slist_insert_sorted(level->files, full_filename, (GCompareFunc) strcmp);
1334 +              msg_debug("Adding include file",
1335 +                        evt_tag_str("filename", entry),
1336 +                        NULL);
1337 +            }
1338 +        }
1339 +      g_dir_close(dir);
1340 +      if (!level->files)
1341 +        {
1342 +          /* no include files in the specified directory */
1343 +          msg_debug("No files in this include directory",
1344 +                    evt_tag_str("dir", filename),
1345 +                    NULL);
1346 +          include_depth--;
1347 +          include_stack[include_depth].yybuf = NULL;
1348 +          return TRUE;
1349 +        }
1350 +    }
1351 +  else
1352 +    {
1353 +      g_assert(level->files == NULL);
1354 +      level->files = g_slist_prepend(level->files, g_strdup(filename));
1355 +    }
1356 +  return cfg_start_next_include(TRUE);
1357 + drop_level:
1358 +  g_slist_foreach(level->files, (GFunc) g_free, NULL);
1359 +  g_slist_free(level->files);
1360 +  level->files = NULL;
1361 +  return FALSE;
1362 +}
1363 +
1364 +int 
1365 +cfg_lex_init(FILE *file, gint init_line_num)
1366 +{
1367 +  CfgIncludeLevel *level;
1368 +  
1369 +  yyrestart(file);
1370 +  level = &include_stack[0];
1371 +  level->current_file = g_strdup(configuration->filename);
1372 +  level->linenum = init_line_num;
1373 +  return 0;
1374 +}
1375 +
1376 +void
1377 +cfg_lex_deinit(void)
1378 +{
1379 +  gint i;
1380 +  
1381 +  for (i = 0; i < include_depth; i++)
1382 +    {
1383 +      CfgIncludeLevel *level = &include_stack[i];
1384 +
1385 +      if (level->current_file)
1386 +        g_free(level->current_file);
1387 +      
1388 +      g_slist_foreach(level->files, (GFunc) g_free, NULL);
1389 +      g_slist_free(level->files);
1390 +      level->files = NULL;
1391 +      if (level->yybuf)
1392 +        yy_delete_buffer(level->yybuf);
1393 +    }
1394 +}
1395 diff --git a/src/cfg.c b/src/cfg.c
1396 index 23d93b6..45e5119 100644
1397 --- a/src/cfg.c
1398 +++ b/src/cfg.c
1399 @@ -34,6 +34,8 @@
1400  #include "logparser.h"
1401  #include "serialize.h"
1402  
1403 +#include <sys/types.h>
1404 +#include <signal.h>
1405  #include <stdio.h>
1406  #include <string.h>
1407  
1408 @@ -203,15 +205,6 @@ cfg_deinit(GlobalConfig *cfg)
1409    return log_center_deinit(cfg->center);
1410  }
1411  
1412 -/* extern declarations in the generated parser & lexer */
1413 -extern FILE *yyin;
1414 -extern int yyparse();
1415 -extern void lex_init(FILE *, gint lineno);
1416 -extern int yydebug;
1417 -extern int linenum;
1418 -
1419 -extern void yyparser_reset(void);
1420 -
1421  gboolean
1422  cfg_read_pragmas(GlobalConfig *self, FILE *cfg, gint *lineno)
1423  {
1424 @@ -358,8 +351,9 @@ cfg_new(gchar *fname)
1425            self->chain_hostnames = TRUE;
1426          }
1427  
1428 -      lex_init(cfg, lineno);
1429 +      cfg_lex_init(cfg, lineno);
1430        res = yyparse();
1431 +      cfg_lex_deinit();
1432        fclose(cfg);
1433        if (!res)
1434         {
1435 @@ -481,7 +475,15 @@ cfg_reload_config(gchar *fname, GlobalConfig *cfg)
1436      {
1437        msg_error("Error initializing new configuration, reverting to old config", NULL);
1438        cfg_persist_config_move(new_cfg, cfg);
1439 -      cfg_init(cfg);
1440 +      if (!cfg_init(cfg))
1441 +        {
1442 +          /* hmm. hmmm, error reinitializing old configuration, we're hosed.
1443 +           * Best is to kill ourselves in the hope that the supervisor
1444 +           * restarts us.
1445 +           */
1446 +          kill(getpid(), SIGQUIT);
1447 +          g_assert_not_reached();
1448 +        }
1449        return cfg;
1450      }
1451  }
1452 diff --git a/src/cfg.h b/src/cfg.h
1453 index d7b4edc..91f3060 100644
1454 --- a/src/cfg.h
1455 +++ b/src/cfg.h
1456 @@ -28,6 +28,7 @@
1457  
1458  #include <sys/types.h>
1459  #include <regex.h>
1460 +#include <stdio.h>
1461  
1462  struct _LogSourceGroup;
1463  struct _LogDestGroup;
1464 @@ -148,6 +149,19 @@ void cfg_persist_set_version(GlobalConfig *cfg, const gint version);
1465  
1466  void persist_config_free(PersistentConfig *persist);
1467  
1468 +/* defined in the lexer */
1469 +void yyerror(char *msg);
1470 +int yylex();
1471 +int cfg_lex_init(FILE *file, gint init_line_num);
1472 +void cfg_lex_deinit(void);
1473 +gboolean cfg_lex_process_include(const gchar *filename);
1474 +const gchar *cfg_lex_get_current_file(void);
1475 +gint cfg_lex_get_current_lineno(void);
1476 +char *cfg_lex_get_keyword_string(int kw);
1477 +
1478 +/* defined in the parser */
1479 +int yyparse(void);
1480 +
1481  static inline gboolean 
1482  cfg_check_current_config_version(gint req)
1483  {
1484 diff --git a/src/dnscache.c b/src/dnscache.c
1485 index ef8cc8f..bd23648 100644
1486 --- a/src/dnscache.c
1487 +++ b/src/dnscache.c
1488 @@ -66,6 +66,7 @@ static gint dns_cache_expire_failed = 60;
1489  static gint dns_cache_persistent_count = 0;
1490  static gchar *dns_cache_hosts = NULL;
1491  static time_t dns_cache_hosts_mtime = -1;
1492 +static time_t dns_cache_hosts_checktime = 0;
1493  
1494  static gboolean 
1495  dns_cache_key_equal(DNSCacheKey *e1, DNSCacheKey *e2)
1496 @@ -156,6 +157,12 @@ static void
1497  dns_cache_check_hosts(void)
1498  {
1499    struct stat st;
1500 +  time_t t = time(NULL);
1501 +
1502 +  if (G_LIKELY(dns_cache_hosts_checktime == t))
1503 +    return;
1504 +
1505 +  dns_cache_hosts_checktime = t;
1506    
1507    if (!dns_cache_hosts || stat(dns_cache_hosts, &st) < 0)
1508      {
1509 @@ -299,6 +306,7 @@ dns_cache_set_params(gint cache_size, gint expire, gint expire_failed, const gch
1510    dns_cache_expire_failed = expire_failed;
1511    dns_cache_hosts = g_strdup(hosts);
1512    dns_cache_hosts_mtime = -1;
1513 +  dns_cache_hosts_checktime = 0;
1514  }
1515  
1516  void
1517 diff --git a/src/filter.c b/src/filter.c
1518 index 0d1fe57..3a14fdd 100644
1519 --- a/src/filter.c
1520 +++ b/src/filter.c
1521 @@ -375,6 +375,11 @@ filter_netmask_eval(FilterExprNode *s, LogMessage *msg)
1522      {
1523        addr.s_addr = htonl(INADDR_LOOPBACK);
1524      }
1525 +  else
1526 +    {
1527 +      /* no address information, return FALSE */
1528 +      return s->comp;
1529 +    }
1530    return ((addr.s_addr & self->netmask.s_addr) == (self->address.s_addr)) ^ s->comp;
1531  
1532  }
1533 diff --git a/src/gprocess.c b/src/gprocess.c
1534 index 5a4a76f..004f57c 100644
1535 --- a/src/gprocess.c
1536 +++ b/src/gprocess.c
1537 @@ -87,7 +87,9 @@ static struct
1538    GProcessMode mode;
1539    const gchar *name;
1540    const gchar *user;
1541 +  uid_t uid;
1542    const gchar *group;
1543 +  gid_t gid;
1544    const gchar *chroot_dir;
1545    const gchar *pidfile;
1546    const gchar *pidfile_dir;
1547 @@ -109,9 +111,15 @@ static struct
1548    .argv = NULL,
1549    .argv_start = NULL,
1550    .argv_env_len = 0,
1551 +#ifdef __CYGWIN__
1552 +  .fd_limit_min = 256,
1553 +#else
1554    .fd_limit_min = 4096,
1555 +#endif
1556    .check_period = -1,
1557    .check_fn = NULL,
1558 +  .uid = -1,
1559 +  .gid = -1
1560  };
1561  
1562  #if ENABLE_LINUX_CAPS
1563 @@ -255,6 +263,8 @@ g_process_set_user(const gchar *user)
1564  {
1565    if (!process_opts.user)
1566      process_opts.user = user;
1567 +
1568 +
1569  }
1570  
1571  /**
1572 @@ -268,6 +278,7 @@ g_process_set_group(const gchar *group)
1573  {
1574    if (!process_opts.group)
1575      process_opts.group = group;
1576 +
1577  }
1578  
1579  /**
1580 @@ -666,35 +677,20 @@ g_process_change_root(void)
1581  static gboolean
1582  g_process_change_user(void)
1583  {
1584 -  uid_t uid = -1;
1585 -  gid_t gid = -1;
1586 -  
1587  #if ENABLE_LINUX_CAPS
1588    if (process_opts.caps)
1589      prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
1590  #endif
1591  
1592 -  if (process_opts.user && !resolve_user(process_opts.user, &uid))
1593 -    {
1594 -      g_process_message("Error resolving user; user='%s'", process_opts.user);
1595 -      return FALSE;
1596 -    }
1597 -
1598 -  if (process_opts.group && !resolve_group(process_opts.group, &gid))
1599 -    {
1600 -      g_process_message("Error resolving group; group='%s'", process_opts.group);
1601 -      return FALSE;
1602 -    }
1603 -
1604 -  if ((gint) gid != -1)
1605 +  if ((gint) process_opts.gid != -1)
1606      {
1607 -      if (setgid(gid) < 0)
1608 +      if (setgid(process_opts.gid) < 0)
1609          {
1610 -          g_process_message("Error in setgid(); group='%s', error='%s'", process_opts.group, g_strerror(errno));
1611 +          g_process_message("Error in setgid(); group='%s', gid='%d', error='%s'", process_opts.group, (gint) process_opts.gid, g_strerror(errno));
1612            if (getuid() == 0)
1613              return FALSE;
1614          }
1615 -      if (process_opts.user && initgroups(process_opts.user, gid) < 0)
1616 +      if (process_opts.user && initgroups(process_opts.user, process_opts.gid) < 0)
1617          {
1618            g_process_message("Error in initgroups(); user='%s', error='%s'", process_opts.user, g_strerror(errno));
1619            if (getuid() == 0)
1620 @@ -702,11 +698,11 @@ g_process_change_user(void)
1621          }
1622      }
1623  
1624 -  if ((gint) uid != -1)
1625 +  if ((gint) process_opts.uid != -1)
1626      {
1627 -      if (setuid(uid) < 0)
1628 +      if (setuid(process_opts.uid) < 0)
1629          {
1630 -          g_process_message("Error in setuid(); user='%s', error='%s'", process_opts.user, g_strerror(errno));
1631 +          g_process_message("Error in setuid(); user='%s', uid='%d', error='%s'", process_opts.user, (gint) process_opts.uid, g_strerror(errno));
1632            if (getuid() == 0)
1633              return FALSE;
1634          }
1635 @@ -763,6 +759,21 @@ g_process_change_caps(void)
1636  
1637  #endif
1638  
1639 +static void
1640 +g_process_resolve_names(void)
1641 +{
1642 +  if (process_opts.user && !resolve_user(process_opts.user, &process_opts.uid))
1643 +    {
1644 +      g_process_message("Error resolving user; user='%s'", process_opts.user);
1645 +      process_opts.uid = (uid_t) -1;
1646 +    }
1647 +  if (process_opts.group && !resolve_group(process_opts.group, &process_opts.gid))
1648 +    {
1649 +      g_process_message("Error resolving group; group='%s'", process_opts.group);
1650 +      process_opts.gid = (gid_t) -1;
1651 +    }
1652 +}
1653 +
1654  /**
1655   * g_process_change_dir:
1656   *
1657 @@ -1116,6 +1127,7 @@ g_process_start(void)
1658    
1659    g_process_detach_tty();
1660    g_process_change_limits();
1661 +  g_process_resolve_names();
1662    
1663    if (process_opts.mode == G_PM_BACKGROUND)
1664      {
1665 diff --git a/src/logmsg.c b/src/logmsg.c
1666 index 9bad35f..d7f7558 100644
1667 --- a/src/logmsg.c
1668 +++ b/src/logmsg.c
1669 @@ -264,6 +264,10 @@ log_msg_get_value(LogMessage *self, const gchar *value_name, gssize *length)
1670    return value;
1671  }
1672  
1673 +/**
1674 + * NOTE: the new_value is taken as a reference, e.g. it'll be assigned to
1675 + * the LogMessage and freed later on.
1676 + **/
1677  void
1678  log_msg_set_value(LogMessage *self, const gchar *value_name, gchar *new_value, gssize length)
1679  {
1680 @@ -1065,7 +1069,7 @@ log_msg_parse_version(LogMessage *self, const guchar **data, gint *length)
1681  }
1682  
1683  static void
1684 -log_msg_parse_legacy_program_name(LogMessage *self, const guchar **data, gint *length)
1685 +log_msg_parse_legacy_program_name(LogMessage *self, const guchar **data, gint *length, guint flags)
1686  { 
1687    /* the data pointer will not change */ 
1688    const guchar *src, *prog_start;
1689 @@ -1110,6 +1114,11 @@ log_msg_parse_legacy_program_name(LogMessage *self, const guchar **data, gint *l
1690        src++;
1691        left--;
1692      }
1693 +  if (flags & LP_STORE_LEGACY_MSGHDR)
1694 +    {
1695 +      log_msg_set_value(self, "LEGACY_MSGHDR", g_strndup((gchar *) *data, *length - left), *length - left);
1696 +      self->flags |= LF_LEGACY_MSGHDR;
1697 +    }
1698    *data = src;
1699    *length = left;
1700  }
1701 @@ -1573,7 +1582,7 @@ log_msg_parse_legacy(LogMessage *self, const guchar *data, gint length, guint fl
1702            log_msg_parse_skip_chars(self, &src, &left, " ", -1);
1703  
1704            /* Try to extract a program name */
1705 -          log_msg_parse_legacy_program_name(self, &src, &left);
1706 +          log_msg_parse_legacy_program_name(self, &src, &left, flags);
1707          }
1708  
1709        /* If we did manage to find a hostname, store it. */
1710 @@ -1598,7 +1607,7 @@ log_msg_parse_legacy(LogMessage *self, const guchar *data, gint length, guint fl
1711        else
1712          {
1713            /* Capture the program name */
1714 -          log_msg_parse_legacy_program_name(self, &src, &left);
1715 +          log_msg_parse_legacy_program_name(self, &src, &left, flags);
1716          }
1717        self->timestamps[LM_TS_STAMP] = self->timestamps[LM_TS_RECVD];
1718      }
1719 @@ -1607,7 +1616,7 @@ log_msg_parse_legacy(LogMessage *self, const guchar *data, gint length, guint fl
1720    self->message_len = left;
1721    if ((flags & LP_VALIDATE_UTF8) && g_utf8_validate((gchar *) src, left, NULL))
1722      self->flags |= LF_UTF8;
1723 -    
1724 +
1725    return TRUE;
1726  }
1727  
1728 diff --git a/src/logmsg.h b/src/logmsg.h
1729 index 17d4b5c..6e0a9be 100644
1730 --- a/src/logmsg.h
1731 +++ b/src/logmsg.h
1732 @@ -47,6 +47,7 @@
1733  #define LP_ASSUME_UTF8     0x0080
1734  #define LP_VALIDATE_UTF8   0x0100
1735  #define LP_NO_MULTI_LINE   0x0200
1736 +#define LP_STORE_LEGACY_MSGHDR 0x0400
1737  
1738  
1739  typedef struct _LogPathOptions LogPathOptions;
1740 @@ -97,6 +98,13 @@ enum
1741    LF_OWN_MATCHES      = 0x4000,
1742    LF_OWN_ALL          = 0x7FF0,
1743    LF_CHAINED_HOSTNAME = 0x8000,
1744 +
1745 +  /* originally parsed from RFC 3164 format and the legacy message header
1746 +   * was saved in $LEGACY_MSGHDR. This flag is a hack to avoid a hash lookup
1747 +   * in the fast path and indicates that the parser has saved the legacy
1748 +   * message header intact in a value named LEGACY_MSGHDR.
1749 +   */
1750 +  LF_LEGACY_MSGHDR    = 0x00010000,
1751  };
1752  
1753  typedef struct _LogMessageSDParam  LogMessageSDParam;
1754 @@ -129,12 +137,25 @@ typedef struct _LogMessageMatch
1755        guint16 ofs;
1756        guint16 len;
1757  #else
1758 +
1759 +#if GLIB_SIZEOF_VOID_P == 4
1760 +      guint16 ofs;
1761 +      guint8 __pad;
1762 +      guint8 flags;
1763 +      guint16 len;
1764 +      guint8 builtin_value;
1765 +      guint8 type;
1766 +#elif GLIB_SIZEOF_VOID_P == 8
1767        guint16 ofs;
1768        guint16 len;
1769        guint8 builtin_value;
1770        guint8 type;
1771        guint8 __pad;
1772        guint8 flags;
1773 +#else
1774 +#error "Unknown pointer size"
1775 +#endif
1776 +
1777  #endif
1778      };
1779    };
1780 @@ -156,9 +177,10 @@ struct _LogMessage
1781     */
1782    struct
1783    {
1784 -    guint16 flags;
1785 -    guint16 pri;
1786 +    guint32 flags;
1787      guint32 message_len;
1788 +    guint16 pri;
1789 +    /* 6 bytes hole */
1790      
1791      LogStamp timestamps[LM_TS_MAX];
1792      gchar * const host;
1793 diff --git a/src/logproto.c b/src/logproto.c
1794 index b2c30ee..9d7187b 100644
1795 --- a/src/logproto.c
1796 +++ b/src/logproto.c
1797 @@ -8,11 +8,22 @@
1798  gboolean
1799  log_proto_set_encoding(LogProto *self, const gchar *encoding)
1800  {
1801 -  self->convert = g_iconv_open("utf-8", encoding);
1802    if (self->convert != (GIConv) -1)
1803      {
1804 -      return FALSE;
1805 +      g_iconv_close(self->convert);
1806 +      self->convert = (GIConv) -1;
1807 +    }
1808 +  if (self->encoding)
1809 +    {
1810 +      g_free(self->encoding);
1811 +      self->encoding = NULL;
1812      }
1813 +
1814 +  self->convert = g_iconv_open("utf-8", encoding);
1815 +  if (self->convert == (GIConv) -1)
1816 +    return FALSE;
1817 +
1818 +  self->encoding = g_strdup(encoding);
1819    return TRUE;
1820  }
1821  
1822 @@ -23,6 +34,8 @@ log_proto_free(LogProto *s)
1823      s->free_fn(s);
1824    if (s->convert != (GIConv) -1)
1825      g_iconv_close(s->convert);
1826 +  if (s->encoding)
1827 +    g_free(s->encoding);
1828    log_transport_free(s->transport);
1829    g_free(s);
1830  }
1831 @@ -159,6 +172,8 @@ struct _LogProtoPlainServer
1832    gsize buffer_size, buffer_end, buffer_pos;
1833    gsize padding_size, max_msg_size;
1834    GSockAddr *prev_saddr;
1835 +  gchar raw_buffer_leftover[8];
1836 +  gint raw_buffer_leftover_size;
1837    LogProtoStatus status;
1838  };
1839  
1840 @@ -487,7 +502,8 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
1841            /* if conversion is needed, we first read into an on-stack
1842             * buffer, and then convert it into our internal buffer */
1843  
1844 -          raw_buffer = g_alloca(self->max_msg_size);
1845 +          raw_buffer = g_alloca(self->max_msg_size + self->raw_buffer_leftover_size);
1846 +          memcpy(raw_buffer, self->raw_buffer_leftover, self->raw_buffer_leftover_size);
1847            if (!self->padding_size)
1848              {
1849                avail = self->max_msg_size;
1850 @@ -499,7 +515,7 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
1851              }
1852          }
1853  
1854 -      rc = log_transport_read(self->super.transport, raw_buffer, avail, sa);
1855 +      rc = log_transport_read(self->super.transport, raw_buffer + self->raw_buffer_leftover_size, avail, sa);
1856        if (sa && *sa)
1857          self->prev_saddr = *sa;
1858        if (rc < 0)
1859 @@ -534,6 +550,13 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
1860                msg_verbose("EOF occurred while reading", 
1861                            evt_tag_int(EVT_TAG_FD, self->super.transport->fd),
1862                            NULL);
1863 +              if (self->raw_buffer_leftover_size > 0)
1864 +                {
1865 +                  msg_error("EOF read on a channel with leftovers from previous character conversion, dropping input",
1866 +                            NULL);
1867 +                  self->status = LPS_EOF;
1868 +                  return self->status;
1869 +                }
1870                self->status = LPS_EOF;
1871                if (log_proto_plain_server_fetch_from_buf(self, msg, msg_len, TRUE))
1872                  {
1873 @@ -562,6 +585,9 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
1874          }
1875        else
1876          {
1877 +          rc += self->raw_buffer_leftover_size;
1878 +          self->raw_buffer_leftover_size = 0;
1879 +
1880            /* some data was read */
1881            if (self->super.convert != (GIConv) -1)
1882              {
1883 @@ -581,22 +607,62 @@ log_proto_plain_server_fetch(LogProto *s, const guchar **msg, gsize *msg_len, GS
1884                        switch (errno)
1885                          {
1886                          case EINVAL:
1887 -                          /* Incomplete text, do not report an error */
1888 +                          /* Incomplete text, do not report an error, rather try to read again */
1889 +                          self->buffer_end = self->buffer_size - avail_out;
1890 +
1891 +                          if (avail_in > 0)
1892 +                            {
1893 +                              if (avail_in > sizeof(self->raw_buffer_leftover))
1894 +                                {
1895 +                                  msg_error("Invalid byte sequence, the remaining raw buffer is larger than the supported leftover size",
1896 +                                            evt_tag_str("encoding", self->super.encoding),
1897 +                                            evt_tag_int("avail_in", avail_in),
1898 +                                            evt_tag_int("leftover_size", sizeof(self->raw_buffer_leftover)),
1899 +                                            NULL);
1900 +                                  self->status = LPS_ERROR;
1901 +                                  return self->status;
1902 +                                }
1903 +                              memcpy(self->raw_buffer_leftover, raw_buffer, avail_in);
1904 +                              self->raw_buffer_leftover_size = avail_in;
1905 +                              msg_debug("Leftover characters remained after conversion, delaying message until another chunk arrives",
1906 +                                        evt_tag_str("encoding", self->super.encoding),
1907 +                                        evt_tag_int("avail_in", avail_in),
1908 +                                        NULL);
1909 +                              return LPS_SUCCESS;
1910 +                            }
1911                            break;
1912                          case E2BIG:
1913                            
1914                            self->buffer_end = self->buffer_size - avail_out;
1915                            /* extend the buffer */
1916 -                          self->buffer_size *= 2; 
1917 -                          self->buffer = g_realloc(self->buffer, self->buffer_size);
1918                            
1919 -                          /* recalculate the out pointer, and add what we have now */
1920 -                          ret = -1;
1921 +                          if (self->buffer_size < self->max_msg_size * 6)
1922 +                            {
1923 +                              self->buffer_size *= 2;
1924 +                              self->buffer = g_realloc(self->buffer, self->buffer_size);
1925 +
1926 +                              /* recalculate the out pointer, and add what we have now */
1927 +                              ret = -1;
1928 +                            }
1929 +                          else
1930 +                            {
1931 +                              msg_error("Incoming byte stream requires a too large conversion buffer, probably invalid character sequence",
1932 +                                        evt_tag_str("encoding", self->super.encoding),
1933 +                                        evt_tag_printf("buffer", "%.*s", self->buffer_end, self->buffer),
1934 +                                        NULL);
1935 +                              self->status = LPS_ERROR;
1936 +                              return self->status;
1937 +                            }
1938                            break;
1939                          case EILSEQ:
1940                          default:
1941 -                          msg_error("Invalid byte sequence or other error while converting input", 
1942 -                                    NULL);
1943 +                          msg_notice("Invalid byte sequence or other error while converting input, skipping character",
1944 +                                     evt_tag_str("encoding", self->super.encoding),
1945 +                                     evt_tag_printf("char", "0x%02x", *(guchar *) raw_buffer),
1946 +                                     NULL);
1947 +                          self->buffer_end = self->buffer_size - avail_out;
1948 +                          raw_buffer++;
1949 +                          avail_in--;
1950                            break;
1951                          }
1952                      }
1953 diff --git a/src/logproto.h b/src/logproto.h
1954 index 8a03d75..f94e5df 100644
1955 --- a/src/logproto.h
1956 +++ b/src/logproto.h
1957 @@ -18,6 +18,7 @@ struct _LogProto
1958  {
1959    LogTransport *transport;
1960    GIConv convert;
1961 +  gchar *encoding;
1962    guint flags;
1963    gboolean (*read_state)(LogProto *s, SerializeArchive *archive);
1964    gboolean (*write_state)(LogProto *s, SerializeArchive *archive);
1965 diff --git a/src/logreader.c b/src/logreader.c
1966 index f9567ff..ca800d0 100644
1967 --- a/src/logreader.c
1968 +++ b/src/logreader.c
1969 @@ -103,7 +103,7 @@ log_reader_fd_prepare(GSource *source,
1970  
1971    if (self->reader->flags & LR_FOLLOW)
1972      {
1973 -      *timeout = self->reader->options->follow_freq * 1000;
1974 +      *timeout = self->reader->options->follow_freq;
1975        return FALSE;
1976      }
1977    
1978 @@ -167,7 +167,7 @@ log_reader_fd_check(GSource *source)
1979          
1980        if (self->reader->follow_filename && stat(self->reader->follow_filename, &followed_st) != -1)
1981          {
1982 -          if (fd < 0 || st.st_ino != followed_st.st_ino)
1983 +          if (fd < 0 || (st.st_ino != followed_st.st_ino && followed_st.st_size > 0))
1984              {
1985                msg_trace("log_reader_fd_check file moved eof",
1986                          evt_tag_int("pos", pos),
1987 @@ -278,6 +278,8 @@ log_reader_fetch_log(LogReader *self, LogProto *proto)
1988      parse_flags |= LP_VALIDATE_UTF8;
1989    if (self->options->options & LRO_NO_MULTI_LINE)
1990      parse_flags |= LP_NO_MULTI_LINE;
1991 +  if (self->options->options & LRO_STORE_LEGACY_MSGHDR)
1992 +    parse_flags |= LP_STORE_LEGACY_MSGHDR;
1993      
1994    if (self->waiting_for_preemption)
1995      may_read = FALSE;
1996 @@ -321,7 +323,7 @@ log_reader_fetch_log(LogReader *self, LogProto *proto)
1997            /* no more messages for now */
1998            break;
1999          }
2000 -      if (msg_len > 0)
2001 +      if (msg_len > 0 || (self->options->options & LRO_EMPTY_LINES))
2002          {
2003            msg_count++;
2004  
2005 @@ -772,6 +774,10 @@ log_reader_options_lookup_flag(const gchar *flag)
2006      return LRO_VALIDATE_UTF8;
2007    if (strcmp(flag, "no-multi-line") == 0 || strcmp(flag, "no_multi_line") == 0)
2008      return LRO_NO_MULTI_LINE;
2009 +  if (strcmp(flag, "store-legacy-msghdr") == 0 || strcmp(flag, "store_legacy_msghdr") == 0)
2010 +    return LRO_STORE_LEGACY_MSGHDR;
2011 +  if (strcmp(flag, "empty-lines") == 0 || strcmp(flag, "empty_lines") == 0)
2012 +    return LRO_EMPTY_LINES;
2013    msg_error("Unknown parse flag", evt_tag_str("flag", flag), NULL);
2014    return 0;
2015  }
2016 diff --git a/src/logreader.h b/src/logreader.h
2017 index 8e5bc7c..11ff0da 100644
2018 --- a/src/logreader.h
2019 +++ b/src/logreader.h
2020 @@ -43,6 +43,8 @@
2021  #define LRO_SYSLOG_PROTOCOL  0x0004
2022  #define LRO_VALIDATE_UTF8    0x0008
2023  #define LRO_NO_MULTI_LINE    0x0010
2024 +#define LRO_STORE_LEGACY_MSGHDR 0x0020
2025 +#define LRO_EMPTY_LINES      0x0040
2026  
2027  typedef struct _LogReaderWatch LogReaderWatch;
2028  
2029 @@ -77,7 +79,7 @@ typedef struct _LogReader
2030    GSockAddr *peer_addr;
2031    gchar *follow_filename;
2032    ino_t inode;
2033 -  off_t size;
2034 +  gint64 size;
2035    
2036  } LogReader;
2037  
2038 @@ -86,7 +88,7 @@ void log_reader_set_follow_filename(LogPipe *self, const gchar *follow_filename)
2039  void log_reader_set_peer_addr(LogPipe *s, GSockAddr *peer_addr);
2040  void log_reader_set_immediate_check(LogPipe *s);
2041  
2042 -void log_reader_update_pos(LogReader *self, off_t ofs);
2043 +void log_reader_update_pos(LogReader *self, gint64 ofs);
2044  void log_reader_save_state(LogReader *self, SerializeArchive *archive);
2045  void log_reader_restore_state(LogReader *self, SerializeArchive *archive);
2046  
2047 diff --git a/src/logwriter.c b/src/logwriter.c
2048 index bb01148..4d586e5 100644
2049 --- a/src/logwriter.c
2050 +++ b/src/logwriter.c
2051 @@ -236,7 +236,7 @@ log_writer_fd_dispatch(GSource *source,
2052        log_writer_broken(self->writer, NC_CLOSE);
2053        return FALSE;
2054      }
2055 -  else if (self->pollfd.revents & (G_IO_ERR))
2056 +  else if (self->pollfd.revents & (G_IO_ERR) && num_elements == 0)
2057      {
2058        msg_error("POLLERR occurred while idle",
2059                  evt_tag_int("fd", log_proto_get_fd(self->proto)),
2060 @@ -595,9 +595,20 @@ log_writer_format_log(LogWriter *self, LogMessage *lm, GString *result)
2061            g_string_append_len(result, lm->host, lm->host_len);
2062            g_string_append_c(result, ' ');
2063  
2064 -          g_string_append_len(result, lm->program, lm->program_len);
2065 -          if (lm->program_len > 0)
2066 +          if ((lm->flags & LF_LEGACY_MSGHDR))
2067              {
2068 +              gssize length;
2069 +              const gchar *msghdr;
2070 +
2071 +              msghdr = log_msg_get_value(lm, "LEGACY_MSGHDR", &length);
2072 +              if (msghdr)
2073 +                {
2074 +                  g_string_append_len(result, msghdr, length);
2075 +                }
2076 +            }
2077 +          else if (lm->program_len > 0)
2078 +            {
2079 +              g_string_append_len(result, lm->program, lm->program_len);
2080                if (lm->pid_len > 0)
2081                  {
2082                    g_string_append_c(result, '[');
2083 diff --git a/src/main.c b/src/main.c
2084 index ba97f0c..f78dcc1 100644
2085 --- a/src/main.c
2086 +++ b/src/main.c
2087 @@ -366,8 +366,6 @@ main(int argc, char *argv[])
2088  
2089    g_process_set_name("syslog-ng");
2090    
2091 -#if ENABLE_LINUX_CAPS
2092 -  
2093    /* in this case we switch users early while retaining a limited set of
2094     * credentials in order to initialize/reinitialize the configuration.
2095     */
2096 @@ -381,27 +379,11 @@ main(int argc, char *argv[])
2097      }
2098    else
2099      {
2100 -      g_process_startup_ok();
2101 +      if (syntax_only)
2102 +        g_process_startup_failed(0, TRUE);
2103 +      else
2104 +        g_process_startup_ok();
2105      }
2106 -#else
2107 -
2108 -  /* if Linux capabilities are not compiled in, the initial setup is
2109 -   * performed as the root user, and then the switch to a limited user
2110 -   * account is made. This is compatible how syslog-ng behaved before
2111 -   * capability support.
2112 -   */
2113 -   
2114 -  rc = initial_init(&cfg);
2115 -  if (rc)
2116 -    {
2117 -      return rc;
2118 -    }
2119 -  g_process_start();
2120 -  g_process_startup_ok();
2121 -#endif
2122 -
2123 -  if (syntax_only)
2124 -    return 0;
2125  
2126    /* we are running as a non-root user from this point */
2127    
2128 @@ -424,6 +406,7 @@ main(int argc, char *argv[])
2129    app_shutdown();
2130    tls_deinit();
2131    z_mem_trace_dump();
2132 +  g_process_finish();
2133    return rc;
2134  }
2135  
2136 diff --git a/src/memtrace.c b/src/memtrace.c
2137 index ef4729a..eb33f4f 100644
2138 --- a/src/memtrace.c
2139 +++ b/src/memtrace.c
2140 @@ -121,7 +121,7 @@ z_mem_trace_init(gchar *tracefile)
2141        for (i = 0; i < MEMTRACE_HASH_SIZE; i++) 
2142          {
2143            mem_trace_hash[i].list = -1;
2144 -          memset(&mem_trace_hash[i].lock, 0, sizeof(GStaticMutex));
2145 +          g_static_mutex_init(&mem_trace_hash[i].lock);
2146          }
2147        old_malloc = dlsym(RTLD_NEXT, "malloc");
2148        old_free = dlsym(RTLD_NEXT, "free");
2149 diff --git a/src/misc.c b/src/misc.c
2150 index 96fcdd2..364ead6 100644
2151 --- a/src/misc.c
2152 +++ b/src/misc.c
2153 @@ -274,7 +274,7 @@ resolve_user(const char *user, uid_t *uid)
2154    struct passwd *pw;
2155  
2156    *uid = 0;
2157 -  if (*user)
2158 +  if (!(*user))
2159      return FALSE;
2160      
2161    pw = getpwnam(user);
2162 @@ -299,7 +299,7 @@ resolve_group(const char *group, gid_t *gid)
2163    struct group *gr;
2164  
2165    *gid = 0;
2166 -  if (!*group)
2167 +  if (!(*group))
2168      return FALSE;
2169      
2170    gr = getgrnam(group);
2171 diff --git a/src/sgroup.c b/src/sgroup.c
2172 index add7ac9..27e863f 100644
2173 --- a/src/sgroup.c
2174 +++ b/src/sgroup.c
2175 @@ -25,8 +25,10 @@
2176  #include "misc.h"
2177  #include "messages.h"
2178  #include "stats.h"
2179 +#include "afinter.h"
2180  
2181  #include <time.h>
2182 +#include <string.h>
2183  
2184  static gboolean
2185  log_source_group_init(LogPipe *s)
2186 diff --git a/src/templates.c b/src/templates.c
2187 index aee1f34..67b8217 100644
2188 --- a/src/templates.c
2189 +++ b/src/templates.c
2190 @@ -339,17 +339,33 @@ log_macro_expand(GString *result, gint id, guint32 flags, gint ts_format, TimeZo
2191          }
2192        break;
2193      case M_MSGHDR:
2194 -      /* message, complete with program name and pid */
2195 -      result_append(result, msg->program, msg->program_len, !!(flags & LT_ESCAPE));
2196 -      if (msg->program_len > 0)
2197 +      if ((msg->flags & LF_LEGACY_MSGHDR))
2198          {
2199 -          if (msg->pid_len > 0)
2200 +          gssize length;
2201 +          const gchar *msghdr;
2202 +
2203 +          /* fast path for now, as most messages come from legacy devices */
2204 +
2205 +          msghdr = log_msg_get_value(msg, "LEGACY_MSGHDR", &length);
2206 +          if (msghdr)
2207              {
2208 -              result_append(result, "[", 1, !!(flags & LT_ESCAPE));
2209 -              result_append(result, msg->pid, msg->pid_len, !!(flags & LT_ESCAPE));
2210 -              result_append(result, "]", 1, !!(flags & LT_ESCAPE));
2211 +              result_append(result, msghdr, length, !!(flags & LT_ESCAPE));
2212 +            }
2213 +        }
2214 +      else
2215 +        {
2216 +          /* message, complete with program name and pid */
2217 +          result_append(result, msg->program, msg->program_len, !!(flags & LT_ESCAPE));
2218 +          if (msg->program_len > 0)
2219 +            {
2220 +              if (msg->pid_len > 0)
2221 +                {
2222 +                  result_append(result, "[", 1, !!(flags & LT_ESCAPE));
2223 +                  result_append(result, msg->pid, msg->pid_len, !!(flags & LT_ESCAPE));
2224 +                  result_append(result, "]", 1, !!(flags & LT_ESCAPE));
2225 +                }
2226 +              result_append(result, ": ", 2, !!(flags & LT_ESCAPE));
2227              }
2228 -          result_append(result, ": ", 2, !!(flags & LT_ESCAPE));
2229          }
2230        break;
2231      case M_MESSAGE:
2232 @@ -433,6 +449,9 @@ log_macro_expand(GString *result, gint id, guint32 flags, gint ts_format, TimeZo
2233           *   local timezone
2234           */
2235          zone_ofs = (zone_info != NULL ? time_zone_info_get_offset(zone_info, stamp->time.tv_sec) : stamp->zone_offset);
2236 +        if (zone_ofs == -1)
2237 +          zone_ofs = stamp->zone_offset;
2238 +
2239          t = stamp->time.tv_sec + zone_ofs;
2240          tm = gmtime_r(&t, &tm_storage);
2241  
2242 @@ -506,9 +525,6 @@ log_macro_expand(GString *result, gint id, guint32 flags, gint ts_format, TimeZo
2243            }
2244          break;
2245        }
2246 -
2247 -
2248 -
2249        g_assert_not_reached();
2250        break;
2251      }
2252 @@ -634,6 +650,9 @@ log_template_compile(LogTemplate *self, GError **error)
2253    
2254    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
2255    
2256 +  if (self->compiled_template)
2257 +    return TRUE;
2258 +
2259    p = self->template;
2260    
2261    while (*p)
2262 @@ -754,7 +773,7 @@ log_template_append_format(LogTemplate *self, LogMessage *lm, guint flags, gint
2263    
2264    flags |= self->flags;
2265    
2266 -  if (self->compiled_template == NULL && !log_template_compile(self, NULL))
2267 +  if (!log_template_compile(self, NULL))
2268      return;
2269  
2270    for (p = self->compiled_template; p; p = g_list_next(p))
2271 diff --git a/src/tlscontext.c b/src/tlscontext.c
2272 index b22b546..c06ec88 100644
2273 --- a/src/tlscontext.c
2274 +++ b/src/tlscontext.c
2275 @@ -102,28 +102,41 @@ tls_session_verify_dn(X509_STORE_CTX *ctx)
2276  }
2277  
2278  int
2279 -tls_session_verify(int ok, X509_STORE_CTX *ctx)
2280 +tls_session_verify(TLSSession *self, int ok, X509_STORE_CTX *ctx)
2281  {
2282 +  /* untrusted means that we have to accept the certificate even if it is untrusted */
2283 +  if (self->ctx->verify_mode & TVM_UNTRUSTED)
2284 +    return 1;
2285 +
2286 +  /* accept certificate if its fingerprint matches, again regardless whether x509 certificate validation was successful */
2287    if (tls_session_verify_fingerprint(ctx))
2288 -    return 1; /* success */
2289 +    {
2290 +      msg_debug("Certificate accepted because its fingerprint is listed", NULL);
2291 +      return 1;
2292 +    }
2293 +
2294 +  if (ok && ctx->error_depth != 0 && (ctx->current_cert->ex_flags & EXFLAG_CA) == 0)
2295 +    {
2296 +      msg_debug("Invalid certificate found in chain, basicConstraints.ca is unset in non-leaf certificate", NULL);
2297 +      ctx->error = X509_V_ERR_INVALID_CA;
2298 +      return 0;
2299 +    }
2300   
2301 +  /* reject certificate if it is valid, but its DN is not trusted */
2302    if (ok && ctx->error_depth == 0 && !tls_session_verify_dn(ctx))
2303      {
2304 +      msg_debug("Certificate valid, but DN constraints were not met, rejecting", NULL);
2305        ctx->error = X509_V_ERR_CERT_UNTRUSTED;
2306 -      return 0; /* fail */
2307 +      return 0;
2308      }
2309 -  
2310 -  return ok; 
2311 -}
2312 -
2313 -int
2314 -tls_session_ignore_errors(int ok, X509_STORE_CTX *ctx)
2315 -{
2316    /* if the crl_dir is set in the configuration file but the directory is empty ignore this error */
2317 -  if (ok == 0 && ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
2318 -    return 1;
2319 -  else
2320 -    return ok;
2321 +  if (!ok && ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL)
2322 +    {
2323 +      msg_notice("CRL directory is set but no CRLs found", NULL);
2324 +      return 1;
2325 +    }
2326 +
2327 +  return ok;
2328  }
2329  
2330  int
2331 @@ -132,10 +145,8 @@ tls_session_verify_callback(int ok, X509_STORE_CTX *ctx)
2332    SSL *ssl = X509_STORE_CTX_get_app_data(ctx);
2333    TLSSession *self = SSL_get_app_data(ssl);
2334  
2335 -  ok = tls_session_verify(ok, ctx);
2336 +  ok = tls_session_verify(self, ok, ctx);
2337      
2338 -  ok = tls_session_ignore_errors(ok, ctx);
2339 -
2340    tls_log_certificate_validation_progress(ok, ctx);
2341    
2342    if (self->verify_func)
2343 @@ -165,9 +176,6 @@ tls_session_set_verify(TLSSession *self, TLSSessionVerifyFunc verify_func, gpoin
2344    self->verify_func = verify_func;
2345    self->verify_data = verify_data;
2346    self->verify_data_destroy = verify_destroy;
2347 -
2348 -  SSL_set_app_data(self->ssl, self);
2349 -  SSL_set_verify(self->ssl, SSL_get_verify_mode(self->ssl), tls_session_verify_callback);
2350  }
2351  
2352  static TLSSession *
2353 @@ -212,11 +220,13 @@ TLSSession *
2354  tls_context_setup_session(TLSContext *self)
2355  {
2356    SSL *ssl;
2357 +  TLSSession *session;
2358    gint ssl_error;
2359  
2360    if (!self->ssl_ctx)
2361      {  
2362        gint verify_mode = 0;
2363 +      gint verify_flags = X509_V_FLAG_POLICY_CHECK;
2364        
2365        if (self->mode == TM_CLIENT)
2366          self->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
2367 @@ -240,7 +250,9 @@ tls_context_setup_session(TLSContext *self)
2368          goto error;
2369        
2370        if (self->crl_dir)
2371 -        X509_VERIFY_PARAM_set_flags(self->ssl_ctx->param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
2372 +        verify_flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
2373 +
2374 +      X509_VERIFY_PARAM_set_flags(self->ssl_ctx->param, verify_flags);
2375          
2376        switch (self->verify_mode)
2377          {
2378 @@ -254,7 +266,7 @@ tls_context_setup_session(TLSContext *self)
2379            verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
2380            break;
2381          case TVM_REQUIRED | TVM_UNTRUSTED:
2382 -          verify_mode = SSL_VERIFY_NONE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2383 +          verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2384            break;
2385          case TVM_REQUIRED | TVM_TRUSTED:
2386            verify_mode = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
2387 @@ -263,7 +275,7 @@ tls_context_setup_session(TLSContext *self)
2388            g_assert_not_reached();
2389          }  
2390        
2391 -      SSL_CTX_set_verify(self->ssl_ctx, verify_mode, NULL);
2392 +      SSL_CTX_set_verify(self->ssl_ctx, verify_mode, tls_session_verify_callback);
2393        SSL_CTX_set_options(self->ssl_ctx, SSL_OP_NO_SSLv2);
2394      }
2395  
2396 @@ -273,7 +285,10 @@ tls_context_setup_session(TLSContext *self)
2397      SSL_set_connect_state(ssl);
2398    else
2399      SSL_set_accept_state(ssl);
2400 -  return tls_session_new(ssl, self);
2401 +
2402 +  session = tls_session_new(ssl, self);
2403 +  SSL_set_app_data(ssl, session);
2404 +  return session;
2405  
2406   error:
2407    ssl_error = ERR_get_error();
2408 diff --git a/src/tlscontext.h b/src/tlscontext.h
2409 index ada8e18..568682d 100644
2410 --- a/src/tlscontext.h
2411 +++ b/src/tlscontext.h
2412 @@ -7,7 +7,7 @@
2413  
2414  #include "syslog-ng.h"
2415  
2416 -#ifdef ENABLE_SSL
2417 +#if ENABLE_SSL
2418  
2419  #include <openssl/ssl.h>
2420  
2421 @@ -69,6 +69,9 @@ gboolean tls_verify_certificate_name(X509 *cert, const gchar *hostname);
2422  
2423  #else
2424  
2425 +typedef struct _TLSContext TLSContext;
2426 +typedef struct _TLSSession TLSSession;
2427 +
2428  #define tls_context_new(m)
2429  
2430  #endif
2431 diff --git a/src/tlstransport.c b/src/tlstransport.c
2432 index 608a427..2f07625 100644
2433 --- a/src/tlstransport.c
2434 +++ b/src/tlstransport.c
2435 @@ -1,5 +1,7 @@
2436  #include "tlstransport.h"
2437  
2438 +#if ENABLE_SSL
2439 +
2440  #include "messages.h"
2441  
2442  #include <openssl/ssl.h>
2443 @@ -149,4 +151,4 @@ log_transport_tls_free_method(LogTransport *s)
2444    log_transport_free_method(s);
2445  }
2446  
2447 -
2448 +#endif
2449 diff --git a/tests/functional/func_test.py b/tests/functional/func_test.py
2450 index d7af8ff..ffd0fae 100755
2451 --- a/tests/functional/func_test.py
2452 +++ b/tests/functional/func_test.py
2453 @@ -2,6 +2,7 @@
2454  
2455  import os, sys, signal, traceback, time, errno
2456  from socket import *
2457 +import struct
2458  
2459  padding = 'x' * 250
2460  session_counter = 0
2461 @@ -39,12 +40,24 @@ class SocketSender(MessageSender):
2462              self.sock = socket(self.family, SOCK_STREAM)
2463          
2464          self.sock.connect(self.sock_name)
2465 +        self.sock.setsockopt(SOL_SOCKET, SO_SNDTIMEO, struct.pack('ll', 3, 0))
2466 +        if self.dgram:
2467 +                self.sock.send('')
2468      
2469      def sendMessage(self, msg):
2470          line = '%s%s' % (msg, self.terminate_seq)
2471          if self.send_by_bytes:
2472              for c in line:
2473 -                self.sock.send(c)
2474 +                try:
2475 +                    self.sock.send(c)
2476 +                except error, e:
2477 +                    if e[0] == errno.ENOBUFS:
2478 +                        print 'got ENOBUFS, sleeping...'
2479 +                        time.sleep(0.5)
2480 +                        repeat = True
2481 +                    else:
2482 +                        print "hmm... got an error to the 'send' call, maybe syslog-ng is not accepting messages?"
2483 +                        raise
2484          else:
2485              repeat = True
2486              while repeat:
2487 @@ -59,6 +72,9 @@ class SocketSender(MessageSender):
2488                          print 'got ENOBUFS, sleeping...'
2489                          time.sleep(0.5)
2490                          repeat = True
2491 +                    else:
2492 +                        print "hmm... got an error to the 'send' call, maybe syslog-ng is not accepting messages?"
2493 +                        raise
2494  
2495      def __str__(self):
2496          if self.family == AF_UNIX:
2497 diff --git a/tests/unit/test_logqueue.c b/tests/unit/test_logqueue.c
2498 index 6e9dd00..b27f08e 100644
2499 --- a/tests/unit/test_logqueue.c
2500 +++ b/tests/unit/test_logqueue.c
2501 @@ -115,6 +115,91 @@ testcase_zero_diskbuf_alternating_send_acks()
2502    log_queue_free(q);
2503  }
2504  
2505 +#if 0
2506 +
2507 +/* no synchronization between the feed/consume threads, therefore it does
2508 + * not succeed reliably. commented out for now, will fix at the next
2509 + * logqueue related threaded issue */
2510 +
2511 +GStaticMutex threaded_lock = G_STATIC_MUTEX_INIT;
2512 +
2513 +gpointer
2514 +threaded_feed(gpointer st)
2515 +{
2516 +  LogQueue *q = (LogQueue *) st;
2517 +  char *msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép";
2518 +  gint i;
2519 +  LogPathOptions path_options = LOG_PATH_OPTIONS_INIT;
2520 +  LogMessage *msg;
2521 +
2522 +  for (i = 0; i < 100000; i++)
2523 +    {
2524 +      msg = log_msg_new(msg_str, strlen(msg_str), g_sockaddr_inet_new("10.10.10.10", 1010), 0, NULL, -1);
2525 +      log_msg_add_ack(msg, &path_options);
2526 +      msg->ack_func = test_ack;
2527 +
2528 +      g_static_mutex_lock(&threaded_lock);
2529 +      if (!log_queue_push_tail(q, msg, &path_options))
2530 +        {
2531 +          fprintf(stderr, "Queue unable to consume enough messages: %d\n", fed_messages);
2532 +          return GUINT_TO_POINTER(1);
2533 +        }
2534 +      g_static_mutex_unlock(&threaded_lock);
2535 +    }
2536 +  return NULL;
2537 +}
2538 +
2539 +gpointer
2540 +threaded_consume(gpointer st)
2541 +{
2542 +  LogQueue *q = (LogQueue *) st;
2543 +  LogMessage *msg;
2544 +  LogPathOptions path_options = LOG_PATH_OPTIONS_INIT;
2545 +  gboolean success;
2546 +  gint i;
2547 +
2548 +  for (i = 0; i < 100000; i++)
2549 +    {
2550 +      g_static_mutex_lock(&threaded_lock);
2551 +      msg = NULL;
2552 +      success = log_queue_pop_head(q, &msg, &path_options, FALSE);
2553 +      g_static_mutex_unlock(&threaded_lock);
2554 +
2555 +      g_assert(!success || (success && msg != NULL));
2556 +      if (!success)
2557 +        {
2558 +          fprintf(stderr, "Queue didn't return enough messages: i=%d\n", i);
2559 +          return GUINT_TO_POINTER(1);
2560 +        }
2561 +
2562 +      log_msg_ack(msg, &path_options);
2563 +      log_msg_unref(msg);
2564 +    }
2565 +
2566 +  return NULL;
2567 +}
2568 +
2569 +void
2570 +testcase_with_threads()
2571 +{
2572 +  LogQueue *q;
2573 +  GThread *thread_feed, *thread_consume;
2574 +  gint i;
2575 +
2576 +  for (i = 0; i < 100; i++)
2577 +    {
2578 +      q = log_queue_new(100000, 0, 64);
2579 +      thread_feed = g_thread_create(threaded_feed, q, TRUE, NULL);
2580 +
2581 +      thread_consume = g_thread_create(threaded_consume, q, TRUE, NULL);
2582 +      g_thread_join(thread_feed);
2583 +      g_thread_join(thread_consume);
2584 +
2585 +      log_queue_free(q);
2586 +    }
2587 +}
2588 +#endif
2589 +
2590  int 
2591  main()
2592  {
2593 diff --git a/tests/unit/test_template.c b/tests/unit/test_template.c
2594 index 675b9d6..c499d8d 100644
2595 --- a/tests/unit/test_template.c
2596 +++ b/tests/unit/test_template.c
2597 @@ -18,9 +18,13 @@ testcase(LogMessage *msg, gchar *template, gchar *expected)
2598  {
2599    LogTemplate *templ;
2600    GString *res = g_string_sized_new(128);
2601 +  static TimeZoneInfo *tzinfo = NULL;
2602 +
2603 +  if (!tzinfo)
2604 +    tzinfo = time_zone_info_new(NULL);
2605    
2606    templ = log_template_new("dummy", template);
2607 -  log_template_format(templ, msg, LT_ESCAPE, TS_FMT_BSD, NULL, 3, 0, res);
2608 +  log_template_format(templ, msg, LT_ESCAPE, TS_FMT_BSD, tzinfo, 3, 0, res);
2609    
2610    if (strcmp(res->str, expected) != 0)
2611      {
2612 @@ -39,7 +43,7 @@ int
2613  main(int argc G_GNUC_UNUSED, char *argv[] G_GNUC_UNUSED)
2614  {
2615    LogMessage *msg;
2616 -  char *msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]: árvíztűrőtükörfúrógép";
2617 +  char *msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]:árvíztűrőtükörfúrógép";
2618    GlobalConfig dummy;
2619    
2620    if (argc > 1)
2621 @@ -172,6 +176,14 @@ main(int argc G_GNUC_UNUSED, char *argv[] G_GNUC_UNUSED)
2622    testcase(msg, "$PID", "");
2623    log_msg_unref(msg);
2624  
2625 +  msg_str = "<155>2006-02-11T10:34:56+01:00 bzorp syslog-ng[23323]:árvíztűrőtükörfúrógép";
2626 +
2627 +  msg = log_msg_new(msg_str, strlen(msg_str), g_sockaddr_inet_new("10.10.10.10", 1010), LP_STORE_LEGACY_MSGHDR, NULL, -1);
2628 +
2629 +  testcase(msg, "$LEGACY_MSGHDR", "syslog-ng[23323]:");
2630 +  testcase(msg, "$MSGHDR", "syslog-ng[23323]:");
2631 +  log_msg_unref(msg);
2632 +
2633    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..."; 
2634    msg = log_msg_new(msg_str, strlen(msg_str), g_sockaddr_inet_new("10.10.10.10", 1010), LP_SYSLOG_PROTOCOL, NULL, -1);
2635  
2636 diff --git a/tgz2build/rules b/tgz2build/rules
2637 index 57eb338..7f2c776 100644
2638 --- a/tgz2build/rules
2639 +++ b/tgz2build/rules
2640 @@ -3,7 +3,7 @@ STAMPDIR=tgz2build/stamps
2641  DOCDIR=$(PREFIX)/doc
2642  
2643  
2644 -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
2645 +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
2646  INSTALL:=./install-sh
2647  RPATH=-Wl,-R/opt/syslog-ng/lib
2648  
This page took 0.283836 seconds and 3 git commands to generate.