Merge branch 'collectd-5.5' into collectd-5.6
authorFlorian Forster <octo@collectd.org>
Mon, 7 Nov 2016 07:43:17 +0000 (08:43 +0100)
committerFlorian Forster <octo@collectd.org>
Mon, 7 Nov 2016 07:48:45 +0000 (08:48 +0100)
1  2 
configure.ac
src/apcups.c
src/modbus.c
src/write_kafka.c
src/write_riemann.c
src/write_riemann_threshold.c

diff --combined configure.ac
@@@ -1,7 -1,6 +1,7 @@@
  dnl Process this file with autoconf to produce a configure script.
 +AC_PREREQ([2.60])
  AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)])
 -AC_CONFIG_SRCDIR(src/)
 +AC_CONFIG_SRCDIR(src/target_set.c)
  AC_CONFIG_HEADERS(src/config.h)
  AC_CONFIG_AUX_DIR([libltdl/config])
  
@@@ -32,7 -31,7 +32,7 @@@ m4_ifdef([LT_PACKAGE_VERSION]
  
  AM_CONDITIONAL([BUILD_INCLUDED_LTDL], [test "x$LTDLDEPS" != "x"])
  
 -AM_INIT_AUTOMAKE([tar-pax dist-bzip2 foreign])
 +AM_INIT_AUTOMAKE([subdir-objects tar-pax dist-bzip2 no-dist-gzip foreign])
  m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
  AC_LANG(C)
  
@@@ -43,10 -42,7 +43,10 @@@ AC_SYS_LARGEFIL
  #
  # Checks for programs.
  #
 -AC_PROG_CC
 +AC_PROG_CC_C99([],
 +  [AC_MSG_ERROR([No compiler found that supports C99])]
 +)
 +AC_PROG_CXX
  AC_PROG_CPP
  AC_PROG_EGREP
  AC_PROG_INSTALL
@@@ -60,8 -56,6 +60,8 @@@ AC_PROG_LIBTOO
  AC_PROG_LEX
  AC_PROG_YACC
  
 +AC_PATH_PROG([VALGRIND], [valgrind])
 +
  # Warn when pkg.m4 is missing
  m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config])
  
@@@ -79,33 -73,26 +79,33 @@@ the
        AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison])
  fi
  
 -AC_CHECK_PROG([have_protoc_c], [protoc-c], [yes], [no])
 -if test "x$have_protoc_c" = "xno"
 -then
 -      have_protoc_c="no (protoc-c compiler not found)"
 +AC_ARG_VAR([PROTOC], [path to the protoc binary])
 +AC_PATH_PROG([PROTOC], [protoc])
 +have_protoc3="no"
 +if test "x$PROTOC" != "x"; then
 +      AC_MSG_CHECKING([for protoc 3.0.0+])
 +      if $PROTOC --version | $EGREP libprotoc.3 >/dev/null; then
 +              protoc3="yes (`$PROTOC --version`)"
 +              have_protoc3="yes"
 +      else
 +              protoc3="no (`$PROTOC --version`)"
 +      fi
 +      AC_MSG_RESULT([$protoc3])
  fi
 +AM_CONDITIONAL(HAVE_PROTOC3, test "x$have_protoc3" = "xyes")
  
 -if test "x$have_protoc_c" = "xyes"
 -then
 -      AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h],
 -                       [have_protoc_c="yes"; break],
 -                       [have_protoc_c="no (<google/protobuf-c/protobuf-c.h> not found)"])
 -fi
 -if test "x$have_protoc_c" = "xyes"
 -then
 -      AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack],
 -                   [have_protoc_c="yes"],
 -                   [have_protoc_c="no (libprotobuf-c not found)"])
 +AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary])
 +AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin])
 +AM_CONDITIONAL(HAVE_GRPC_CPP, test "x$GRPC_CPP_PLUGIN" != "x")
  
 +AC_ARG_VAR([PROTOC_C], [path to the protoc-c binary])
 +AC_PATH_PROG([PROTOC_C], [protoc-c])
 +if test "x$PROTOC_C" = "x"
 +then
 +  have_protoc_c="no (protoc-c compiler not found)"
 +else
 +  have_protoc_c="yes"
  fi
 -AM_CONDITIONAL(HAVE_PROTOC_C, test "x$have_protoc_c" = "xyes")
  
  AC_MSG_CHECKING([for kernel type ($host_os)])
  case $host_os in
        AC_DEFINE([KERNEL_OPENBSD], 1, [True if program is to be compiled for an OpenBSD kernel])
        ac_system="OpenBSD"
        ;;
 +      *netbsd*)
 +      AC_DEFINE([KERNEL_NETBSD], 1, [True if program is to be compiled for a NetBSD kernel])
 +      ac_system="NetBSD"
 +      ;;
        *aix*)
        AC_DEFINE([KERNEL_AIX], 1, [True if program is to be compiled for a AIX kernel])
        ac_system="AIX"
  esac
  AC_MSG_RESULT([$ac_system])
  
 -AM_CONDITIONAL([BUILD_LINUX],[test "x$ac_system" = "xLinux"])
 -AM_CONDITIONAL([BUILD_SOLARIS],[test "x$ac_system" = "xSolaris"])
 -AM_CONDITIONAL([BUILD_DARWIN],[test "x$ac_system" = "xDarwin"])
 -AM_CONDITIONAL([BUILD_OPENBSD],[test "x$ac_system" = "xOpenBSD"])
 -AM_CONDITIONAL([BUILD_AIX],[test "x$ac_system" = "xAIX"])
 -AM_CONDITIONAL([BUILD_FREEBSD],[test "x$ac_system" = "xFreeBSD"])
 +AM_CONDITIONAL([BUILD_AIX], [test "x$ac_system" = "xAIX"])
 +AM_CONDITIONAL([BUILD_DARWIN], [test "x$ac_system" = "xDarwin"])
 +AM_CONDITIONAL([BUILD_FREEBSD], [test "x$ac_system" = "xFreeBSD"])
 +AM_CONDITIONAL([BUILD_LINUX], [test "x$ac_system" = "xLinux"])
 +AM_CONDITIONAL([BUILD_OPENBSD], [test "x$ac_system" = "xOpenBSD"])
 +AM_CONDITIONAL([BUILD_SOLARIS], [test "x$ac_system" = "xSolaris"])
  
  if test "x$ac_system" = "xLinux"
  then
@@@ -216,19 -199,6 +216,19 @@@ AC_HEADER_STDBOO
  
  AC_CHECK_HEADERS(stdio.h errno.h math.h stdarg.h syslog.h fcntl.h signal.h assert.h sys/types.h sys/socket.h sys/select.h poll.h netdb.h arpa/inet.h sys/resource.h sys/param.h kstat.h regex.h sys/ioctl.h endian.h sys/isa_defs.h fnmatch.h libgen.h)
  
 +# For entropy plugin on newer NetBSD
 +AC_CHECK_HEADERS(sys/rndio.h, [], [],
 +[#if HAVE_SYS_TYPES_H
 +# include <sys/types.h>
 +#endif
 +#if HAVE_SYS_IOCTL_H
 +# include <sys/ioctl.h>
 +#endif
 +#if HAVE_SYS_PARAM_H
 +# include <sys/param.h>
 +#endif
 +])
 +
  # For ping library
  AC_CHECK_HEADERS(netinet/in_systm.h, [], [],
  [#if HAVE_STDINT_H
@@@ -443,7 -413,7 +443,7 @@@ AC_CHECK_HEADERS(sys/sysctl.h, [], []
  AC_MSG_CHECKING([for sysctl kern.cp_times])
  if test -x /sbin/sysctl
  then
 -      /sbin/sysctl kern.cp_times 2>/dev/null
 +      /sbin/sysctl kern.cp_times >/dev/null 2>&1
        if test $? -eq 0
        then
                AC_MSG_RESULT([yes])
@@@ -456,22 -426,6 +456,22 @@@ els
        AC_MSG_RESULT([no])
  fi
  
 +AC_MSG_CHECKING([for sysctl kern.cp_time])
 +if test -x /sbin/sysctl
 +then
 +      /sbin/sysctl kern.cp_time >/dev/null 2>&1
 +      if test $? -eq 0
 +      then
 +              AC_MSG_RESULT([yes])
 +              AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIME, 1,
 +                      [Define if sysctl supports kern.cp_time])
 +      else
 +              AC_MSG_RESULT([no])
 +      fi
 +else
 +      AC_MSG_RESULT([no])
 +fi
 +
  # For hddtemp module
  AC_CHECK_HEADERS(linux/major.h)
  
@@@ -491,7 -445,7 +491,7 @@@ els
        have_linux_raid_md_u_h="no"
  fi
  
 -# For the swap module
 +# For the wireless module
  have_linux_wireless_h="no"
  if test "x$ac_system" = "xLinux"
  then
@@@ -683,26 -637,10 +683,26 @@@ AC_CHECK_HEADERS([ 
    wordexp.h \
  ])
  
 -AC_CHECK_HEADERS([xfs/xqm.h], [], [],
 -[
 -#define _GNU_SOURCE
 -])
 +# --enable-xfs {{{
 +AC_ARG_ENABLE([xfs],
 +  [AS_HELP_STRING([--enable-xfs], [xfs support in df plugin @<:@default=yes@:>@])],
 +  [],
 +  [enable_xfs="auto"]
 +)
 +
 +if test "x$enable_xfs" != "xno"; then
 +  AC_CHECK_HEADERS([xfs/xqm.h],
 +    [],
 +    [
 +      if test "x$enable_xfs" = "xyes"; then
 +        AC_MSG_ERROR([xfs/xqm.h not found])
 +      fi
 +    ],
 +    [[#define _GNU_SOURCE]]
 +  )
 +fi
 +
 +# }}}
  
  # For the dns plugin
  AC_CHECK_HEADERS(arpa/nameser.h)
@@@ -742,6 -680,8 +742,6 @@@ AC_CHECK_HEADERS(netinet/if_ether.h, []
  #endif
  ])
  
 -AC_CHECK_HEADERS(netinet/ip_compat.h)
 -
  have_net_pfvar_h="no"
  AC_CHECK_HEADERS(net/pfvar.h,
                 [have_net_pfvar_h="yes"],
  have_termios_h="no"
  AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"])
  
 +# For cpusleep plugin
 +AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported],
 +                     [c_cv_have_clock_boottime_monotonic],
 +                     AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
 +[[
 +#include <time.h>
 +]],
 +[[
 + struct timespec b, m;
 + clock_gettime(CLOCK_BOOTTIME, &b );
 + clock_gettime(CLOCK_MONOTONIC, &m );
 +]]
 +                     )],
 +                     [c_cv_have_clock_boottime_monotonic="yes"],
 +                     [c_cv_have_clock_boottime_monotonic="no"]))
 +
 +
  # For the turbostat plugin
  have_asm_msrindex_h="no"
  AC_CHECK_HEADERS(asm/msr-index.h, [have_asm_msrindex_h="yes"])
  have_cpuid_h="no"
  AC_CHECK_HEADERS(cpuid.h, [have_cpuid_h="yes"])
  
 -AC_CHECK_HEADERS(sys/capability.h)
 +have_capability="yes"
 +AC_CHECK_HEADERS(sys/capability.h,
 +                 [have_capability="yes"],
 +                 [have_capability="no (<sys/capability.h> not found)"])
 +if test "x$have_capability" = "xyes"; then
 +AC_CHECK_LIB(cap, cap_get_bound,
 +                 [have_capability="yes"],
 +                 [have_capability="no (cap_get_bound() not found)"])
 +fi
 +if test "x$have_capability" = "xyes"; then
 +  AC_DEFINE(HAVE_CAPABILITY, 1, [Define to 1 if you have cap_get_bound() (-lcap).])
 +fi
 +AM_CONDITIONAL(BUILD_WITH_CAPABILITY, test "x$have_capability" = "xyes")
 +
  #
  # Checks for typedefs, structures, and compiler characteristics.
  #
  AC_C_CONST
 -AC_C_INLINE
 -AC_TYPE_OFF_T
  AC_TYPE_PID_T
  AC_TYPE_SIZE_T
 -AC_TYPE_SSIZE_T
  AC_TYPE_UID_T
 -AC_TYPE_UINT32_T
  AC_HEADER_TIME
  
  #
  # Checks for library functions.
  #
 -AC_PROG_GCC_TRADITIONAL
 -AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale)
 +AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale asprintf)
  
  AC_FUNC_STRERROR_R
  
 +test_cxx_flags() {
 +      AC_LANG_PUSH([C++])
 +      AC_LANG_CONFTEST([
 +              AC_LANG_SOURCE([[int main(void){}]])
 +      ])
 +      $CXX -c conftest.cpp $CXXFLAGS $@ > /dev/null 2> /dev/null
 +      ret=$?
 +      rm -f conftest.o
 +      AC_LANG_POP([C++])
 +      return $ret
 +}
 +
  SAVE_CFLAGS="$CFLAGS"
  # Emulate behavior of src/Makefile.am
  if test "x$GCC" = "xyes"
@@@ -949,6 -852,8 +949,6 @@@ f
  if test "x$have_clock_gettime" = "xyes"
  then
        AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if the clock_gettime(2) function is available.])
 -else
 -      AC_MSG_WARN(cannot find clock_gettime)
  fi
  
  nanosleep_needs_rt="no"
@@@ -1400,20 -1305,6 +1400,20 @@@ AC_ARG_WITH(useragent, [AS_HELP_STRING(
  
  # }}}
  
 +# --with-data-max-name-len {{{
 +AC_ARG_WITH(data-max-name-len, [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])],
 +[
 +    if test "x$withval" != "x" && test $withval -gt 0
 +    then
 +        AC_DEFINE_UNQUOTED(DATA_MAX_NAME_LEN, [$withval], [Maximum length of data buffers])
 +    else
 +        AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given])
 +    fi
 +],
 +[   AC_DEFINE(DATA_MAX_NAME_LEN, 128, [Maximum length of data buffers])]
 +)
 +# }}}
 +
  have_getfsstat="no"
  AC_CHECK_FUNCS(getfsstat, [have_getfsstat="yes"])
  have_getvfsstat="no"
@@@ -1491,15 -1382,15 +1491,15 @@@ if test "x$have_getmntent" = "xc"; the
  fi
  if test "x$have_getmntent" = "xsun"; then
        AC_DEFINE(HAVE_SUN_GETMNTENT, 1,
 -                [Define if the function getmntent exists. It's the version from libsun.])
 +                [Define if the function getmntent exists. It is the version from libsun.])
  fi
  if test "x$have_getmntent" = "xseq"; then
        AC_DEFINE(HAVE_SEQ_GETMNTENT, 1,
 -                [Define if the function getmntent exists. It's the version from libseq.])
 +                [Define if the function getmntent exists. It is the version from libseq.])
  fi
  if test "x$have_getmntent" = "xgen"; then
        AC_DEFINE(HAVE_GEN_GETMNTENT, 1,
 -                [Define if the function getmntent exists. It's the version from libgen.])
 +                [Define if the function getmntent exists. It is the version from libgen.])
  fi
  
  # Check for htonll
@@@ -1590,24 -1481,6 +1590,24 @@@ AC_CHECK_MEMBERS([struct kinfo_proc.p_p
  #include <kvm.h>
        ])
  
 +
 +AC_CHECK_MEMBERS([struct kinfo_proc2.p_pid, struct kinfo_proc2.p_uru_maxrss],
 +      [
 +              AC_DEFINE(HAVE_STRUCT_KINFO_PROC2_NETBSD, 1,
 +                      [Define if struct kinfo_proc2 exists in the NetBSD variant.])
 +              have_struct_kinfo_proc2_netbsd="yes"
 +      ],
 +      [
 +              have_struct_kinfo_proc2_netbsd="no"
 +      ],
 +      [
 +#include <sys/param.h>
 +#include <sys/sysctl.h>
 +#include <kvm.h>
 +      ])
 +
 +
 +
  AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [],
  [#define _BSD_SOURCE
  #define _DEFAULT_SOURCE
@@@ -1675,48 -1548,18 +1675,48 @@@ AC_CHECK_LIB(resolv, res_search
  AM_CONDITIONAL(BUILD_WITH_LIBRESOLV, test "x$with_libresolv" = "xyes")
  
  dnl Check for HAL (hardware abstraction library)
 -with_libhal="yes"
 -AC_CHECK_LIB(hal,libhal_device_property_exists,
 -           [AC_DEFINE(HAVE_LIBHAL, 1, [Define to 1 if you have 'hal' library])],
 -           [with_libhal="no"])
 -if test "x$with_libhal" = "xyes"; then
 -      if test "x$PKG_CONFIG" != "x"; then
 -              BUILD_WITH_LIBHAL_CFLAGS="`$PKG_CONFIG --cflags hal`"
 -              BUILD_WITH_LIBHAL_LIBS="`$PKG_CONFIG --libs hal`"
 -              AC_SUBST(BUILD_WITH_LIBHAL_CFLAGS)
 -              AC_SUBST(BUILD_WITH_LIBHAL_LIBS)
 -      fi
 -fi
 +with_libhal="no"
 +PKG_CHECK_MODULES([HAL], [hal],
 +  [
 +    SAVE_LIBS="$LIBS"
 +    LIBS="$HAL_LIBS $LIBS"
 +    AC_CHECK_LIB([hal], [libhal_device_property_exists],
 +      [
 +        SAVE_CPPFLAGS="$CPPFLAGS"
 +        CPPFLAGS="$HAL_CFLAGS $CPPFLAGS"
 +        AC_CHECK_HEADERS([libhal.h],
 +        [
 +          with_libhal="yes"
 +          BUILD_WITH_LIBHAL_CFLAGS="$HAL_CFLAGS"
 +          BUILD_WITH_LIBHAL_LIBS="$HAL_LIBS"
 +        ])
 +        CPPFLAGS="$SAVE_CPPFLAGS"
 +      ],
 +      [ : ]
 +    )
 +    LIBS="$SAVE_LIBS"
 +  ],
 +  [ : ]
 +)
 +AC_SUBST(BUILD_WITH_LIBHAL_CFLAGS)
 +AC_SUBST(BUILD_WITH_LIBHAL_LIBS)
 +
 +
 +SAVE_LIBS="$LIBS"
 +AC_CHECK_LIB([pthread],
 +  [pthread_create],
 +  [],
 +  [AC_MSG_ERROR([Symbol 'pthread_create' not found in libpthread"])],
 +  []
 +)
 +PTHREAD_LIBS="$LIBS"
 +LIBS="$SAVE_LIBS"
 +
 +AC_CHECK_HEADERS([pthread.h],
 +  [],
 +  [AC_MSG_ERROR([pthread.h not found])]
 +)
 +AC_SUBST([PTHREAD_LIBS])
  
  m4_divert_once([HELP_WITH], [
  collectd additional packages:])
  fi
  if test "x$with_libcurl" = "xyes"
  then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      SAVE_LDFLAGS="$LDFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_curl_cflags"
 +      LDFLAGS="$LDFLAGS $with_curl_libs"
 +      AC_CACHE_CHECK([for CURLINFO_APPCONNECT_TIME],
 +              [c_cv_have_curlinfo_appconnect_time],
 +              AC_LINK_IFELSE([AC_LANG_PROGRAM(
 +[[
 +#include <curl/curl.h>
 +]],
 +[[
 +int val = CURLINFO_APPCONNECT_TIME;
 +return val;
 +]]
 +                      )],
 +                      [c_cv_have_curlinfo_appconnect_time="yes"],
 +                      [c_cv_have_curlinfo_appconnect_time="no"]
 +              )
 +      )
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +      LDFLAGS="$SAVE_LDFLAGS"
 +fi
 +AM_CONDITIONAL(BUILD_WITH_LIBCURL, test "x$with_libcurl" = "xyes")
 +if test "x$c_cv_have_curlinfo_appconnect_time" = "xyes"
 +then
 +      AC_DEFINE(HAVE_CURLINFO_APPCONNECT_TIME, 1, [Define if curl.h defines CURLINFO_APPCONNECT_TIME.])
 +fi
 +
 +if test "x$with_libcurl" = "xyes"
 +then
        BUILD_WITH_LIBCURL_CFLAGS="$with_curl_cflags"
        BUILD_WITH_LIBCURL_LIBS="$with_curl_libs"
        AC_SUBST(BUILD_WITH_LIBCURL_CFLAGS)
                AC_DEFINE(HAVE_CURLOPT_TIMEOUT_MS, 1, [Define if libcurl supports CURLOPT_TIMEOUT_MS option.])
        fi
  fi
 -AM_CONDITIONAL(BUILD_WITH_LIBCURL, test "x$with_libcurl" = "xyes")
  # }}}
  
  # --with-libdbi {{{
@@@ -2297,6 -2111,12 +2297,6 @@@ the
        AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer,
                [with_libgcrypt="yes"],
                [with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"])
 -
 -      if test "$with_libgcrypt" != "no"; then
 -              m4_ifdef([AM_PATH_LIBGCRYPT],[AM_PATH_LIBGCRYPT(1:1.2.0,,with_libgcrypt="no (version 1.2.0+ required)")])
 -              GCRYPT_CPPFLAGS="$LIBGCRYPT_CPPFLAGS $LIBGCRYPT_CFLAGS"
 -              GCRYPT_LIBS="$LIBGCRYPT_LIBS"
 -      fi
  fi
  
  CPPFLAGS="$SAVE_CPPFLAGS"
@@@ -2314,146 -2134,6 +2314,146 @@@ AC_SUBST(GCRYPT_LIBS
  AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes")
  # }}}
  
 +# --with-libgps {{{
 +with_libgps_cflags=""
 +with_libgps_ldflags=""
 +AC_ARG_WITH(libgps, [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])],
 +[
 +      if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +      then
 +              with_libgps_cflags="-I$withval/include"
 +              with_libgps_ldflags="-L$withval/lib"
 +              with_libgps="yes"
 +      else
 +              with_libgps="$withval"
 +      fi
 +],
 +[
 +      with_libgps="yes"
 +])
 +if test "x$with_libgps" = "xyes"
 +then
 +      SAVE_CFLAGS="$CFLAGS"
 +      CFLAGS="$CFLAGS $with_libgps_cflags"
 +
 +      AC_CHECK_HEADERS(gps.h, [with_libgps="yes"], [with_libgps="no (gps.h not found)"])
 +
 +      CFLAGS="$SAVE_CFLAGS"
 +fi
 +if test "x$with_libgps" = "xyes"
 +then
 +      SAVE_CFLAGS="$CFLAGS"
 +      SAVE_LDFLAGS="$LDFLAGS"
 +      CFLAGS="$CFLAGS $with_libgps_cflags"
 +      LDFLAGS="$LDFLAGS $with_libgps_ldflags"
 +
 +      AC_CHECK_LIB(gps, gps_open, [with_libgps="yes"], [with_libgps="no (symbol gps_open not found)"])
 +
 +      CFLAGS="$SAVE_CFLAGS"
 +      LDFLAGS="$SAVE_LDFLAGS"
 +fi
 +if test "x$with_libgps" = "xyes"
 +then
 +      BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags"
 +      BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags"
 +      BUILD_WITH_LIBGPS_LIBS="-lgps"
 +      AC_SUBST(BUILD_WITH_LIBGPS_CFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBGPS_LDFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBGPS_LIBS)
 +fi
 +AM_CONDITIONAL(BUILD_WITH_LIBGPS, test "x$with_libgps" = "xyes")
 +# }}}
 +
 +# --with-libgrpc++ {{{
 +with_libgrpcpp_cppflags=""
 +with_libgrpcpp_ldflags=""
 +AC_ARG_WITH([libgrpc++], [AS_HELP_STRING([--with-libgrpc++@<:@=PREFIX@:>@], [Path to libgrpc++.])],
 +  [
 +    with_grpcpp="$withval"
 +    if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +    then
 +      with_libgrpcpp_cppflags="-I$withval/include"
 +      with_libgrpcpp_ldflags="-L$withval/lib"
 +      with_libgrpcpp="yes"
 +    fi
 +    if test "x$withval" = "xno"
 +    then
 +      with_libgrpcpp="no (disabled on command line)"
 +    fi
 +  ],
 +  [withval="yes"]
 +)
 +if test "x$withval" = "xyes"
 +then
 +PKG_CHECK_MODULES([GRPCPP], [grpc++],
 +  [with_libgrpcpp="yes"],
 +  [with_libgrpcpp="no (pkg-config could not find libgrpc++)"]
 +)
 +fi
 +
 +if test "x$withval" != "xno"
 +then
 +  AC_MSG_CHECKING([whether $CXX accepts -std=c++11])
 +  if test_cxx_flags -std=c++11; then
 +    AC_MSG_RESULT([yes])
 +  else
 +    AC_MSG_RESULT([no])
 +    with_libgrpcpp="no (requires C++11 support)"
 +  fi
 +fi
 +
 +if test "x$with_libgrpcpp" = "xyes"
 +then
 +  AC_LANG_PUSH(C++)
 +  SAVE_CPPFLAGS="$CPPFLAGS"
 +  CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
 +  AC_CHECK_HEADERS([grpc++/grpc++.h], [],
 +    [with_libgrpcpp="no (<grpc++/grpc++.h> not found)"]
 +  )
 +  CPPFLAGS="$SAVE_CPPFLAGS"
 +  AC_LANG_POP(C++)
 +fi
 +if test "x$with_libgrpcpp" = "xyes"
 +then
 +  AC_LANG_PUSH(C++)
 +  SAVE_CPPFLAGS="$CPPFLAGS"
 +  SAVE_LDFLAGS="$LDFLAGS"
 +  SAVE_LIBS="$LIBS"
 +  CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
 +  LDFLAGS="$with_libgrpcpp_ldflags"
 +  if test "x$GRPCPP_LIBS" = "x"
 +  then
 +    LIBS="-lgrpc++"
 +  else
 +    LIBS="$GRPCPP_LIBS"
 +  fi
 +  AC_LINK_IFELSE(
 +    [AC_LANG_PROGRAM(
 +      [[#include <grpc++/grpc++.h>]],
 +      [[grpc::ServerBuilder sb;]]
 +    )],
 +    [
 +      with_libgrpcpp="yes"
 +      if test "x$GRPCPP_LIBS" = "x"
 +      then
 +        GRPCPP_LIBS="-lgrpc++"
 +      fi
 +    ],
 +    [with_libgrpcpp="no (libgrpc++ not found)"]
 +  )
 +  CPPFLAGS="$SAVE_CPPFLAGS"
 +  LDFLAGS="$SAVE_LDFLAGS"
 +  LIBS="$SAVE_LIBS"
 +  AC_LANG_POP(C++)
 +fi
 +BUILD_WITH_LIBGRPCPP_CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS"
 +BUILD_WITH_LIBGRPCPP_LDFLAGS="$with_libgrpcpp_ldflags"
 +BUILD_WITH_LIBGRPCPP_LIBS="$GRPCPP_LIBS"
 +AC_SUBST([BUILD_WITH_LIBGRPCPP_CPPFLAGS])
 +AC_SUBST([BUILD_WITH_LIBGRPCPP_LDFLAGS])
 +AC_SUBST([BUILD_WITH_LIBGRPCPP_LIBS])
 +# }}}
 +
  # --with-libiptc {{{
  AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])],
  [
        fi
  ])
  
 -if test "x$with_libiptc" = "xpkgconfig" && test "x$PKG_CONFIG" = "x"
 -then
 -      with_libiptc="no (Don't have pkg-config)"
 -fi
 -
  if test "x$with_libiptc" = "xpkgconfig"
  then
        $PKG_CONFIG --exists 'libiptc' 2>/dev/null
@@@ -2550,6 -2235,9 +2550,6 @@@ if test "x$with_java_home" = "x
  then
        with_java_home="/usr/lib/jvm"
  fi
 -with_java_vmtype="client"
 -with_java_cflags=""
 -with_java_libs=""
  JAVAC="$JAVAC"
  JAR="$JAR"
  AC_ARG_WITH(java, [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])],
@@@ -2642,10 -2330,6 +2642,10 @@@ if test "x$JAVA_LDFLAGS" != "x
  then
        AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
  fi
 +if test "x$JAVA_LIBS" != "x"
 +then
 +      AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
 +fi
  if test "x$JAVAC" = "x"
  then
        with_javac_path="$PATH"
  SAVE_CPPFLAGS="$CPPFLAGS"
  SAVE_CFLAGS="$CFLAGS"
  SAVE_LDFLAGS="$LDFLAGS"
 +SAVE_LIBS="$LIBS"
  CPPFLAGS="$CPPFLAGS $JAVA_CPPFLAGS"
  CFLAGS="$CFLAGS $JAVA_CFLAGS"
  LDFLAGS="$LDFLAGS $JAVA_LDFLAGS"
 +LIBS="$LIBS $JAVA_LIBS"
  
  if test "x$with_java" = "xyes"
  then
@@@ -2700,8 -2382,8 +2700,8 @@@ if test "x$with_java" = "xyes
  then
        AC_CHECK_LIB(jvm, JNI_CreateJavaVM,
        [with_java="yes"],
 -      [with_java="no (libjvm not found)"],
 -      [$JAVA_LIBS])
 +      [with_java="no (Symbol 'JNI_CreateJavaVM' not found)"],
 +      [$JAVA_LIBS $PTHREAD_LIBS])
  fi
  if test "x$with_java" = "xyes"
  then
  CPPFLAGS="$SAVE_CPPFLAGS"
  CFLAGS="$SAVE_CFLAGS"
  LDFLAGS="$SAVE_LDFLAGS"
 +LIBS="$SAVE_LIBS"
  
  AC_SUBST(JAVA_CPPFLAGS)
  AC_SUBST(JAVA_CFLAGS)
  AM_CONDITIONAL(BUILD_WITH_LIBLDAP, test "x$with_libldap" = "xyes")
  # }}}
  
 +# --with-liblua {{{
 +AC_ARG_VAR([LIBLUA_PKG_CONFIG_NAME], [Name of liblua used by pkg-config])
 +if test "x$LIBLUA_PKG_CONFIG_NAME" != "x"
 +then
 +  PKG_CHECK_MODULES([LUA], [$LIBLUA_PKG_CONFIG_NAME],
 +    [with_liblua="yes"],
 +    [with_liblua="no"]
 +  )
 +else
 +  PKG_CHECK_MODULES([LUA], [lua],
 +    [with_liblua="yes"],
 +    [
 +      PKG_CHECK_MODULES([LUA], [lua-5.3],
 +        [with_liblua="yes"],
 +        [
 +        PKG_CHECK_MODULES([LUA], [lua5.3],
 +            [with_liblua="yes"],
 +            [
 +              PKG_CHECK_MODULES([LUA], [lua-5.2],
 +                [with_liblua="yes"],
 +                [
 +                  PKG_CHECK_MODULES([LUA], [lua5.2],
 +                    [with_liblua="yes"],
 +                    [
 +                      PKG_CHECK_MODULES([LUA], [lua-5.1],
 +                        [with_liblua="yes"],
 +                        [
 +                          PKG_CHECK_MODULES([LUA], [lua5.1],
 +                            [with_liblua="yes"],
 +                            [with_liblua="no (pkg-config cannot find liblua)"]
 +                          )
 +                        ]
 +                      )
 +                    ]
 +                  )
 +                ]
 +              )
 +            ]
 +          )
 +        ]
 +      )
 +    ]
 +  )
 +fi
 +
 +if test "x$with_liblua" = "xyes"
 +then
 +  SAVE_CFLAGS="$CFLAGS"
 +  CFLAGS="$CFLAGS $LUA_CFLAGS"
 +
 +  AC_CHECK_HEADERS([lua.h lauxlib.h lualib.h],
 +    [with_liblua="yes"],
 +    [with_liblua="no (header not found)"]
 +  )
 +
 +  CFLAGS="$SAVE_CFLAGS"
 +fi
 +
 +if test "x$with_liblua" = "xyes"
 +then
 +  SAVE_LIBS="$LIBS"
 +  LIBS="$LIBS $LUA_LIBS"
 +
 +  AC_CHECK_FUNC([lua_settop],
 +    [with_liblua="yes"],
 +    [with_liblua="no (symbol 'lua_settop' not found)"]
 +  )
 +
 +  LIBS="$SAVE_LIBS"
 +fi
 +
 +if test "x$with_liblua" = "xyes"
 +then
 +    BUILD_WITH_LIBLUA_CFLAGS="$LUA_CFLAGS"
 +    BUILD_WITH_LIBLUA_LIBS="$LUA_LIBS"
 +fi
 +AC_SUBST(BUILD_WITH_LIBLUA_CFLAGS)
 +AC_SUBST(BUILD_WITH_LIBLUA_LIBS)
 +# }}}
 +
  # --with-liblvm2app {{{
  with_liblvm2app_cppflags=""
  with_liblvm2app_ldflags=""
  AC_ARG_WITH(liblvm2app, [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])],
  [
 -        if test "x$withval" != "xno" && test "x$withval" != "xyes"
 -        then
 -                with_liblvm2app_cppflags="-I$withval/include"
 -                with_liblvm2app_ldflags="-L$withval/lib"
 -                with_liblvm2app="yes"
 -        else
 -                with_liblvm2app="$withval"
 +      if test "x$withval" = "xno"
 +      then
 +              with_liblvm2app="no"
 +      else
 +              with_liblvm2app="yes"
 +              if test "x$withval" != "xyes"
 +              then
 +                      with_liblvm2app_cppflags="-I$withval/include"
 +                      with_liblvm2app_ldflags="-L$withval/lib"
 +              fi
          fi
  ],
  [
 -        with_liblvm2app="yes"
 +      if test "x$ac_system" = "xLinux"
 +      then
 +              with_liblvm2app="yes"
 +      else
 +              with_liblvm2app="no (Linux only library)"
 +      fi
  ])
  if test "x$with_liblvm2app" = "xyes"
  then
@@@ -2995,6 -2588,13 +2995,6 @@@ AC_ARG_WITH(libmodbus, [AS_HELP_STRING(
  # configure using pkg-config
  if test "x$with_libmodbus" = "xuse_pkgconfig"
  then
 -      if test "x$PKG_CONFIG" = "x"
 -      then
 -              with_libmodbus="no (Don't have pkg-config)"
 -      fi
 -fi
 -if test "x$with_libmodbus" = "xuse_pkgconfig"
 -then
        AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG])
        $PKG_CONFIG --exists 'libmodbus' 2>/dev/null
        if test $? -ne 0
  AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
  # }}}
  
 -# --with-libmysql {{{
 -with_mysql_config="mysql_config"
 -with_mysql_cflags=""
 -with_mysql_libs=""
 -AC_ARG_WITH(libmysql, [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to libmysql.])],
 +# --with-libmosquitto {{{
 +with_libmosquitto_cppflags=""
 +with_libmosquitto_ldflags=""
 +AC_ARG_WITH(libmosquitto, [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@], [Path to libmosquitto.])],
  [
 -      if test "x$withval" = "xno"
 -      then
 -              with_libmysql="no"
 -      else if test "x$withval" = "xyes"
 +      if test "x$withval" != "xno" && test "x$withval" != "xyes"
        then
 -              with_libmysql="yes"
 +              with_libmosquitto_cppflags="-I$withval/include"
 +              with_libmosquitto_ldflags="-L$withval/lib"
 +              with_libmosquitto="yes"
        else
 -              if test -f "$withval" && test -x "$withval";
 -              then
 -                      with_mysql_config="$withval"
 -              else if test -x "$withval/bin/mysql_config"
 -              then
 -                      with_mysql_config="$withval/bin/mysql_config"
 -              fi; fi
 -              with_libmysql="yes"
 +              with_libmosquitto="$withval"
 +      fi
 +],
 +[
 +      with_libmosquitto="yes"
 +])
 +if test "x$with_libmosquitto" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
 +
 +      AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +if test "x$with_libmosquitto" = "xyes"
 +then
 +      SAVE_LDFLAGS="$LDFLAGS"
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags"
 +      CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
 +
 +      AC_CHECK_LIB(mosquitto, mosquitto_connect, [with_libmosquitto="yes"], [with_libmosquitto="no (libmosquitto not found)"])
 +
 +      LDFLAGS="$SAVE_LDFLAGS"
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +if test "x$with_libmosquitto" = "xyes"
 +then
 +      BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
 +      BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags"
 +      BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto"
 +      AC_SUBST(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LIBS)
 +fi
 +# }}}
 +
 +# --with-libmysql {{{
 +with_mysql_config="mysql_config"
 +with_mysql_cflags=""
 +with_mysql_libs=""
 +AC_ARG_WITH(libmysql, [AS_HELP_STRING([--with-libmysql@<:@=PREFIX@:>@], [Path to libmysql.])],
 +[
 +      if test "x$withval" = "xno"
 +      then
 +              with_libmysql="no"
 +      else if test "x$withval" = "xyes"
 +      then
 +              with_libmysql="yes"
 +      else
 +              if test -f "$withval" && test -x "$withval";
 +              then
 +                      with_mysql_config="$withval"
 +              else if test -x "$withval/bin/mysql_config"
 +              then
 +                      with_mysql_config="$withval/bin/mysql_config"
 +              fi; fi
 +              with_libmysql="yes"
        fi; fi
  ],
  [
@@@ -3285,6 -2836,10 +3285,6 @@@ AC_ARG_WITH(libmnl, [AS_HELP_STRING([--
         with_libmnl="no (Linux only library)"
   fi
  ])
 -if test "x$PKG_CONFIG" = "x"
 -then
 -      with_libmnl="no (Don't have pkg-config)"
 -fi
  if test "x$with_libmnl" = "xyes"
  then
        if $PKG_CONFIG --exists libmnl 2>/dev/null; then
@@@ -3415,7 -2970,7 +3415,7 @@@ the
  
        if test "x$LIBNETAPP_LIBS" = "x"
        then
 -              LIBNETAPP_LIBS="-lpthread -lxml -ladt -lssl -lm -lcrypto -lz"
 +              LIBNETAPP_LIBS="$PTHREAD_LIBS -lxml -ladt -lssl -lm -lcrypto -lz"
        fi
        AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS])
  
@@@ -3441,6 -2996,9 +3441,6 @@@ AM_CONDITIONAL(BUILD_WITH_LIBNETAPP, te
  # }}}
  
  # --with-libnetsnmp {{{
 -with_snmp_config="net-snmp-config"
 -with_snmp_cflags=""
 -with_snmp_libs=""
  AC_ARG_WITH(libnetsnmp, [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Path to the Net-SNMPD library.])],
  [
        if test "x$withval" = "xno"
        then
                with_libnetsnmp="yes"
        else
 -              if test -x "$withval"
 -              then
 -                      with_snmp_config="$withval"
 -                      with_libnetsnmp="yes"
 -              else
 -                      with_snmp_config="$withval/bin/net-snmp-config"
 -                      with_libnetsnmp="yes"
 -              fi
 +              with_libnetsnmp_cppflags="-I$withval/include"
 +              with_libnetsnmp_ldflags="-I$withval/lib"
 +              with_libnetsnmp="yes"
        fi; fi
  ],
  [with_libnetsnmp="yes"])
  if test "x$with_libnetsnmp" = "xyes"
  then
 -      with_snmp_cflags=`$with_snmp_config --cflags 2>/dev/null`
 -      snmp_config_status=$?
 -
 -      if test $snmp_config_status -ne 0
 -      then
 -              with_libnetsnmp="no ($with_snmp_config failed)"
 -      else
 -              SAVE_CPPFLAGS="$CPPFLAGS"
 -              CPPFLAGS="$CPPFLAGS $with_snmp_cflags"
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags"
  
 -              AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"])
 +      AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"])
  
 -              CPPFLAGS="$SAVE_CPPFLAGS"
 -      fi
 +      CPPFLAGS="$SAVE_CPPFLAGS"
  fi
  if test "x$with_libnetsnmp" = "xyes"
  then
 -      with_snmp_libs=`$with_snmp_config --libs 2>/dev/null`
 -      snmp_config_status=$?
 +      SAVE_LDFLAGS="$LDFLAGS"
 +      LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
  
 -      if test $snmp_config_status -ne 0
 -      then
 -              with_libnetsnmp="no ($with_snmp_config failed)"
 -      else
 -              AC_CHECK_LIB(netsnmp, init_snmp,
 +      AC_CHECK_LIB(netsnmp, init_snmp,
                [with_libnetsnmp="yes"],
                [with_libnetsnmp="no (libnetsnmp not found)"],
                [$with_snmp_libs])
 -      fi
 +
 +      LDFLAGS="$SAVE_LDFLAGS"
  fi
  if test "x$with_libnetsnmp" = "xyes"
  then
 -      BUILD_WITH_LIBSNMP_CFLAGS="$with_snmp_cflags"
 -      BUILD_WITH_LIBSNMP_LIBS="$with_snmp_libs"
 -      AC_SUBST(BUILD_WITH_LIBSNMP_CFLAGS)
 -      AC_SUBST(BUILD_WITH_LIBSNMP_LIBS)
 +      BUILD_WITH_LIBNETSNMP_CPPFLAGS="$with_libnetsnmp_cppflags"
 +      BUILD_WITH_LIBNETSNMP_LDFLAGS="$with_libnetsnmp_ldflags"
 +      BUILD_WITH_LIBNETSNMP_LIBS="-lnetsnmp"
  fi
 -AM_CONDITIONAL(BUILD_WITH_LIBNETSNMP, test "x$with_libnetsnmp" = "xyes")
 +AC_SUBST(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
 +AC_SUBST(BUILD_WITH_LIBNETSNMP_LDFLAGS)
 +AC_SUBST(BUILD_WITH_LIBNETSNMP_LIBS)
  # }}}
  
  # --with-liboconfig {{{
@@@ -3518,7 -3091,7 +3518,7 @@@ save_LDFLAGS="$LDFLAGS
  save_CPPFLAGS="$CPPFLAGS"
  LDFLAGS="$liboconfig_LDFLAGS"
  CPPFLAGS="$liboconfig_CPPFLAGS"
 -AC_CHECK_LIB(oconfig, oconfig_parse_fh,
 +AC_CHECK_LIB(oconfig, oconfig_parse_file,
  [
        with_liboconfig="yes"
        with_own_liboconfig="no"
  fi
  if test "x$with_oracle" = "xyes"
  then
 -      BUILD_WITH_ORACLE_CFLAGS="$with_oracle_cppflags"
 +      BUILD_WITH_ORACLE_CPPFLAGS="$with_oracle_cppflags"
        BUILD_WITH_ORACLE_LIBS="$with_oracle_libs"
 -      AC_SUBST(BUILD_WITH_ORACLE_CFLAGS)
 +      AC_SUBST(BUILD_WITH_ORACLE_CPPFLAGS)
        AC_SUBST(BUILD_WITH_ORACLE_LIBS)
  fi
  # }}}
  
  # --with-libowcapi {{{
  with_libowcapi_cppflags=""
 -with_libowcapi_libs="-lowcapi"
 +with_libowcapi_ldflags=""
  AC_ARG_WITH(libowcapi, [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])],
  [
        if test "x$withval" != "xno" && test "x$withval" != "xyes"
        then
                with_libowcapi_cppflags="-I$withval/include"
 -              with_libowcapi_libs="-L$withval/lib -lowcapi"
 +              with_libowcapi_ldflags="-L$withval/lib"
                with_libowcapi="yes"
        else
                with_libowcapi="$withval"
  if test "x$with_libowcapi" = "xyes"
  then
        SAVE_CPPFLAGS="$CPPFLAGS"
 -      CPPFLAGS="$with_libowcapi_cppflags"
 +      CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags"
  
        AC_CHECK_HEADERS(owcapi.h, [with_libowcapi="yes"], [with_libowcapi="no (owcapi.h not found)"])
  
@@@ -3693,7 -3266,7 +3693,7 @@@ if test "x$with_libowcapi" = "xyes
  then
        SAVE_LDFLAGS="$LDFLAGS"
        SAVE_CPPFLAGS="$CPPFLAGS"
 -      LDFLAGS="$with_libowcapi_libs"
 +      LDFLAGS="$LDFLAGS $with_libowcapi_ldflags"
        CPPFLAGS="$with_libowcapi_cppflags"
  
        AC_CHECK_LIB(owcapi, OW_get, [with_libowcapi="yes"], [with_libowcapi="no (libowcapi not found)"])
  if test "x$with_libowcapi" = "xyes"
  then
        BUILD_WITH_LIBOWCAPI_CPPFLAGS="$with_libowcapi_cppflags"
 -      BUILD_WITH_LIBOWCAPI_LIBS="$with_libowcapi_libs"
 +      BUILD_WITH_LIBOWCAPI_LDFLAGS="$with_libowcapi_ldflags"
 +      BUILD_WITH_LIBOWCAPI_LIBS="-lowcapi"
        AC_SUBST(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBOWCAPI_LDFLAGS)
        AC_SUBST(BUILD_WITH_LIBOWCAPI_LIBS)
  fi
  # }}}
@@@ -3802,7 -3373,7 +3802,7 @@@ the
    SAVE_CFLAGS="$CFLAGS"
    SAVE_LIBS="$LIBS"
  dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string)
 -  PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ccopts`
 +  PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e perl_inc`
    PERL_LIBS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ldopts`
    CFLAGS="$CFLAGS $PERL_CFLAGS"
    LIBS="$LIBS $PERL_LIBS"
  AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes")
  # }}}
  
 -# --with-libpthread {{{
 -AC_ARG_WITH(libpthread, [AS_HELP_STRING([--with-libpthread=@<:@=PREFIX@:>@], [Path to libpthread.])],
 -[     if test "x$withval" != "xno" \
 -              && test "x$withval" != "xyes"
 -      then
 -              LDFLAGS="$LDFLAGS -L$withval/lib"
 -              CPPFLAGS="$CPPFLAGS -I$withval/include"
 -              with_libpthread="yes"
 -      else
 -              if test "x$withval" = "xno"
 -              then
 -                      with_libpthread="no (disabled)"
 -              fi
 -      fi
 -], [with_libpthread="yes"])
 -if test "x$with_libpthread" = "xyes"
 +# --with-libprotobuf {{{
 +with_libprotobuf_cppflags=""
 +with_libprotobuf_ldflags=""
 +AC_ARG_WITH([libprotobuf], [AS_HELP_STRING([--with-libprotobuf@<:@=PREFIX@:>@], [Path to libprotobuf.])],
 +  [
 +    if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +    then
 +      with_libprotobuf_cppflags="-I$withval/include"
 +      with_libprotobuf_ldflags="-L$withval/lib"
 +      with_libprotobuf="yes"
 +    fi
 +    if test "x$withval" = "xno"
 +    then
 +      with_libprotobuf="no (disabled on command line)"
 +    fi
 +  ],
 +  [withval="yes"]
 +)
 +if test "x$withval" = "xyes"
  then
 -      AC_CHECK_LIB(pthread, pthread_create, [with_libpthread="yes"], [with_libpthread="no (libpthread not found)"], [])
 +PKG_CHECK_MODULES([PROTOBUF], [protobuf],
 +  [with_libprotobuf="yes"],
 +  [with_libprotobuf="no (pkg-config could not find libprotobuf)"]
 +)
  fi
  
 -if test "x$with_libpthread" = "xyes"
 -then
 -      AC_CHECK_HEADERS(pthread.h,, [with_libpthread="no (pthread.h not found)"])
 -fi
 -if test "x$with_libpthread" = "xyes"
 +if test "x$withval" != "xno"
  then
 -      collect_pthread=1
 -else
 -      collect_pthread=0
 +  SAVE_LDFLAGS="$LDFLAGS"
 +  SAVE_LIBS="$LIBS"
 +  LDFLAGS="$with_libprotobuf_ldflags"
 +  LIBS="$PROTOBUF_LIBS $LIBS"
 +  AC_LANG_PUSH([C++])
 +  AC_CHECK_LIB([protobuf], [main],
 +    [
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS"
 +      if test "x$PROTOBUF_LIBS" = "x"
 +      then
 +        PROTOBUF_LIBS="-lprotobuf"
 +      fi
 +      AC_CHECK_HEADERS([google/protobuf/util/time_util.h],
 +        [with_libprotobuf="yes"],
 +        [with_libprotobuf="no (<google/protobuf/util/time_util.h> not found)"]
 +      )
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +    ],
 +    [with_libprotobuf="no (libprotobuf not found)"]
 +  )
 +  AC_LANG_POP([C++])
 +  LDFLAGS="$SAVE_LDFLAGS"
 +  LIBS="$SAVE_LIBS"
  fi
 -AC_DEFINE_UNQUOTED(HAVE_LIBPTHREAD, [$collect_pthread],
 -      [Wether or not to use pthread (POSIX threads) library])
 -AM_CONDITIONAL(BUILD_WITH_LIBPTHREAD, test "x$with_libpthread" = "xyes")
 +BUILD_WITH_LIBPROTOBUF_CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS"
 +BUILD_WITH_LIBPROTOBUF_LDFLAGS="$with_libprotobuf_ldflags"
 +BUILD_WITH_LIBPROTOBUF_LIBS="$PROTOBUF_LIBS"
 +AC_SUBST([BUILD_WITH_LIBPROTOBUF_CPPFLAGS])
 +AC_SUBST([BUILD_WITH_LIBPROTOBUF_LDFLAGS])
 +AC_SUBST([BUILD_WITH_LIBPROTOBUF_LIBS])
  # }}}
  
 -# --with-python {{{
 -with_python_prog=""
 -with_python_path="$PATH"
 -AC_ARG_WITH(python, [AS_HELP_STRING([--with-python@<:@=PREFIX@:>@], [Path to the python interpreter.])],
 -[
 - if test "x$withval" = "xyes" || test "x$withval" = "xno"
 - then
 -       with_python="$withval"
 - else if test -x "$withval"
 - then
 -       with_python_prog="$withval"
 -       with_python_path="`dirname \"$withval\"`$PATH_SEPARATOR$with_python_path"
 -       with_python="yes"
 - else if test -d "$withval"
 - then
 -       with_python_path="$withval$PATH_SEPARATOR$with_python_path"
 -       with_python="yes"
 - else
 -       AC_MSG_WARN([Argument not recognized: $withval])
 - fi; fi; fi
 -], [with_python="yes"])
 -
 -SAVE_PATH="$PATH"
 -SAVE_CPPFLAGS="$CPPFLAGS"
 -SAVE_LDFLAGS="$LDFLAGS"
 -SAVE_LIBS="$LIBS"
 -
 -PATH="$with_python_path"
 -
 -if test "x$with_python" = "xyes" && test "x$with_python_prog" = "x"
 -then
 -      AC_MSG_CHECKING([for python])
 -      with_python_prog="`which python 2>/dev/null`"
 -      if test "x$with_python_prog" = "x"
 -      then
 -              AC_MSG_RESULT([not found])
 -              with_python="no (interpreter not found)"
 -      else
 -              AC_MSG_RESULT([$with_python_prog])
 -      fi
 -fi
 -
 -if test "x$with_python" = "xyes"
 -then
 -      AC_MSG_CHECKING([for Python CPPFLAGS])
 -      python_include_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_python_inc())" | "$with_python_prog" 2>&1`
 -      python_config_status=$?
 -
 -      if test "$python_config_status" -ne 0 || test "x$python_include_path" = "x"
 -      then
 -              AC_MSG_RESULT([failed with status $python_config_status (output: $python_include_path)])
 -              with_python="no"
 -      else
 -              AC_MSG_RESULT([$python_include_path])
 -      fi
 -fi
 -
 -if test "x$with_python" = "xyes"
 +# --with-libprotobuf-c {{{
 +with_libprotobuf_c_cppflags=""
 +with_libprotobuf_c_ldflags=""
 +AC_ARG_WITH([libprotobuf-c], [AS_HELP_STRING([--with-libprotobuf-c@<:@=PREFIX@:>@], [Path to libprotobuf-c.])],
 +  [
 +    if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +    then
 +      with_libprotobuf_c_cppflags="-I$withval/include"
 +      with_libprotobuf_c_ldflags="-L$withval/lib"
 +      with_libprotobuf_c="yes"
 +    fi
 +    if test "x$withval" = "xno"
 +    then
 +      with_libprotobuf_c="no (disabled on command line)"
 +    fi
 +  ],
 +  [withval="yes"]
 +)
 +if test "x$withval" = "xyes"
  then
 -      CPPFLAGS="-I$python_include_path $CPPFLAGS"
 -      AC_CHECK_HEADERS(Python.h,
 -                       [with_python="yes"],
 -                       [with_python="no ('Python.h' not found)"])
 +PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c],
 +  [with_libprotobuf_c="yes"],
 +  [with_libprotobuf_c="no (pkg-config could not find libprotobuf-c)"]
 +)
  fi
  
 -if test "x$with_python" = "xyes"
 +if test "x$withval" != "xno"
  then
 -      AC_MSG_CHECKING([for Python LDFLAGS])
 -      python_library_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"LIBDIR\").__getitem__(0))" | "$with_python_prog" 2>&1`
 -      python_config_status=$?
 -
 -      if test "$python_config_status" -ne 0 || test "x$python_library_path" = "x"
 -      then
 -              AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_path)])
 -              with_python="no"
 -      else
 -              AC_MSG_RESULT([$python_library_path])
 -      fi
 +  SAVE_LDFLAGS="$LDFLAGS"
 +  SAVE_LIBS="$LIBS"
 +  LDFLAGS="$with_libprotobuf_c_ldflags"
 +  LIBS="$PROTOBUF_C_LIBS $LIBS"
 +  AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack],
 +    [
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS"
 +      if test "x$PROTOBUF_C_LIBS" = "x"
 +      then
 +        PROTOBUF_C_LIBS="-lprotobuf-c"
 +      fi
 +      AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h],
 +        [
 +          with_libprotobuf_c="yes"
 +          break
 +        ],
 +        [with_libprotobuf_c="no (<protobuf-c.h> not found)"]
 +      )
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +    ],
 +    [with_libprotobuf_c="no (libprotobuf-c not found)"]
 +  )
 +  LDFLAGS="$SAVE_LDFLAGS"
 +  LIBS="$SAVE_LIBS"
  fi
 +BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS"
 +BUILD_WITH_LIBPROTOBUF_C_LDFLAGS="$with_libprotobuf_c_ldflags"
 +BUILD_WITH_LIBPROTOBUF_C_LIBS="$PROTOBUF_C_LIBS"
 +AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS])
 +AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LDFLAGS])
 +AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LIBS])
 +# }}}
  
 -if test "x$with_python" = "xyes"
 -then
 -      AC_MSG_CHECKING([for Python LIBS])
 -      python_library_flags=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"BLDLIBRARY\").__getitem__(0))" | "$with_python_prog" 2>&1`
 -      python_config_status=$?
 +# --with-libpython {{{
 +AC_ARG_VAR([LIBPYTHON_CPPFLAGS], [Preprocessor flags for libpython])
 +AC_ARG_VAR([LIBPYTHON_LDFLAGS], [Linker flags for libpython])
 +AC_ARG_VAR([LIBPYTHON_LIBS], [Libraries for libpython])
  
 -      if test "$python_config_status" -ne 0 || test "x$python_library_flags" = "x"
 -      then
 -              AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_flags)])
 -              with_python="no"
 -      else
 -              AC_MSG_RESULT([$python_library_flags])
 -      fi
 +AC_ARG_WITH([libpython],
 +  [AS_HELP_STRING([--with-libpython],
 +    [if we should build with libpython @<:@default=yes@:>@])
 +  ],
 +  [with_libpython="$withval"],
 +  [with_libpython="check"]
 +)
 +if test "$with_libpython" != "no"; then
 +  if test "$LIBPYTHON_CPPFLAGS" = "" && test "$LIBPYTHON_LDFLAGS" = ""; then
 +    AC_ARG_VAR([PYTHON_CONFIG], [path to python-config])
 +    AC_PATH_PROGS([PYTHON_CONFIG],
 +      [python3-config python2-config python-config]
 +    )
 +    if test "$PYTHON_CONFIG" = ""; then
 +      if test "$with_libpython" = "yes"; then
 +        AC_MSG_ERROR([Unable to find python-config])
 +      fi
 +      with_libpython="no"
 +    fi
 +  fi
  fi
  
 -if test "x$with_python" = "xyes"
 -then
 -      LDFLAGS="-L$python_library_path $LDFLAGS"
 -      LIBS="$python_library_flags $LIBS"
 -
 -      AC_CHECK_FUNC(PyObject_CallFunction,
 -                    [with_python="yes"],
 -                    [with_python="no (Symbol 'PyObject_CallFunction' not found)"])
 +if test "$PYTHON_CONFIG" != ""; then
 +  LIBPYTHON_CPPFLAGS="`${PYTHON_CONFIG} --includes`"
 +  if test $? -ne 0; then
 +    with_libpython="no"
 +  fi
 +  LIBPYTHON_LDFLAGS="`${PYTHON_CONFIG} --ldflags`"
 +  if test $? -ne 0; then
 +    with_libpython="no"
 +  fi
 +  LIBPYTHON_LIBS="`${PYTHON_CONFIG} --libs`"
 +  if test $? -ne 0; then
 +    with_libpython="no"
 +  fi
  fi
  
 -PATH="$SAVE_PATH"
 -CPPFLAGS="$SAVE_CPPFLAGS"
 -LDFLAGS="$SAVE_LDFLAGS"
 -LIBS="$SAVE_LIBS"
 -
 -if test "x$with_python" = "xyes"
 -then
 -      BUILD_WITH_PYTHON_CPPFLAGS="-I$python_include_path"
 -      BUILD_WITH_PYTHON_LDFLAGS="-L$python_library_path"
 -      BUILD_WITH_PYTHON_LIBS="$python_library_flags"
 -      AC_SUBST(BUILD_WITH_PYTHON_CPPFLAGS)
 -      AC_SUBST(BUILD_WITH_PYTHON_LDFLAGS)
 -      AC_SUBST(BUILD_WITH_PYTHON_LIBS)
 +if test "$with_libpython" != "xno"; then
 +  SAVE_CPPFLAGS="$CPPFLAGS"
 +  SAVE_LDFLAGS="$LDFLAGS"
 +  SAVE_LIBS="$LIBS"
 +  CPPFLAGS="$LIBPYTHON_CPPFLAGS $CPPFLAGS"
 +  LDFLAGS="$LIBPYTHON_LDFLAGS $LDFLAGS"
 +  LIBS="$LIBPYTHON_LIBS $LIBS"
 +  AC_CHECK_HEADERS([Python.h],
 +    [
 +      AC_MSG_CHECKING([for libpython])
 +      AC_LINK_IFELSE([AC_LANG_PROGRAM(
 +          [[#include <Python.h>]],
 +          [[Py_Initialize();]])
 +        ],
 +        [with_libpython="yes"],
 +        [with_libpython="no"]
 +      )
 +      AC_MSG_RESULT([$with_libpython])
 +    ],
 +    [with_libpython="no"]
 +  )
 +  CPPFLAGS="$SAVE_CPPFLAGS"
 +  LDFLAGS="$SAVE_LDFLAGS"
 +  LIBS="$SAVE_LIBS"
  fi
 -# }}} --with-python
 +# }}} --with-libpython
  
  # --with-librabbitmq {{{
  with_librabbitmq_cppflags=""
    if test "x$with_librdkafka_log_cb" = "xyes"
    then
          AC_DEFINE(HAVE_LIBRDKAFKA_LOG_CB, 1, [Define if librdkafka log facility is present and usable.])
-   fi
-   if test "x$with_librdkafka_logger" = "xyes"
+   else if test "x$with_librdkafka_logger" = "xyes"
    then
          AC_DEFINE(HAVE_LIBRDKAFKA_LOGGER, 1, [Define if librdkafka log facility is present and usable.])
-   fi
+   fi; fi
  fi
  CPPFLAGS="$SAVE_CPPFLAGS"
  LDFLAGS="$SAVE_LDFLAGS"
@@@ -4579,6 -4113,11 +4578,6 @@@ the
        SAVE_CPPFLAGS="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS $with_sensors_cflags"
  
 -#     AC_CHECK_HEADERS(sensors/sensors.h,
 -#     [
 -#             AC_DEFINE(HAVE_SENSORS_SENSORS_H, 1, [Define to 1 if you have the <sensors/sensors.h> header file.])
 -#     ],
 -#     [with_libsensors="no (sensors/sensors.h not found)"])
        AC_CHECK_HEADERS(sensors/sensors.h, [], [with_libsensors="no (sensors/sensors.h not found)"])
  
        CPPFLAGS="$SAVE_CPPFLAGS"
  AM_CONDITIONAL(BUILD_WITH_LM_SENSORS, test "x$with_libsensors" = "xyes")
  # }}}
  
 -# --with-libsigrok {{{
 -with_libsigrok_cflags=""
 -with_libsigrok_ldflags=""
 -AC_ARG_WITH(libsigrok, [AS_HELP_STRING([--with-libsigrok@<:@=PREFIX@:>@], [Path to libsigrok.])],
 -[
 -      if test "x$withval" = "xno"
 -      then
 -              with_libsigrok="no"
 -      else
 -              with_libsigrok="yes"
 -              if test "x$withval" != "xyes"
 -              then
 -                      with_libsigrok_cflags="-I$withval/include"
 -                      with_libsigrok_ldflags="-L$withval/lib"
 -              fi
 -      fi
 -],[with_libsigrok="yes"])
 -
 -# libsigrok has a glib dependency
 -if test "x$with_libsigrok" = "xyes"
 -then
 -m4_ifdef([AM_PATH_GLIB_2_0],
 -      [
 -       AM_PATH_GLIB_2_0([2.28.0],
 -              [with_libsigrok_cflags="$with_libsigrok_cflags $GLIB_CFLAGS"; with_libsigrok_ldflags="$with_libsigrok_ldflags $GLIB_LIBS"])
 -      ],
 -      [
 -       with_libsigrok="no (glib not available)"
 -      ]
 +# libsigrok {{{
 +AC_SUBST([LIBSIGROK_CFLAGS])
 +AC_SUBST([LIBSIGROK_LIBS])
 +PKG_CHECK_MODULES([LIBSIGROK], [libsigrok < 0.4],
 +  [with_libsigrok="yes"],
 +  [with_libsigrok="no (pkg-config could not find libsigrok)"]
  )
 -fi
 -
 -# libsigrok headers
 -if test "x$with_libsigrok" = "xyes"
 -then
 -      SAVE_CPPFLAGS="$CPPFLAGS"
 -      CPPFLAGS="$CPPFLAGS $with_libsigrok_cflags"
 -
 -      AC_CHECK_HEADERS(libsigrok/libsigrok.h, [], [with_libsigrok="no (libsigrok/libsigrok.h not found)"])
 -
 -      CPPFLAGS="$SAVE_CPPFLAGS"
 -fi
 -
 -# libsigrok library
 -if test "x$with_libsigrok" = "xyes"
 -then
 -      SAVE_CPPFLAGS="$CPPFLAGS"
 -      SAVE_LDFLAGS="$LDFLAGS"
 -      CPPFLAGS="$CPPFLAGS $with_libsigrok_cflags"
 -      LDFLAGS="$LDFLAGS $with_libsigrok_ldflags"
 -
 -      AC_CHECK_LIB(sigrok, sr_init,
 -      [
 -              AC_DEFINE(HAVE_LIBSIGROK, 1, [Define to 1 if you have the sigrok library (-lsigrok).])
 -      ],
 -      [with_libsigrok="no (libsigrok not found)"])
 -
 -      CPPFLAGS="$SAVE_CPPFLAGS"
 -      LDFLAGS="$SAVE_LDFLAGS"
 -fi
 -if test "x$with_libsigrok" = "xyes"
 -then
 -      BUILD_WITH_LIBSIGROK_CFLAGS="$with_libsigrok_cflags"
 -      BUILD_WITH_LIBSIGROK_LDFLAGS="$with_libsigrok_ldflags"
 -      AC_SUBST(BUILD_WITH_LIBSIGROK_CFLAGS)
 -      AC_SUBST(BUILD_WITH_LIBSIGROK_LDFLAGS)
 -fi
 -AM_CONDITIONAL(BUILD_WITH_LIBSIGROK, test "x$with_libsigrok" = "xyes")
  # }}}
  
  # --with-libstatgrab {{{
@@@ -4643,16 -4243,23 +4642,16 @@@ AC_ARG_WITH(libstatgrab, [AS_HELP_STRIN
  if test "x$with_libstatgrab" = "xyes" \
    && test "x$with_libstatgrab_pkg_config" = "xyes"
  then
 -  if test "x$PKG_CONFIG" != "x"
 +  AC_MSG_CHECKING([pkg-config for libstatgrab])
 +  temp_result="found"
 +  $PKG_CONFIG --exists libstatgrab 2>/dev/null
 +  if test "$?" != "0"
    then
 -    AC_MSG_CHECKING([pkg-config for libstatgrab])
 -    temp_result="found"
 -    $PKG_CONFIG --exists libstatgrab 2>/dev/null
 -    if test "$?" != "0"
 -    then
 -      with_libstatgrab_pkg_config="no"
 -      with_libstatgrab="no (pkg-config doesn't know libstatgrab)"
 -      temp_result="not found"
 -    fi
 -    AC_MSG_RESULT([$temp_result])
 -  else
 -    AC_MSG_NOTICE([pkg-config not available, trying to guess flags for the statgrab library.])
      with_libstatgrab_pkg_config="no"
 -    with_libstatgrab_ldflags="$with_libstatgrab_ldflags -lstatgrab"
 +    with_libstatgrab="no (pkg-config doesn't know libstatgrab)"
 +    temp_result="not found"
    fi
 +  AC_MSG_RESULT([$temp_result])
  fi
  
  if test "x$with_libstatgrab" = "xyes" \
  if test "x$with_libstatgrab" = "xyes"
  then
    SAVE_CFLAGS="$CFLAGS"
 +  SAVE_LDFLAGS="$LDFLAGS"
    SAVE_LIBS="$LIBS"
  
    CFLAGS="$CFLAGS $with_libstatgrab_cflags"
  # configure using pkg-config
  if test "x$with_libupsclient" = "xuse_pkgconfig"
  then
 -      if test "x$PKG_CONFIG" = "x"
 -      then
 -              with_libupsclient="no (Don't have pkg-config)"
 -      fi
 -fi
 -if test "x$with_libupsclient" = "xuse_pkgconfig"
 -then
        AC_MSG_NOTICE([Checking for libupsclient using $PKG_CONFIG])
        $PKG_CONFIG --exists 'libupsclient' 2>/dev/null
        if test $? -ne 0
  fi
  # }}}
  
 +# --with-libxenctrl {{{
 +with_libxenctrl_cppflags=""
 +with_libxenctrl_ldflags=""
 +AC_ARG_WITH(libxenctrl, [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])],
 +[
 +      if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +      then
 +              with_libxenctrl_cppflags="-I$withval/include"
 +              with_libxenctrl_ldflags="-L$withval/lib"
 +              with_libxenctrl="yes"
 +      else
 +              with_libxenctrl="$withval"
 +      fi
 +],
 +[
 +      with_libxenctrl="yes"
 +])
 +if test "x$with_libxenctrl" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
 +
 +      AC_CHECK_HEADERS(xenctrl.h, [with_libxenctrl="yes"], [with_libxenctrl="no (xenctrl.h not found)"])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +if test "x$with_libxenctrl" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      SAVE_LDFLAGS="$LDFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
 +      LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags"
 +
 +      #Xen versions older than 3.4 has no xc_getcpuinfo()
 +      AC_CHECK_LIB(xenctrl, xc_getcpuinfo, [with_libxenctrl="yes"], [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"], [])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +      LDFLAGS="$SAVE_LDFLAGS"
 +      LIBXENCTL_CPPFLAGS="$with_libxenctl_cppflags"
 +      LIBXENCTL_LDFLAGS="$with_libxenctl_ldflags"
 +      AC_SUBST(LIBXENCTL_CPPFLAGS)
 +      AC_SUBST(LIBXENCTL_LDFLAGS)
 +fi
 +# }}}
 +
  # --with-libxmms {{{
  with_xmms_config="xmms-config"
  with_xmms_cflags=""
@@@ -5207,7 -4775,7 +5206,7 @@@ AC_ARG_WITH(mic,[AS_HELP_STRING([--with
                AC_MSG_NOTICE([Not checking for Intel Mic: Manually configured])
                with_mic_cflags="-I$withval/include"
                with_mic_ldpath="-L$withval/lib/Linux"
 -              with_mic_libs="-lMicAccessSDK -lscif -lpthread"
 +              with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"
                with_mic="yes"
        fi; fi; fi
  ],
@@@ -5229,8 -4797,8 +5228,8 @@@ the
  
        AC_CHECK_LIB(MicAccessSDK, MicInitAPI,
                        [with_mic_ldpath="$with_mic_ldpath"
 -                      with_mic_libs="-lMicAccessSDK -lscif -lpthread"],
 -                      [with_mic="no (symbol MicInitAPI not found)"],[-lscif -lpthread])
 +                      with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"],
 +                      [with_mic="no (symbol MicInitAPI not found)"],[$PTHREAD_LIBS -lscif])
  
        CPPFLAGS="$SAVE_CPPFLAGS"
        LDFLAGS="$SAVE_LDFLAGS"
@@@ -5272,6 -4840,13 +5271,6 @@@ AC_ARG_WITH(libvarnish, [AS_HELP_STRING
  # configure using pkg-config
  if test "x$with_libvarnish" = "xuse_pkgconfig"
  then
 -      if test "x$PKG_CONFIG" = "x"
 -      then
 -              with_libvarnish="no (Don't have pkg-config)"
 -      fi
 -fi
 -if test "x$with_libvarnish" = "xuse_pkgconfig"
 -then
        AC_MSG_NOTICE([Checking for varnishapi using $PKG_CONFIG])
        $PKG_CONFIG --exists 'varnishapi' 2>/dev/null
        if test $? -ne 0
@@@ -5331,20 -4906,23 +5330,20 @@@ with_libxml2_ldflags="
  with_libvirt="no (pkg-config isn't available)"
  with_libvirt_cflags=""
  with_libvirt_ldflags=""
 -if test "x$PKG_CONFIG" != "x"
 +$PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
 +if test "$?" = "0"
  then
 -      $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
 -      if test "$?" = "0"
 -      then
 -              with_libxml2="yes"
 -      else
 -              with_libxml2="no (pkg-config doesn't know libxml-2.0)"
 -      fi
 +      with_libxml2="yes"
 +else
 +      with_libxml2="no (pkg-config doesn't know libxml-2.0)"
 +fi
  
 -      $PKG_CONFIG --exists libvirt 2>/dev/null
 -      if test "$?" = "0"
 -      then
 -              with_libvirt="yes"
 -      else
 -              with_libvirt="no (pkg-config doesn't know libvirt)"
 -      fi
 +$PKG_CONFIG --exists libvirt 2>/dev/null
 +if test "$?" = "0"
 +then
 +      with_libvirt="yes"
 +else
 +      with_libvirt="no (pkg-config doesn't know libvirt)"
  fi
  if test "x$with_libxml2" = "xyes"
  then
@@@ -5443,6 -5021,17 +5442,6 @@@ with_libopenipmipthread="yes
  with_libopenipmipthread_cflags=""
  with_libopenipmipthread_libs=""
  
 -AC_MSG_CHECKING([for pkg-config])
 -temp_result="no"
 -if test "x$PKG_CONFIG" = "x"
 -then
 -      with_libopenipmipthread="no"
 -      temp_result="no"
 -else
 -      temp_result="$PKG_CONFIG"
 -fi
 -AC_MSG_RESULT([$temp_result])
 -
  if test "x$with_libopenipmipthread" = "xyes"
  then
        AC_MSG_CHECKING([for libOpenIPMIpthread])
@@@ -5566,12 -5155,11 +5565,12 @@@ AM_CONDITIONAL(BUILD_WITH_LIBATASMART, 
  
  PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
                [with_libnotify="yes"],
 -              [if test "x$LIBNOTIFY_PKG_ERRORS" = "x"; then
 -                       with_libnotify="no"
 -               else
 -                       with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"
 -               fi])
 +              [with_libnotify="no (pkg-config doesn't know libnotify)"]
 +)
 +
 +PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.6.0],
 + [with_libriemann_client="yes"],
 + [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"])
  
  # Check for enabled/disabled features
  #
@@@ -5664,7 -5252,7 +5663,7 @@@ AC_DEFUN
             then
                     enable_plugin="yes"
             else
 -                   enable_plugin="no"
 +                   enable_plugin="$2"
             fi
         else
             enable_plugin="$enable_all_plugins"
                    fi
            else # User passed "yes" but dependency checking yielded "no" => Dependency problem.
                    dependency_error="yes"
 -                  enable_plugin="no (dependency error)"
 +                  enable_plugin="$2 (dependency error)"
            fi
      fi
      AM_CONDITIONAL([BUILD_PLUGIN_]my_toupper([$1]), test "x$enable_plugin" = "xyes")
@@@ -5695,7 -5283,6 +5694,7 @@@ collectd features:]
  AC_COLLECTD([debug],     [enable],  [feature], [debugging])
  AC_COLLECTD([daemon],    [disable], [feature], [daemon mode])
  AC_COLLECTD([getifaddrs],[enable],  [feature], [getifaddrs under Linux])
 +AC_COLLECTD([werror],    [disable], [feature], [building with -Werror])
  
  dependency_warning="no"
  dependency_error="no"
@@@ -5710,7 -5297,6 +5709,7 @@@ plugin_conntrack="no
  plugin_contextswitch="no"
  plugin_cpu="no"
  plugin_cpufreq="no"
 +plugin_cpusleep="no"
  plugin_curl_json="no"
  plugin_curl_xml="no"
  plugin_df="no"
@@@ -5720,8 -5306,6 +5719,8 @@@ plugin_entropy="no
  plugin_ethstat="no"
  plugin_fhcount="no"
  plugin_fscache="no"
 +plugin_gps="no"
 +plugin_grpc="no"
  plugin_interface="no"
  plugin_ipmi="no"
  plugin_ipvs="no"
@@@ -5733,10 -5317,8 +5732,10 @@@ plugin_multimeter="no
  plugin_nfs="no"
  plugin_numa="no"
  plugin_perl="no"
 +plugin_pinba="no"
  plugin_processes="no"
  plugin_protocols="no"
 +plugin_python="no"
  plugin_serial="no"
  plugin_smart="no"
  plugin_swap="no"
@@@ -5751,18 -5333,16 +5750,18 @@@ plugin_virt="no
  plugin_vmem="no"
  plugin_vserver="no"
  plugin_wireless="no"
 +plugin_xencpu="no"
  plugin_zfs_arc="no"
 +plugin_zone="no"
  plugin_zookeeper="no"
  
  # Linux
  if test "x$ac_system" = "xLinux"
  then
        plugin_battery="yes"
 +      plugin_cgroups="yes"
        plugin_conntrack="yes"
        plugin_contextswitch="yes"
 -      plugin_cgroups="yes"
        plugin_cpu="yes"
        plugin_cpufreq="yes"
        plugin_disk="yes"
        then
                plugin_turbostat="yes"
        fi
 +      
 +      if test "x$c_cv_have_clock_boottime_monotonic" = "xyes"
 +      then
 +              plugin_cpusleep="yes"
 +      fi
  fi
  
  if test "x$ac_system" = "xOpenBSD"
        plugin_tcpconns="yes"
  fi
  
 +if test "x$ac_system" = "xNetBSD"
 +then
 +      plugin_disk="yes"
 +      plugin_entropy="yes"
 +      plugin_irq="yes"
 +      plugin_processes="yes"
 +fi
 +
  # Mac OS X devices
  if test "x$with_libiokit" = "xyes"
  then
  
  if test "x$ac_system" = "xAIX"
  then
 -      plugin_tcpconns="yes"
        plugin_ipc="yes"
 +      plugin_tcpconns="yes"
  fi
  
  # FreeBSD
  
  if test "x$ac_system" = "xFreeBSD"
  then
 +      plugin_disk="yes"
        plugin_zfs_arc="yes"
  fi
  
  
  if test "x$with_perfstat" = "xyes"
  then
 -      plugin_cpu="yes"
        plugin_contextswitch="yes"
 +      plugin_cpu="yes"
        plugin_disk="yes"
 -      plugin_memory="yes"
 -      plugin_swap="yes"
        plugin_interface="yes"
        plugin_load="yes"
 +      plugin_memory="yes"
 +      plugin_swap="yes"
        plugin_uptime="yes"
  fi
  
@@@ -5866,7 -5432,6 +5865,7 @@@ the
        plugin_processes="yes"
        plugin_uptime="yes"
        plugin_zfs_arc="yes"
 +      plugin_zone="yes"
  fi
  
  if test "x$with_devinfo$with_kstat" = "xyesyes"
@@@ -5879,6 -5444,7 +5878,6 @@@ the
  fi
  
  # libi2c-dev
 -with_libi2c="no"
  if test "x$ac_system" = "xLinux"
  then
  AC_CHECK_DECL(i2c_smbus_read_i2c_block_data,
        [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
        [[#include <stdlib.h>
        #include <linux/i2c-dev.h>]])
 +else
 +      with_libi2c="no (Linux only)"
  fi
  
  if test "x$with_libi2c" = "xyes"
        plugin_ethstat="yes"
  fi
  
 +if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x"
 +then
 +      plugin_grpc="yes"
 +fi
 +
  if test "x$have_getifaddrs" = "xyes"
  then
        plugin_interface="yes"
  fi
  
 +if test "x$with_libgps" = "xyes"
 +then
 +      plugin_gps="yes"
 +fi
 +
  if test "x$have_getloadavg" = "xyes"
  then
        plugin_load="yes"
        plugin_perl="yes"
  fi
  
 +if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes"
 +then
 +      plugin_pinba="yes"
 +fi
 +
  # Mac OS X memory interface
  if test "x$have_host_statistics" = "xyes"
  then
        plugin_processes="yes"
  fi
  
 +if test "x$with_libpython" != "xno"
 +then
 +      plugin_python="yes"
 +fi
 +
  if test "x$with_libatasmart" = "xyes" && test "x$with_libudev" = "xyes"
  then
        plugin_smart="yes"
        plugin_swap="yes"
  fi
  
 +if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_three_args" = "xyes"
 +then
 +      plugin_swap="yes"
 +fi
 +
  if test "x$with_kvm_openfiles$with_kvm_nlist" = "xyesyes"
  then
        plugin_tcpconns="yes"
        plugin_virt="yes"
  fi
  
 +if test "x$with_libxenctrl" = "xyes"
 +then
 +  plugin_xencpu="yes"
 +fi
  
  m4_divert_once([HELP_ENABLE], [
  collectd plugins:])
@@@ -6138,150 -5673,141 +6137,150 @@@ AC_ARG_ENABLE([all-plugins]
  
  m4_divert_once([HELP_ENABLE], [])
  
 -AC_PLUGIN([aggregation], [yes],                [Aggregation plugin])
 -AC_PLUGIN([amqp],        [$with_librabbitmq],  [AMQP output plugin])
 -AC_PLUGIN([apache],      [$with_libcurl],      [Apache httpd statistics])
 -AC_PLUGIN([apcups],      [yes],                [Statistics of UPSes by APC])
 -AC_PLUGIN([apple_sensors], [$with_libiokit],   [Apple's hardware sensors])
 -AC_PLUGIN([aquaero],     [$with_libaquaero5],  [Aquaero's hardware sensors])
 -AC_PLUGIN([ascent],      [$plugin_ascent],     [AscentEmu player statistics])
 -AC_PLUGIN([barometer],   [$plugin_barometer],  [Barometer sensor on I2C])
 -AC_PLUGIN([battery],     [$plugin_battery],    [Battery statistics])
 -AC_PLUGIN([bind],        [$plugin_bind],       [ISC Bind nameserver statistics])
 -AC_PLUGIN([ceph],        [$plugin_ceph],       [Ceph daemon statistics])
 -AC_PLUGIN([conntrack],   [$plugin_conntrack],  [nf_conntrack statistics])
 -AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
 -AC_PLUGIN([cpufreq],     [$plugin_cpufreq],    [CPU frequency statistics])
 -AC_PLUGIN([cpu],         [$plugin_cpu],        [CPU usage statistics])
 -AC_PLUGIN([csv],         [yes],                [CSV output plugin])
 -AC_PLUGIN([curl],        [$with_libcurl],      [CURL generic web statistics])
 -AC_PLUGIN([curl_json],   [$plugin_curl_json],    [CouchDB statistics])
 -AC_PLUGIN([curl_xml],   [$plugin_curl_xml],    [CURL generic xml statistics])
 -AC_PLUGIN([cgroups],     [$plugin_cgroups],    [CGroups CPU usage accounting])
 -AC_PLUGIN([dbi],         [$with_libdbi],       [General database statistics])
 -AC_PLUGIN([df],          [$plugin_df],         [Filesystem usage statistics])
 -AC_PLUGIN([disk],        [$plugin_disk],       [Disk usage statistics])
 -AC_PLUGIN([drbd],        [$plugin_drbd],       [DRBD statistics])
 -AC_PLUGIN([dns],         [$with_libpcap],      [DNS traffic analysis])
 -AC_PLUGIN([email],       [yes],                [EMail statistics])
 -AC_PLUGIN([entropy],     [$plugin_entropy],    [Entropy statistics])
 -AC_PLUGIN([ethstat],     [$plugin_ethstat],    [Stats from NIC driver])
 -AC_PLUGIN([exec],        [yes],                [Execution of external programs])
 -AC_PLUGIN([fhcount],     [$plugin_fhcount],    [File handles statistics])
 -AC_PLUGIN([filecount],   [yes],                [Count files in directories])
 -AC_PLUGIN([fscache],     [$plugin_fscache],    [fscache statistics])
 -AC_PLUGIN([gmond],       [$with_libganglia],   [Ganglia plugin])
 -AC_PLUGIN([hddtemp],     [yes],                [Query hddtempd])
 -AC_PLUGIN([interface],   [$plugin_interface],  [Interface traffic statistics])
 -AC_PLUGIN([ipc],         [$plugin_ipc],        [IPC statistics])
 -AC_PLUGIN([ipmi],        [$plugin_ipmi],       [IPMI sensor statistics])
 -AC_PLUGIN([iptables],    [$with_libiptc],      [IPTables rule counters])
 -AC_PLUGIN([ipvs],        [$plugin_ipvs],       [IPVS connection statistics])
 -AC_PLUGIN([irq],         [$plugin_irq],        [IRQ statistics])
 -AC_PLUGIN([java],        [$with_java],         [Embed the Java Virtual Machine])
 -AC_PLUGIN([load],        [$plugin_load],       [System load])
 -AC_PLUGIN([logfile],     [yes],                [File logging plugin])
 -AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging])
 -AC_PLUGIN([lpar],        [$with_perfstat],     [AIX logical partitions statistics])
 -AC_PLUGIN([lvm],         [$with_liblvm2app],   [LVM statistics])
 -AC_PLUGIN([madwifi],     [$have_linux_wireless_h], [Madwifi wireless statistics])
 -AC_PLUGIN([match_empty_counter], [yes],        [The empty counter match])
 -AC_PLUGIN([match_hashed], [yes],               [The hashed match])
 -AC_PLUGIN([match_regex], [yes],                [The regex match])
 -AC_PLUGIN([match_timediff], [yes],             [The timediff match])
 -AC_PLUGIN([match_value], [yes],                [The value match])
 -AC_PLUGIN([mbmon],       [yes],                [Query mbmond])
 -AC_PLUGIN([md],          [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
 -AC_PLUGIN([memcachec],   [$with_libmemcached], [memcachec statistics])
 -AC_PLUGIN([memcached],   [yes],                [memcached statistics])
 -AC_PLUGIN([memory],      [$plugin_memory],     [Memory usage])
 -AC_PLUGIN([mic],         [$with_mic],          [Intel Many Integrated Core stats])
 -AC_PLUGIN([modbus],      [$with_libmodbus],    [Modbus plugin])
 -AC_PLUGIN([multimeter],  [$plugin_multimeter], [Read multimeter values])
 -AC_PLUGIN([mysql],       [$with_libmysql],     [MySQL statistics])
 -AC_PLUGIN([netapp],      [$with_libnetapp],    [NetApp plugin])
 -AC_PLUGIN([netlink],     [$with_libmnl],       [Enhanced Linux network statistics])
 -AC_PLUGIN([network],     [yes],                [Network communication plugin])
 -AC_PLUGIN([nfs],         [$plugin_nfs],        [NFS statistics])
 -AC_PLUGIN([nginx],       [$with_libcurl],      [nginx statistics])
 -AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
 -AC_PLUGIN([notify_email], [$with_libesmtp],    [Email notifier])
 -AC_PLUGIN([ntpd],        [yes],                [NTPd statistics])
 -AC_PLUGIN([numa],        [$plugin_numa],       [NUMA virtual memory statistics])
 -AC_PLUGIN([nut],         [$with_libupsclient], [Network UPS tools statistics])
 -AC_PLUGIN([olsrd],       [yes],                [olsrd statistics])
 -AC_PLUGIN([onewire],     [$with_libowcapi],    [OneWire sensor statistics])
 -AC_PLUGIN([openldap],    [$with_libldap],      [OpenLDAP statistics])
 -AC_PLUGIN([openvpn],     [yes],                [OpenVPN client statistics])
 -AC_PLUGIN([oracle],      [$with_oracle],       [Oracle plugin])
 -AC_PLUGIN([perl],        [$plugin_perl],       [Embed a Perl interpreter])
 -AC_PLUGIN([pf],          [$have_net_pfvar_h],  [BSD packet filter (PF) statistics])
 +AC_PLUGIN([aggregation],         [yes],                     [Aggregation plugin])
 +AC_PLUGIN([amqp],                [$with_librabbitmq],       [AMQP output plugin])
 +AC_PLUGIN([apache],              [$with_libcurl],           [Apache httpd statistics])
 +AC_PLUGIN([apcups],              [yes],                     [Statistics of UPSes by APC])
 +AC_PLUGIN([apple_sensors],       [$with_libiokit],          [Apple hardware sensors])
 +AC_PLUGIN([aquaero],             [$with_libaquaero5],       [Aquaero hardware sensors])
 +AC_PLUGIN([ascent],              [$plugin_ascent],          [AscentEmu player statistics])
 +AC_PLUGIN([barometer],           [$plugin_barometer],       [Barometer sensor on I2C])
 +AC_PLUGIN([battery],             [$plugin_battery],         [Battery statistics])
 +AC_PLUGIN([bind],                [$plugin_bind],            [ISC Bind nameserver statistics])
 +AC_PLUGIN([ceph],                [$plugin_ceph],            [Ceph daemon statistics])
 +AC_PLUGIN([cgroups],             [$plugin_cgroups],         [CGroups CPU usage accounting])
 +AC_PLUGIN([chrony],              [yes],                     [Chrony statistics])
 +AC_PLUGIN([conntrack],           [$plugin_conntrack],       [nf_conntrack statistics])
 +AC_PLUGIN([contextswitch],       [$plugin_contextswitch],   [context switch statistics])
 +AC_PLUGIN([cpu],                 [$plugin_cpu],             [CPU usage statistics])
 +AC_PLUGIN([cpufreq],             [$plugin_cpufreq],         [CPU frequency statistics])
 +AC_PLUGIN([cpusleep],            [$plugin_cpusleep],        [CPU sleep statistics])
 +AC_PLUGIN([csv],                 [yes],                     [CSV output plugin])
 +AC_PLUGIN([curl],                [$with_libcurl],           [CURL generic web statistics])
 +AC_PLUGIN([curl_json],           [$plugin_curl_json],       [CouchDB statistics])
 +AC_PLUGIN([curl_xml],            [$plugin_curl_xml],        [CURL generic xml statistics])
 +AC_PLUGIN([dbi],                 [$with_libdbi],            [General database statistics])
 +AC_PLUGIN([df],                  [$plugin_df],              [Filesystem usage statistics])
 +AC_PLUGIN([disk],                [$plugin_disk],            [Disk usage statistics])
 +AC_PLUGIN([dns],                 [$with_libpcap],           [DNS traffic analysis])
 +AC_PLUGIN([drbd],                [$plugin_drbd],            [DRBD statistics])
 +AC_PLUGIN([email],               [yes],                     [EMail statistics])
 +AC_PLUGIN([entropy],             [$plugin_entropy],         [Entropy statistics])
 +AC_PLUGIN([ethstat],             [$plugin_ethstat],         [Stats from NIC driver])
 +AC_PLUGIN([exec],                [yes],                     [Execution of external programs])
 +AC_PLUGIN([fhcount],             [$plugin_fhcount],         [File handles statistics])
 +AC_PLUGIN([filecount],           [yes],                     [Count files in directories])
 +AC_PLUGIN([fscache],             [$plugin_fscache],         [fscache statistics])
 +AC_PLUGIN([gmond],               [$with_libganglia],        [Ganglia plugin])
 +AC_PLUGIN([gps],                 [$plugin_gps],             [GPS plugin])
 +AC_PLUGIN([grpc],                [$plugin_grpc],            [gRPC plugin])
 +AC_PLUGIN([hddtemp],             [yes],                     [Query hddtempd])
 +AC_PLUGIN([interface],           [$plugin_interface],       [Interface traffic statistics])
 +AC_PLUGIN([ipc],                 [$plugin_ipc],             [IPC statistics])
 +AC_PLUGIN([ipmi],                [$plugin_ipmi],            [IPMI sensor statistics])
 +AC_PLUGIN([iptables],            [$with_libiptc],           [IPTables rule counters])
 +AC_PLUGIN([ipvs],                [$plugin_ipvs],            [IPVS connection statistics])
 +AC_PLUGIN([irq],                 [$plugin_irq],             [IRQ statistics])
 +AC_PLUGIN([java],                [$with_java],              [Embed the Java Virtual Machine])
 +AC_PLUGIN([load],                [$plugin_load],            [System load])
 +AC_PLUGIN([log_logstash],        [$plugin_log_logstash],    [Logstash json_event compatible logging])
 +AC_PLUGIN([logfile],             [yes],                     [File logging plugin])
 +AC_PLUGIN([lpar],                [$with_perfstat],          [AIX logical partitions statistics])
 +AC_PLUGIN([lua],                 [$with_liblua],            [Lua plugin])
 +AC_PLUGIN([lvm],                 [$with_liblvm2app],        [LVM statistics])
 +AC_PLUGIN([madwifi],             [$have_linux_wireless_h],  [Madwifi wireless statistics])
 +AC_PLUGIN([match_empty_counter], [yes],                     [The empty counter match])
 +AC_PLUGIN([match_hashed],        [yes],                     [The hashed match])
 +AC_PLUGIN([match_regex],         [yes],                     [The regex match])
 +AC_PLUGIN([match_timediff],      [yes],                     [The timediff match])
 +AC_PLUGIN([match_value],         [yes],                     [The value match])
 +AC_PLUGIN([mbmon],               [yes],                     [Query mbmond])
 +AC_PLUGIN([md],                  [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
 +AC_PLUGIN([memcachec],           [$with_libmemcached],      [memcachec statistics])
 +AC_PLUGIN([memcached],           [yes],                     [memcached statistics])
 +AC_PLUGIN([memory],              [$plugin_memory],          [Memory usage])
 +AC_PLUGIN([mic],                 [$with_mic],               [Intel Many Integrated Core stats])
 +AC_PLUGIN([modbus],              [$with_libmodbus],         [Modbus plugin])
 +AC_PLUGIN([mqtt],                [$with_libmosquitto],      [MQTT output plugin])
 +AC_PLUGIN([multimeter],          [$plugin_multimeter],      [Read multimeter values])
 +AC_PLUGIN([mysql],               [$with_libmysql],          [MySQL statistics])
 +AC_PLUGIN([netapp],              [$with_libnetapp],         [NetApp plugin])
 +AC_PLUGIN([netlink],             [$with_libmnl],            [Enhanced Linux network statistics])
 +AC_PLUGIN([network],             [yes],                     [Network communication plugin])
 +AC_PLUGIN([nfs],                 [$plugin_nfs],             [NFS statistics])
 +AC_PLUGIN([nginx],               [$with_libcurl],           [nginx statistics])
 +AC_PLUGIN([notify_desktop],      [$with_libnotify],         [Desktop notifications])
 +AC_PLUGIN([notify_email],        [$with_libesmtp],          [Email notifier])
 +AC_PLUGIN([notify_nagios],       [yes],                     [Nagios notification plugin])
 +AC_PLUGIN([ntpd],                [yes],                     [NTPd statistics])
 +AC_PLUGIN([numa],                [$plugin_numa],            [NUMA virtual memory statistics])
 +AC_PLUGIN([nut],                 [$with_libupsclient],      [Network UPS tools statistics])
 +AC_PLUGIN([olsrd],               [yes],                     [olsrd statistics])
 +AC_PLUGIN([onewire],             [$with_libowcapi],         [OneWire sensor statistics])
 +AC_PLUGIN([openldap],            [$with_libldap],           [OpenLDAP statistics])
 +AC_PLUGIN([openvpn],             [yes],                     [OpenVPN client statistics])
 +AC_PLUGIN([oracle],              [$with_oracle],            [Oracle plugin])
 +AC_PLUGIN([perl],                [$plugin_perl],            [Embed a Perl interpreter])
 +AC_PLUGIN([pf],                  [$have_net_pfvar_h],       [BSD packet filter (PF) statistics])
  # FIXME: Check for libevent, too.
 -AC_PLUGIN([pinba],       [$have_protoc_c],     [Pinba statistics])
 -AC_PLUGIN([ping],        [$with_liboping],     [Network latency statistics])
 -AC_PLUGIN([postgresql],  [$with_libpq],        [PostgreSQL database statistics])
 -AC_PLUGIN([powerdns],    [yes],                [PowerDNS statistics])
 -AC_PLUGIN([processes],   [$plugin_processes],  [Process statistics])
 -AC_PLUGIN([protocols],   [$plugin_protocols],  [Protocol (IP, TCP, ...) statistics])
 -AC_PLUGIN([python],      [$with_python],       [Embed a Python interpreter])
 -AC_PLUGIN([redis],       [$with_libhiredis],    [Redis plugin])
 -AC_PLUGIN([routeros],    [$with_librouteros],  [RouterOS plugin])
 -AC_PLUGIN([rrdcached],   [$librrd_rrdc_update], [RRDTool output plugin])
 -AC_PLUGIN([rrdtool],     [$with_librrd],       [RRDTool output plugin])
 -AC_PLUGIN([sensors],     [$with_libsensors],   [lm_sensors statistics])
 -AC_PLUGIN([serial],      [$plugin_serial],     [serial port traffic])
 -AC_PLUGIN([sigrok],      [$with_libsigrok],    [sigrok acquisition sources])
 -AC_PLUGIN([smart],       [$plugin_smart],      [SMART statistics])
 -AC_PLUGIN([snmp],        [$with_libnetsnmp],   [SNMP querying plugin])
 -AC_PLUGIN([statsd],      [yes],                [StatsD plugin])
 -AC_PLUGIN([swap],        [$plugin_swap],       [Swap usage statistics])
 -AC_PLUGIN([syslog],      [$have_syslog],       [Syslog logging plugin])
 -AC_PLUGIN([table],       [yes],                [Parsing of tabular data])
 -AC_PLUGIN([tail],        [yes],                [Parsing of logfiles])
 -AC_PLUGIN([tail_csv],    [yes],                [Parsing of CSV files])
 -AC_PLUGIN([tape],        [$plugin_tape],       [Tape drive statistics])
 -AC_PLUGIN([target_notification], [yes],        [The notification target])
 -AC_PLUGIN([target_replace], [yes],             [The replace target])
 -AC_PLUGIN([target_scale],[yes],                [The scale target])
 -AC_PLUGIN([target_set],  [yes],                [The set target])
 -AC_PLUGIN([target_v5upgrade], [yes],           [The v5upgrade target])
 -AC_PLUGIN([tcpconns],    [$plugin_tcpconns],   [TCP connection statistics])
 -AC_PLUGIN([teamspeak2],  [yes],                [TeamSpeak2 server statistics])
 -AC_PLUGIN([ted],         [$plugin_ted],        [Read The Energy Detective values])
 -AC_PLUGIN([thermal],     [$plugin_thermal],    [Linux ACPI thermal zone statistics])
 -AC_PLUGIN([threshold],   [yes],                [Threshold checking plugin])
 -AC_PLUGIN([tokyotyrant], [$with_libtokyotyrant],  [TokyoTyrant database statistics])
 -AC_PLUGIN([turbostat],   [$plugin_turbostat],  [Advanced statistic on Intel cpu states])
 -AC_PLUGIN([unixsock],    [yes],                [Unixsock communication plugin])
 -AC_PLUGIN([uptime],      [$plugin_uptime],     [Uptime statistics])
 -AC_PLUGIN([users],       [$plugin_users],      [User statistics])
 -AC_PLUGIN([uuid],        [yes],                [UUID as hostname plugin])
 -AC_PLUGIN([varnish],     [$with_libvarnish],   [Varnish cache statistics])
 -AC_PLUGIN([virt],        [$plugin_virt],       [Virtual machine statistics])
 -AC_PLUGIN([vmem],        [$plugin_vmem],       [Virtual memory statistics])
 -AC_PLUGIN([vserver],     [$plugin_vserver],    [Linux VServer statistics])
 -AC_PLUGIN([wireless],    [$plugin_wireless],   [Wireless statistics])
 -AC_PLUGIN([write_graphite], [yes],             [Graphite / Carbon output plugin])
 -AC_PLUGIN([write_http],  [$with_libcurl],      [HTTP output plugin])
 -AC_PLUGIN([write_kafka],  [$with_librdkafka],  [Kafka output plugin])
 -AC_PLUGIN([write_log], [yes],                  [Log output plugin])
 -AC_PLUGIN([write_mongodb], [$with_libmongoc],  [MongoDB output plugin])
 -AC_PLUGIN([write_redis], [$with_libhiredis],    [Redis output plugin])
 -AC_PLUGIN([write_riemann], [$have_protoc_c],   [Riemann output plugin])
 -AC_PLUGIN([write_sensu], [yes],                [Sensu output plugin])
 -AC_PLUGIN([write_tsdb],  [yes],                [TSDB output plugin])
 -AC_PLUGIN([xmms],        [$with_libxmms],      [XMMS statistics])
 -AC_PLUGIN([zfs_arc],     [$plugin_zfs_arc],    [ZFS ARC statistics])
 -AC_PLUGIN([zookeeper],   [yes],              [Zookeeper statistics])
 +AC_PLUGIN([pinba],               [$plugin_pinba],           [Pinba statistics])
 +AC_PLUGIN([ping],                [$with_liboping],          [Network latency statistics])
 +AC_PLUGIN([postgresql],          [$with_libpq],             [PostgreSQL database statistics])
 +AC_PLUGIN([powerdns],            [yes],                     [PowerDNS statistics])
 +AC_PLUGIN([processes],           [$plugin_processes],       [Process statistics])
 +AC_PLUGIN([protocols],           [$plugin_protocols],       [Protocol (IP, TCP, ...) statistics])
 +AC_PLUGIN([python],              [$plugin_python],          [Embed a Python interpreter])
 +AC_PLUGIN([redis],               [$with_libhiredis],        [Redis plugin])
 +AC_PLUGIN([routeros],            [$with_librouteros],       [RouterOS plugin])
 +AC_PLUGIN([rrdcached],           [$librrd_rrdc_update],     [RRDTool output plugin])
 +AC_PLUGIN([rrdtool],             [$with_librrd],            [RRDTool output plugin])
 +AC_PLUGIN([sensors],             [$with_libsensors],        [lm_sensors statistics])
 +AC_PLUGIN([serial],              [$plugin_serial],          [serial port traffic])
 +AC_PLUGIN([sigrok],              [$with_libsigrok],         [sigrok acquisition sources])
 +AC_PLUGIN([smart],               [$plugin_smart],           [SMART statistics])
 +AC_PLUGIN([snmp],                [$with_libnetsnmp],        [SNMP querying plugin])
 +AC_PLUGIN([statsd],              [yes],                     [StatsD plugin])
 +AC_PLUGIN([swap],                [$plugin_swap],            [Swap usage statistics])
 +AC_PLUGIN([syslog],              [$have_syslog],            [Syslog logging plugin])
 +AC_PLUGIN([table],               [yes],                     [Parsing of tabular data])
 +AC_PLUGIN([tail],                [yes],                     [Parsing of logfiles])
 +AC_PLUGIN([tail_csv],            [yes],                     [Parsing of CSV files])
 +AC_PLUGIN([tape],                [$plugin_tape],            [Tape drive statistics])
 +AC_PLUGIN([target_notification], [yes],                     [The notification target])
 +AC_PLUGIN([target_replace],      [yes],                     [The replace target])
 +AC_PLUGIN([target_scale],        [yes],                     [The scale target])
 +AC_PLUGIN([target_set],          [yes],                     [The set target])
 +AC_PLUGIN([target_v5upgrade],    [yes],                     [The v5upgrade target])
 +AC_PLUGIN([tcpconns],            [$plugin_tcpconns],        [TCP connection statistics])
 +AC_PLUGIN([teamspeak2],          [yes],                     [TeamSpeak2 server statistics])
 +AC_PLUGIN([ted],                 [$plugin_ted],             [Read The Energy Detective values])
 +AC_PLUGIN([thermal],             [$plugin_thermal],         [Linux ACPI thermal zone statistics])
 +AC_PLUGIN([threshold],           [yes],                     [Threshold checking plugin])
 +AC_PLUGIN([tokyotyrant],         [$with_libtokyotyrant],    [TokyoTyrant database statistics])
 +AC_PLUGIN([turbostat],           [$plugin_turbostat],       [Advanced statistic on Intel cpu states])
 +AC_PLUGIN([unixsock],            [yes],                     [Unixsock communication plugin])
 +AC_PLUGIN([uptime],              [$plugin_uptime],          [Uptime statistics])
 +AC_PLUGIN([users],               [$plugin_users],           [User statistics])
 +AC_PLUGIN([uuid],                [yes],                     [UUID as hostname plugin])
 +AC_PLUGIN([varnish],             [$with_libvarnish],        [Varnish cache statistics])
 +AC_PLUGIN([virt],                [$plugin_virt],            [Virtual machine statistics])
 +AC_PLUGIN([vmem],                [$plugin_vmem],            [Virtual memory statistics])
 +AC_PLUGIN([vserver],             [$plugin_vserver],         [Linux VServer statistics])
 +AC_PLUGIN([wireless],            [$plugin_wireless],        [Wireless statistics])
 +AC_PLUGIN([write_graphite],      [yes],                     [Graphite / Carbon output plugin])
 +AC_PLUGIN([write_http],          [$with_libcurl],           [HTTP output plugin])
 +AC_PLUGIN([write_kafka],         [$with_librdkafka],        [Kafka output plugin])
 +AC_PLUGIN([write_log],           [yes],                     [Log output plugin])
 +AC_PLUGIN([write_mongodb],       [$with_libmongoc],         [MongoDB output plugin])
 +AC_PLUGIN([write_redis],         [$with_libhiredis],        [Redis output plugin])
 +AC_PLUGIN([write_riemann],       [$with_libriemann_client], [Riemann output plugin])
 +AC_PLUGIN([write_sensu],         [yes],                     [Sensu output plugin])
 +AC_PLUGIN([write_tsdb],          [yes],                     [TSDB output plugin])
 +AC_PLUGIN([xencpu],              [$plugin_xencpu],          [Xen Host CPU usage])
 +AC_PLUGIN([xmms],                [$with_libxmms],           [XMMS statistics])
 +AC_PLUGIN([zfs_arc],             [$plugin_zfs_arc],         [ZFS ARC statistics])
 +AC_PLUGIN([zone],                [$plugin_zone],            [Solaris container statistics])
 +AC_PLUGIN([zookeeper],           [yes],                     [Zookeeper statistics])
  
  dnl Default configuration file
  # Load either syslog or logfile
@@@ -6406,18 -5932,6 +6405,18 @@@ AC_ARG_WITH(perl-bindings, [AS_HELP_STR
                with_perl_bindings="no (no perl interpreter found)"
        fi
  ])
 +
 +if test "x$with_perl_bindings" = "xyes"
 +then
 +      AC_MSG_CHECKING([for the ExtUtils::MakeMaker module])
 +      if $PERL -MExtUtils::MakeMaker -e '' 2>/dev/null; then
 +              AC_MSG_RESULT([yes])
 +      else
 +              AC_MSG_RESULT([no])
 +              with_perl_bindings="no (ExtUtils::MakeMaker not found)"
 +      fi
 +fi
 +
  if test "x$with_perl_bindings" = "xyes"
  then
        PERL_BINDINGS="perl"
@@@ -6444,17 -5958,7 +6443,17 @@@ AC_SUBST(LCC_VERSION_STRING
  
  AC_CONFIG_FILES(src/libcollectdclient/collectd/lcc_features.h)
  
 -AC_CONFIG_FILES([Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile])
 +AM_CFLAGS="-Wall"
 +AM_CXXFLAGS="-Wall"
 +if test "x$enable_werror" != "xno"
 +then
 +        AM_CFLAGS="$AM_CFLAGS -Werror"
 +        AM_CXXFLAGS="$AM_CXXFLAGS -Werror"
 +fi
 +AC_SUBST([AM_CFLAGS])
 +AC_SUBST([AM_CXXFLAGS])
 +
 +AC_CONFIG_FILES([Makefile proto/Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile])
  AC_OUTPUT
  
  if test "x$with_librrd" = "xyes" \
        with_perl_bindings="yes ($PERL_BINDINGS_OPTIONS)"
  fi
  
 -cat <<EOF;
 -
 -Configuration:
 -  Libraries:
 -    intel mic . . . . . . $with_mic
 -    libaquaero5 . . . . . $with_libaquaero5
 -    libatasmart . . . . . $with_libatasmart
 -    libcurl . . . . . . . $with_libcurl
 -    libdbi  . . . . . . . $with_libdbi
 -    libesmtp  . . . . . . $with_libesmtp
 -    libganglia  . . . . . $with_libganglia
 -    libgcrypt . . . . . . $with_libgcrypt
 -    libhal  . . . . . . . $with_libhal
 -    libhiredis  . . . . . $with_libhiredis
 -    libi2c-dev  . . . . . $with_libi2c
 -    libiokit  . . . . . . $with_libiokit
 -    libiptc . . . . . . . $with_libiptc
 -    libjvm  . . . . . . . $with_java
 -    libkstat  . . . . . . $with_kstat
 -    libkvm  . . . . . . . $with_libkvm
 -    libldap . . . . . . . $with_libldap
 -    liblvm2app  . . . . . $with_liblvm2app
 -    libmemcached  . . . . $with_libmemcached
 -    libmnl  . . . . . . . $with_libmnl
 -    libmodbus . . . . . . $with_libmodbus
 -    libmongoc . . . . . . $with_libmongoc
 -    libmysql  . . . . . . $with_libmysql
 -    libnetapp . . . . . . $with_libnetapp
 -    libnetsnmp  . . . . . $with_libnetsnmp
 -    libnotify . . . . . . $with_libnotify
 -    liboconfig  . . . . . $with_liboconfig
 -    libopenipmi . . . . . $with_libopenipmipthread
 -    liboping  . . . . . . $with_liboping
 -    libowcapi . . . . . . $with_libowcapi
 -    libpcap . . . . . . . $with_libpcap
 -    libperfstat . . . . . $with_perfstat
 -    libperl . . . . . . . $with_libperl
 -    libpq . . . . . . . . $with_libpq
 -    libpthread  . . . . . $with_libpthread
 -    librabbitmq . . . . . $with_librabbitmq
 -    librdkafka  . . . . . $with_librdkafka
 -    librouteros . . . . . $with_librouteros
 -    librrd  . . . . . . . $with_librrd
 -    libsensors  . . . . . $with_libsensors
 -    libsigrok   . . . . . $with_libsigrok
 -    libstatgrab . . . . . $with_libstatgrab
 -    libtokyotyrant  . . . $with_libtokyotyrant
 -    libudev . . . . . . . $with_libudev
 -    libupsclient  . . . . $with_libupsclient
 -    libvarnish  . . . . . $with_libvarnish
 -    libvirt . . . . . . . $with_libvirt
 -    libxml2 . . . . . . . $with_libxml2
 -    libxmms . . . . . . . $with_libxmms
 -    libyajl . . . . . . . $with_libyajl
 -    oracle  . . . . . . . $with_oracle
 -    protobuf-c  . . . . . $have_protoc_c
 -    python  . . . . . . . $with_python
 -
 -  Features:
 -    daemon mode . . . . . $enable_daemon
 -    debug . . . . . . . . $enable_debug
 -
 -  Bindings:
 -    perl  . . . . . . . . $with_perl_bindings
 -
 -  Modules:
 -    aggregation . . . . . $enable_aggregation
 -    amqp    . . . . . . . $enable_amqp
 -    apache  . . . . . . . $enable_apache
 -    apcups  . . . . . . . $enable_apcups
 -    apple_sensors . . . . $enable_apple_sensors
 -    aquaero . . . . . . . $enable_aquaero
 -    ascent  . . . . . . . $enable_ascent
 -    barometer . . . . . . $enable_barometer
 -    battery . . . . . . . $enable_battery
 -    bind  . . . . . . . . $enable_bind
 -    ceph  . . . . . . . . $enable_ceph
 -    cgroups . . . . . . . $enable_cgroups
 -    conntrack . . . . . . $enable_conntrack
 -    contextswitch . . . . $enable_contextswitch
 -    cpu . . . . . . . . . $enable_cpu
 -    cpufreq . . . . . . . $enable_cpufreq
 -    csv . . . . . . . . . $enable_csv
 -    curl  . . . . . . . . $enable_curl
 -    curl_json . . . . . . $enable_curl_json
 -    curl_xml  . . . . . . $enable_curl_xml
 -    dbi . . . . . . . . . $enable_dbi
 -    df  . . . . . . . . . $enable_df
 -    disk  . . . . . . . . $enable_disk
 -    dns . . . . . . . . . $enable_dns
 -    drbd  . . . . . . . . $enable_drbd
 -    email . . . . . . . . $enable_email
 -    entropy . . . . . . . $enable_entropy
 -    ethstat . . . . . . . $enable_ethstat
 -    exec  . . . . . . . . $enable_exec
 -    fhcount . . . . . . . $enable_fhcount
 -    filecount . . . . . . $enable_filecount
 -    fscache . . . . . . . $enable_fscache
 -    gmond . . . . . . . . $enable_gmond
 -    hddtemp . . . . . . . $enable_hddtemp
 -    interface . . . . . . $enable_interface
 -    ipc . . . . . . . . . $enable_ipc
 -    ipmi  . . . . . . . . $enable_ipmi
 -    iptables  . . . . . . $enable_iptables
 -    ipvs  . . . . . . . . $enable_ipvs
 -    irq . . . . . . . . . $enable_irq
 -    java  . . . . . . . . $enable_java
 -    load  . . . . . . . . $enable_load
 -    logfile . . . . . . . $enable_logfile
 -    log_logstash  . . . . $enable_log_logstash
 -    lpar  . . . . . . . . $enable_lpar
 -    lvm . . . . . . . . . $enable_lvm
 -    madwifi . . . . . . . $enable_madwifi
 -    match_empty_counter . $enable_match_empty_counter
 -    match_hashed  . . . . $enable_match_hashed
 -    match_regex . . . . . $enable_match_regex
 -    match_timediff  . . . $enable_match_timediff
 -    match_value . . . . . $enable_match_value
 -    mbmon . . . . . . . . $enable_mbmon
 -    md  . . . . . . . . . $enable_md
 -    memcachec . . . . . . $enable_memcachec
 -    memcached . . . . . . $enable_memcached
 -    memory  . . . . . . . $enable_memory
 -    mic . . . . . . . . . $enable_mic
 -    modbus  . . . . . . . $enable_modbus
 -    multimeter  . . . . . $enable_multimeter
 -    mysql . . . . . . . . $enable_mysql
 -    netapp  . . . . . . . $enable_netapp
 -    netlink . . . . . . . $enable_netlink
 -    network . . . . . . . $enable_network
 -    nfs . . . . . . . . . $enable_nfs
 -    nginx . . . . . . . . $enable_nginx
 -    notify_desktop  . . . $enable_notify_desktop
 -    notify_email  . . . . $enable_notify_email
 -    ntpd  . . . . . . . . $enable_ntpd
 -    numa  . . . . . . . . $enable_numa
 -    nut . . . . . . . . . $enable_nut
 -    olsrd . . . . . . . . $enable_olsrd
 -    onewire . . . . . . . $enable_onewire
 -    openldap  . . . . . . $enable_openldap
 -    openvpn . . . . . . . $enable_openvpn
 -    oracle  . . . . . . . $enable_oracle
 -    perl  . . . . . . . . $enable_perl
 -    pf  . . . . . . . . . $enable_pf
 -    pinba . . . . . . . . $enable_pinba
 -    ping  . . . . . . . . $enable_ping
 -    postgresql  . . . . . $enable_postgresql
 -    powerdns  . . . . . . $enable_powerdns
 -    processes . . . . . . $enable_processes
 -    protocols . . . . . . $enable_protocols
 -    python  . . . . . . . $enable_python
 -    redis . . . . . . . . $enable_redis
 -    routeros  . . . . . . $enable_routeros
 -    rrdcached . . . . . . $enable_rrdcached
 -    rrdtool . . . . . . . $enable_rrdtool
 -    sensors . . . . . . . $enable_sensors
 -    serial  . . . . . . . $enable_serial
 -    sigrok  . . . . . . . $enable_sigrok
 -    smart . . . . . . . . $enable_smart
 -    snmp  . . . . . . . . $enable_snmp
 -    statsd  . . . . . . . $enable_statsd
 -    swap  . . . . . . . . $enable_swap
 -    syslog  . . . . . . . $enable_syslog
 -    table . . . . . . . . $enable_table
 -    tail_csv  . . . . . . $enable_tail_csv
 -    tail  . . . . . . . . $enable_tail
 -    tape  . . . . . . . . $enable_tape
 -    target_notification . $enable_target_notification
 -    target_replace  . . . $enable_target_replace
 -    target_scale  . . . . $enable_target_scale
 -    target_set  . . . . . $enable_target_set
 -    target_v5upgrade  . . $enable_target_v5upgrade
 -    tcpconns  . . . . . . $enable_tcpconns
 -    teamspeak2  . . . . . $enable_teamspeak2
 -    ted . . . . . . . . . $enable_ted
 -    thermal . . . . . . . $enable_thermal
 -    threshold . . . . . . $enable_threshold
 -    tokyotyrant . . . . . $enable_tokyotyrant
 -    turbostat . . . . . . $enable_turbostat
 -    unixsock  . . . . . . $enable_unixsock
 -    uptime  . . . . . . . $enable_uptime
 -    users . . . . . . . . $enable_users
 -    uuid  . . . . . . . . $enable_uuid
 -    varnish . . . . . . . $enable_varnish
 -    virt  . . . . . . . . $enable_virt
 -    vmem  . . . . . . . . $enable_vmem
 -    vserver . . . . . . . $enable_vserver
 -    wireless  . . . . . . $enable_wireless
 -    write_graphite  . . . $enable_write_graphite
 -    write_http  . . . . . $enable_write_http
 -    write_kafka . . . . . $enable_write_kafka
 -    write_log . . . . . . $enable_write_log
 -    write_mongodb . . . . $enable_write_mongodb
 -    write_redis . . . . . $enable_write_redis
 -    write_riemann . . . . $enable_write_riemann
 -    write_sensu . . . . . $enable_write_sensu
 -    write_tsdb  . . . . . $enable_write_tsdb
 -    xmms  . . . . . . . . $enable_xmms
 -    zfs_arc . . . . . . . $enable_zfs_arc
 -    zookeeper . . . . . . $enable_zookeeper
 -
 -EOF
 +AC_MSG_RESULT()
 +AC_MSG_RESULT([Configuration:])
 +AC_MSG_RESULT([  Build:])
 +AC_MSG_RESULT([    Platform  . . . . . . $ac_system])
 +AC_MSG_RESULT([    CC  . . . . . . . . . $CC])
 +AC_MSG_RESULT([    CFLAGS  . . . . . . . $AM_CFLAGS $CFLAGS])
 +AC_MSG_RESULT([    CXXFLAGS  . . . . . . $AM_CXXFLAGS $CXXFLAGS])
 +AC_MSG_RESULT([    CPP . . . . . . . . . $CPP])
 +AC_MSG_RESULT([    CPPFLAGS  . . . . . . $CPPFLAGS])
 +AC_MSG_RESULT([    GRPC_CPP_PLUGIN . . . $GRPC_CPP_PLUGIN])
 +AC_MSG_RESULT([    LD  . . . . . . . . . $LD])
 +AC_MSG_RESULT([    LDFLAGS . . . . . . . $LDFLAGS])
 +AC_MSG_RESULT([    PROTOC  . . . . . . . $PROTOC])
 +AC_MSG_RESULT([    YACC  . . . . . . . . $YACC])
 +AC_MSG_RESULT([    YFLAGS  . . . . . . . $YFLAGS])
 +AC_MSG_RESULT()
 +AC_MSG_RESULT([  Libraries:])
 +AC_MSG_RESULT([    intel mic . . . . . . $with_mic])
 +AC_MSG_RESULT([    libaquaero5 . . . . . $with_libaquaero5])
 +AC_MSG_RESULT([    libatasmart . . . . . $with_libatasmart])
 +AC_MSG_RESULT([    libcurl . . . . . . . $with_libcurl])
 +AC_MSG_RESULT([    libdbi  . . . . . . . $with_libdbi])
 +AC_MSG_RESULT([    libesmtp  . . . . . . $with_libesmtp])
 +AC_MSG_RESULT([    libganglia  . . . . . $with_libganglia])
 +AC_MSG_RESULT([    libgcrypt . . . . . . $with_libgcrypt])
 +AC_MSG_RESULT([    libgps  . . . . . . . $with_libgps])
 +AC_MSG_RESULT([    libgrpc++ . . . . . . $with_libgrpcpp])
 +AC_MSG_RESULT([    libhal  . . . . . . . $with_libhal])
 +AC_MSG_RESULT([    libhiredis  . . . . . $with_libhiredis])
 +AC_MSG_RESULT([    libi2c-dev  . . . . . $with_libi2c])
 +AC_MSG_RESULT([    libiokit  . . . . . . $with_libiokit])
 +AC_MSG_RESULT([    libiptc . . . . . . . $with_libiptc])
 +AC_MSG_RESULT([    libjvm  . . . . . . . $with_java])
 +AC_MSG_RESULT([    libkstat  . . . . . . $with_kstat])
 +AC_MSG_RESULT([    libkvm  . . . . . . . $with_libkvm])
 +AC_MSG_RESULT([    libldap . . . . . . . $with_libldap])
 +AC_MSG_RESULT([    liblua  . . . . . . . $with_liblua])
 +AC_MSG_RESULT([    liblvm2app  . . . . . $with_liblvm2app])
 +AC_MSG_RESULT([    libmemcached  . . . . $with_libmemcached])
 +AC_MSG_RESULT([    libmnl  . . . . . . . $with_libmnl])
 +AC_MSG_RESULT([    libmodbus . . . . . . $with_libmodbus])
 +AC_MSG_RESULT([    libmongoc . . . . . . $with_libmongoc])
 +AC_MSG_RESULT([    libmosquitto  . . . . $with_libmosquitto])
 +AC_MSG_RESULT([    libmysql  . . . . . . $with_libmysql])
 +AC_MSG_RESULT([    libnetapp . . . . . . $with_libnetapp])
 +AC_MSG_RESULT([    libnetsnmp  . . . . . $with_libnetsnmp])
 +AC_MSG_RESULT([    libnotify . . . . . . $with_libnotify])
 +AC_MSG_RESULT([    liboconfig  . . . . . $with_liboconfig])
 +AC_MSG_RESULT([    libopenipmi . . . . . $with_libopenipmipthread])
 +AC_MSG_RESULT([    liboping  . . . . . . $with_liboping])
 +AC_MSG_RESULT([    libowcapi . . . . . . $with_libowcapi])
 +AC_MSG_RESULT([    libpcap . . . . . . . $with_libpcap])
 +AC_MSG_RESULT([    libperfstat . . . . . $with_perfstat])
 +AC_MSG_RESULT([    libperl . . . . . . . $with_libperl])
 +AC_MSG_RESULT([    libpq . . . . . . . . $with_libpq])
 +AC_MSG_RESULT([    libprotobuf . . . . . $with_libprotobuf])
 +AC_MSG_RESULT([    libprotobuf-c . . . . $with_libprotobuf_c])
 +AC_MSG_RESULT([    libpython . . . . . . $with_libpython])
 +AC_MSG_RESULT([    librabbitmq . . . . . $with_librabbitmq])
 +AC_MSG_RESULT([    libriemann-client . . $with_libriemann_client])
 +AC_MSG_RESULT([    librdkafka  . . . . . $with_librdkafka])
 +AC_MSG_RESULT([    librouteros . . . . . $with_librouteros])
 +AC_MSG_RESULT([    librrd  . . . . . . . $with_librrd])
 +AC_MSG_RESULT([    libsensors  . . . . . $with_libsensors])
 +AC_MSG_RESULT([    libsigrok   . . . . . $with_libsigrok])
 +AC_MSG_RESULT([    libstatgrab . . . . . $with_libstatgrab])
 +AC_MSG_RESULT([    libtokyotyrant  . . . $with_libtokyotyrant])
 +AC_MSG_RESULT([    libudev . . . . . . . $with_libudev])
 +AC_MSG_RESULT([    libupsclient  . . . . $with_libupsclient])
 +AC_MSG_RESULT([    libvarnish  . . . . . $with_libvarnish])
 +AC_MSG_RESULT([    libvirt . . . . . . . $with_libvirt])
 +AC_MSG_RESULT([    libxenctrl  . . . . . $with_libxenctrl])
 +AC_MSG_RESULT([    libxml2 . . . . . . . $with_libxml2])
 +AC_MSG_RESULT([    libxmms . . . . . . . $with_libxmms])
 +AC_MSG_RESULT([    libyajl . . . . . . . $with_libyajl])
 +AC_MSG_RESULT([    oracle  . . . . . . . $with_oracle])
 +AC_MSG_RESULT([    protobuf-c  . . . . . $have_protoc_c])
 +AC_MSG_RESULT([    protoc 3  . . . . . . $have_protoc3])
 +AC_MSG_RESULT()
 +AC_MSG_RESULT([  Features:])
 +AC_MSG_RESULT([    daemon mode . . . . . $enable_daemon])
 +AC_MSG_RESULT([    debug . . . . . . . . $enable_debug])
 +AC_MSG_RESULT()
 +AC_MSG_RESULT([  Bindings:])
 +AC_MSG_RESULT([    perl  . . . . . . . . $with_perl_bindings])
 +AC_MSG_RESULT()
 +AC_MSG_RESULT([  Modules:])
 +AC_MSG_RESULT([    aggregation . . . . . $enable_aggregation])
 +AC_MSG_RESULT([    amqp    . . . . . . . $enable_amqp])
 +AC_MSG_RESULT([    apache  . . . . . . . $enable_apache])
 +AC_MSG_RESULT([    apcups  . . . . . . . $enable_apcups])
 +AC_MSG_RESULT([    apple_sensors . . . . $enable_apple_sensors])
 +AC_MSG_RESULT([    aquaero . . . . . . . $enable_aquaero])
 +AC_MSG_RESULT([    ascent  . . . . . . . $enable_ascent])
 +AC_MSG_RESULT([    barometer . . . . . . $enable_barometer])
 +AC_MSG_RESULT([    battery . . . . . . . $enable_battery])
 +AC_MSG_RESULT([    bind  . . . . . . . . $enable_bind])
 +AC_MSG_RESULT([    ceph  . . . . . . . . $enable_ceph])
 +AC_MSG_RESULT([    cgroups . . . . . . . $enable_cgroups])
 +AC_MSG_RESULT([    chrony. . . . . . . . $enable_chrony])
 +AC_MSG_RESULT([    conntrack . . . . . . $enable_conntrack])
 +AC_MSG_RESULT([    contextswitch . . . . $enable_contextswitch])
 +AC_MSG_RESULT([    cpu . . . . . . . . . $enable_cpu])
 +AC_MSG_RESULT([    cpufreq . . . . . . . $enable_cpufreq])
 +AC_MSG_RESULT([    cpusleep  . . . . . . $enable_cpusleep])
 +AC_MSG_RESULT([    csv . . . . . . . . . $enable_csv])
 +AC_MSG_RESULT([    curl  . . . . . . . . $enable_curl])
 +AC_MSG_RESULT([    curl_json . . . . . . $enable_curl_json])
 +AC_MSG_RESULT([    curl_xml  . . . . . . $enable_curl_xml])
 +AC_MSG_RESULT([    dbi . . . . . . . . . $enable_dbi])
 +AC_MSG_RESULT([    df  . . . . . . . . . $enable_df])
 +AC_MSG_RESULT([    disk  . . . . . . . . $enable_disk])
 +AC_MSG_RESULT([    dns . . . . . . . . . $enable_dns])
 +AC_MSG_RESULT([    drbd  . . . . . . . . $enable_drbd])
 +AC_MSG_RESULT([    email . . . . . . . . $enable_email])
 +AC_MSG_RESULT([    entropy . . . . . . . $enable_entropy])
 +AC_MSG_RESULT([    ethstat . . . . . . . $enable_ethstat])
 +AC_MSG_RESULT([    exec  . . . . . . . . $enable_exec])
 +AC_MSG_RESULT([    fhcount . . . . . . . $enable_fhcount])
 +AC_MSG_RESULT([    filecount . . . . . . $enable_filecount])
 +AC_MSG_RESULT([    fscache . . . . . . . $enable_fscache])
 +AC_MSG_RESULT([    gmond . . . . . . . . $enable_gmond])
 +AC_MSG_RESULT([    gps . . . . . . . . . $enable_gps])
 +AC_MSG_RESULT([    grpc  . . . . . . . . $enable_grpc])
 +AC_MSG_RESULT([    hddtemp . . . . . . . $enable_hddtemp])
 +AC_MSG_RESULT([    interface . . . . . . $enable_interface])
 +AC_MSG_RESULT([    ipc . . . . . . . . . $enable_ipc])
 +AC_MSG_RESULT([    ipmi  . . . . . . . . $enable_ipmi])
 +AC_MSG_RESULT([    iptables  . . . . . . $enable_iptables])
 +AC_MSG_RESULT([    ipvs  . . . . . . . . $enable_ipvs])
 +AC_MSG_RESULT([    irq . . . . . . . . . $enable_irq])
 +AC_MSG_RESULT([    java  . . . . . . . . $enable_java])
 +AC_MSG_RESULT([    load  . . . . . . . . $enable_load])
 +AC_MSG_RESULT([    logfile . . . . . . . $enable_logfile])
 +AC_MSG_RESULT([    log_logstash  . . . . $enable_log_logstash])
 +AC_MSG_RESULT([    lpar  . . . . . . . . $enable_lpar])
 +AC_MSG_RESULT([    lua . . . . . . . . . $enable_lua])
 +AC_MSG_RESULT([    lvm . . . . . . . . . $enable_lvm])
 +AC_MSG_RESULT([    madwifi . . . . . . . $enable_madwifi])
 +AC_MSG_RESULT([    match_empty_counter . $enable_match_empty_counter])
 +AC_MSG_RESULT([    match_hashed  . . . . $enable_match_hashed])
 +AC_MSG_RESULT([    match_regex . . . . . $enable_match_regex])
 +AC_MSG_RESULT([    match_timediff  . . . $enable_match_timediff])
 +AC_MSG_RESULT([    match_value . . . . . $enable_match_value])
 +AC_MSG_RESULT([    mbmon . . . . . . . . $enable_mbmon])
 +AC_MSG_RESULT([    md  . . . . . . . . . $enable_md])
 +AC_MSG_RESULT([    memcachec . . . . . . $enable_memcachec])
 +AC_MSG_RESULT([    memcached . . . . . . $enable_memcached])
 +AC_MSG_RESULT([    memory  . . . . . . . $enable_memory])
 +AC_MSG_RESULT([    mic . . . . . . . . . $enable_mic])
 +AC_MSG_RESULT([    modbus  . . . . . . . $enable_modbus])
 +AC_MSG_RESULT([    mqtt  . . . . . . . . $enable_mqtt])
 +AC_MSG_RESULT([    multimeter  . . . . . $enable_multimeter])
 +AC_MSG_RESULT([    mysql . . . . . . . . $enable_mysql])
 +AC_MSG_RESULT([    netapp  . . . . . . . $enable_netapp])
 +AC_MSG_RESULT([    netlink . . . . . . . $enable_netlink])
 +AC_MSG_RESULT([    network . . . . . . . $enable_network])
 +AC_MSG_RESULT([    nfs . . . . . . . . . $enable_nfs])
 +AC_MSG_RESULT([    nginx . . . . . . . . $enable_nginx])
 +AC_MSG_RESULT([    notify_desktop  . . . $enable_notify_desktop])
 +AC_MSG_RESULT([    notify_email  . . . . $enable_notify_email])
 +AC_MSG_RESULT([    notify_nagios . . . . $enable_notify_nagios])
 +AC_MSG_RESULT([    ntpd  . . . . . . . . $enable_ntpd])
 +AC_MSG_RESULT([    numa  . . . . . . . . $enable_numa])
 +AC_MSG_RESULT([    nut . . . . . . . . . $enable_nut])
 +AC_MSG_RESULT([    olsrd . . . . . . . . $enable_olsrd])
 +AC_MSG_RESULT([    onewire . . . . . . . $enable_onewire])
 +AC_MSG_RESULT([    openldap  . . . . . . $enable_openldap])
 +AC_MSG_RESULT([    openvpn . . . . . . . $enable_openvpn])
 +AC_MSG_RESULT([    oracle  . . . . . . . $enable_oracle])
 +AC_MSG_RESULT([    perl  . . . . . . . . $enable_perl])
 +AC_MSG_RESULT([    pf  . . . . . . . . . $enable_pf])
 +AC_MSG_RESULT([    pinba . . . . . . . . $enable_pinba])
 +AC_MSG_RESULT([    ping  . . . . . . . . $enable_ping])
 +AC_MSG_RESULT([    postgresql  . . . . . $enable_postgresql])
 +AC_MSG_RESULT([    powerdns  . . . . . . $enable_powerdns])
 +AC_MSG_RESULT([    processes . . . . . . $enable_processes])
 +AC_MSG_RESULT([    protocols . . . . . . $enable_protocols])
 +AC_MSG_RESULT([    python  . . . . . . . $enable_python])
 +AC_MSG_RESULT([    redis . . . . . . . . $enable_redis])
 +AC_MSG_RESULT([    routeros  . . . . . . $enable_routeros])
 +AC_MSG_RESULT([    rrdcached . . . . . . $enable_rrdcached])
 +AC_MSG_RESULT([    rrdtool . . . . . . . $enable_rrdtool])
 +AC_MSG_RESULT([    sensors . . . . . . . $enable_sensors])
 +AC_MSG_RESULT([    serial  . . . . . . . $enable_serial])
 +AC_MSG_RESULT([    sigrok  . . . . . . . $enable_sigrok])
 +AC_MSG_RESULT([    smart . . . . . . . . $enable_smart])
 +AC_MSG_RESULT([    snmp  . . . . . . . . $enable_snmp])
 +AC_MSG_RESULT([    statsd  . . . . . . . $enable_statsd])
 +AC_MSG_RESULT([    swap  . . . . . . . . $enable_swap])
 +AC_MSG_RESULT([    syslog  . . . . . . . $enable_syslog])
 +AC_MSG_RESULT([    table . . . . . . . . $enable_table])
 +AC_MSG_RESULT([    tail_csv  . . . . . . $enable_tail_csv])
 +AC_MSG_RESULT([    tail  . . . . . . . . $enable_tail])
 +AC_MSG_RESULT([    tape  . . . . . . . . $enable_tape])
 +AC_MSG_RESULT([    target_notification . $enable_target_notification])
 +AC_MSG_RESULT([    target_replace  . . . $enable_target_replace])
 +AC_MSG_RESULT([    target_scale  . . . . $enable_target_scale])
 +AC_MSG_RESULT([    target_set  . . . . . $enable_target_set])
 +AC_MSG_RESULT([    target_v5upgrade  . . $enable_target_v5upgrade])
 +AC_MSG_RESULT([    tcpconns  . . . . . . $enable_tcpconns])
 +AC_MSG_RESULT([    teamspeak2  . . . . . $enable_teamspeak2])
 +AC_MSG_RESULT([    ted . . . . . . . . . $enable_ted])
 +AC_MSG_RESULT([    thermal . . . . . . . $enable_thermal])
 +AC_MSG_RESULT([    threshold . . . . . . $enable_threshold])
 +AC_MSG_RESULT([    tokyotyrant . . . . . $enable_tokyotyrant])
 +AC_MSG_RESULT([    turbostat . . . . . . $enable_turbostat])
 +AC_MSG_RESULT([    unixsock  . . . . . . $enable_unixsock])
 +AC_MSG_RESULT([    uptime  . . . . . . . $enable_uptime])
 +AC_MSG_RESULT([    users . . . . . . . . $enable_users])
 +AC_MSG_RESULT([    uuid  . . . . . . . . $enable_uuid])
 +AC_MSG_RESULT([    varnish . . . . . . . $enable_varnish])
 +AC_MSG_RESULT([    virt  . . . . . . . . $enable_virt])
 +AC_MSG_RESULT([    vmem  . . . . . . . . $enable_vmem])
 +AC_MSG_RESULT([    vserver . . . . . . . $enable_vserver])
 +AC_MSG_RESULT([    wireless  . . . . . . $enable_wireless])
 +AC_MSG_RESULT([    write_graphite  . . . $enable_write_graphite])
 +AC_MSG_RESULT([    write_http  . . . . . $enable_write_http])
 +AC_MSG_RESULT([    write_kafka . . . . . $enable_write_kafka])
 +AC_MSG_RESULT([    write_log . . . . . . $enable_write_log])
 +AC_MSG_RESULT([    write_mongodb . . . . $enable_write_mongodb])
 +AC_MSG_RESULT([    write_redis . . . . . $enable_write_redis])
 +AC_MSG_RESULT([    write_riemann . . . . $enable_write_riemann])
 +AC_MSG_RESULT([    write_sensu . . . . . $enable_write_sensu])
 +AC_MSG_RESULT([    write_tsdb  . . . . . $enable_write_tsdb])
 +AC_MSG_RESULT([    xencpu  . . . . . . . $enable_xencpu])
 +AC_MSG_RESULT([    xmms  . . . . . . . . $enable_xmms])
 +AC_MSG_RESULT([    zfs_arc . . . . . . . $enable_zfs_arc])
 +AC_MSG_RESULT([    zone  . . . . . . . . $enable_zone])
 +AC_MSG_RESULT([    zookeeper . . . . . . $enable_zookeeper])
 +AC_MSG_RESULT()
  
  if test "x$dependency_error" = "xyes"; then
        AC_MSG_ERROR("Some plugins are missing dependencies - see the summary above for details")
diff --combined src/apcups.c
@@@ -1,6 -1,6 +1,6 @@@
  /*
   * collectd - src/apcups.c
 - * Copyright (C) 2006-2012  Florian octo Forster
 + * Copyright (C) 2006-2015  Florian octo Forster
   * Copyright (C) 2006       Anthony Gialluca <tonyabg at charter.net>
   * Copyright (C) 2000-2004  Kern Sibbald
   * Copyright (C) 1996-1999  Andre M. Hedrick <andre at suse.com>
   **/
  
  #include "collectd.h"
 +
  #include "common.h"      /* rrd_update_file */
  #include "plugin.h"      /* plugin_register, plugin_submit */
 -#include "configfile.h"  /* cf_register */
  
  #if HAVE_SYS_TYPES_H
  # include <sys/types.h>
  #endif
 -#if HAVE_SYS_SOCKET_H
 -# include <sys/socket.h>
 -#endif
  #if HAVE_NETDB_H
  # include <netdb.h>
  #endif
  # include <netinet/in.h>
  #endif
  
 -#define NISPORT 3551
 -#define MAXSTRING               256
 -#define MODULE_NAME "apcups"
 +#ifndef APCUPS_SERVER_TIMEOUT
 +# define APCUPS_SERVER_TIMEOUT 15.0
 +#endif
  
 -#define APCUPS_DEFAULT_HOST "localhost"
 +#ifndef APCUPS_DEFAULT_NODE
 +# define APCUPS_DEFAULT_NODE "localhost"
 +#endif
 +
 +#ifndef APCUPS_DEFAULT_SERVICE
 +# define APCUPS_DEFAULT_SERVICE "3551"
 +#endif
  
  /*
   * Private data types
   */
- struct apc_detail_s
+ typedef struct
  {
-       double linev;
-       double loadpct;
-       double bcharge;
-       double timeleft;
-       double outputv;
-       double itemp;
-       double battv;
-       double linefreq;
- };
+       gauge_t linev;
+       gauge_t loadpct;
+       gauge_t bcharge;
+       gauge_t timeleft;
+       gauge_t outputv;
+       gauge_t itemp;
+       gauge_t battv;
+       gauge_t linefreq;
+ } apc_detail_t;
  
  /*
   * Private variables
   */
  /* Default values for contacting daemon */
 -static char *conf_host = NULL;
 -static int   conf_port = NISPORT;
 +static char *conf_node = NULL;
 +static char *conf_service = NULL;
  /* Defaults to false for backwards compatibility. */
  static _Bool conf_report_seconds = 0;
 +static _Bool conf_persistent_conn = 1;
  
  static int global_sockfd = -1;
  
  static int count_retries = 0;
  static int count_iterations = 0;
 -static _Bool close_socket = 0;
 -
 -static const char *config_keys[] =
 -{
 -      "Host",
 -      "Port",
 -      "ReportSeconds"
 -};
 -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
  
  static int net_shutdown (int *fd)
  {
@@@ -89,7 -94,7 +89,7 @@@
        if ((fd == NULL) || (*fd < 0))
                return (EINVAL);
  
 -      swrite (*fd, (void *) &packet_size, sizeof (packet_size));
 +      (void)swrite (*fd, (void *) &packet_size, sizeof (packet_size));
        close (*fd);
        *fd = -1;
  
@@@ -111,20 -116,26 +111,20 @@@ static int apcups_shutdown (void
   * Returns -1 on error
   * Returns socket file descriptor otherwise
   */
 -static int net_open (char *host, int port)
 +static int net_open (char const *node, char const *service)
  {
        int              sd;
        int              status;
 -      char             port_str[8];
 -      struct addrinfo  ai_hints;
        struct addrinfo *ai_return;
        struct addrinfo *ai_list;
  
 -      assert ((port > 0x00000000) && (port <= 0x0000FFFF));
 -
 -      /* Convert the port to a string */
 -      ssnprintf (port_str, sizeof (port_str), "%i", port);
 -
 -      /* Resolve name */
 -      memset ((void *) &ai_hints, '\0', sizeof (ai_hints));
 -      ai_hints.ai_family   = AF_INET; /* XXX: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */
 -      ai_hints.ai_socktype = SOCK_STREAM;
 +      /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */
 +      struct addrinfo ai_hints = {
 +              .ai_family = AF_INET,
 +              .ai_socktype = SOCK_STREAM
 +      };
  
 -      status = getaddrinfo (host, port_str, &ai_hints, &ai_return);
 +      status = getaddrinfo (node, service, &ai_hints, &ai_return);
        if (status != 0)
        {
                char errbuf[1024];
        DEBUG ("apcups plugin: Done opening a socket %i", sd);
  
        return (sd);
 -} /* int net_open (char *host, char *service, int port) */
 +} /* int net_open */
  
  /*
   * Receive a message from the other end. Each message consists of
@@@ -223,7 -234,7 +223,7 @@@ static int net_recv (int *sockfd, char 
   * Returns zero on success
   * Returns non-zero on error
   */
 -static int net_send (int *sockfd, char *buff, int len)
 +static int net_send (int *sockfd, const char *buff, int len)
  {
        uint16_t packet_size;
  
  }
  
  /* Get and print status from apcupsd NIS server */
 -static int apc_query_server (char *host, int port,
 +static int apc_query_server (char const *node, char const *service,
-               struct apc_detail_s *apcups_detail)
+               apc_detail_t *apcups_detail)
  {
        int     n;
        char    recvline[1024];
        char   *tokptr;
        char   *toksaveptr;
-       char   *key;
-       double  value;
        _Bool retry = 1;
        int status;
  
        {
                if (global_sockfd < 0)
                {
 -                      global_sockfd = net_open (host, port);
 +                      global_sockfd = net_open (node, service);
                        if (global_sockfd < 0)
                        {
                                ERROR ("apcups plugin: Connecting to the "
                                "first %i iterations. Will close the socket "
                                "in future iterations.",
                                count_retries, count_iterations);
 -              close_socket = 1;
 +              conf_persistent_conn = 0;
        }
  
        while ((n = net_recv (&global_sockfd, recvline, sizeof (recvline) - 1)) > 0)
        {
 -              assert ((unsigned int)n < sizeof (recvline));
 -              recvline[n] = '\0';
 +              assert ((size_t)n < sizeof (recvline));
 +              recvline[n] = 0;
  #if APCMAIN
                printf ("net_recv = `%s';\n", recvline);
  #endif /* if APCMAIN */
                tokptr = strtok_r (recvline, " :\t", &toksaveptr);
                while (tokptr != NULL)
                {
-                       key = tokptr;
+                       char *key = tokptr;
                        if ((tokptr = strtok_r (NULL, " :\t", &toksaveptr)) == NULL)
                                continue;
-                       value = atof (tokptr);
+                       gauge_t value;
+                       if (strtogauge (tokptr, &value) != 0)
+                               continue;
  
                        PRINT_VALUE (key, value);
  
        }
        status = errno; /* save errno, net_shutdown() may re-set it. */
  
 -      if (close_socket)
 +      if (!conf_persistent_conn)
                net_shutdown (&global_sockfd);
  
        if (n < 0)
        return (0);
  }
  
 -static int apcups_config (const char *key, const char *value)
 +static int apcups_config (oconfig_item_t *ci)
  {
 -      if (strcasecmp (key, "host") == 0)
 -      {
 -              if (conf_host != NULL)
 -              {
 -                      free (conf_host);
 -                      conf_host = NULL;
 -              }
 -              if ((conf_host = strdup (value)) == NULL)
 -                      return (1);
 -      }
 -      else if (strcasecmp (key, "Port") == 0)
 +      _Bool persistent_conn_set = 0;
 +
 +      for (int i = 0; i < ci->children_num; i++)
        {
 -              int port_tmp = atoi (value);
 -              if (port_tmp < 1 || port_tmp > 65535)
 -              {
 -                      WARNING ("apcups plugin: Invalid port: %i", port_tmp);
 -                      return (1);
 +              oconfig_item_t *child = ci->children + i;
 +
 +              if (strcasecmp (child->key, "Host") == 0)
 +                      cf_util_get_string (child, &conf_node);
 +              else if (strcasecmp (child->key, "Port") == 0)
 +                      cf_util_get_service (child, &conf_service);
 +              else if (strcasecmp (child->key, "ReportSeconds") == 0)
 +                      cf_util_get_boolean (child, &conf_report_seconds);
 +              else if (strcasecmp (child->key, "PersistentConnection") == 0) {
 +                      cf_util_get_boolean (child, &conf_persistent_conn);
 +                      persistent_conn_set = 1;
                }
 -              conf_port = port_tmp;
 -      }
 -      else if (strcasecmp (key, "ReportSeconds") == 0)
 -      {
 -              if (IS_TRUE (value))
 -                      conf_report_seconds = 1;
                else
 -                      conf_report_seconds = 0;
 +                      ERROR ("apcups plugin: Unknown config option \"%s\".", child->key);
        }
 -      else
 -      {
 -              return (-1);
 +
 +      if (!persistent_conn_set) {
 +              double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval());
 +              if (interval > APCUPS_SERVER_TIMEOUT) {
 +                      NOTICE ("apcups plugin: Plugin poll interval set to %.3f seconds. "
 +                              "Apcupsd NIS socket timeout is %.3f seconds, "
 +                              "PersistentConnection disabled by default.",
 +                              interval, APCUPS_SERVER_TIMEOUT);
 +                      conf_persistent_conn = 0;
 +              }
        }
 +
        return (0);
 -}
 +} /* int apcups_config */
  
- static void apc_submit_generic (const char *type, const char *type_inst, double value)
 -static void apc_submit_generic (char *type, char *type_inst, gauge_t value)
++static void apc_submit_generic (const char *type, const char *type_inst, gauge_t value)
  {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
  
+       if (isnan (value))
+               return;
        values[0].gauge = value;
  
        vl.values = values;
        plugin_dispatch_values (&vl);
  }
  
- static void apc_submit (struct apc_detail_s *apcups_detail)
+ static void apc_submit (apc_detail_t const *apcups_detail)
  {
        apc_submit_generic ("voltage",    "input",   apcups_detail->linev);
        apc_submit_generic ("voltage",    "output",  apcups_detail->outputv);
  
  static int apcups_read (void)
  {
-       struct apc_detail_s apcups_detail;
-       int status;
+       apc_detail_t apcups_detail = {
+               .linev    = NAN,
+               .outputv  = NAN,
+               .battv    = NAN,
+               .loadpct  = NAN,
+               .bcharge  = NAN,
+               .timeleft = NAN,
+               .itemp    = NAN,
+               .linefreq = NAN,
+       };
  
-       apcups_detail.linev    =   -1.0;
-       apcups_detail.outputv  =   -1.0;
-       apcups_detail.battv    =   -1.0;
-       apcups_detail.loadpct  =   -1.0;
-       apcups_detail.bcharge  =   -1.0;
-       apcups_detail.timeleft =    NAN;
-       apcups_detail.itemp    = -300.0;
-       apcups_detail.linefreq =   -1.0;
-       status = apc_query_server ((conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
-                       (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
-                       &apcups_detail);
-       /*
-        * if we did not connect then do not bother submitting
-        * zeros. We want rrd files to have NAN.
-        */
 -      int status = apc_query_server (conf_host == NULL
 -                      ? APCUPS_DEFAULT_HOST
 -                      : conf_host,
 -                      conf_port, &apcups_detail);
++      int status = apc_query_server (conf_node == NULL
++                      ? APCUPS_DEFAULT_NODE
++                      : conf_node,
++                      conf_service, &apcups_detail);
        if (status != 0)
        {
-               DEBUG ("apcups plugin: apc_query_server (%s, %s) = %i",
-                               (conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
-                               (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
-                               status);
-               return (-1);
 -              DEBUG ("apcups plugin: apc_query_server (%s, %i) = %i",
 -                              conf_host == NULL ? APCUPS_DEFAULT_HOST : conf_host,
 -                              conf_port, status);
++              DEBUG ("apcups plugin: apc_query_server (\"%s\", \"%s\") = %d",
++                              conf_node == NULL ? APCUPS_DEFAULT_NODE : conf_node,
++                              conf_service, status);
+               return (status);
        }
  
        apc_submit (&apcups_detail);
  
  void module_register (void)
  {
 -      plugin_register_config ("apcups", apcups_config, config_keys,
 -                      config_keys_num);
 +      plugin_register_complex_config ("apcups", apcups_config);
        plugin_register_read ("apcups", apcups_read);
        plugin_register_shutdown ("apcups", apcups_shutdown);
  } /* void module_register */
diff --combined src/modbus.c
  #include "collectd.h"
  
  #include "common.h"
+ #include "configfile.h"
  #include "plugin.h"
  
- #include <netdb.h>
  #include <modbus.h>
+ #include <netdb.h>
+ #include <sys/socket.h>
  
  #ifndef LIBMODBUS_VERSION_CHECK
  /* Assume version 2.0.3 */
@@@ -80,7 -81,7 +81,7 @@@ enum mb_register_type_e /* {{{ *
    REG_TYPE_UINT32,
    REG_TYPE_FLOAT
  }; /* }}} */
 -enum mb_mreg_type_e /* {{{ */ 
 +enum mb_mreg_type_e /* {{{ */
  {
    MREG_HOLDING,
    MREG_INPUT
@@@ -161,10 -162,12 +162,10 @@@ static mb_data_t *data_definitions = NU
  static mb_data_t *data_get_by_name (mb_data_t *src, /* {{{ */
      const char *name)
  {
 -  mb_data_t *ptr;
 -
    if (name == NULL)
      return (NULL);
  
 -  for (ptr = src; ptr != NULL; ptr = ptr->next)
 +  for (mb_data_t *ptr = src; ptr != NULL; ptr = ptr->next)
      if (strcasecmp (ptr->name, name) == 0)
        return (ptr);
  
@@@ -255,7 -258,7 +256,7 @@@ static int mb_submit (mb_host_t *host, 
    if ((host == NULL) || (slave == NULL) || (data == NULL))
      return (EINVAL);
  
 -  if (host->interval <= 0)
 +  if (host->interval == 0)
      host->interval = plugin_get_interval ();
  
    if (slave->instance[0] == 0)
@@@ -425,7 -428,7 +426,7 @@@ static int mb_init_connection (mb_host_
  static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
      mb_data_t *data)
  {
 -  uint16_t values[2];
 +  uint16_t values[2] = { 0 };
    int values_num;
    const data_set_t *ds;
    int status = 0;
  
    if (ds->ds_num != 1)
    {
 -    ERROR ("Modbus plugin: The type \"%s\" has %i data sources. "
 +    ERROR ("Modbus plugin: The type \"%s\" has %zu data sources. "
          "I can only handle data sets with only one data source.",
          data->type, ds->ds_num);
      return (-1);
          "is not UINT32.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type));
    }
  
 -  memset (values, 0, sizeof (values));
    if ((data->register_type == REG_TYPE_INT32)
        || (data->register_type == REG_TYPE_UINT32)
        || (data->register_type == REG_TYPE_FLOAT))
    }
    else if (host->conntype == MBCONN_TCP)
    {
-     struct sockaddr sockaddr;
-     socklen_t saddrlen = sizeof (sockaddr);
-     status = getpeername (modbus_get_socket (host->connection),
-         &sockaddr, &saddrlen);
-     if (status != 0)
+     if (getpeername (modbus_get_socket (host->connection),
+           (void *) &(struct sockaddr_storage) {0},
+           &(socklen_t) {sizeof(struct sockaddr_storage)}) != 0)
        status = errno;
    }
  
      modbus_free (host->connection);
  #endif
    }
 - 
 +
  #if LEGACY_LIBMODBUS
    /* Version 2.0.3: Pass the connection struct as a pointer and pass the slave
     * id to each call of "read_holding_registers". */
  
  static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */
  {
 -  mb_data_t *data;
    int success;
    int status;
  
      return (EINVAL);
  
    success = 0;
 -  for (data = slave->collect; data != NULL; data = data->next)
 +  for (mb_data_t *data = slave->collect; data != NULL; data = data->next)
    {
      status = mb_read_data (host, slave, data);
      if (status == 0)
  static int mb_read (user_data_t *user_data) /* {{{ */
  {
    mb_host_t *host;
 -  size_t i;
    int success;
    int status;
  
    host = user_data->data;
  
    success = 0;
 -  for (i = 0; i < host->slaves_num; i++)
 +  for (size_t i = 0; i < host->slaves_num; i++)
    {
      status = mb_read_slave (host, host->slaves + i);
      if (status == 0)
@@@ -690,10 -693,12 +688,10 @@@ static void data_free_all (mb_data_t *d
  
  static void slaves_free_all (mb_slave_t *slaves, size_t slaves_num) /* {{{ */
  {
 -  size_t i;
 -
    if (slaves == NULL)
      return;
  
 -  for (i = 0; i < slaves_num; i++)
 +  for (size_t i = 0; i < slaves_num; i++)
      data_free_all (slaves[i].collect);
    sfree (slaves);
  } /* }}} void slaves_free_all */
@@@ -713,9 -718,11 +711,9 @@@ static void host_free (void *void_host
  
  static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */
  {
 -  mb_data_t data;
 +  mb_data_t data = { 0 };
    int status;
 -  int i;
  
 -  memset (&data, 0, sizeof (data));
    data.name = NULL;
    data.register_type = REG_TYPE_UINT16;
    data.next = NULL;
    if (status != 0)
      return (status);
  
 -  for (i = 0; i < ci->children_num; i++)
 +  for (int i = 0; i < ci->children_num; i++)
    {
      oconfig_item_t *child = ci->children + i;
  
@@@ -810,17 -817,24 +808,17 @@@ static int mb_config_set_host_address (
      const char *address)
  {
    struct addrinfo *ai_list;
 -  struct addrinfo *ai_ptr;
 -  struct addrinfo  ai_hints;
    int status;
  
    if ((host == NULL) || (address == NULL))
      return (EINVAL);
  
 -  memset (&ai_hints, 0, sizeof (ai_hints));
 -#if AI_ADDRCONFIG
 -  ai_hints.ai_flags |= AI_ADDRCONFIG;
 -#endif
 -  /* XXX: libmodbus can only handle IPv4 addresses. */
 -  ai_hints.ai_family = AF_INET;
 -  ai_hints.ai_addr = NULL;
 -  ai_hints.ai_canonname = NULL;
 -  ai_hints.ai_next = NULL;
 +  struct addrinfo  ai_hints = {
 +    /* XXX: libmodbus can only handle IPv4 addresses. */
 +    .ai_family = AF_INET,
 +    .ai_flags = AI_ADDRCONFIG
 +  };
  
 -  ai_list = NULL;
    status = getaddrinfo (address, /* service = */ NULL,
        &ai_hints, &ai_list);
    if (status != 0)
      return (status);
    }
  
 -  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
 +  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
    {
      status = getnameinfo (ai_ptr->ai_addr, ai_ptr->ai_addrlen,
          host->node, sizeof (host->node),
@@@ -860,6 -874,7 +858,6 @@@ static int mb_config_add_slave (mb_host
  {
    mb_slave_t *slave;
    int status;
 -  int i;
  
    if ((host == NULL) || (ci == NULL))
      return (EINVAL);
    if (status != 0)
      return (status);
  
 -  for (i = 0; i < ci->children_num; i++)
 +  for (int i = 0; i < ci->children_num; i++)
    {
      oconfig_item_t *child = ci->children + i;
  
@@@ -919,10 -934,12 +917,10 @@@ static int mb_config_add_host (oconfig_
  {
    mb_host_t *host;
    int status;
 -  int i;
  
 -  host = malloc (sizeof (*host));
 +  host = calloc (1, sizeof (*host));
    if (host == NULL)
      return (ENOMEM);
 -  memset (host, 0, sizeof (*host));
    host->slaves = NULL;
  
    status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host));
      return (EINVAL);
    }
  
 -  for (i = 0; i < ci->children_num; i++)
 +  for (int i = 0; i < ci->children_num; i++)
    {
      oconfig_item_t *child = ci->children + i;
      status = 0;
    {
      user_data_t ud;
      char name[1024];
 -    struct timespec interval = { 0, 0 };
  
      ud.data = host;
      ud.free_func = host_free;
  
      ssnprintf (name, sizeof (name), "modbus-%s", host->host);
  
 -    CDTIME_T_TO_TIMESPEC (host->interval, &interval);
 -
      plugin_register_complex_read (/* group = */ NULL, name,
          /* callback = */ mb_read,
 -        /* interval = */ (host->interval > 0) ? &interval : NULL,
 +        /* interval = */ host->interval,
          &ud);
    }
    else
  
  static int mb_config (oconfig_item_t *ci) /* {{{ */
  {
 -  int i;
 -
    if (ci == NULL)
      return (EINVAL);
  
 -  for (i = 0; i < ci->children_num; i++)
 +  for (int i = 0; i < ci->children_num; i++)
    {
      oconfig_item_t *child = ci->children + i;
  
diff --combined src/write_kafka.c
  
  #include "plugin.h"
  #include "common.h"
 -#include "configfile.h"
 -#include "utils_cache.h"
  #include "utils_cmd_putval.h"
  #include "utils_format_graphite.h"
  #include "utils_format_json.h"
 -#include "utils_crc32.h"
  
  #include <stdint.h>
  #include <librdkafka/rdkafka.h>
 -#include <pthread.h>
 -#include <zlib.h>
  #include <errno.h>
  
  struct kafka_topic_context {
  #define KAFKA_FORMAT_JSON        0
  #define KAFKA_FORMAT_COMMAND     1
  #define KAFKA_FORMAT_GRAPHITE    2
 -    uint8_t                     format;
 +    uint8_t                      format;
      unsigned int                 graphite_flags;
      _Bool                        store_rates;
      rd_kafka_topic_conf_t       *conf;
      rd_kafka_topic_t            *topic;
      rd_kafka_conf_t             *kafka_conf;
      rd_kafka_t                  *kafka;
 -    int                          has_key;
 -    uint32_t                    key;
 +    char                        *key;
      char                        *prefix;
      char                        *postfix;
      char                         escape_char;
      char                        *topic_name;
 -    pthread_mutex_t           lock;
 +    pthread_mutex_t              lock;
  };
  
  static int kafka_handle(struct kafka_topic_context *);
@@@ -60,7 -66,14 +60,14 @@@ static int kafka_write(const data_set_
  static int32_t kafka_partition(const rd_kafka_topic_t *, const void *, size_t,
                                 int32_t, void *, void *);
  
- #if defined HAVE_LIBRDKAFKA_LOGGER || defined HAVE_LIBRDKAFKA_LOG_CB
+ /* Version 0.9.0 of librdkafka deprecates rd_kafka_set_logger() in favor of
+  * rd_kafka_conf_set_log_cb(). This is to make sure we're not using the
+  * deprecated function. */
+ #ifdef HAVE_LIBRDKAFKA_LOG_CB
+ # undef HAVE_LIBRDKAFKA_LOGGER
+ #endif
+ #if defined(HAVE_LIBRDKAFKA_LOGGER) || defined(HAVE_LIBRDKAFKA_LOG_CB)
  static void kafka_log(const rd_kafka_t *, int, const char *, const char *);
  
  static void kafka_log(const rd_kafka_t *rkt, int level,
  }
  #endif
  
 +static uint32_t kafka_hash(const char *keydata, size_t keylen)
 +{
 +    uint32_t hash = 5381;
 +    for (; keylen > 0; keylen--)
 +        hash = ((hash << 5) + hash) + keydata[keylen - 1];
 +    return hash;
 +}
 +
 +/* 31 bit -> 4 byte -> 8 byte hex string + null byte */
 +#define KAFKA_RANDOM_KEY_SIZE 9
 +#define KAFKA_RANDOM_KEY_BUFFER (char[KAFKA_RANDOM_KEY_SIZE]) {""}
 +static char *kafka_random_key(char buffer[static KAFKA_RANDOM_KEY_SIZE])
 +{
 +    ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08lX", (unsigned long) mrand48());
 +    return buffer;
 +}
 +
  static int32_t kafka_partition(const rd_kafka_topic_t *rkt,
                                 const void *keydata, size_t keylen,
                                 int32_t partition_cnt, void *p, void *m)
  {
 -    uint32_t key = *((uint32_t *)keydata );
 +    uint32_t key = kafka_hash(keydata, keylen);
      uint32_t target = key % partition_cnt;
 -    int32_t   i = partition_cnt;
 +    int32_t  i = partition_cnt;
  
      while (--i > 0 && !rd_kafka_topic_partition_available(rkt, target)) {
          target = (target + 1) % partition_cnt;
@@@ -118,37 -114,37 +125,37 @@@ static int kafka_handle(struct kafka_to
  
          if ((ctx->kafka = rd_kafka_new(RD_KAFKA_PRODUCER, conf,
                                      errbuf, sizeof(errbuf))) == NULL) {
 -              ERROR("write_kafka plugin: cannot create kafka handle.");
 -              return 1;
 +            ERROR("write_kafka plugin: cannot create kafka handle.");
 +            return 1;
          }
  
 -      rd_kafka_conf_destroy(ctx->kafka_conf);
 -      ctx->kafka_conf = NULL;
 +        rd_kafka_conf_destroy(ctx->kafka_conf);
 +        ctx->kafka_conf = NULL;
  
 -      INFO ("write_kafka plugin: created KAFKA handle : %s", rd_kafka_name(ctx->kafka));
 +        INFO ("write_kafka plugin: created KAFKA handle : %s", rd_kafka_name(ctx->kafka));
  
 -#ifdef HAVE_LIBRDKAFKA_LOGGER
 -      rd_kafka_set_logger(ctx->kafka, kafka_log);
 +#if defined(HAVE_LIBRDKAFKA_LOGGER) && !defined(HAVE_LIBRDKAFKA_LOG_CB)
 +        rd_kafka_set_logger(ctx->kafka, kafka_log);
  #endif
      }
  
      if (ctx->topic == NULL ) {
 -      if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) {
 +        if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) {
              ERROR("write_kafka plugin: cannot duplicate kafka topic config");
              return 1;
 -      }
 +        }
  
 -      if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name,
 -                                                      topic_conf)) == NULL) {
 -              ERROR("write_kafka plugin: cannot create topic : %s\n", 
 -                      rd_kafka_err2str(rd_kafka_errno2err(errno)));
 -              return errno;
 -      }
 +        if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name,
 +                                            topic_conf)) == NULL) {
 +            ERROR("write_kafka plugin: cannot create topic : %s\n",
 +            rd_kafka_err2str(rd_kafka_errno2err(errno)));
 +            return errno;
 +        }
  
 -      rd_kafka_topic_conf_destroy(ctx->conf);
 -      ctx->conf = NULL;
 +        rd_kafka_topic_conf_destroy(ctx->conf);
 +        ctx->conf = NULL;
  
 -      INFO ("write_kafka plugin: handle created for topic : %s", rd_kafka_topic_name(ctx->topic));
 +        INFO ("write_kafka plugin: handle created for topic : %s", rd_kafka_topic_name(ctx->topic));
      }
  
      return(0);
  } /* }}} int kafka_handle */
  
  static int kafka_write(const data_set_t *ds, /* {{{ */
 -            const value_list_t *vl,
 -            user_data_t *ud)
 +          const value_list_t *vl,
 +          user_data_t *ud)
  {
 -      int                      status = 0;
 -    uint32_t    key;
 -    char         buffer[8192];
 -    size_t bfree = sizeof(buffer);
 -    size_t bfill = 0;
 -    size_t blen = 0;
 -      struct kafka_topic_context      *ctx = ud->data;
 +    int      status = 0;
 +    void    *key;
 +    size_t   keylen = 0;
 +    char     buffer[8192];
 +    size_t   bfree = sizeof(buffer);
 +    size_t   bfill = 0;
 +    size_t   blen = 0;
 +    struct   kafka_topic_context  *ctx = ud->data;
  
      if ((ds == NULL) || (vl == NULL) || (ctx == NULL))
          return EINVAL;
          blen = strlen(buffer);
          break;
      case KAFKA_FORMAT_JSON:
 -
          format_json_initialize(buffer, &bfill, &bfree);
          format_json_value_list(buffer, &bfill, &bfree, ds, vl,
                                 ctx->store_rates);
          return -1;
      }
  
 -    /*
 -     * We partition our stream by metric name
 -     */
 -    if (ctx->has_key)
 -        key = ctx->key;
 -    else
 -        key = rand();
 +    key = (ctx->key != NULL)
 +        ? ctx->key
 +        : kafka_random_key(KAFKA_RANDOM_KEY_BUFFER);
 +    keylen = strlen (key);
  
      rd_kafka_produce(ctx->topic, RD_KAFKA_PARTITION_UA,
                       RD_KAFKA_MSG_F_COPY, buffer, blen,
 -                     &key, sizeof(key), NULL);
 +                     key, keylen, NULL);
  
 -      return status;
 +    return status;
  } /* }}} int kafka_write */
  
  static void kafka_topic_context_free(void *p) /* {{{ */
  {
 -      struct kafka_topic_context *ctx = p;
 +    struct kafka_topic_context *ctx = p;
  
 -      if (ctx == NULL)
 -              return;
 +    if (ctx == NULL)
 +        return;
  
      if (ctx->topic_name != NULL)
          sfree(ctx->topic_name);
  static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{ */
  {
      int                          status;
 -    int                          i;
      struct kafka_topic_context  *tctx;
      char                        *key = NULL;
      char                        *val;
      char                         callback_name[DATA_MAX_NAME_LEN];
      char                         errbuf[1024];
 -    user_data_t                  ud;
 -      oconfig_item_t              *child;
 +    oconfig_item_t              *child;
      rd_kafka_conf_res_t          ret;
  
 -      if ((tctx = calloc(1, sizeof (*tctx))) == NULL) {
 -              ERROR ("write_kafka plugin: calloc failed.");
 +    if ((tctx = calloc(1, sizeof (*tctx))) == NULL) {
 +        ERROR ("write_kafka plugin: calloc failed.");
          return;
 -      }
 +    }
  
      tctx->escape_char = '.';
      tctx->store_rates = 1;
      tctx->format = KAFKA_FORMAT_JSON;
 +    tctx->key = NULL;
  
      if ((tctx->kafka_conf = rd_kafka_conf_dup(conf)) == NULL) {
          sfree(tctx);
          goto errout;
      }
  
 -      for (i = 0; i < ci->children_num; i++) {
 -              /*
 -               * The code here could be simplified but makes room
 -               * for easy adding of new options later on.
 -               */
 -              child = &ci->children[i];
 -              status = 0;
 -
 -              if (strcasecmp ("Property", child->key) == 0) {
 -                      if (child->values_num != 2) {
 -                              WARNING("kafka properties need both a key and a value.");
 +    for (int i = 0; i < ci->children_num; i++) {
 +        /*
 +         * The code here could be simplified but makes room
 +         * for easy adding of new options later on.
 +         */
 +        child = &ci->children[i];
 +        status = 0;
 +
 +        if (strcasecmp ("Property", child->key) == 0) {
 +            if (child->values_num != 2) {
 +                WARNING("kafka properties need both a key and a value.");
                  goto errout;
 -                      }
 -                      if (child->values[0].type != OCONFIG_TYPE_STRING ||
 -                          child->values[1].type != OCONFIG_TYPE_STRING) {
 -                              WARNING("kafka properties needs string arguments.");
 +            }
 +            if (child->values[0].type != OCONFIG_TYPE_STRING ||
 +                child->values[1].type != OCONFIG_TYPE_STRING) {
 +                WARNING("kafka properties needs string arguments.");
                  goto errout;
 -                      }
 +            }
              key = child->values[0].value.string;
              val = child->values[1].value.string;
              ret = rd_kafka_topic_conf_set(tctx->conf,key, val,
                                            errbuf, sizeof(errbuf));
              if (ret != RD_KAFKA_CONF_OK) {
 -                              WARNING("cannot set kafka topic property %s to %s: %s.",
 +                WARNING("cannot set kafka topic property %s to %s: %s.",
                          key, val, errbuf);
                  goto errout;
 -                      }
 -
 -        } else if (strcasecmp ("Key", child->key) == 0)  {
 -            char *tmp_buf = NULL;
 -            status = cf_util_get_string(child, &tmp_buf);
 -            if (status != 0) {
 -                WARNING("write_kafka plugin: invalid key supplied");
 -                break;
              }
  
 -            if (strcasecmp(tmp_buf, "Random") != 0) {
 -                tctx->has_key = 1;
 -                tctx->key = crc32_buffer((u_char *)tmp_buf, strlen(tmp_buf));
 +        } else if (strcasecmp ("Key", child->key) == 0)  {
 +            if (cf_util_get_string (child, &tctx->key) != 0)
 +                continue;
 +            if (strcasecmp ("Random", tctx->key) == 0) {
 +                sfree(tctx->key);
 +                tctx->key = strdup (kafka_random_key (KAFKA_RANDOM_KEY_BUFFER));
              }
 -            sfree(tmp_buf);
 -
          } else if (strcasecmp ("Format", child->key) == 0) {
              status = cf_util_get_string(child, &key);
              if (status != 0)
      ssnprintf(callback_name, sizeof(callback_name),
                "write_kafka/%s", tctx->topic_name);
  
 -    ud.data = tctx;
 -    ud.free_func = kafka_topic_context_free;
 +    user_data_t ud = {
 +        .data = tctx,
 +        .free_func = kafka_topic_context_free
 +    };
  
 -      status = plugin_register_write (callback_name, kafka_write, &ud);
 -      if (status != 0) {
 -              WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
 -                              "failed with status %i.",
 -                              callback_name, status);
 +    status = plugin_register_write (callback_name, kafka_write, &ud);
 +    if (status != 0) {
 +        WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
 +                "failed with status %i.",
 +                callback_name, status);
          goto errout;
      }
  
      if (tctx->conf != NULL)
          rd_kafka_topic_conf_destroy(tctx->conf);
      if (tctx->kafka_conf != NULL)
 -              rd_kafka_conf_destroy(tctx->kafka_conf);
 +        rd_kafka_conf_destroy(tctx->kafka_conf);
      sfree(tctx);
  } /* }}} int kafka_config_topic */
  
  static int kafka_config(oconfig_item_t *ci) /* {{{ */
  {
 -      int                          i;
 -      oconfig_item_t              *child;
 +    oconfig_item_t              *child;
      rd_kafka_conf_t             *conf;
      rd_kafka_conf_res_t          ret;
      char                         errbuf[1024];
          WARNING("cannot allocate kafka configuration.");
          return -1;
      }
 -      for (i = 0; i < ci->children_num; i++)  {
 -              child = &ci->children[i];
 +    for (int i = 0; i < ci->children_num; i++)  {
 +        child = &ci->children[i];
  
 -              if (strcasecmp("Topic", child->key) == 0) {
 -                      kafka_config_topic (conf, child);
 -              } else if (strcasecmp(child->key, "Property") == 0) {
 -                      char *key = NULL;
 -                      char *val = NULL;
 +        if (strcasecmp("Topic", child->key) == 0) {
 +            kafka_config_topic (conf, child);
 +        } else if (strcasecmp(child->key, "Property") == 0) {
 +            char *key = NULL;
 +            char *val = NULL;
  
 -                      if (child->values_num != 2) {
 -                              WARNING("kafka properties need both a key and a value.");
 +            if (child->values_num != 2) {
 +                WARNING("kafka properties need both a key and a value.");
                  goto errout;
 -                      }
 -                      if (child->values[0].type != OCONFIG_TYPE_STRING ||
 -                          child->values[1].type != OCONFIG_TYPE_STRING) {
 -                              WARNING("kafka properties needs string arguments.");
 +            }
 +            if (child->values[0].type != OCONFIG_TYPE_STRING ||
 +                child->values[1].type != OCONFIG_TYPE_STRING) {
 +                WARNING("kafka properties needs string arguments.");
                  goto errout;
 -                      }
 -                      if ((key = strdup(child->values[0].value.string)) == NULL) {
 -                              WARNING("cannot allocate memory for attribute key.");
 +            }
 +            if ((key = strdup(child->values[0].value.string)) == NULL) {
 +                WARNING("cannot allocate memory for attribute key.");
                  goto errout;
 -                      }
 -                      if ((val = strdup(child->values[1].value.string)) == NULL) {
 -                              WARNING("cannot allocate memory for attribute value.");
 +            }
 +            if ((val = strdup(child->values[1].value.string)) == NULL) {
 +                WARNING("cannot allocate memory for attribute value.");
 +                sfree(key);
                  goto errout;
 -                      }
 +            }
              ret = rd_kafka_conf_set(conf, key, val, errbuf, sizeof(errbuf));
              if (ret != RD_KAFKA_CONF_OK) {
                  WARNING("cannot set kafka property %s to %s: %s",
                          key, val, errbuf);
 +                sfree(key);
 +                sfree(val);
                  goto errout;
              }
 -                      sfree(key);
 -                      sfree(val);
 -              } else {
 -                      WARNING ("write_kafka plugin: Ignoring unknown "
 -                               "configuration option \"%s\" at top level.",
 -                               child->key);
 -              }
 -      }
 +            sfree(key);
 +            sfree(val);
 +        } else {
 +            WARNING ("write_kafka plugin: Ignoring unknown "
 +                 "configuration option \"%s\" at top level.",
 +                 child->key);
 +        }
 +    }
      if (conf != NULL)
          rd_kafka_conf_destroy(conf);
      return (0);
  
  void module_register(void)
  {
 -      plugin_register_complex_config ("write_kafka", kafka_config);
 +    plugin_register_complex_config ("write_kafka", kafka_config);
  }
 -
 -/* vim: set sw=8 sts=8 ts=8 noet : */
diff --combined src/write_riemann.c
@@@ -2,7 -2,6 +2,7 @@@
   * collectd - src/write_riemann.c
   * Copyright (C) 2012,2013  Pierre-Yves Ritschard
   * Copyright (C) 2013       Florian octo Forster
 + * Copyright (C) 2015,2016  Gergely Nagy
   *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * Authors:
   *   Pierre-Yves Ritschard <pyr at spootnik.org>
   *   Florian octo Forster <octo at collectd.org>
 + *   Gergely Nagy <algernon at madhouse-project.org>
   */
  
  #include "collectd.h"
  
 -#include "plugin.h"
  #include "common.h"
 -#include "configfile.h"
 +#include "plugin.h"
  #include "utils_cache.h"
 -#include "riemann.pb-c.h"
 +#include "utils_complain.h"
  #include "write_riemann_threshold.h"
  
- #include <errno.h>
 -#include <sys/socket.h>
 -#include <arpa/inet.h>
 -#include <netdb.h>
 +#include <riemann/riemann-client.h>
  
 -#define RIEMANN_HOST          "localhost"
 -#define RIEMANN_PORT          "5555"
 -#define RIEMANN_TTL_FACTOR    2.0
 -#define RIEMANN_BATCH_MAX     8192
 +#define RIEMANN_HOST "localhost"
 +#define RIEMANN_PORT 5555
 +#define RIEMANN_TTL_FACTOR 2.0
 +#define RIEMANN_BATCH_MAX 8192
  
  struct riemann_host {
 -      char                    *name;
 -      char                    *event_service_prefix;
 -#define F_CONNECT      0x01
 -      uint8_t                  flags;
 -      pthread_mutex_t  lock;
 -    _Bool            batch_mode;
 -      _Bool            notifications;
 -      _Bool            check_thresholds;
 -      _Bool                    store_rates;
 -      _Bool                    always_append_ds;
 -      char                    *node;
 -      char                    *service;
 -      _Bool                    use_tcp;
 -      int                          s;
 -      double                   ttl_factor;
 -    Msg             *batch_msg;
 -    cdtime_t         batch_init;
 -    int              batch_max;
 -      int                          reference_count;
 +  c_complain_t init_complaint;
 +  char *name;
 +  char *event_service_prefix;
 +  pthread_mutex_t lock;
 +  _Bool batch_mode;
 +  _Bool notifications;
 +  _Bool check_thresholds;
 +  _Bool store_rates;
 +  _Bool always_append_ds;
 +  char *node;
 +  int port;
 +  riemann_client_type_t client_type;
 +  riemann_client_t *client;
 +  double ttl_factor;
 +  cdtime_t batch_init;
 +  int batch_max;
 +  int batch_timeout;
 +  int reference_count;
 +  riemann_message_t *batch_msg;
 +  char *tls_ca_file;
 +  char *tls_cert_file;
 +  char *tls_key_file;
 +  struct timeval timeout;
  };
  
 -static char   **riemann_tags;
 -static size_t   riemann_tags_num;
 -static char   **riemann_attrs;
 -static size_t     riemann_attrs_num;
 -
 -static void riemann_event_protobuf_free (Event *event) /* {{{ */
 -{
 -      size_t i;
 -
 -      if (event == NULL)
 -              return;
 -
 -      sfree (event->state);
 -      sfree (event->service);
 -      sfree (event->host);
 -      sfree (event->description);
 -
 -      strarray_free (event->tags, event->n_tags);
 -      event->tags = NULL;
 -      event->n_tags = 0;
 -
 -      for (i = 0; i < event->n_attributes; i++)
 -      {
 -              sfree (event->attributes[i]->key);
 -              sfree (event->attributes[i]->value);
 -              sfree (event->attributes[i]);
 -      }
 -      sfree (event->attributes);
 -      event->n_attributes = 0;
 -
 -      sfree (event);
 -} /* }}} void riemann_event_protobuf_free */
 -
 -static void riemann_msg_protobuf_free(Msg *msg) /* {{{ */
 -{
 -      size_t i;
 -
 -      if (msg == NULL)
 -              return;
 -
 -      for (i = 0; i < msg->n_events; i++)
 -      {
 -              riemann_event_protobuf_free (msg->events[i]);
 -              msg->events[i] = NULL;
 -      }
 -
 -      sfree (msg->events);
 -      msg->n_events = 0;
 -
 -      sfree (msg);
 -} /* }}} void riemann_msg_protobuf_free */
 +static char **riemann_tags;
 +static size_t riemann_tags_num;
 +static char **riemann_attrs;
 +static size_t riemann_attrs_num;
  
  /* host->lock must be held when calling this function. */
 -static int riemann_connect(struct riemann_host *host) /* {{{ */
 +static int wrr_connect(struct riemann_host *host) /* {{{ */
  {
 -      int                      e;
 -      struct addrinfo         *ai, *res, hints;
 -      char const              *node;
 -      char const              *service;
 -
 -      if (host->flags & F_CONNECT)
 -              return 0;
 -
 -      memset(&hints, 0, sizeof(hints));
 -      memset(&service, 0, sizeof(service));
 -      hints.ai_family = AF_UNSPEC;
 -      hints.ai_socktype = host->use_tcp ? SOCK_STREAM : SOCK_DGRAM;
 -#ifdef AI_ADDRCONFIG
 -      hints.ai_flags |= AI_ADDRCONFIG;
 +  char const *node;
 +  int port;
 +
 +  if (host->client)
 +    return 0;
 +
 +  node = (host->node != NULL) ? host->node : RIEMANN_HOST;
 +  port = (host->port) ? host->port : RIEMANN_PORT;
 +
 +  host->client = NULL;
 +
 +  host->client = riemann_client_create(
 +      host->client_type, node, port, RIEMANN_CLIENT_OPTION_TLS_CA_FILE,
 +      host->tls_ca_file, RIEMANN_CLIENT_OPTION_TLS_CERT_FILE,
 +      host->tls_cert_file, RIEMANN_CLIENT_OPTION_TLS_KEY_FILE,
 +      host->tls_key_file, RIEMANN_CLIENT_OPTION_NONE);
 +  if (host->client == NULL) {
 +    c_complain(LOG_ERR, &host->init_complaint,
 +               "write_riemann plugin: Unable to connect to Riemann at %s:%d",
 +               node, port);
 +    return -1;
 +  }
 +#if RCC_VERSION_NUMBER >= 0x010800
 +  if (host->timeout.tv_sec != 0) {
 +    if (riemann_client_set_timeout(host->client, &host->timeout) != 0) {
 +      riemann_client_free(host->client);
 +      host->client = NULL;
 +      c_complain(LOG_ERR, &host->init_complaint,
 +                 "write_riemann plugin: Unable to connect to Riemann at %s:%d",
 +                 node, port);
 +      return -1;
 +    }
 +  }
  #endif
  
 -      node = (host->node != NULL) ? host->node : RIEMANN_HOST;
 -      service = (host->service != NULL) ? host->service : RIEMANN_PORT;
 -
 -      if ((e = getaddrinfo(node, service, &hints, &res)) != 0) {
 -              ERROR ("write_riemann plugin: Unable to resolve host \"%s\": %s",
 -                      node, gai_strerror(e));
 -              return -1;
 -      }
 -
 -      host->s = -1;
 -      for (ai = res; ai != NULL; ai = ai->ai_next) {
 -              if ((host->s = socket(ai->ai_family,
 -                                    ai->ai_socktype,
 -                                    ai->ai_protocol)) == -1) {
 -                      continue;
 -              }
 -
 -              if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) {
 -                      close(host->s);
 -                      host->s = -1;
 -                      continue;
 -              }
 -
 -              host->flags |= F_CONNECT;
 -              DEBUG("write_riemann plugin: got a successful connection for: %s:%s",
 -                              node, service);
 -              break;
 -      }
 -
 -      freeaddrinfo(res);
 -
 -      if (host->s < 0) {
 -              WARNING("write_riemann plugin: Unable to connect to Riemann at %s:%s",
 -                              node, service);
 -              return -1;
 -      }
 -      return 0;
 -} /* }}} int riemann_connect */
 +  set_sock_opts(riemann_client_get_fd(host->client));
 +
 +  c_release(LOG_INFO, &host->init_complaint,
 +            "write_riemann plugin: Successfully connected to %s:%d", node,
 +            port);
 +
 +  return 0;
 +} /* }}} int wrr_connect */
  
  /* host->lock must be held when calling this function. */
 -static int riemann_disconnect (struct riemann_host *host) /* {{{ */
 +static int wrr_disconnect(struct riemann_host *host) /* {{{ */
  {
 -      if ((host->flags & F_CONNECT) == 0)
 -              return (0);
 +  if (!host->client)
 +    return (0);
  
 -      close (host->s);
 -      host->s = -1;
 -      host->flags &= ~F_CONNECT;
 +  riemann_client_free(host->client);
 +  host->client = NULL;
  
 -      return (0);
 -} /* }}} int riemann_disconnect */
 +  return (0);
 +} /* }}} int wrr_disconnect */
  
 -static int riemann_send_msg (struct riemann_host *host, const Msg *msg) /* {{{ */
 -{
 -      int status = 0;
 -      u_char *buffer = NULL;
 -      size_t  buffer_len;
 -
 -      status = riemann_connect (host);
 -      if (status != 0)
 -              return status;
 -
 -      buffer_len = msg__get_packed_size(msg);
 -
 -      if (host->use_tcp)
 -              buffer_len += 4;
 -
 -      buffer = malloc (buffer_len);
 -      if (buffer == NULL) {
 -              ERROR ("write_riemann plugin: malloc failed.");
 -              return ENOMEM;
 -      }
 -      memset (buffer, 0, buffer_len);
 -
 -      if (host->use_tcp)
 -      {
 -              uint32_t length = htonl ((uint32_t) (buffer_len - 4));
 -              memcpy (buffer, &length, 4);
 -              msg__pack(msg, buffer + 4);
 -      }
 -      else
 -      {
 -              msg__pack(msg, buffer);
 -      }
 -
 -      status = (int) swrite (host->s, buffer, buffer_len);
 -      if (status != 0)
 -      {
 -              char errbuf[1024];
 -              ERROR ("write_riemann plugin: Sending to Riemann at %s:%s failed: %s",
 -                              (host->node != NULL) ? host->node : RIEMANN_HOST,
 -                              (host->service != NULL) ? host->service : RIEMANN_PORT,
 -                              sstrerror (errno, errbuf, sizeof (errbuf)));
 -              sfree (buffer);
 -              return -1;
 -      }
 -
 -      sfree (buffer);
 -      return 0;
 -} /* }}} int riemann_send_msg */
 -
 -static int riemann_recv_ack(struct riemann_host *host) /* {{{ */
 +/**
 + * Function to send messages to riemann.
 + *
 + * Acquires the host lock, disconnects on errors.
 + */
 +static int wrr_send_nolock(struct riemann_host *host,
 +                           riemann_message_t *msg) /* {{{ */
  {
 -      int status = 0;
 -      Msg *msg = NULL;
 -      uint32_t header;
 +  int status = 0;
  
 -      status = (int) sread (host->s, &header, 4);
 +  status = wrr_connect(host);
 +  if (status != 0) {
 +    return status;
 +  }
  
 -      if (status != 0)
 -              return -1;
 +  status = riemann_client_send_message(host->client, msg);
 +  if (status != 0) {
 +    wrr_disconnect(host);
 +    return status;
 +  }
  
 -      size_t size = ntohl(header);
 +  /*
 +   * For TCP we need to receive message acknowledgemenent.
 +   */
 +  if (host->client_type != RIEMANN_CLIENT_UDP) {
 +    riemann_message_t *response;
  
 -      // Buffer on the stack since acknowledges are typically small.
 -      u_char buffer[size];
 -      memset (buffer, 0, size);
 +    response = riemann_client_recv_message(host->client);
  
 -      status = (int) sread (host->s, buffer, size);
 +    if (response == NULL) {
 +      wrr_disconnect(host);
 +      return errno;
 +    }
 +    riemann_message_free(response);
 +  }
  
 -      if (status != 0)
 -              return status;
 +  return 0;
 +} /* }}} int wrr_send */
  
 -      msg = msg__unpack (NULL, size, buffer);
 +static int wrr_send(struct riemann_host *host, riemann_message_t *msg) {
 +  int status = 0;
  
 -      if (msg == NULL)
 -              return -1;
 +  pthread_mutex_lock(&host->lock);
 +  status = wrr_send_nolock(host, msg);
 +  pthread_mutex_unlock(&host->lock);
 +  return status;
 +}
  
 -      if (!msg->ok)
 -      {
 -              ERROR ("write_riemann plugin: Sending to Riemann at %s:%s acknowledgement message reported error: %s",
 -                              (host->node != NULL) ? host->node : RIEMANN_HOST,
 -                              (host->service != NULL) ? host->service : RIEMANN_PORT,
 -                              msg->error);
 +static riemann_message_t *
 +wrr_notification_to_message(struct riemann_host *host, /* {{{ */
 +                            notification_t const *n) {
 +  riemann_message_t *msg;
 +  riemann_event_t *event;
 +  char service_buffer[6 * DATA_MAX_NAME_LEN];
 +  char const *severity;
 +
 +  switch (n->severity) {
 +  case NOTIF_OKAY:
 +    severity = "ok";
 +    break;
 +  case NOTIF_WARNING:
 +    severity = "warning";
 +    break;
 +  case NOTIF_FAILURE:
 +    severity = "critical";
 +    break;
 +  default:
 +    severity = "unknown";
 +  }
 +
 +  format_name(service_buffer, sizeof(service_buffer),
 +              /* host = */ "", n->plugin, n->plugin_instance, n->type,
 +              n->type_instance);
 +
 +  event = riemann_event_create(
 +      RIEMANN_EVENT_FIELD_HOST, n->host, RIEMANN_EVENT_FIELD_TIME,
 +      (int64_t)CDTIME_T_TO_TIME_T(n->time), RIEMANN_EVENT_FIELD_TAGS,
 +      "notification", NULL, RIEMANN_EVENT_FIELD_STATE, severity,
 +      RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
 +      RIEMANN_EVENT_FIELD_NONE);
 +
 +  if (n->host[0] != 0)
 +    riemann_event_string_attribute_add(event, "host", n->host);
 +  if (n->plugin[0] != 0)
 +    riemann_event_string_attribute_add(event, "plugin", n->plugin);
 +  if (n->plugin_instance[0] != 0)
 +    riemann_event_string_attribute_add(event, "plugin_instance",
 +                                       n->plugin_instance);
 +
 +  if (n->type[0] != 0)
 +    riemann_event_string_attribute_add(event, "type", n->type);
 +  if (n->type_instance[0] != 0)
 +    riemann_event_string_attribute_add(event, "type_instance",
 +                                       n->type_instance);
 +
 +  for (size_t i = 0; i < riemann_attrs_num; i += 2)
 +    riemann_event_string_attribute_add(event, riemann_attrs[i],
 +                                       riemann_attrs[i + 1]);
 +
 +  for (size_t i = 0; i < riemann_tags_num; i++)
 +    riemann_event_tag_add(event, riemann_tags[i]);
 +
 +  if (n->message[0] != 0)
 +    riemann_event_string_attribute_add(event, "description", n->message);
 +
 +  /* Pull in values from threshold and add extra attributes */
 +  for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) {
 +    if (strcasecmp("CurrentValue", meta->name) == 0 &&
 +        meta->type == NM_TYPE_DOUBLE) {
 +      riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
 +                        (double)meta->nm_value.nm_double,
 +                        RIEMANN_EVENT_FIELD_NONE);
 +      continue;
 +    }
  
 -              msg__free_unpacked(msg, NULL);
 -              return -1;
 -      }
 +    if (meta->type == NM_TYPE_STRING) {
 +      riemann_event_string_attribute_add(event, meta->name,
 +                                         meta->nm_value.nm_string);
 +      continue;
 +    }
 +  }
 +
 +  msg = riemann_message_create_with_events(event, NULL);
 +  if (msg == NULL) {
 +    ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
 +    riemann_event_free(event);
 +    return (NULL);
 +  }
 +
 +  DEBUG("write_riemann plugin: Successfully created message for notification: "
 +        "host = \"%s\", service = \"%s\", state = \"%s\"",
 +        event->host, event->service, event->state);
 +  return (msg);
 +} /* }}} riemann_message_t *wrr_notification_to_message */
 +
 +static riemann_event_t *
 +wrr_value_to_event(struct riemann_host const *host, /* {{{ */
 +                   data_set_t const *ds, value_list_t const *vl, size_t index,
 +                   gauge_t const *rates, int status) {
 +  riemann_event_t *event;
 +  char name_buffer[5 * DATA_MAX_NAME_LEN];
 +  char service_buffer[6 * DATA_MAX_NAME_LEN];
 +  size_t i;
 +
 +  event = riemann_event_new();
 +  if (event == NULL) {
 +    ERROR("write_riemann plugin: riemann_event_new() failed.");
 +    return (NULL);
 +  }
 +
 +  format_name(name_buffer, sizeof(name_buffer),
 +              /* host = */ "", vl->plugin, vl->plugin_instance, vl->type,
 +              vl->type_instance);
 +  if (host->always_append_ds || (ds->ds_num > 1)) {
 +    if (host->event_service_prefix == NULL)
 +      ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
 +                &name_buffer[1], ds->ds[index].name);
 +    else
 +      ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
 +                host->event_service_prefix, &name_buffer[1],
 +                ds->ds[index].name);
 +  } else {
 +    if (host->event_service_prefix == NULL)
 +      sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
 +    else
 +      ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
 +                host->event_service_prefix, &name_buffer[1]);
 +  }
 +
 +  riemann_event_set(
 +      event, RIEMANN_EVENT_FIELD_HOST, vl->host, RIEMANN_EVENT_FIELD_TIME,
 +      (int64_t)CDTIME_T_TO_TIME_T(vl->time), RIEMANN_EVENT_FIELD_TTL,
 +      (float)CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
 +      RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES, "plugin", vl->plugin, "type",
 +      vl->type, "ds_name", ds->ds[index].name, NULL,
 +      RIEMANN_EVENT_FIELD_SERVICE, service_buffer, RIEMANN_EVENT_FIELD_NONE);
 +
 +  if (host->check_thresholds) {
 +    const char *state = NULL;
 +
 +    switch (status) {
 +    case STATE_OKAY:
 +      state = "ok";
 +      break;
 +    case STATE_ERROR:
 +      state = "critical";
 +      break;
 +    case STATE_WARNING:
 +      state = "warning";
 +      break;
 +    case STATE_MISSING:
 +      state = "unknown";
 +      break;
 +    }
 +    if (state)
 +      riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
 +                        RIEMANN_EVENT_FIELD_NONE);
 +  }
 +
 +  if (vl->plugin_instance[0] != 0)
 +    riemann_event_string_attribute_add(event, "plugin_instance",
 +                                       vl->plugin_instance);
 +  if (vl->type_instance[0] != 0)
 +    riemann_event_string_attribute_add(event, "type_instance",
 +                                       vl->type_instance);
 +
 +  if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
 +    char ds_type[DATA_MAX_NAME_LEN];
 +
 +    ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
 +              DS_TYPE_TO_STRING(ds->ds[index].type));
 +    riemann_event_string_attribute_add(event, "ds_type", ds_type);
 +  } else {
 +    riemann_event_string_attribute_add(event, "ds_type",
 +                                       DS_TYPE_TO_STRING(ds->ds[index].type));
 +  }
 +
 +  {
 +    char ds_index[DATA_MAX_NAME_LEN];
 +
 +    ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
 +    riemann_event_string_attribute_add(event, "ds_index", ds_index);
 +  }
 +
 +  for (i = 0; i < riemann_attrs_num; i += 2)
 +    riemann_event_string_attribute_add(event, riemann_attrs[i],
 +                                       riemann_attrs[i + 1]);
 +
 +  for (i = 0; i < riemann_tags_num; i++)
 +    riemann_event_tag_add(event, riemann_tags[i]);
 +
 +  if (ds->ds[index].type == DS_TYPE_GAUGE) {
 +    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
 +                      (double)vl->values[index].gauge,
 +                      RIEMANN_EVENT_FIELD_NONE);
 +  } else if (rates != NULL) {
 +    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)rates[index],
 +                      RIEMANN_EVENT_FIELD_NONE);
 +  } else {
 +    int64_t metric;
 +
 +    if (ds->ds[index].type == DS_TYPE_DERIVE)
 +      metric = (int64_t)vl->values[index].derive;
 +    else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
 +      metric = (int64_t)vl->values[index].absolute;
 +    else
 +      metric = (int64_t)vl->values[index].counter;
 +
 +    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_S64, (int64_t)metric,
 +                      RIEMANN_EVENT_FIELD_NONE);
 +  }
 +
 +  DEBUG("write_riemann plugin: Successfully created message for metric: "
 +        "host = \"%s\", service = \"%s\"",
 +        event->host, event->service);
 +  return (event);
 +} /* }}} riemann_event_t *wrr_value_to_event */
 +
 +static riemann_message_t *
 +wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */
 +                          data_set_t const *ds, value_list_t const *vl,
 +                          int *statuses) {
 +  riemann_message_t *msg;
 +  size_t i;
 +  gauge_t *rates = NULL;
 +
 +  /* Initialize the Msg structure. */
 +  msg = riemann_message_new();
 +  if (msg == NULL) {
 +    ERROR("write_riemann plugin: riemann_message_new failed.");
 +    return (NULL);
 +  }
 +
 +  if (host->store_rates) {
 +    rates = uc_get_rate(ds, vl);
 +    if (rates == NULL) {
 +      ERROR("write_riemann plugin: uc_get_rate failed.");
 +      riemann_message_free(msg);
 +      return (NULL);
 +    }
 +  }
  
 -      msg__free_unpacked (msg, NULL);
 -      return 0;
 -} /* }}} int riemann_recv_ack */
 +  for (i = 0; i < vl->values_len; i++) {
 +    riemann_event_t *event;
  
 -/**
 - * Function to send messages (Msg) to riemann.
 - *
 - * Acquires the host lock, disconnects on errors.
 - */
 -static int riemann_send(struct riemann_host *host, Msg const *msg) /* {{{ */
 -{
 -      int status = 0;
 -      pthread_mutex_lock (&host->lock);
 -
 -      status = riemann_send_msg(host, msg);
 -      if (status != 0) {
 -              riemann_disconnect (host);
 -              pthread_mutex_unlock (&host->lock);
 -              return status;
 -      }
 -
 -      /*
 -       * For TCP we need to receive message acknowledgemenent.
 -       */
 -      if (host->use_tcp)
 -      {
 -              status = riemann_recv_ack(host);
 -
 -              if (status != 0)
 -              {
 -                      riemann_disconnect (host);
 -                      pthread_mutex_unlock (&host->lock);
 -                      return status;
 -              }
 -      }
 -
 -      pthread_mutex_unlock (&host->lock);
 -      return 0;
 -} /* }}} int riemann_send */
 -
 -static int riemann_event_add_tag (Event *event, char const *tag) /* {{{ */
 -{
 -      return (strarray_add (&event->tags, &event->n_tags, tag));
 -} /* }}} int riemann_event_add_tag */
 -
 -static int riemann_event_add_attribute(Event *event, /* {{{ */
 -              char const *key, char const *value)
 -{
 -      Attribute **new_attributes;
 -      Attribute *a;
 -
 -      new_attributes = realloc (event->attributes,
 -                      sizeof (*event->attributes) * (event->n_attributes + 1));
 -      if (new_attributes == NULL)
 -      {
 -              ERROR ("write_riemann plugin: realloc failed.");
 -              return (ENOMEM);
 -      }
 -      event->attributes = new_attributes;
 -
 -      a = malloc (sizeof (*a));
 -      if (a == NULL)
 -      {
 -              ERROR ("write_riemann plugin: malloc failed.");
 -              return (ENOMEM);
 -      }
 -      attribute__init (a);
 -
 -      a->key = strdup (key);
 -      if (value != NULL)
 -              a->value = strdup (value);
 -
 -      event->attributes[event->n_attributes] = a;
 -      event->n_attributes++;
 -
 -      return (0);
 -} /* }}} int riemann_event_add_attribute */
 -
 -static Msg *riemann_notification_to_protobuf(struct riemann_host *host, /* {{{ */
 -              notification_t const *n)
 -{
 -      Msg *msg;
 -      Event *event;
 -      char service_buffer[6 * DATA_MAX_NAME_LEN];
 -      char const *severity;
 -      notification_meta_t *meta;
 -      int i;
 -
 -      msg = malloc (sizeof (*msg));
 -      if (msg == NULL)
 -      {
 -              ERROR ("write_riemann plugin: malloc failed.");
 -              return (NULL);
 -      }
 -      memset (msg, 0, sizeof (*msg));
 -      msg__init (msg);
 -
 -      msg->events = malloc (sizeof (*msg->events));
 -      if (msg->events == NULL)
 -      {
 -              ERROR ("write_riemann plugin: malloc failed.");
 -              sfree (msg);
 -              return (NULL);
 -      }
 -
 -      event = malloc (sizeof (*event));
 -      if (event == NULL)
 -      {
 -              ERROR ("write_riemann plugin: malloc failed.");
 -              sfree (msg->events);
 -              sfree (msg);
 -              return (NULL);
 -      }
 -      memset (event, 0, sizeof (*event));
 -      event__init (event);
 -
 -      msg->events[0] = event;
 -      msg->n_events = 1;
 -
 -      event->host = strdup (n->host);
 -      event->time = CDTIME_T_TO_TIME_T (n->time);
 -      event->has_time = 1;
 -
 -      switch (n->severity)
 -      {
 -              case NOTIF_OKAY:        severity = "ok"; break;
 -              case NOTIF_WARNING:     severity = "warning"; break;
 -              case NOTIF_FAILURE:     severity = "critical"; break;
 -              default:                severity = "unknown";
 -      }
 -      event->state = strdup (severity);
 -
 -      riemann_event_add_tag (event, "notification");
 -      if (n->host[0] != 0)
 -              riemann_event_add_attribute (event, "host", n->host);
 -      if (n->plugin[0] != 0)
 -              riemann_event_add_attribute (event, "plugin", n->plugin);
 -      if (n->plugin_instance[0] != 0)
 -              riemann_event_add_attribute (event, "plugin_instance",
 -                              n->plugin_instance);
 -
 -      if (n->type[0] != 0)
 -              riemann_event_add_attribute (event, "type", n->type);
 -      if (n->type_instance[0] != 0)
 -              riemann_event_add_attribute (event, "type_instance",
 -                              n->type_instance);
 -
 -      for (i = 0; i < riemann_attrs_num; i += 2)
 -              riemann_event_add_attribute(event,
 -                                          riemann_attrs[i],
 -                                          riemann_attrs[i +1]);
 -
 -      for (i = 0; i < riemann_tags_num; i++)
 -              riemann_event_add_tag (event, riemann_tags[i]);
 -
 -      format_name (service_buffer, sizeof (service_buffer),
 -                      /* host = */ "", n->plugin, n->plugin_instance,
 -                      n->type, n->type_instance);
 -      event->service = strdup (&service_buffer[1]);
 -
 -      if (n->message[0] != 0)
 -              riemann_event_add_attribute (event, "description", n->message);
 -
 -      /* Pull in values from threshold and add extra attributes */
 -      for (meta = n->meta; meta != NULL; meta = meta->next)
 -      {
 -              if (strcasecmp ("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE)
 -              {
 -                      event->metric_d = meta->nm_value.nm_double;
 -                      event->has_metric_d = 1;
 -                      continue;
 -              }
 -
 -              if (meta->type == NM_TYPE_STRING) {
 -                      riemann_event_add_attribute (event, meta->name, meta->nm_value.nm_string);
 -                      continue;
 -              }
 -      }
 -
 -      DEBUG ("write_riemann plugin: Successfully created protobuf for notification: "
 -                      "host = \"%s\", service = \"%s\", state = \"%s\"",
 -                      event->host, event->service, event->state);
 -      return (msg);
 -} /* }}} Msg *riemann_notification_to_protobuf */
 -
 -static Event *riemann_value_to_protobuf(struct riemann_host const *host, /* {{{ */
 -              data_set_t const *ds,
 -              value_list_t const *vl, size_t index,
 -                                       gauge_t const *rates,
 -                                       int status)
 -{
 -      Event *event;
 -      char name_buffer[5 * DATA_MAX_NAME_LEN];
 -      char service_buffer[6 * DATA_MAX_NAME_LEN];
 -      double ttl;
 -      int i;
 -
 -      event = malloc (sizeof (*event));
 -      if (event == NULL)
 -      {
 -              ERROR ("write_riemann plugin: malloc failed.");
 -              return (NULL);
 -      }
 -      memset (event, 0, sizeof (*event));
 -      event__init (event);
 -
 -      event->host = strdup (vl->host);
 -      event->time = CDTIME_T_TO_TIME_T (vl->time);
 -      event->has_time = 1;
 -
 -      if (host->check_thresholds) {
 -              switch (status) {
 -                      case STATE_OKAY:
 -                              event->state = strdup("ok");
 -                              break;
 -                      case STATE_ERROR:
 -                              event->state = strdup("critical");
 -                              break;
 -                      case STATE_WARNING:
 -                              event->state = strdup("warning");
 -                              break;
 -                      case STATE_MISSING:
 -                              event->state = strdup("unknown");
 -                              break;
 -              }
 -      }
 -
 -      ttl = CDTIME_T_TO_DOUBLE (vl->interval) * host->ttl_factor;
 -      event->ttl = (float) ttl;
 -      event->has_ttl = 1;
 -
 -      riemann_event_add_attribute (event, "plugin", vl->plugin);
 -      if (vl->plugin_instance[0] != 0)
 -              riemann_event_add_attribute (event, "plugin_instance",
 -                              vl->plugin_instance);
 -
 -      riemann_event_add_attribute (event, "type", vl->type);
 -      if (vl->type_instance[0] != 0)
 -              riemann_event_add_attribute (event, "type_instance",
 -                              vl->type_instance);
 -
 -      if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL))
 -      {
 -              char ds_type[DATA_MAX_NAME_LEN];
 -
 -              ssnprintf (ds_type, sizeof (ds_type), "%s:rate",
 -                              DS_TYPE_TO_STRING(ds->ds[index].type));
 -              riemann_event_add_attribute (event, "ds_type", ds_type);
 -      }
 -      else
 -      {
 -              riemann_event_add_attribute (event, "ds_type",
 -                              DS_TYPE_TO_STRING(ds->ds[index].type));
 -      }
 -      riemann_event_add_attribute (event, "ds_name", ds->ds[index].name);
 -      {
 -              char ds_index[DATA_MAX_NAME_LEN];
 -
 -              ssnprintf (ds_index, sizeof (ds_index), "%zu", index);
 -              riemann_event_add_attribute (event, "ds_index", ds_index);
 -      }
 -
 -      for (i = 0; i < riemann_attrs_num; i += 2)
 -              riemann_event_add_attribute(event,
 -                                          riemann_attrs[i],
 -                                          riemann_attrs[i +1]);
 -
 -      for (i = 0; i < riemann_tags_num; i++)
 -              riemann_event_add_tag (event, riemann_tags[i]);
 -
 -      if (ds->ds[index].type == DS_TYPE_GAUGE)
 -      {
 -              event->has_metric_d = 1;
 -              event->metric_d = (double) vl->values[index].gauge;
 -      }
 -      else if (rates != NULL)
 -      {
 -              event->has_metric_d = 1;
 -              event->metric_d = (double) rates[index];
 -      }
 -      else
 -      {
 -              event->has_metric_sint64 = 1;
 -              if (ds->ds[index].type == DS_TYPE_DERIVE)
 -                      event->metric_sint64 = (int64_t) vl->values[index].derive;
 -              else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
 -                      event->metric_sint64 = (int64_t) vl->values[index].absolute;
 -              else
 -                      event->metric_sint64 = (int64_t) vl->values[index].counter;
 -      }
 -
 -      format_name (name_buffer, sizeof (name_buffer),
 -                      /* host = */ "", vl->plugin, vl->plugin_instance,
 -                      vl->type, vl->type_instance);
 -      if (host->always_append_ds || (ds->ds_num > 1))
 -      {
 -              if (host->event_service_prefix == NULL)
 -                      ssnprintf (service_buffer, sizeof (service_buffer), "%s/%s",
 -                                      &name_buffer[1], ds->ds[index].name);
 -              else
 -                      ssnprintf (service_buffer, sizeof (service_buffer), "%s%s/%s",
 -                                      host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
 -      }
 -      else
 -      {
 -              if (host->event_service_prefix == NULL)
 -                      sstrncpy (service_buffer, &name_buffer[1], sizeof (service_buffer));
 -              else
 -                      ssnprintf (service_buffer, sizeof (service_buffer), "%s%s",
 -                                      host->event_service_prefix, &name_buffer[1]);
 -      }
 -
 -      event->service = strdup (service_buffer);
 -
 -      DEBUG ("write_riemann plugin: Successfully created protobuf for metric: "
 -                      "host = \"%s\", service = \"%s\"",
 -                      event->host, event->service);
 -      return (event);
 -} /* }}} Event *riemann_value_to_protobuf */
 -
 -static Msg *riemann_value_list_to_protobuf (struct riemann_host const *host, /* {{{ */
 -                                          data_set_t const *ds,
 -                                          value_list_t const *vl,
 -                                          int *statuses)
 -{
 -      Msg *msg;
 -      size_t i;
 -      gauge_t *rates = NULL;
 -
 -      /* Initialize the Msg structure. */
 -      msg = malloc (sizeof (*msg));
 -      if (msg == NULL)
 -      {
 -              ERROR ("write_riemann plugin: malloc failed.");
 -              return (NULL);
 -      }
 -      memset (msg, 0, sizeof (*msg));
 -      msg__init (msg);
 -
 -      /* Set up events. First, the list of pointers. */
 -      msg->n_events = (size_t) vl->values_len;
 -      msg->events = calloc (msg->n_events, sizeof (*msg->events));
 -      if (msg->events == NULL)
 -      {
 -              ERROR ("write_riemann plugin: calloc failed.");
 -              riemann_msg_protobuf_free (msg);
 -              return (NULL);
 -      }
 -
 -      if (host->store_rates)
 -      {
 -              rates = uc_get_rate (ds, vl);
 -              if (rates == NULL)
 -              {
 -                      ERROR ("write_riemann plugin: uc_get_rate failed.");
 -                      riemann_msg_protobuf_free (msg);
 -                      return (NULL);
 -              }
 -      }
 -
 -      for (i = 0; i < msg->n_events; i++)
 -      {
 -              msg->events[i] = riemann_value_to_protobuf (host, ds, vl,
 -                                                          (int) i, rates, statuses[i]);
 -              if (msg->events[i] == NULL)
 -              {
 -                      riemann_msg_protobuf_free (msg);
 -                      sfree (rates);
 -                      return (NULL);
 -              }
 -      }
 -
 -      sfree (rates);
 -      return (msg);
 -} /* }}} Msg *riemann_value_list_to_protobuf */
 +    event = wrr_value_to_event(host, ds, vl, (int)i, rates, statuses[i]);
 +    if (event == NULL) {
 +      riemann_message_free(msg);
 +      sfree(rates);
 +      return (NULL);
 +    }
 +    riemann_message_append_events(msg, event, NULL);
 +  }
  
 +  sfree(rates);
 +  return (msg);
 +} /* }}} riemann_message_t *wrr_value_list_to_message */
  
  /*
   * Always call while holding host->lock !
   */
 -static int riemann_batch_flush_nolock (cdtime_t timeout,
 -                                       struct riemann_host *host)
 -{
 -    cdtime_t    now;
 -    int         status = 0;
 -
 -    if (timeout > 0) {
 -        now = cdtime ();
 -        if ((host->batch_init + timeout) > now)
 -            return status;
 +static int wrr_batch_flush_nolock(cdtime_t timeout, struct riemann_host *host) {
 +  cdtime_t now;
 +  int status = 0;
 +
 +  now = cdtime();
 +  if (timeout > 0) {
 +    if ((host->batch_init + timeout) > now) {
 +      return status;
      }
 -    riemann_send_msg(host, host->batch_msg);
 -    riemann_msg_protobuf_free(host->batch_msg);
 -
 -      if (host->use_tcp && ((status = riemann_recv_ack(host)) != 0))
 -        riemann_disconnect (host);
 +  }
 +  wrr_send_nolock(host, host->batch_msg);
 +  riemann_message_free(host->batch_msg);
  
 -    host->batch_init = cdtime();
 -    host->batch_msg = NULL;
 -    return status;
 +  host->batch_init = now;
 +  host->batch_msg = NULL;
 +  return status;
  }
  
 -static int riemann_batch_flush (cdtime_t timeout,
 -        const char *identifier __attribute__((unused)),
 -        user_data_t *user_data)
 -{
 -    struct riemann_host *host;
 -    int status;
 +static int wrr_batch_flush(cdtime_t timeout,
 +                           const char *identifier __attribute__((unused)),
 +                           user_data_t *user_data) {
 +  struct riemann_host *host;
 +  int status;
 +
 +  if (user_data == NULL)
 +    return (-EINVAL);
 +
 +  host = user_data->data;
 +  pthread_mutex_lock(&host->lock);
 +  status = wrr_batch_flush_nolock(timeout, host);
 +  if (status != 0)
 +    c_complain(
 +        LOG_ERR, &host->init_complaint,
 +        "write_riemann plugin: riemann_client_send failed with status %i",
 +        status);
 +  else
 +    c_release(LOG_DEBUG, &host->init_complaint,
 +              "write_riemann plugin: batch sent.");
 +
 +  pthread_mutex_unlock(&host->lock);
 +  return status;
 +}
  
 -    if (user_data == NULL)
 -        return (-EINVAL);
 +static int wrr_batch_add_value_list(struct riemann_host *host, /* {{{ */
 +                                    data_set_t const *ds,
 +                                    value_list_t const *vl, int *statuses) {
 +  riemann_message_t *msg;
 +  size_t len;
 +  int ret;
 +  cdtime_t timeout;
  
 -    host = user_data->data;
 -    pthread_mutex_lock (&host->lock);
 -    status = riemann_batch_flush_nolock (timeout, host);
 -    if (status != 0)
 -        ERROR ("write_riemann plugin: riemann_send failed with status %i",
 -               status);
 +  msg = wrr_value_list_to_message(host, ds, vl, statuses);
 +  if (msg == NULL)
 +    return -1;
  
 -    pthread_mutex_unlock(&host->lock);
 -    return status;
 -}
 +  pthread_mutex_lock(&host->lock);
  
 -static int riemann_batch_add_value_list (struct riemann_host *host, /* {{{ */
 -                                         data_set_t const *ds,
 -                                         value_list_t const *vl,
 -                                         int *statuses)
 -{
 -      size_t i;
 -    Event **events;
 -    Msg *msg;
 -    size_t len;
 -    int ret;
 +  if (host->batch_msg == NULL) {
 +    host->batch_msg = msg;
 +  } else {
 +    int status;
  
 -    msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
 -    if (msg == NULL)
 -        return -1;
 +    status = riemann_message_append_events_n(host->batch_msg, msg->n_events,
 +                                             msg->events);
 +    msg->n_events = 0;
 +    msg->events = NULL;
  
 -    pthread_mutex_lock(&host->lock);
 +    riemann_message_free(msg);
  
 -    if (host->batch_msg == NULL) {
 -        host->batch_msg = msg;
 -    } else {
 -        len = msg->n_events + host->batch_msg->n_events;
 -        events = realloc(host->batch_msg->events,
 -                         (len * sizeof(*host->batch_msg->events)));
 -        if (events == NULL) {
 -            pthread_mutex_unlock(&host->lock);
 -            ERROR ("write_riemann plugin: out of memory");
 -            riemann_msg_protobuf_free (msg);
 -            return -1;
 -        }
 -        host->batch_msg->events = events;
 -
 -        for (i = host->batch_msg->n_events; i < len; i++)
 -            host->batch_msg->events[i] = msg->events[i - host->batch_msg->n_events];
 -
 -        host->batch_msg->n_events = len;
 -        sfree (msg->events);
 -        msg->n_events = 0;
 -        sfree (msg);
 +    if (status != 0) {
 +      pthread_mutex_unlock(&host->lock);
 +      ERROR("write_riemann plugin: out of memory");
 +      return -1;
      }
 -
 -      len = msg__get_packed_size(host->batch_msg);
 -    ret = 0;
 -    if (len >= host->batch_max) {
 -        ret = riemann_batch_flush_nolock(0, host);
 +  }
 +
 +  len = riemann_message_get_packed_size(host->batch_msg);
 +  ret = 0;
 +  if ((host->batch_max < 0) || (((size_t)host->batch_max) <= len)) {
 +    ret = wrr_batch_flush_nolock(0, host);
 +  } else {
 +    if (host->batch_timeout > 0) {
 +      timeout = TIME_T_TO_CDTIME_T((time_t)host->batch_timeout);
 +      ret = wrr_batch_flush_nolock(timeout, host);
      }
 +  }
  
 -    pthread_mutex_unlock(&host->lock);
 -    return ret;
 -} /* }}} Msg *riemann_batch_add_value_list */
 -
 -static int riemann_notification(const notification_t *n, user_data_t *ud) /* {{{ */
 -{
 -      int                      status;
 -      struct riemann_host     *host = ud->data;
 -      Msg                     *msg;
 +  pthread_mutex_unlock(&host->lock);
 +  return ret;
 +} /* }}} riemann_message_t *wrr_batch_add_value_list */
  
 -      if (!host->notifications)
 -              return 0;
 -
 -    /*
 -     * Never batch for notifications, send them ASAP
 -     */
 -      msg = riemann_notification_to_protobuf (host, n);
 -      if (msg == NULL)
 -              return (-1);
 -
 -      status = riemann_send (host, msg);
 -      if (status != 0)
 -              ERROR ("write_riemann plugin: riemann_send failed with status %i",
 -                              status);
 -
 -      riemann_msg_protobuf_free (msg);
 -      return (status);
 -} /* }}} int riemann_notification */
 -
 -static int riemann_write(const data_set_t *ds, /* {{{ */
 -            const value_list_t *vl,
 -            user_data_t *ud)
 +static int wrr_notification(const notification_t *n, user_data_t *ud) /* {{{ */
  {
 -      int                      status = 0;
 -      int                      statuses[vl->values_len];
 -      struct riemann_host     *host = ud->data;
 -      Msg                     *msg;
 +  int status;
 +  struct riemann_host *host = ud->data;
 +  riemann_message_t *msg;
 +
 +  if (!host->notifications)
 +    return 0;
 +
 +  /*
 +   * Never batch for notifications, send them ASAP
 +   */
 +  msg = wrr_notification_to_message(host, n);
 +  if (msg == NULL)
 +    return (-1);
 +
 +  status = wrr_send(host, msg);
 +  if (status != 0)
 +    c_complain(
 +        LOG_ERR, &host->init_complaint,
 +        "write_riemann plugin: riemann_client_send failed with status %i",
 +        status);
 +  else
 +    c_release(LOG_DEBUG, &host->init_complaint,
 +              "write_riemann plugin: riemann_client_send succeeded");
 +
 +  riemann_message_free(msg);
 +  return (status);
 +} /* }}} int wrr_notification */
 +
 +static int wrr_write(const data_set_t *ds, /* {{{ */
 +                     const value_list_t *vl, user_data_t *ud) {
 +  int status = 0;
 +  int statuses[vl->values_len];
 +  struct riemann_host *host = ud->data;
 +  riemann_message_t *msg;
 +
 +  if (host->check_thresholds) {
 +    status = write_riemann_threshold_check(ds, vl, statuses);
 +    if (status != 0)
 +      return status;
 +  } else {
 +    memset(statuses, 0, sizeof(statuses));
 +  }
 +
 +  if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
 +    wrr_batch_add_value_list(host, ds, vl, statuses);
 +  } else {
 +    msg = wrr_value_list_to_message(host, ds, vl, statuses);
 +    if (msg == NULL)
 +      return (-1);
  
 -      if (host->check_thresholds)
 -              write_riemann_threshold_check(ds, vl, statuses);
 +    status = wrr_send(host, msg);
  
 -    if (host->use_tcp == 1 && host->batch_mode) {
 +    riemann_message_free(msg);
 +  }
 +  return status;
 +} /* }}} int wrr_write */
  
 -        riemann_batch_add_value_list (host, ds, vl, statuses);
 +static void wrr_free(void *p) /* {{{ */
 +{
 +  struct riemann_host *host = p;
  
 +  if (host == NULL)
 +    return;
  
 -    } else {
 +  pthread_mutex_lock(&host->lock);
  
 -        msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
 -        if (msg == NULL)
 -            return (-1);
 +  host->reference_count--;
 +  if (host->reference_count > 0) {
 +    pthread_mutex_unlock(&host->lock);
 +    return;
 +  }
  
 -        status = riemann_send (host, msg);
 -        if (status != 0)
 -            ERROR ("write_riemann plugin: riemann_send failed with status %i",
 -                   status);
 +  wrr_disconnect(host);
  
 -        riemann_msg_protobuf_free (msg);
 -    }
 -      return status;
 -} /* }}} int riemann_write */
 +  pthread_mutex_destroy(&host->lock);
 +  sfree(host);
 +} /* }}} void wrr_free */
  
 -static void riemann_free(void *p) /* {{{ */
 +static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
  {
 -      struct riemann_host     *host = p;
 -
 -      if (host == NULL)
 -              return;
 -
 -      pthread_mutex_lock (&host->lock);
 -
 -      host->reference_count--;
 -      if (host->reference_count > 0)
 -      {
 -              pthread_mutex_unlock (&host->lock);
 -              return;
 -      }
 +  struct riemann_host *host = NULL;
 +  int status = 0;
 +  int i;
 +  oconfig_item_t *child;
 +  char callback_name[DATA_MAX_NAME_LEN];
 +
 +  if ((host = calloc(1, sizeof(*host))) == NULL) {
 +    ERROR("write_riemann plugin: calloc failed.");
 +    return ENOMEM;
 +  }
 +  pthread_mutex_init(&host->lock, NULL);
 +  C_COMPLAIN_INIT(&host->init_complaint);
 +  host->reference_count = 1;
 +  host->node = NULL;
 +  host->port = 0;
 +  host->notifications = 1;
 +  host->check_thresholds = 0;
 +  host->store_rates = 1;
 +  host->always_append_ds = 0;
 +  host->batch_mode = 1;
 +  host->batch_max = RIEMANN_BATCH_MAX; /* typical MSS */
 +  host->batch_init = cdtime();
 +  host->batch_timeout = 0;
 +  host->ttl_factor = RIEMANN_TTL_FACTOR;
 +  host->client = NULL;
 +  host->client_type = RIEMANN_CLIENT_TCP;
 +  host->timeout.tv_sec = 0;
 +  host->timeout.tv_usec = 0;
 +
 +  status = cf_util_get_string(ci, &host->name);
 +  if (status != 0) {
 +    WARNING("write_riemann plugin: Required host name is missing.");
 +    wrr_free(host);
 +    return -1;
 +  }
 +
 +  for (i = 0; i < ci->children_num; i++) {
 +    /*
 +     * The code here could be simplified but makes room
 +     * for easy adding of new options later on.
 +     */
 +    child = &ci->children[i];
 +    status = 0;
 +
 +    if (strcasecmp("Host", child->key) == 0) {
 +      status = cf_util_get_string(child, &host->node);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("Notifications", child->key) == 0) {
 +      status = cf_util_get_boolean(child, &host->notifications);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("EventServicePrefix", child->key) == 0) {
 +      status = cf_util_get_string(child, &host->event_service_prefix);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("CheckThresholds", child->key) == 0) {
 +      status = cf_util_get_boolean(child, &host->check_thresholds);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("Batch", child->key) == 0) {
 +      status = cf_util_get_boolean(child, &host->batch_mode);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("BatchMaxSize", child->key) == 0) {
 +      status = cf_util_get_int(child, &host->batch_max);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("BatchFlushTimeout", child->key) == 0) {
 +      status = cf_util_get_int(child, &host->batch_timeout);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("Timeout", child->key) == 0) {
 +#if RCC_VERSION_NUMBER >= 0x010800
 +      status = cf_util_get_int(child, (int *)&host->timeout.tv_sec);
 +      if (status != 0)
 +        break;
 +#else
 +      WARNING("write_riemann plugin: The Timeout option is not supported. Please upgrade the Riemann client to at least 1.8.0.");
 +#endif
 +    } else if (strcasecmp("Port", child->key) == 0) {
 +      host->port = cf_util_get_port_number(child);
 +      if (host->port == -1) {
 +        ERROR("write_riemann plugin: Invalid argument "
 +              "configured for the \"Port\" "
 +              "option.");
 +        break;
 +      }
 +    } else if (strcasecmp("Protocol", child->key) == 0) {
 +      char tmp[16];
 +      status = cf_util_get_string_buffer(child, tmp, sizeof(tmp));
 +      if (status != 0) {
 +        ERROR("write_riemann plugin: cf_util_get_"
 +              "string_buffer failed with "
 +              "status %i.",
 +              status);
 +        break;
 +      }
 +
 +      if (strcasecmp("UDP", tmp) == 0)
 +        host->client_type = RIEMANN_CLIENT_UDP;
 +      else if (strcasecmp("TCP", tmp) == 0)
 +        host->client_type = RIEMANN_CLIENT_TCP;
 +      else if (strcasecmp("TLS", tmp) == 0)
 +        host->client_type = RIEMANN_CLIENT_TLS;
 +      else
 +        WARNING("write_riemann plugin: The value "
 +                "\"%s\" is not valid for the "
 +                "\"Protocol\" option. Use "
 +                "either \"UDP\", \"TCP\" or \"TLS\".",
 +                tmp);
 +    } else if (strcasecmp("TLSCAFile", child->key) == 0) {
 +      status = cf_util_get_string(child, &host->tls_ca_file);
 +      if (status != 0) {
 +        ERROR("write_riemann plugin: cf_util_get_"
 +              "string_buffer failed with "
 +              "status %i.",
 +              status);
 +        break;
 +      }
 +    } else if (strcasecmp("TLSCertFile", child->key) == 0) {
 +      status = cf_util_get_string(child, &host->tls_cert_file);
 +      if (status != 0) {
 +        ERROR("write_riemann plugin: cf_util_get_"
 +              "string_buffer failed with "
 +              "status %i.",
 +              status);
 +        break;
 +      }
 +    } else if (strcasecmp("TLSKeyFile", child->key) == 0) {
 +      status = cf_util_get_string(child, &host->tls_key_file);
 +      if (status != 0) {
 +        ERROR("write_riemann plugin: cf_util_get_"
 +              "string_buffer failed with "
 +              "status %i.",
 +              status);
 +        break;
 +      }
 +    } else if (strcasecmp("StoreRates", child->key) == 0) {
 +      status = cf_util_get_boolean(child, &host->store_rates);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("AlwaysAppendDS", child->key) == 0) {
 +      status = cf_util_get_boolean(child, &host->always_append_ds);
 +      if (status != 0)
 +        break;
 +    } else if (strcasecmp("TTLFactor", child->key) == 0) {
 +      double tmp = NAN;
 +      status = cf_util_get_double(child, &tmp);
 +      if (status != 0)
 +        break;
 +      if (tmp >= 2.0) {
 +        host->ttl_factor = tmp;
 +      } else if (tmp >= 1.0) {
 +        NOTICE("write_riemann plugin: The configured "
 +               "TTLFactor is very small "
 +               "(%.1f). A value of 2.0 or "
 +               "greater is recommended.",
 +               tmp);
 +        host->ttl_factor = tmp;
 +      } else if (tmp > 0.0) {
 +        WARNING("write_riemann plugin: The configured "
 +                "TTLFactor is too small to be "
 +                "useful (%.1f). I'll use it "
 +                "since the user knows best, "
 +                "but under protest.",
 +                tmp);
 +        host->ttl_factor = tmp;
 +      } else { /* zero, negative and NAN */
 +        ERROR("write_riemann plugin: The configured "
 +              "TTLFactor is invalid (%.1f).",
 +              tmp);
 +      }
 +    } else {
 +      WARNING("write_riemann plugin: ignoring unknown config "
 +              "option: \"%s\"",
 +              child->key);
 +    }
 +  }
 +  if (status != 0) {
 +    wrr_free(host);
 +    return status;
 +  }
 +
 +  ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
 +            host->name);
 +
 +  user_data_t ud = {
 +    .data = host,
 +    .free_func = wrr_free
 +  };
 +
 +  pthread_mutex_lock(&host->lock);
 +
 +  status = plugin_register_write(callback_name, wrr_write, &ud);
 +
 +  if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
 +    ud.free_func = NULL;
 +    plugin_register_flush(callback_name, wrr_batch_flush, &ud);
 +  }
 +  if (status != 0)
 +    WARNING("write_riemann plugin: plugin_register_write (\"%s\") "
 +            "failed with status %i.",
 +            callback_name, status);
 +  else /* success */
 +    host->reference_count++;
 +
 +  status = plugin_register_notification(callback_name, wrr_notification, &ud);
 +  if (status != 0)
 +    WARNING("write_riemann plugin: plugin_register_notification (\"%s\") "
 +            "failed with status %i.",
 +            callback_name, status);
 +  else /* success */
 +    host->reference_count++;
 +
 +  if (host->reference_count <= 1) {
 +    /* Both callbacks failed => free memory.
 +     * We need to unlock here, because riemann_free() will lock.
 +     * This is not a race condition, because we're the only one
 +     * holding a reference. */
 +    pthread_mutex_unlock(&host->lock);
 +    wrr_free(host);
 +    return (-1);
 +  }
  
 -      riemann_disconnect (host);
 +  host->reference_count--;
 +  pthread_mutex_unlock(&host->lock);
  
 -      sfree(host->service);
 -      pthread_mutex_destroy (&host->lock);
 -      sfree(host);
 -} /* }}} void riemann_free */
 +  return status;
 +} /* }}} int wrr_config_node */
  
 -static int riemann_config_node(oconfig_item_t *ci) /* {{{ */
 +static int wrr_config(oconfig_item_t *ci) /* {{{ */
  {
 -      struct riemann_host     *host = NULL;
 -      int                      status = 0;
 -      int                      i;
 -      oconfig_item_t          *child;
 -      char                     callback_name[DATA_MAX_NAME_LEN];
 -      user_data_t              ud;
 -
 -      if ((host = calloc(1, sizeof (*host))) == NULL) {
 -              ERROR ("write_riemann plugin: calloc failed.");
 -              return ENOMEM;
 -      }
 -      pthread_mutex_init (&host->lock, NULL);
 -      host->reference_count = 1;
 -      host->node = NULL;
 -      host->service = NULL;
 -      host->notifications = 1;
 -      host->check_thresholds = 0;
 -      host->store_rates = 1;
 -      host->always_append_ds = 0;
 -      host->use_tcp = 1;
 -      host->batch_mode = 1;
 -      host->batch_max = RIEMANN_BATCH_MAX; /* typical MSS */
 -      host->batch_init = cdtime();
 -      host->ttl_factor = RIEMANN_TTL_FACTOR;
 -
 -      status = cf_util_get_string (ci, &host->name);
 -      if (status != 0) {
 -              WARNING("write_riemann plugin: Required host name is missing.");
 -              riemann_free (host);
 -              return -1;
 -      }
 -
 -      for (i = 0; i < ci->children_num; i++) {
 -              /*
 -               * The code here could be simplified but makes room
 -               * for easy adding of new options later on.
 -               */
 -              child = &ci->children[i];
 -              status = 0;
 -
 -              if (strcasecmp ("Host", child->key) == 0) {
 -                      status = cf_util_get_string (child, &host->node);
 -                      if (status != 0)
 -                              break;
 -              } else if (strcasecmp ("Notifications", child->key) == 0) {
 -                      status = cf_util_get_boolean(child, &host->notifications);
 -                      if (status != 0)
 -                              break;
 -              } else if (strcasecmp ("EventServicePrefix", child->key) == 0) {
 -                      status = cf_util_get_string (child, &host->event_service_prefix);
 -                      if (status != 0)
 -                              break;
 -              } else if (strcasecmp ("CheckThresholds", child->key) == 0) {
 -                      status = cf_util_get_boolean(child, &host->check_thresholds);
 -                      if (status != 0)
 -                              break;
 -        } else if (strcasecmp ("Batch", child->key) == 0) {
 -            status = cf_util_get_boolean(child, &host->batch_mode);
 -            if (status != 0)
 -                break;
 -        } else if (strcasecmp("BatchMaxSize", child->key) == 0) {
 -            status = cf_util_get_int(child, &host->batch_max);
 -            if (status != 0)
 -                break;
 -              } else if (strcasecmp ("Port", child->key) == 0) {
 -                      status = cf_util_get_service (child, &host->service);
 -                      if (status != 0) {
 -                              ERROR ("write_riemann plugin: Invalid argument "
 -                                              "configured for the \"Port\" "
 -                                              "option.");
 -                              break;
 -                      }
 -              } else if (strcasecmp ("Protocol", child->key) == 0) {
 -                      char tmp[16];
 -                      status = cf_util_get_string_buffer (child,
 -                                      tmp, sizeof (tmp));
 -                      if (status != 0)
 -                      {
 -                              ERROR ("write_riemann plugin: cf_util_get_"
 -                                              "string_buffer failed with "
 -                                              "status %i.", status);
 -                              break;
 -                      }
 -
 -                      if (strcasecmp ("UDP", tmp) == 0)
 -                              host->use_tcp = 0;
 -                      else if (strcasecmp ("TCP", tmp) == 0)
 -                              host->use_tcp = 1;
 -                      else
 -                              WARNING ("write_riemann plugin: The value "
 -                                              "\"%s\" is not valid for the "
 -                                              "\"Protocol\" option. Use "
 -                                              "either \"UDP\" or \"TCP\".",
 -                                              tmp);
 -              } else if (strcasecmp ("StoreRates", child->key) == 0) {
 -                      status = cf_util_get_boolean (child, &host->store_rates);
 -                      if (status != 0)
 -                              break;
 -              } else if (strcasecmp ("AlwaysAppendDS", child->key) == 0) {
 -                      status = cf_util_get_boolean (child,
 -                                      &host->always_append_ds);
 -                      if (status != 0)
 -                              break;
 -              } else if (strcasecmp ("TTLFactor", child->key) == 0) {
 -                      double tmp = NAN;
 -                      status = cf_util_get_double (child, &tmp);
 -                      if (status != 0)
 -                              break;
 -                      if (tmp >= 2.0) {
 -                              host->ttl_factor = tmp;
 -                      } else if (tmp >= 1.0) {
 -                              NOTICE ("write_riemann plugin: The configured "
 -                                              "TTLFactor is very small "
 -                                              "(%.1f). A value of 2.0 or "
 -                                              "greater is recommended.",
 -                                              tmp);
 -                              host->ttl_factor = tmp;
 -                      } else if (tmp > 0.0) {
 -                              WARNING ("write_riemann plugin: The configured "
 -                                              "TTLFactor is too small to be "
 -                                              "useful (%.1f). I'll use it "
 -                                              "since the user knows best, "
 -                                              "but under protest.",
 -                                              tmp);
 -                              host->ttl_factor = tmp;
 -                      } else { /* zero, negative and NAN */
 -                              ERROR ("write_riemann plugin: The configured "
 -                                              "TTLFactor is invalid (%.1f).",
 -                                              tmp);
 -                      }
 -              } else {
 -                      WARNING("write_riemann plugin: ignoring unknown config "
 -                              "option: \"%s\"", child->key);
 -              }
 -      }
 -      if (status != 0) {
 -              riemann_free (host);
 -              return status;
 -      }
 -
 -      ssnprintf (callback_name, sizeof (callback_name), "write_riemann/%s",
 -                      host->name);
 -      ud.data = host;
 -      ud.free_func = riemann_free;
 -
 -      pthread_mutex_lock (&host->lock);
 -
 -      status = plugin_register_write (callback_name, riemann_write, &ud);
 -
 -    if (host->use_tcp == 1 && host->batch_mode) {
 -        ud.free_func = NULL;
 -        plugin_register_flush(callback_name, riemann_batch_flush, &ud);
 +  int i;
 +  oconfig_item_t *child;
 +  int status;
 +
 +  for (i = 0; i < ci->children_num; i++) {
 +    child = &ci->children[i];
 +
 +    if (strcasecmp("Node", child->key) == 0) {
 +      wrr_config_node(child);
 +    } else if (strcasecmp(child->key, "attribute") == 0) {
 +      char *key = NULL;
 +      char *val = NULL;
 +
 +      if (child->values_num != 2) {
 +        WARNING("riemann attributes need both a key and a value.");
 +        return (-1);
 +      }
 +      if (child->values[0].type != OCONFIG_TYPE_STRING ||
 +          child->values[1].type != OCONFIG_TYPE_STRING) {
 +        WARNING("riemann attribute needs string arguments.");
 +        return (-1);
 +      }
 +      if ((key = strdup(child->values[0].value.string)) == NULL) {
 +        WARNING("cannot allocate memory for attribute key.");
 +        return (-1);
 +      }
 +      if ((val = strdup(child->values[1].value.string)) == NULL) {
 +        WARNING("cannot allocate memory for attribute value.");
 +        sfree(key);
 +        return (-1);
 +      }
 +      strarray_add(&riemann_attrs, &riemann_attrs_num, key);
 +      strarray_add(&riemann_attrs, &riemann_attrs_num, val);
 +      DEBUG("write_riemann: got attr: %s => %s", key, val);
 +      sfree(key);
 +      sfree(val);
 +    } else if (strcasecmp(child->key, "tag") == 0) {
 +      char *tmp = NULL;
 +      status = cf_util_get_string(child, &tmp);
 +      if (status != 0)
 +        continue;
 +
 +      strarray_add(&riemann_tags, &riemann_tags_num, tmp);
 +      DEBUG("write_riemann plugin: Got tag: %s", tmp);
 +      sfree(tmp);
 +    } else {
 +      WARNING("write_riemann plugin: Ignoring unknown "
 +              "configuration option \"%s\" at top level.",
 +              child->key);
      }
 -      if (status != 0)
 -              WARNING ("write_riemann plugin: plugin_register_write (\"%s\") "
 -                              "failed with status %i.",
 -                              callback_name, status);
 -      else /* success */
 -              host->reference_count++;
 -
 -      status = plugin_register_notification (callback_name,
 -                      riemann_notification, &ud);
 -      if (status != 0)
 -              WARNING ("write_riemann plugin: plugin_register_notification (\"%s\") "
 -                              "failed with status %i.",
 -                              callback_name, status);
 -      else /* success */
 -              host->reference_count++;
 -
 -      if (host->reference_count <= 1)
 -      {
 -              /* Both callbacks failed => free memory.
 -               * We need to unlock here, because riemann_free() will lock.
 -               * This is not a race condition, because we're the only one
 -               * holding a reference. */
 -              pthread_mutex_unlock (&host->lock);
 -              riemann_free (host);
 -              return (-1);
 -      }
 -
 -      host->reference_count--;
 -      pthread_mutex_unlock (&host->lock);
 -
 -      return status;
 -} /* }}} int riemann_config_node */
 -
 -static int riemann_config(oconfig_item_t *ci) /* {{{ */
 -{
 -      int              i;
 -      oconfig_item_t  *child;
 -      int              status;
 -
 -      for (i = 0; i < ci->children_num; i++)  {
 -              child = &ci->children[i];
 -
 -              if (strcasecmp("Node", child->key) == 0) {
 -                      riemann_config_node (child);
 -              } else if (strcasecmp(child->key, "attribute") == 0) {
 -                      char *key = NULL;
 -                      char *val = NULL;
 -
 -                      if (child->values_num != 2) {
 -                              WARNING("riemann attributes need both a key and a value.");
 -                              return (-1);
 -                      }
 -                      if (child->values[0].type != OCONFIG_TYPE_STRING ||
 -                          child->values[1].type != OCONFIG_TYPE_STRING) {
 -                              WARNING("riemann attribute needs string arguments.");
 -                              return (-1);
 -                      }
 -                      if ((key = strdup(child->values[0].value.string)) == NULL) {
 -                              WARNING("cannot allocate memory for attribute key.");
 -                              return (-1);
 -                      }
 -                      if ((val = strdup(child->values[1].value.string)) == NULL) {
 -                              WARNING("cannot allocate memory for attribute value.");
 -                              sfree (key);
 -                              return (-1);
 -                      }
 -                      strarray_add(&riemann_attrs, &riemann_attrs_num, key);
 -                      strarray_add(&riemann_attrs, &riemann_attrs_num, val);
 -                      DEBUG("write_riemann: got attr: %s => %s", key, val);
 -                      sfree(key);
 -                      sfree(val);
 -              } else if (strcasecmp(child->key, "tag") == 0) {
 -                      char *tmp = NULL;
 -                      status = cf_util_get_string(child, &tmp);
 -                      if (status != 0)
 -                              continue;
 -
 -                      strarray_add (&riemann_tags, &riemann_tags_num, tmp);
 -                      DEBUG("write_riemann plugin: Got tag: %s", tmp);
 -                      sfree (tmp);
 -              } else {
 -                      WARNING ("write_riemann plugin: Ignoring unknown "
 -                               "configuration option \"%s\" at top level.",
 -                               child->key);
 -              }
 -      }
 -      return (0);
 -} /* }}} int riemann_config */
 -
 -void module_register(void)
 -{
 -      plugin_register_complex_config ("write_riemann", riemann_config);
 +  }
 +  return (0);
 +} /* }}} int wrr_config */
 +
 +void module_register(void) {
 +  plugin_register_complex_config("write_riemann", wrr_config);
  }
  
  /* vim: set sw=8 sts=8 ts=8 noet : */
@@@ -34,6 -34,8 +34,8 @@@
  #include "utils_threshold.h"
  #include "write_riemann_threshold.h"
  
+ #include <ltdl.h>
  /*
   * Threshold management
   * ====================
@@@ -131,6 -133,7 +133,6 @@@ static int ut_check_one_threshold (cons
      int *statuses)
  { /* {{{ */
    int ret = -1;
 -  int i;
    int status;
    gauge_t values_copy[ds->ds_num];
  
      }
  
      /* Prepare `sum' and `num'. */
 -    for (i = 0; i < ds->ds_num; i++)
 +    for (size_t i = 0; i < ds->ds_num; i++)
        if (!isnan (values[i]))
        {
          num++;
      if ((num == 0) /* All data sources are undefined. */
          || (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */
      {
 -      for (i = 0; i < ds->ds_num; i++)
 +      for (size_t i = 0; i < ds->ds_num; i++)
          values_copy[i] = NAN;
      }
      else /* We can actually calculate the percentage. */
      {
 -      for (i = 0; i < ds->ds_num; i++)
 +      for (size_t i = 0; i < ds->ds_num; i++)
          values_copy[i] = 100.0 * values[i] / sum;
      }
    } /* if (UT_FLAG_PERCENTAGE) */
  
 -  for (i = 0; i < ds->ds_num; i++)
 +  for (size_t i = 0; i < ds->ds_num; i++)
    {
      status = ut_check_one_data_source (ds, vl, th, values_copy, i);
      if (status != -1) {
@@@ -199,9 -202,7 +201,9 @@@ int write_riemann_threshold_check (cons
    gauge_t *values;
    int status;
  
 +  assert (vl->values_len > 0);
    memset(statuses, 0, vl->values_len * sizeof(*statuses));
 +
    if (threshold_tree == NULL)
          return 0;