Merge branch 'collectd-4.10' into collectd-5.0
authorFlorian Forster <octo@collectd.org>
Thu, 11 Oct 2012 08:07:41 +0000 (10:07 +0200)
committerFlorian Forster <octo@collectd.org>
Thu, 11 Oct 2012 08:07:41 +0000 (10:07 +0200)
Conflicts:
src/snmp.c

1  2 
configure.in
src/Makefile.am
src/snmp.c

diff --combined configure.in
@@@ -91,7 -91,6 +91,7 @@@ f
  if test "x$ac_system" = "xSolaris"
  then
        AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Define to enforce POSIX thread semantics under Solaris.])
 +      AC_DEFINE(_REENTRANT,               1, [Define to enable reentrancy interfaces.])
  fi
  if test "x$ac_system" = "xAIX"
  then
@@@ -110,13 -109,9 +110,13 @@@ AC_ARG_ENABLE(standards
  if test "x$enable_standards" = "xyes"
  then
        AC_DEFINE(_ISOC99_SOURCE,        1, [Define to enforce ISO C99 compliance.])
 -      AC_DEFINE(_POSIX_C_SOURCE, 200112L, [Define to enforce POSIX.1-2001 compliance.])
 -      AC_DEFINE(_XOPEN_SOURCE,       600, [Define to enforce X/Open 6 (XSI) compliance.])
 +      AC_DEFINE(_POSIX_C_SOURCE, 200809L, [Define to enforce POSIX.1-2008 compliance.])
 +      AC_DEFINE(_XOPEN_SOURCE,       700, [Define to enforce X/Open 7 (XSI) compliance.])
        AC_DEFINE(_REENTRANT,            1, [Define to enable reentrancy interfaces.])
 +      if test "x$GCC" = "xyes"
 +      then
 +              CFLAGS="$CFLAGS -std=c99"
 +      fi
  fi
  AM_CONDITIONAL(BUILD_FEATURE_STANDARDS, test "x$enable_standards" = "xyes")
  
@@@ -491,8 -486,6 +491,8 @@@ AC_CHECK_HEADERS(netinet/if_ether.h, []
  #endif
  ])
  
 +AC_CHECK_HEADERS(netinet/ip_compat.h)
 +
  # For the multimeter plugin
  have_termios_h="no"
  AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"])
@@@ -594,27 -587,6 +594,27 @@@ socket_needs_socket="no
  AC_CHECK_FUNCS(socket, [], AC_CHECK_LIB(socket, socket, [socket_needs_socket="yes"], AC_MSG_ERROR(cannot find socket)))
  AM_CONDITIONAL(BUILD_WITH_LIBSOCKET, test "x$socket_needs_socket" = "xyes")
  
 +clock_gettime_needs_rt="no"
 +clock_gettime_needs_posix4="no"
 +have_clock_gettime="no"
 +AC_CHECK_FUNCS(clock_gettime, [have_clock_gettime="yes"])
 +if test "x$have_clock_gettime" = "xno"
 +then
 +      AC_CHECK_LIB(rt, clock_gettime, [clock_gettime_needs_rt="yes"
 +                                       have_clock_gettime="yes"])
 +fi
 +if test "x$have_clock_gettime" = "xno"
 +then
 +      AC_CHECK_LIB(posix4, clock_gettime, [clock_gettime_needs_posix4="yes"
 +                                           have_clock_gettime="yes"])
 +fi
 +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"
  nanosleep_needs_posix4="no"
  AC_CHECK_FUNCS(nanosleep,
          AC_CHECK_LIB(posix4, nanosleep,
              [nanosleep_needs_posix4="yes"],
              AC_MSG_ERROR(cannot find nanosleep))))
 -AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$nanosleep_needs_rt" = "xyes")
 -AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$nanosleep_needs_posix4" = "xyes")
 +
 +AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$clock_gettime_needs_rt" = "xyes" || test "x$nanosleep_needs_rt" = "xyes")
 +AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$clock_gettime_needs_posix4" = "xyes" || test "x$nanosleep_needs_posix4" = "xyes")
  
  AC_CHECK_FUNCS(sysctl, [have_sysctl="yes"], [have_sysctl="no"])
  AC_CHECK_FUNCS(sysctlbyname, [have_sysctlbyname="yes"], [have_sysctlbyname="no"])
@@@ -636,127 -607,13 +636,127 @@@ AC_CHECK_FUNCS(thread_info, [have_threa
  AC_CHECK_FUNCS(statfs, [have_statfs="yes"], [have_statfs="no"])
  AC_CHECK_FUNCS(statvfs, [have_statvfs="yes"], [have_statvfs="no"])
  AC_CHECK_FUNCS(getifaddrs, [have_getifaddrs="yes"], [have_getifaddrs="no"])
 +AC_CHECK_FUNCS(getloadavg, [have_getloadavg="yes"], [have_getloadavg="no"])
  AC_CHECK_FUNCS(syslog, [have_syslog="yes"], [have_syslog="no"])
  AC_CHECK_FUNCS(getutent, [have_getutent="yes"], [have_getutent="no"])
  AC_CHECK_FUNCS(getutxent, [have_getutxent="yes"], [have_getutxent="no"])
 -AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"])
  
 -# For load module
 -AC_CHECK_FUNCS(getloadavg, [have_getloadavg="yes"], [have_getloadavg="no"])
 +# Check for strptime {{{
 +if test "x$GCC" = "xyes"
 +then
 +      SAVE_CFLAGS="$CFLAGS"
 +      CFLAGS="$CFLAGS -Wall -Wextra -Werror"
 +fi
 +
 +AC_CHECK_FUNCS(strptime, [have_strptime="yes"], [have_strptime="no"])
 +if test "x$have_strptime" = "xyes"
 +then
 +      AC_CACHE_CHECK([whether strptime is exported by default],
 +                     [c_cv_have_strptime_default],
 +                     AC_COMPILE_IFELSE(
 +AC_LANG_PROGRAM(
 +[[
 +AC_INCLUDES_DEFAULT
 +#include <time.h>
 +]],
 +[[
 + struct tm stm;
 + (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
 +]]),
 +                     [c_cv_have_strptime_default="yes"],
 +                     [c_cv_have_strptime_default="no"]))
 +fi
 +if test "x$have_strptime" = "xyes" && test "x$c_cv_have_strptime_default" = "xno"
 +then
 +      AC_CACHE_CHECK([whether strptime needs standards mode],
 +                     [c_cv_have_strptime_standards],
 +                     AC_COMPILE_IFELSE(
 +AC_LANG_PROGRAM(
 +[[
 +#ifndef _ISOC99_SOURCE
 +# define _ISOC99_SOURCE 1
 +#endif
 +#ifndef _POSIX_C_SOURCE
 +# define _POSIX_C_SOURCE 200112L
 +#endif
 +#ifndef _XOPEN_SOURCE
 +# define _XOPEN_SOURCE 500
 +#endif
 +AC_INCLUDES_DEFAULT
 +#include <time.h>
 +]],
 +[[
 + struct tm stm;
 + (void) strptime ("2010-12-30%13:42:42", "%Y-%m-%dT%T", &stm);
 +]]),
 +                     [c_cv_have_strptime_standards="yes"],
 +                     [c_cv_have_strptime_standards="no"]))
 +
 +      if test "x$c_cv_have_strptime_standards" = "xyes"
 +      then
 +              AC_DEFINE([STRPTIME_NEEDS_STANDARDS], 1, [Set to true if strptime is only exported in X/Open mode (GNU libc).])
 +      else
 +              have_strptime="no"
 +      fi
 +fi
 +
 +if test "x$GCC" = "xyes"
 +then
 +      CFLAGS="$SAVE_CFLAGS"
 +fi
 +
 +# }}} Check for strptime
 +
 +AC_CHECK_FUNCS(swapctl, [have_swapctl="yes"], [have_swapctl="no"])
 +if test "x$have_swapctl" = "xyes"; then
 +        AC_CACHE_CHECK([whether swapctl takes two arguments],
 +                [c_cv_have_swapctl_two_args],
 +                AC_COMPILE_IFELSE(
 +                        AC_LANG_PROGRAM([[AC_INCLUDES_DEFAULT
 +#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
 +#  undef _FILE_OFFSET_BITS
 +#  undef _LARGEFILE64_SOURCE
 +#endif
 +#include <sys/stat.h>
 +#include <sys/swap.h>]],
 +                                [[
 +                                int num = swapctl(0, NULL);
 +                                ]]
 +                        ),
 +                        [c_cv_have_swapctl_two_args="yes"],
 +                        [c_cv_have_swapctl_two_args="no"]
 +                )
 +        )
 +        AC_CACHE_CHECK([whether swapctl takes three arguments],
 +                [c_cv_have_swapctl_three_args],
 +                AC_COMPILE_IFELSE(
 +                        AC_LANG_PROGRAM([[AC_INCLUDES_DEFAULT
 +#if HAVE_SYS_SWAP_H && !defined(_LP64) && _FILE_OFFSET_BITS == 64
 +#  undef _FILE_OFFSET_BITS
 +#  undef _LARGEFILE64_SOURCE
 +#endif
 +#include <sys/stat.h>
 +#include <sys/swap.h>]],
 +                                [[
 +                                int num = swapctl(0, NULL,0);
 +                                ]]
 +                        ),
 +                        [c_cv_have_swapctl_three_args="yes"],
 +                        [c_cv_have_swapctl_three_args="no"]
 +                )
 +        )
 +fi
 +# Check for different versions of `swapctl' here..
 +if test "x$have_swapctl" = "xyes"; then
 +        if test "x$c_cv_have_swapctl_two_args" = "xyes"; then
 +                AC_DEFINE(HAVE_SWAPCTL_TWO_ARGS, 1,
 +                          [Define if the function swapctl exists and takes two arguments.])
 +        fi
 +        if test "x$c_cv_have_swapctl_three_args" = "xyes"; then
 +                AC_DEFINE(HAVE_SWAPCTL_THREE_ARGS, 1,
 +                          [Define if the function swapctl exists and takes three arguments.])
 +        fi
 +fi
  
  # Check for NAN
  AC_ARG_WITH(nan-emulation, [AS_HELP_STRING([--with-nan-emulation], [use emulated NAN. For crosscompiling only.])],
@@@ -778,7 -635,7 +778,7 @@@ if test "x$nan_type" = "xnone"; the
        [[
  #include <stdlib.h>
  #include <math.h>
 -static float foo = NAN;
 +static double foo = NAN;
        ]],
        [[
         if (isnan (foo))
@@@ -804,7 -661,7 +804,7 @@@ if test "x$nan_type" = "xnone"; the
  #include <stdlib.h>
  #define __USE_ISOC99 1
  #include <math.h>
 -static float foo = NAN;
 +static double foo = NAN;
        ]],
        [[
         if (isnan (foo))
@@@ -838,7 -695,7 +838,7 @@@ if test "x$nan_type" = "xnone"; the
  #ifndef isnan
  # define isnan(f) ((f) != (f))
  #endif
 -static float foo = NAN;
 +static double foo = NAN;
        ]],
        [[
         if (isnan (foo))
  if test "x$with_perfstat" = "xyes"
  then
         AC_DEFINE(HAVE_PERFSTAT, 1, [Define to 1 if you have the 'perfstat' library (-lperfstat)])
 +       # struct members pertaining to donation have been added to libperfstat somewhere between AIX5.3ML5 and AIX5.3ML9
 +       AC_CHECK_MEMBER([perfstat_partition_type_t.b.donate_enabled], [], [], [[#include <libperfstat.h]])
 +       if test "x$av_cv_member_perfstat_partition_type_t_b_donate_enabled" = "xyes"
 +       then
 +              AC_DEFINE(PERFSTAT_SUPPORTS_DONATION, 1, [Define to 1 if your version of the 'perfstat' library supports donation])
 +       fi
  fi
  AM_CONDITIONAL(BUILD_WITH_PERFSTAT, test "x$with_perfstat" = "xyes")
  
  fi
  AM_CONDITIONAL(BUILD_WITH_LIBKVM_OPENFILES, test "x$with_kvm_openfiles" = "xyes")
  
 +# --with-libcredis {{{
 +AC_ARG_WITH(libcredis, [AS_HELP_STRING([--with-libcredis@<:@=PREFIX@:>@], [Path to libcredis.])],
 +[
 + if test "x$withval" = "xyes"
 + then
 +       with_libcredis="yes"
 + else if test "x$withval" = "xno"
 + then
 +       with_libcredis="no"
 + else
 +       with_libcredis="yes"
 +       LIBCREDIS_CPPFLAGS="$LIBCREDIS_CPPFLAGS -I$withval/include"
 +       LIBCREDIS_LDFLAGS="$LIBCREDIS_LDFLAGS -L$withval/lib"
 + fi; fi
 +],
 +[with_libcredis="yes"])
 +
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +
 +CPPFLAGS="$CPPFLAGS $LIBCREDIS_CPPFLAGS"
 +LDFLAGS="$LDFLAGS $LIBCREDIS_LDFLAGS"
 +
 +if test "x$with_libcredis" = "xyes"
 +then
 +      if test "x$LIBCREDIS_CPPFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([libcredis CPPFLAGS: $LIBCREDIS_CPPFLAGS])
 +      fi
 +      AC_CHECK_HEADERS(credis.h,
 +      [with_libcredis="yes"],
 +      [with_libcredis="no (credis.h not found)"])
 +fi
 +if test "x$with_libcredis" = "xyes"
 +then
 +      if test "x$LIBCREDIS_LDFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([libcredis LDFLAGS: $LIBCREDIS_LDFLAGS])
 +      fi
 +      AC_CHECK_LIB(credis, credis_info,
 +      [with_libcredis="yes"],
 +      [with_libcredis="no (symbol 'credis_info' not found)"])
 +
 +fi
 +
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +
 +if test "x$with_libcredis" = "xyes"
 +then
 +      BUILD_WITH_LIBCREDIS_CPPFLAGS="$LIBCREDIS_CPPFLAGS"
 +      BUILD_WITH_LIBCREDIS_LDFLAGS="$LIBCREDIS_LDFLAGS"
 +      AC_SUBST(BUILD_WITH_LIBCREDIS_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBCREDIS_LDFLAGS)
 +fi
 +AM_CONDITIONAL(BUILD_WITH_LIBCREDIS, test "x$with_libcredis" = "xyes")
 +# }}}
 +
  # --with-libcurl {{{
  with_curl_config="curl-config"
  with_curl_cflags=""
@@@ -2164,7 -1957,7 +2164,7 @@@ the
        $PKG_CONFIG --exists 'modbus' 2>/dev/null
        if test $? -ne 0
        then
 -              with_libmodbus="no (pkg-config doesn't know library)"
 +              with_libmodbus="no (pkg-config doesn't know modbus)"
        fi
  fi
  if test "x$with_libmodbus" = "xuse_pkgconfig"
@@@ -2204,9 -1997,9 +2204,9 @@@ the
        CPPFLAGS="$CPPFLAGS $with_libmodbus_cflags"
        LDFLAGS="$LDFLAGS $with_libmodbus_libs"
  
 -      AC_CHECK_LIB(modbus, modbus_init_tcp,
 +      AC_CHECK_LIB(modbus, modbus_connect,
                     [with_libmodbus="yes"],
 -                   [with_libmodbus="no (symbol modbus_init_tcp not found)"])
 +                   [with_libmodbus="no (symbol modbus_connect not found)"])
  
        CPPFLAGS="$SAVE_CPPFLAGS"
        LDFLAGS="$SAVE_LDFLAGS"
@@@ -2699,7 -2492,7 +2699,7 @@@ the
        fi
        AC_CHECK_HEADERS(oping.h,
        [with_liboping="yes"],
 -      [with_liboping="no ('oping.h' not found)"])
 +      [with_liboping="no (oping.h not found)"])
  fi
  if test "x$with_liboping" = "xyes"
  then
@@@ -2870,8 -2663,7 +2870,8 @@@ the
  fi
  if test "x$with_libpcap" = "xyes"
  then
 -      AC_CHECK_HEADERS(pcap-bpf.h)
 +      AC_CHECK_HEADERS(pcap-bpf.h,,
 +                       [with_libpcap="no (pcap-bpf.h not found)"])
  fi
  AM_CONDITIONAL(BUILD_WITH_LIBPCAP, test "x$with_libpcap" = "xyes")
  # }}}
  perl_interpreter="perl"
  AC_ARG_WITH(libperl, [AS_HELP_STRING([--with-libperl@<:@=PREFIX@:>@], [Path to libperl.])],
  [
-       if test -x "$withval"
+       if test -f "$withval" && test -x "$withval"
        then
                perl_interpreter="$withval"
                with_libperl="yes"
  fi
  # }}} --with-python
  
 +# --with-librabbitmq {{{
 +with_librabbitmq_cppflags=""
 +with_librabbitmq_ldflags=""
 +AC_ARG_WITH(librabbitmq, [AS_HELP_STRING([--with-librabbitmq@<:@=PREFIX@:>@], [Path to librabbitmq.])],
 +[
 +      if test "x$withval" != "xno" && test "x$withval" != "xyes"
 +      then
 +              with_librabbitmq_cppflags="-I$withval/include"
 +              with_librabbitmq_ldflags="-L$withval/lib"
 +              with_librabbitmq="yes"
 +      else
 +              with_librabbitmq="$withval"
 +      fi
 +],
 +[
 +      with_librabbitmq="yes"
 +])
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
 +LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      AC_CHECK_HEADERS(amqp.h, [with_librabbitmq="yes"], [with_librabbitmq="no (amqp.h not found)"])
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      # librabbitmq up to version 0.9.1 provides "library_errno", later
 +      # versions use "library_error". The library does not provide a version
 +      # macro :( Use "AC_CHECK_MEMBERS" (plural) for automatic defines.
 +      AC_CHECK_MEMBERS([amqp_rpc_reply_t.library_errno],,,
 +                       [
 +#if HAVE_STDLIB_H
 +# include <stdlib.h>
 +#endif
 +#if HAVE_STDIO_H
 +# include <stdio.h>
 +#endif
 +#if HAVE_STDINT_H
 +# include <stdint.h>
 +#endif
 +#if HAVE_INTTYPES_H
 +# include <inttypes.h>
 +#endif
 +#include <amqp.h>
 +                         ])
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      AC_CHECK_LIB(rabbitmq, amqp_basic_publish, [with_librabbitmq="yes"], [with_librabbitmq="no (Symbol 'amqp_basic_publish' not found)"])
 +fi
 +if test "x$with_librabbitmq" = "xyes"
 +then
 +      BUILD_WITH_LIBRABBITMQ_CPPFLAGS="$with_librabbitmq_cppflags"
 +      BUILD_WITH_LIBRABBITMQ_LDFLAGS="$with_librabbitmq_ldflags"
 +      BUILD_WITH_LIBRABBITMQ_LIBS="-lrabbitmq"
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBRABBITMQ_LIBS)
 +      AC_DEFINE(HAVE_LIBRABBITMQ, 1, [Define if librabbitmq is present and usable.])
 +fi
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +AM_CONDITIONAL(BUILD_WITH_LIBRABBITMQ, test "x$with_librabbitmq" = "xyes")
 +# }}}
 +
  # --with-librouteros {{{
  AC_ARG_WITH(librouteros, [AS_HELP_STRING([--with-librouteros@<:@=PREFIX@:>@], [Path to librouteros.])],
  [
@@@ -3403,7 -3129,7 +3403,7 @@@ the
        fi
        AC_CHECK_HEADERS(routeros_api.h,
        [with_librouteros="yes"],
 -      [with_librouteros="no ('routeros_api.h' not found)"])
 +      [with_librouteros="no (routeros_api.h not found)"])
  fi
  if test "x$with_librouteros" = "xyes"
  then
@@@ -3602,7 -3328,7 +3602,7 @@@ the
      if test "$?" != "0"
      then
        with_libstatgrab_pkg_config="no"
 -      with_libstatgrab="no ($PKG_CONFIG doesn't know libstatgrab)"
 +      with_libstatgrab="no (pkg-config doesn't know libstatgrab)"
        temp_result="not found"
      fi
      AC_MSG_RESULT([$temp_result])
@@@ -3822,7 -3548,7 +3822,7 @@@ the
        $PKG_CONFIG --exists 'libupsclient' 2>/dev/null
        if test $? -ne 0
        then
 -              with_libupsclient="no (pkg-config doesn't know library)"
 +              with_libupsclient="no (pkg-config doesn't know libupsclient)"
        fi
  fi
  if test "x$with_libupsclient" = "xuse_pkgconfig"
  AM_CONDITIONAL(BUILD_WITH_LIBYAJL, test "x$with_libyajl" = "xyes")
  # }}}
  
 +# --with-libvarnish {{{
 +with_libvarnish_cppflags=""
 +with_libvarnish_cflags=""
 +with_libvarnish_libs=""
 +AC_ARG_WITH(libvarnish, [AS_HELP_STRING([--with-libvarnish@<:@=PREFIX@:>@], [Path to libvarnish.])],
 +[
 +      if test "x$withval" = "xno"
 +      then
 +              with_libvarnish="no"
 +      else if test "x$withval" = "xyes"
 +      then
 +              with_libvarnish="use_pkgconfig"
 +      else if test -d "$with_libvarnish/lib"
 +      then
 +              AC_MSG_NOTICE([Not checking for libvarnish: Manually configured])
 +              with_libvarnish_cflags="-I$withval/include"
 +              with_libvarnish_libs="-L$withval/lib -lvarnishapi"
 +              with_libvarnish="yes"
 +      fi; fi; fi
 +],
 +[with_libvarnish="use_pkgconfig"])
 +
 +# 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
 +      then
 +              with_libvarnish="no (pkg-config doesn't know varnishapi)"
 +      fi
 +fi
 +if test "x$with_libvarnish" = "xuse_pkgconfig"
 +then
 +      with_libvarnish_cflags="`$PKG_CONFIG --cflags 'varnishapi'`"
 +      if test $? -ne 0
 +      then
 +              with_libvarnish="no ($PKG_CONFIG failed)"
 +      fi
 +      with_libvarnish_libs="`$PKG_CONFIG --libs 'varnishapi'`"
 +      if test $? -ne 0
 +      then
 +              with_libvarnish="no ($PKG_CONFIG failed)"
 +      fi
 +fi
 +if test "x$with_libvarnish" = "xuse_pkgconfig"
 +then
 +      with_libvarnish="yes"
 +fi
 +
 +# with_libvarnish_cflags and with_libvarnish_libs are set up now, let's do
 +# the actual checks.
 +if test "x$with_libvarnish" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
 +      AC_CHECK_HEADERS(varnish/varnishapi.h, [], [with_libvarnish="no (varnish/varnishapi.h not found)"])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +fi
 +if test "x$with_libvarnish" = "xyes"
 +then
 +      SAVE_CPPFLAGS="$CPPFLAGS"
 +      #SAVE_LDFLAGS="$LDFLAGS"
 +
 +      CPPFLAGS="$CPPFLAGS $with_libvarnish_cflags"
 +      #LDFLAGS="$LDFLAGS $with_libvarnish_libs"
 +
 +      AC_CHECK_LIB(varnishapi, VSL_OpenStats,
 +                   [with_libvarnish="yes"],
 +                   [with_libvarnish="no (symbol VSL_OpenStats not found)"],
 +                   [$with_libvarnish_libs])
 +
 +      CPPFLAGS="$SAVE_CPPFLAGS"
 +      #LDFLAGS="$SAVE_LDFLAGS"
 +fi
 +if test "x$with_libvarnish" = "xyes"
 +then
 +      BUILD_WITH_LIBVARNISH_CFLAGS="$with_libvarnish_cflags"
 +      BUILD_WITH_LIBVARNISH_LIBS="$with_libvarnish_libs"
 +      AC_SUBST(BUILD_WITH_LIBVARNISH_CFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBVARNISH_LIBS)
 +fi
 +# }}}
 +
  # pkg-config --exists 'libxml-2.0'; pkg-config --exists libvirt {{{
  with_libxml2="no (pkg-config isn't available)"
  with_libxml2_cflags=""
@@@ -4118,7 -3752,7 +4118,7 @@@ the
        then
                with_libxml2="yes"
        else
 -              with_libxml2="no (pkg-config doesn't know library)"
 +              with_libxml2="no (pkg-config doesn't know libxml-2.0)"
        fi
  
        pkg-config --exists libvirt 2>/dev/null
        then
                with_libvirt="yes"
        else
 -              with_libvirt="no (pkg-config doesn't know library)"
 +              with_libvirt="no (pkg-config doesn't know libvirt)"
        fi
  fi
  if test "x$with_libxml2" = "xyes"
@@@ -4243,7 -3877,7 +4243,7 @@@ the
        $PKG_CONFIG --exists OpenIPMIpthread 2>/dev/null
        if test "$?" != "0"
        then
 -              with_libopenipmipthread="no ($PKG_CONFIG doesn't know OpenIPMIpthread)"
 +              with_libopenipmipthread="no (pkg-config doesn't know OpenIPMIpthread)"
        fi
        AC_MSG_RESULT([$with_libopenipmipthread])
  fi
  
  PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
                [with_libnotify="yes"],
 -              [with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"])
 +              [if test "x$LIBNOTIFY_PKG_ERRORS" = "x"; then
 +                       with_libnotify="no"
 +               else
 +                       with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"
 +               fi])
  
  # Check for enabled/disabled features
  #
@@@ -4551,6 -4181,11 +4551,6 @@@ the
        plugin_tape="yes"
  fi
  
 -if test "x$have_sys_swap_h$with_kstat$ac_system" = "xyesyesSolaris"
 -then
 -      plugin_swap="yes"
 -fi
 -
  # libstatgrab
  if test "x$with_libstatgrab" = "xyes"
  then
  if test "x$with_libcurl" = "xyes" && test "x$with_libxml2" = "xyes"
  then
        plugin_ascent="yes"
 -      plugin_bind="yes"
 +      if test "x$have_strptime" = "xyes"
 +      then
 +              plugin_bind="yes"
 +      fi
  fi
  
  if test "x$with_libopenipmipthread" = "xyes"
@@@ -4595,15 -4227,11 +4595,15 @@@ if test "x$have_sysctl" = "xyes
  then
        plugin_cpu="yes"
        plugin_memory="yes"
 -      plugin_swap="yes"
        plugin_uptime="yes"
 +      if test "x$ac_system" = "xDarwin"
 +      then
 +              plugin_swap="yes"
 +      fi
  fi
  if test "x$have_sysctlbyname" = "xyes"
  then
 +      plugin_contextswitch="yes"
        plugin_cpu="yes"
        plugin_memory="yes"
        plugin_tcpconns="yes"
@@@ -4691,7 -4319,7 +4691,7 @@@ the
        plugin_swap="yes"
  fi
  
 -if test "x$have_swapctl" = "xyes"
 +if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_two_args" = "xyes"
  then
        plugin_swap="yes"
  fi
@@@ -4731,7 -4359,6 +4731,7 @@@ AC_ARG_ENABLE([all-plugins]
  
  m4_divert_once([HELP_ENABLE], [])
  
 +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])
@@@ -4766,7 -4393,6 +4766,7 @@@ AC_PLUGIN([java],        [$with_java]
  AC_PLUGIN([libvirt],     [$plugin_libvirt],    [Virtual machine statistics])
  AC_PLUGIN([load],        [$plugin_load],       [System load])
  AC_PLUGIN([logfile],     [yes],                [File logging plugin])
 +AC_PLUGIN([lpar],        [$with_perfstat],     [AIX logical partitions 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])
@@@ -4802,7 -4428,6 +4802,7 @@@ AC_PLUGIN([powerdns],    [yes]
  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_libcredis],    [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])
@@@ -4818,23 -4443,19 +4818,23 @@@ AC_PLUGIN([target_notification], [yes]
  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([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([vmem],        [$plugin_vmem],       [Virtual memory statistics])
  AC_PLUGIN([vserver],     [$plugin_vserver],    [Linux VServer statistics])
  AC_PLUGIN([wireless],    [$plugin_wireless],   [Wireless statistics])
  AC_PLUGIN([write_http],  [$with_libcurl],      [HTTP output plugin])
 +AC_PLUGIN([write_redis], [$with_libcredis],    [Redis output plugin])
  AC_PLUGIN([xmms],        [$with_libxmms],      [XMMS statistics])
  AC_PLUGIN([zfs_arc],     [$plugin_zfs_arc],    [ZFS ARC statistics])
  
@@@ -5009,7 -4630,6 +5009,7 @@@ Configuration
    Libraries:
      libcurl . . . . . . . $with_libcurl
      libdbi  . . . . . . . $with_libdbi
 +    libcredis . . . . . . $with_libcredis
      libesmtp  . . . . . . $with_libesmtp
      libganglia  . . . . . $with_libganglia
      libgcrypt . . . . . . $with_libgcrypt
      libperl . . . . . . . $with_libperl
      libpq . . . . . . . . $with_libpq
      libpthread  . . . . . $with_libpthread
 +    librabbitmq . . . . . $with_librabbitmq
      librouteros . . . . . $with_librouteros
      librrd  . . . . . . . $with_librrd
      libsensors  . . . . . $with_libsensors
      libstatgrab . . . . . $with_libstatgrab
      libtokyotyrant  . . . $with_libtokyotyrant
      libupsclient  . . . . $with_libupsclient
 +    libvarnish  . . . . . $with_libvarnish
      libvirt . . . . . . . $with_libvirt
      libxml2 . . . . . . . $with_libxml2
      libxmms . . . . . . . $with_libxmms
      perl  . . . . . . . . $with_perl_bindings
  
    Modules:
 +    amqp    . . . . . . . $enable_amqp
      apache  . . . . . . . $enable_apache
      apcups  . . . . . . . $enable_apcups
      apple_sensors . . . . $enable_apple_sensors
      libvirt . . . . . . . $enable_libvirt
      load  . . . . . . . . $enable_load
      logfile . . . . . . . $enable_logfile
 +    lpar... . . . . . . . $enable_lpar
      madwifi . . . . . . . $enable_madwifi
      match_empty_counter . $enable_match_empty_counter
      match_hashed  . . . . $enable_match_hashed
      processes . . . . . . $enable_processes
      protocols . . . . . . $enable_protocols
      python  . . . . . . . $enable_python
 +    redis . . . . . . . . $enable_redis
      routeros  . . . . . . $enable_routeros
      rrdcached . . . . . . $enable_rrdcached
      rrdtool . . . . . . . $enable_rrdtool
      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
      unixsock  . . . . . . $enable_unixsock
      uptime  . . . . . . . $enable_uptime
      users . . . . . . . . $enable_users
      uuid  . . . . . . . . $enable_uuid
 +    varnish . . . . . . . $enable_varnish
      vmem  . . . . . . . . $enable_vmem
      vserver . . . . . . . $enable_vserver
      wireless  . . . . . . $enable_wireless
      write_http  . . . . . $enable_write_http
 +    write_redis . . . . . $enable_write_redis
      xmms  . . . . . . . . $enable_xmms
      zfs_arc . . . . . . . $enable_zfs_arc
  
diff --combined src/Makefile.am
@@@ -21,7 -21,7 +21,7 @@@ AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdi
  AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"'
  
  sbin_PROGRAMS = collectd collectdmon
 -bin_PROGRAMS = collectd-nagios
 +bin_PROGRAMS = collectd-nagios collectdctl
  
  collectd_SOURCES = collectd.c collectd.h \
                   common.c common.h \
@@@ -40,7 -40,7 +40,7 @@@
                   utils_match.c utils_match.h \
                   utils_subst.c utils_subst.h \
                   utils_tail.c utils_tail.h \
 -                 utils_threshold.c utils_threshold.h \
 +                 utils_time.c utils_time.h \
                   types_list.c types_list.h
  
  collectd_CPPFLAGS =  $(AM_CPPFLAGS) $(LTDLINCL)
@@@ -104,36 -104,11 +104,36 @@@ endi
  collectd_nagios_LDADD += libcollectdclient/libcollectdclient.la
  collectd_nagios_DEPENDENCIES = libcollectdclient/libcollectdclient.la
  
 +
 +collectdctl_SOURCES = collectdctl.c
 +collectdctl_LDADD =
 +if BUILD_WITH_LIBSOCKET
 +collectdctl_LDADD += -lsocket
 +endif
 +if BUILD_AIX
 +collectdctl_LDADD += -lm
 +endif
 +collectdctl_LDADD += libcollectdclient/libcollectdclient.la
 +collectdctl_DEPENDENCIES = libcollectdclient/libcollectdclient.la
 +
 +
  pkglib_LTLIBRARIES = 
  
  BUILT_SOURCES = 
  CLEANFILES = 
  
 +if BUILD_PLUGIN_AMQP
 +pkglib_LTLIBRARIES += amqp.la
 +amqp_la_SOURCES = amqp.c \
 +                utils_cmd_putval.c utils_cmd_putval.h \
 +                utils_format_json.c utils_format_json.h
 +amqp_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
 +amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
 +amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS)
 +collectd_LDADD += "-dlopen" amqp.la
 +collectd_DEPENDENCIES += amqp.la
 +endif
 +
  if BUILD_PLUGIN_APACHE
  pkglib_LTLIBRARIES += apache.la
  apache_la_SOURCES = apache.c
@@@ -525,15 -500,6 +525,15 @@@ collectd_LDADD += "-dlopen" logfile.l
  collectd_DEPENDENCIES += logfile.la
  endif
  
 +if BUILD_PLUGIN_LPAR
 +pkglib_LTLIBRARIES += lpar.la
 +lpar_la_SOURCES = lpar.c
 +lpar_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" lpar.la
 +collectd_DEPENDENCIES += lpar.la
 +lpar_la_LIBADD = -lperfstat
 +endif
 +
  if BUILD_PLUGIN_MADWIFI
  pkglib_LTLIBRARIES += madwifi.la
  madwifi_la_SOURCES = madwifi.c madwifi.h
@@@ -920,16 -886,6 +920,16 @@@ collectd_LDADD += "-dlopen" protocols.l
  collectd_DEPENDENCIES += protocols.la
  endif
  
 +if BUILD_PLUGIN_REDIS
 +pkglib_LTLIBRARIES += redis.la
 +redis_la_SOURCES = redis.c
 +redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS)
 +redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS)
 +redis_la_LIBADD = -lcredis
 +collectd_LDADD += "-dlopen" redis.la
 +collectd_DEPENDENCIES += redis.la
 +endif
 +
  if BUILD_PLUGIN_ROUTEROS
  pkglib_LTLIBRARIES += routeros.la
  routeros_la_SOURCES = routeros.c
@@@ -1087,14 -1043,6 +1087,14 @@@ collectd_LDADD += "-dlopen" target_set.
  collectd_DEPENDENCIES += target_set.la
  endif
  
 +if BUILD_PLUGIN_TARGET_V5UPGRADE
 +pkglib_LTLIBRARIES += target_v5upgrade.la
 +target_v5upgrade_la_SOURCES = target_v5upgrade.c
 +target_v5upgrade_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" target_v5upgrade.la
 +collectd_DEPENDENCIES += target_v5upgrade.la
 +endif
 +
  if BUILD_PLUGIN_TCPCONNS
  pkglib_LTLIBRARIES += tcpconns.la
  tcpconns_la_SOURCES = tcpconns.c
@@@ -1131,14 -1079,6 +1131,14 @@@ collectd_LDADD += "-dlopen" thermal.l
  collectd_DEPENDENCIES += thermal.la
  endif
  
 +if BUILD_PLUGIN_THRESHOLD
 +pkglib_LTLIBRARIES += threshold.la
 +threshold_la_SOURCES = threshold.c
 +threshold_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" threshold.la
 +collectd_DEPENDENCIES += threshold.la
 +endif
 +
  if BUILD_PLUGIN_TOKYOTYRANT
  pkglib_LTLIBRARIES += tokyotyrant.la
  tokyotyrant_la_SOURCES = tokyotyrant.c
@@@ -1157,6 -1097,7 +1157,6 @@@ pkglib_LTLIBRARIES += unixsock.l
  unixsock_la_SOURCES = unixsock.c \
                      utils_cmd_flush.h utils_cmd_flush.c \
                      utils_cmd_getval.h utils_cmd_getval.c \
 -                    utils_cmd_getthreshold.h utils_cmd_getthreshold.c \
                      utils_cmd_listval.h utils_cmd_listval.c \
                      utils_cmd_putval.h utils_cmd_putval.c \
                      utils_cmd_putnotif.h utils_cmd_putnotif.c
@@@ -1203,16 -1144,6 +1203,16 @@@ collectd_LDADD += "-dlopen" uuid.l
  collectd_DEPENDENCIES += uuid.la
  endif
  
 +if BUILD_PLUGIN_VARNISH
 +pkglib_LTLIBRARIES += varnish.la
 +varnish_la_SOURCES = varnish.c
 +varnish_la_LDFLAGS = -module -avoid-version
 +varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS)
 +varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS)
 +collectd_LDADD += "-dlopen" varnish.la
 +collectd_DEPENDENCIES += varnish.la
 +endif
 +
  if BUILD_PLUGIN_VMEM
  pkglib_LTLIBRARIES += vmem.la
  vmem_la_SOURCES = vmem.c
@@@ -1252,16 -1183,6 +1252,16 @@@ endi
  collectd_DEPENDENCIES += write_http.la
  endif
  
 +if BUILD_PLUGIN_WRITE_REDIS
 +pkglib_LTLIBRARIES += write_redis.la
 +write_redis_la_SOURCES = write_redis.c
 +write_redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS)
 +write_redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS)
 +write_redis_la_LIBADD = -lcredis
 +collectd_LDADD += "-dlopen" write_redis.la
 +collectd_DEPENDENCIES += write_redis.la
 +endif
 +
  if BUILD_PLUGIN_XMMS
  pkglib_LTLIBRARIES += xmms.la
  xmms_la_SOURCES = xmms.c
@@@ -1286,14 -1207,12 +1286,14 @@@ dist_man_MANS = collectd.1 
                collectd.conf.5 \
                collectd-email.5 \
                collectd-exec.5 \
 +              collectdctl.1 \
                collectd-java.5 \
                collectdmon.1 \
                collectd-nagios.1 \
                collectd-perl.5 \
                collectd-python.5 \
                collectd-snmp.5 \
 +              collectd-threshold.5 \
                collectd-unixsock.5 \
                types.db.5
  
@@@ -1304,7 -1223,6 +1304,7 @@@ EXTRA_DIST = types.db pinba.prot
  EXTRA_DIST +=   collectd.conf.pod \
                collectd-email.pod \
                collectd-exec.pod \
 +              collectdctl.pod \
                collectd-java.pod \
                collectdmon.pod \
                collectd-nagios.pod \
                collectd-python.pod \
                collectd.pod \
                collectd-snmp.pod \
 +              collectd-threshold.pod \
                collectd-unixsock.pod \
                postgresql_default.conf \
                types.db.pod
        fi
  
  pinba.pb-c.c pinba.pb-c.h: pinba.proto
 -      protoc-c --c_out $(builddir) pinba.proto
 +      protoc-c --c_out . pinba.proto
  
  install-exec-hook:
        $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
        $(INSTALL) -m 0644 $(srcdir)/types.db $(DESTDIR)$(pkgdatadir)/types.db;
        $(INSTALL) -m 0644 $(srcdir)/postgresql_default.conf \
                $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
+ uninstall-hook:
+       rm -f $(DESTDIR)$(pkgdatadir)/types.db;
+       rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
+       rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
diff --combined src/snmp.c
@@@ -1,6 -1,6 +1,6 @@@
  /**
   * collectd - src/snmp.c
-  * Copyright (C) 2007  Florian octo Forster
+  * Copyright (C) 2007-2012  Florian octo Forster
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the
@@@ -16,7 -16,7 +16,7 @@@
   * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
   *
   * Authors:
-  *   Florian octo Forster <octo at verplant.org>
+  *   Florian octo Forster <octo at collectd.org>
   **/
  
  #include "collectd.h"
@@@ -69,7 -69,7 +69,7 @@@ struct host_definition_
    int version;
    void *sess_handle;
    c_complain_t complaint;
 -  uint32_t interval;
 +  cdtime_t interval;
    data_definition_t **data_list;
    int data_list_len;
  };
@@@ -79,7 -79,7 +79,7 @@@ typedef struct host_definition_s host_d
   * gaps in tables. */
  struct csnmp_list_instances_s
  {
-   oid subid;
+   oid_t suffix;
    char instance[DATA_MAX_NAME_LEN];
    struct csnmp_list_instances_s *next;
  };
@@@ -87,7 -87,7 +87,7 @@@ typedef struct csnmp_list_instances_s c
  
  struct csnmp_table_values_s
  {
-   oid subid;
+   oid_t suffix;
    value_t value;
    struct csnmp_table_values_s *next;
  };
@@@ -106,6 -106,54 +106,54 @@@ static int csnmp_read_host (user_data_
  /*
   * Private functions
   */
+ static void csnmp_oid_init (oid_t *dst, oid const *src, size_t n)
+ {
+   assert (n <= STATIC_ARRAY_LEN (dst->oid));
+   memcpy (dst->oid, src, sizeof (*src) * n);
+   dst->oid_len = n;
+ }
+ static int csnmp_oid_compare (oid_t const *left, oid_t const *right)
+ {
+   return (snmp_oid_compare (left->oid, left->oid_len,
+         right->oid, right->oid_len));
+ }
+ static int csnmp_oid_suffix (oid_t *dst, oid_t const *src,
+     oid_t const *root)
+ {
+   /* Make sure "src" is in "root"s subtree. */
+   if (src->oid_len <= root->oid_len)
+     return (EINVAL);
+   if (snmp_oid_ncompare (root->oid, root->oid_len,
+         src->oid, src->oid_len,
+         /* n = */ root->oid_len) != 0)
+     return (EINVAL);
+   memset (dst, 0, sizeof (*dst));
+   dst->oid_len = src->oid_len - root->oid_len;
+   memcpy (dst->oid, &src->oid[root->oid_len],
+       dst->oid_len * sizeof (dst->oid[0]));
+   return (0);
+ }
+ static int csnmp_oid_to_string (char *buffer, size_t buffer_size,
+     oid_t const *o)
+ {
+   char oid_str[MAX_OID_LEN][16];
+   char *oid_str_ptr[MAX_OID_LEN];
+   size_t i;
+   for (i = 0; i < o->oid_len; i++)
+   {
+     ssnprintf (oid_str[i], sizeof (oid_str[i]), "%lu", (unsigned long) o->oid[i]);
+     oid_str_ptr[i] = oid_str[i];
+   }
+   return (strjoin (buffer, buffer_size,
+         oid_str_ptr, o->oid_len, /* separator = */ "."));
+ }
  static void csnmp_host_close_session (host_definition_t *host) /* {{{ */
  {
    if (host->sess_handle == NULL)
@@@ -127,7 -175,7 +175,7 @@@ static void csnmp_host_definition_destr
    if (hd->name != NULL)
    {
      DEBUG ("snmp plugin: Destroying host definition for host `%s'.",
-       hd->name);
+         hd->name);
    }
  
    csnmp_host_close_session (hd);
   *      +-> csnmp_config_add_host_community
   *      +-> csnmp_config_add_host_version
   *      +-> csnmp_config_add_host_collect
 - *      +-> csnmp_config_add_host_interval
   */
  static void call_snmp_init_once (void)
  {
@@@ -212,10 -261,10 +260,10 @@@ static int csnmp_config_add_data_instan
      dd->instance.oid.oid_len = MAX_OID_LEN;
  
      if (!read_objid (ci->values[0].value.string,
-         dd->instance.oid.oid, &dd->instance.oid.oid_len))
+           dd->instance.oid.oid, &dd->instance.oid.oid_len))
      {
        ERROR ("snmp plugin: read_objid (%s) failed.",
-         ci->values[0].value.string);
+           ci->values[0].value.string);
        return (-1);
      }
    }
    {
      /* Instance is a simple string */
      sstrncpy (dd->instance.string, ci->values[0].value.string,
-       sizeof (dd->instance.string));
+         sizeof (dd->instance.string));
    }
  
    return (0);
@@@ -241,7 -290,7 +289,7 @@@ static int csnmp_config_add_data_instan
    if (!dd->is_table)
    {
      WARNING ("snmp plugin: data %s: InstancePrefix is ignored when `Table' "
-       "is set to `false'.", dd->name);
+         "is set to `false'.", dd->name);
      return (-1);
    }
  
@@@ -282,10 -331,10 +330,10 @@@ static int csnmp_config_add_data_value
      dd->values[i].oid_len = MAX_OID_LEN;
  
      if (NULL == snmp_parse_oid (ci->values[i].value.string,
-         dd->values[i].oid, &dd->values[i].oid_len))
+           dd->values[i].oid, &dd->values[i].oid_len))
      {
        ERROR ("snmp plugin: snmp_parse_oid (%s) failed.",
-         ci->values[i].value.string);
+           ci->values[i].value.string);
        free (dd->values);
        dd->values = NULL;
        dd->values_len = 0;
@@@ -523,17 -572,17 +571,17 @@@ static int csnmp_config_add_host_collec
    {
      for (data = data_head; data != NULL; data = data->next)
        if (strcasecmp (ci->values[i].value.string, data->name) == 0)
-       break;
+         break;
  
      if (data == NULL)
      {
        WARNING ("snmp plugin: No such data configured: `%s'",
-         ci->values[i].value.string);
+           ci->values[i].value.string);
        continue;
      }
  
      DEBUG ("snmp plugin: Collect: host = %s, data[%i] = %s;",
-       host->name, host->data_list_len, data->name);
+         host->name, host->data_list_len, data->name);
  
      host->data_list[host->data_list_len] = data;
      host->data_list_len++;
    return (0);
  } /* int csnmp_config_add_host_collect */
  
 -static int csnmp_config_add_host_interval (host_definition_t *hd, oconfig_item_t *ci)
 -{
 -  if ((ci->values_num != 1)
 -      || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
 -  {
 -    WARNING ("snmp plugin: The `Interval' config option needs exactly one number argument.");
 -    return (-1);
 -  }
 -
 -  hd->interval = ci->values[0].value.number >= 0
 -    ? (uint32_t) ci->values[0].value.number
 -    : 0;
 -
 -  return (0);
 -} /* int csnmp_config_add_host_interval */
 -
  static int csnmp_config_add_host (oconfig_item_t *ci)
  {
    host_definition_t *hd;
      else if (strcasecmp ("Collect", option->key) == 0)
        csnmp_config_add_host_collect (hd, option);
      else if (strcasecmp ("Interval", option->key) == 0)
 -      csnmp_config_add_host_interval (hd, option);
 +      cf_util_get_cdtime (option, &hd->interval);
      else
      {
        WARNING ("snmp plugin: csnmp_config_add_host: Option `%s' not allowed here.", option->key);
    cb_data.data = hd;
    cb_data.free_func = csnmp_host_definition_destroy;
  
 -  memset (&cb_interval, 0, sizeof (cb_interval));
 -  if (hd->interval != 0)
 -    cb_interval.tv_sec = (time_t) hd->interval;
 +  CDTIME_T_TO_TIMESPEC (hd->interval, &cb_interval);
  
    status = plugin_register_complex_read (/* group = */ NULL, cb_name,
        csnmp_read_host, /* interval = */ &cb_interval,
@@@ -696,7 -763,7 +744,7 @@@ static void csnmp_host_open_session (ho
      snmp_error (&sess, NULL, NULL, &errstr);
  
      ERROR ("snmp plugin: host %s: snmp_sess_open failed: %s",
-       host->name, (errstr == NULL) ? "Unknown problem" : errstr);
+         host->name, (errstr == NULL) ? "Unknown problem" : errstr);
      sfree (errstr);
    }
  } /* void csnmp_host_open_session */
@@@ -747,16 -814,16 +795,16 @@@ static value_t csnmp_value_list_to_valu
  
      memset (oid_buffer, 0, sizeof (oid_buffer));
      snprint_objid (oid_buffer, sizeof (oid_buffer) - 1,
-       vl->name, vl->name_length);
+         vl->name, vl->name_length);
  
  #ifdef ASN_NULL
      if (vl->type == ASN_NULL)
        INFO ("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)",
-         oid_buffer);
+           oid_buffer);
      else
  #endif
        WARNING ("snmp plugin: I don't know the ASN type \"%i\" (OID: %s)",
-         (int) vl->type, oid_buffer);
+           (int) vl->type, oid_buffer);
  
      defined = 0;
    }
  
        string_length = sizeof (string) - 1;
        if (vl->val_len < string_length)
-       string_length = vl->val_len;
+         string_length = vl->val_len;
  
        /* The strings we get from the Net-SNMP library may not be null
         * terminated. That is why we're using `memcpy' here and not `strcpy'.
        status = parse_value (string, &ret, type);
        if (status != 0)
        {
-       ERROR ("snmp plugin: csnmp_value_list_to_value: Parsing string as %s failed: %s",
-           DS_TYPE_TO_STRING (type), string);
+         ERROR ("snmp plugin: csnmp_value_list_to_value: Parsing string as %s failed: %s",
+             DS_TYPE_TO_STRING (type), string);
        }
      }
  
      {
        switch (type)
        {
-       case DS_TYPE_COUNTER:
-       case DS_TYPE_DERIVE:
-       case DS_TYPE_ABSOLUTE:
-         memset (&ret, 0, sizeof (ret));
-         break;
-       case DS_TYPE_GAUGE:
-         ret.gauge = NAN;
-         break;
-       default:
-         ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown "
-             "data source type: %i.", type);
-         ret.gauge = NAN;
+         case DS_TYPE_COUNTER:
+         case DS_TYPE_DERIVE:
+         case DS_TYPE_ABSOLUTE:
+           memset (&ret, 0, sizeof (ret));
+           break;
+         case DS_TYPE_GAUGE:
+           ret.gauge = NAN;
+           break;
+         default:
+           ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown "
+               "data source type: %i.", type);
+           ret.gauge = NAN;
        }
      }
    } /* if (vl->type == ASN_OCTET_STR) */
    else
    {
      ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source "
-       "type: %i.", type);
+         "type: %i.", type);
      ret.gauge = NAN;
    }
  
@@@ -869,10 -936,10 +917,10 @@@ static int csnmp_check_res_left_subtre
      num_checked++;
  
      if ((vb->type == SNMP_ENDOFMIBVIEW)
-       || (snmp_oid_ncompare (data->values[i].oid,
-           data->values[i].oid_len,
-           vb->name, vb->name_length,
-           data->values[i].oid_len) != 0))
+         || (snmp_oid_ncompare (data->values[i].oid,
+             data->values[i].oid_len,
+             vb->name, vb->name_length,
+             data->values[i].oid_len) != 0))
        num_left_subtree++;
    }
  
    if (i < data->values_len)
    {
      ERROR ("snmp plugin: host %s: Expected %i variables, but got only %i",
-       host->name, data->values_len, i);
+         host->name, data->values_len, i);
      return (-1);
    }
  
      if (vb == NULL)
      {
        ERROR ("snmp plugin: host %s: Expected one more variable for "
-         "the instance..", host->name);
+           "the instance..", host->name);
        return (-1);
      }
  
      num_checked++;
      if (snmp_oid_ncompare (data->instance.oid.oid,
-         data->instance.oid.oid_len,
-         vb->name, vb->name_length,
-         data->instance.oid.oid_len) != 0)
+           data->instance.oid.oid_len,
+           vb->name, vb->name_length,
+           data->instance.oid.oid_len) != 0)
        num_left_subtree++;
    }
  
@@@ -924,7 -991,7 +972,7 @@@ static int csnmp_strvbcopy_hexstring (c
      int status;
  
      status = snprintf (buffer_ptr, buffer_free,
-       (i == 0) ? "%02x" : ":%02x", (unsigned int) vb->val.bitstring[i]);
+         (i == 0) ? "%02x" : ":%02x", (unsigned int) vb->val.bitstring[i]);
  
      if (status >= buffer_free)
      {
@@@ -977,10 -1044,13 +1025,13 @@@ static int csnmp_strvbcopy (char *dst, 
  
  static int csnmp_instance_list_add (csnmp_list_instances_t **head,
      csnmp_list_instances_t **tail,
-     const struct snmp_pdu *res)
+     struct snmp_pdu const *res,
+     oid_t const *root)
  {
    csnmp_list_instances_t *il;
    struct variable_list *vb;
+   oid_t vb_name;
+   int status;
  
    /* Set vb on the last variable */
    for (vb = res->variables;
    if (vb == NULL)
      return (-1);
  
-   il = (csnmp_list_instances_t *) malloc (sizeof (csnmp_list_instances_t));
+   csnmp_oid_init (&vb_name, vb->name, vb->name_length);
+   il = malloc (sizeof (*il));
    if (il == NULL)
    {
      ERROR ("snmp plugin: malloc failed.");
      return (-1);
    }
-   il->subid = vb->name[vb->name_length - 1];
+   memset (il, 0, sizeof (*il));
    il->next = NULL;
  
+   status = csnmp_oid_suffix (&il->suffix, &vb_name, root);
+   if (status != 0)
+   {
+     sfree (il);
+     return (status);
+   }
    /* Get instance name */
    if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR))
    {
      for (ptr = il->instance; *ptr != '\0'; ptr++)
      {
        if ((*ptr > 0) && (*ptr < 32))
-       *ptr = ' ';
+         *ptr = ' ';
        else if (*ptr == '/')
-       *ptr = '_';
+         *ptr = '_';
      }
      DEBUG ("snmp plugin: il->instance = `%s';", il->instance);
    }
    {
      value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, 1.0, 0.0);
      ssnprintf (il->instance, sizeof (il->instance),
-       "%llu", val.counter);
+         "%llu", val.counter);
    }
  
    /* TODO: Debugging output */
@@@ -1044,8 -1123,8 +1104,8 @@@ static int csnmp_dispatch_table (host_d
    csnmp_table_values_t **value_table_ptr;
  
    int i;
-   oid subid;
-   int have_more;
+   _Bool have_more;
+   oid_t current_suffix;
  
    ds = plugin_get_ds (data->type);
    if (!ds)
  
    instance_list_ptr = instance_list;
  
-   value_table_ptr = (csnmp_table_values_t **) malloc (sizeof (csnmp_table_values_t *)
-       * data->values_len);
+   value_table_ptr = malloc (sizeof (*value_table_ptr) * data->values_len);
    if (value_table_ptr == NULL)
      return (-1);
    for (i = 0; i < data->values_len; i++)
      value_table_ptr[i] = value_table[i];
  
    vl.values_len = ds->ds_num;
-   vl.values = (value_t *) malloc (sizeof (value_t) * vl.values_len);
+   vl.values = malloc (sizeof (*vl.values) * vl.values_len);
    if (vl.values == NULL)
    {
      ERROR ("snmp plugin: malloc failed.");
  
    vl.interval = host->interval;
  
-   subid = 0;
    have_more = 1;
-   while (have_more != 0)
+   memset (&current_suffix, 0, sizeof (current_suffix));
+   while (have_more)
    {
+     _Bool suffix_skipped = 0;
+     /* Determine next suffix to handle. */
      if (instance_list != NULL)
      {
-       while ((instance_list_ptr != NULL)
-         && (instance_list_ptr->subid < subid))
-       instance_list_ptr = instance_list_ptr->next;
        if (instance_list_ptr == NULL)
        {
-       have_more = 0;
-       continue;
+         have_more = 0;
+         continue;
        }
-       else if (instance_list_ptr->subid > subid)
+       memcpy (&current_suffix, &instance_list_ptr->suffix, sizeof (current_suffix));
+     }
+     else /* no instance configured */
+     {
+       csnmp_table_values_t *ptr = value_table_ptr[0];
+       if (ptr == NULL)
        {
-       subid = instance_list_ptr->subid;
-       continue;
+         have_more = 0;
+         continue;
        }
-     } /* if (instance_list != NULL) */
  
+       memcpy (&current_suffix, &ptr->suffix, sizeof (current_suffix));
+     }
+     /* Update all the value_table_ptr to point at the entry with the same
+      * trailing partial OID */
      for (i = 0; i < data->values_len; i++)
      {
        while ((value_table_ptr[i] != NULL)
-         && (value_table_ptr[i]->subid < subid))
-       value_table_ptr[i] = value_table_ptr[i]->next;
+           && (csnmp_oid_compare (&value_table_ptr[i]->suffix, &current_suffix) < 0))
+         value_table_ptr[i] = value_table_ptr[i]->next;
  
        if (value_table_ptr[i] == NULL)
        {
-       have_more = 0;
-       break;
+         have_more = 0;
+         break;
        }
-       else if (value_table_ptr[i]->subid > subid)
+       else if (csnmp_oid_compare (&value_table_ptr[i]->suffix, &current_suffix) > 0)
        {
-       subid = value_table_ptr[i]->subid;
-       break;
+         /* This suffix is missing in the subtree. Indicate this with the
+          * "suffix_skipped" flag and try the next instance / suffix. */
+         suffix_skipped = 1;
+         break;
        }
      } /* for (i = 0; i < columns; i++) */
-     /* The subid has been increased - start scanning from the beginning
-      * again.. */
-     if (i < data->values_len)
+     if (!have_more)
+       break;
+     /* Matching the values failed. Start from the beginning again. */
+     if (suffix_skipped)
+     {
+       if (instance_list != NULL)
+         instance_list_ptr = instance_list_ptr->next;
+       else
+         value_table_ptr[0] = value_table_ptr[0]->next;
        continue;
+     }
  
      /* if we reach this line, all value_table_ptr[i] are non-NULL and are set
       * to the same subid. instance_list_ptr is either NULL or points to the
      for (i = 1; i < data->values_len; i++)
      {
        assert (value_table_ptr[i] != NULL);
-       assert (value_table_ptr[i-1]->subid == value_table_ptr[i]->subid);
+       assert (csnmp_oid_compare (&value_table_ptr[i-1]->suffix,
+             &value_table_ptr[i]->suffix) == 0);
      }
      assert ((instance_list_ptr == NULL)
-       || (instance_list_ptr->subid == value_table_ptr[0]->subid));
+         || (csnmp_oid_compare (&instance_list_ptr->suffix,
+             &value_table_ptr[0]->suffix) == 0));
  #endif
  
      sstrncpy (vl.type, data->type, sizeof (vl.type));
        char temp[DATA_MAX_NAME_LEN];
  
        if (instance_list_ptr == NULL)
-       ssnprintf (temp, sizeof (temp), "%"PRIu32, (uint32_t) subid);
+         csnmp_oid_to_string (temp, sizeof (temp), &current_suffix);
        else
-       sstrncpy (temp, instance_list_ptr->instance, sizeof (temp));
+         sstrncpy (temp, instance_list_ptr->instance, sizeof (temp));
  
        if (data->instance_prefix == NULL)
-       sstrncpy (vl.type_instance, temp, sizeof (vl.type_instance));
+         sstrncpy (vl.type_instance, temp, sizeof (vl.type_instance));
        else
-       ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s%s",
-           data->instance_prefix, temp);
+         ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%s%s",
+             data->instance_prefix, temp);
      }
  
      for (i = 0; i < data->values_len; i++)
      /* If we get here `vl.type_instance' and all `vl.values' have been set */
      plugin_dispatch_values (&vl);
  
-     subid++;
-   } /* while (have_more != 0) */
+     if (instance_list != NULL)
+       instance_list_ptr = instance_list_ptr->next;
+     else
+       value_table_ptr[0] = value_table_ptr[0]->next;
+   } /* while (have_more) */
  
    sfree (vl.values);
    sfree (value_table_ptr);
@@@ -1181,13 -1284,13 +1265,13 @@@ static int csnmp_read_table (host_defin
    int status;
    int i;
  
-   /* `value_table' and `value_table_ptr' implement a linked list for each
-    * value. `instance_list' and `instance_list_ptr' implement a linked list of
+   /* `value_list_head' and `value_list_tail' implement a linked list for each
+    * value. `instance_list_head' and `instance_list_tail' implement a linked list of
     * instance names. This is used to jump gaps in the table. */
-   csnmp_list_instances_t *instance_list;
-   csnmp_list_instances_t *instance_list_ptr;
-   csnmp_table_values_t **value_table;
-   csnmp_table_values_t **value_table_ptr;
+   csnmp_list_instances_t *instance_list_head;
+   csnmp_list_instances_t *instance_list_tail;
+   csnmp_table_values_t **value_list_head;
+   csnmp_table_values_t **value_list_tail;
  
    DEBUG ("snmp plugin: csnmp_read_table (host = %s, data = %s)",
        host->name, data->name);
    if (ds->ds_num != data->values_len)
    {
      ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
-       data->type, ds->ds_num, data->values_len);
+         data->type, ds->ds_num, data->values_len);
      return (-1);
    }
  
    else
      oid_list_len--;
  
-   /* Allocate the `value_table' */
-   value_table = (csnmp_table_values_t **) malloc (sizeof (csnmp_table_values_t *)
-       * 2 * data->values_len);
-   if (value_table == NULL)
+   /* We're going to construct n linked lists, one for each "value".
+    * value_list_head will contain pointers to the heads of these linked lists,
+    * value_list_tail will contain pointers to the tail of the lists. */
+   value_list_head = calloc (data->values_len, sizeof (*value_list_head));
+   value_list_tail = calloc (data->values_len, sizeof (*value_list_tail));
+   if ((value_list_head == NULL) || (value_list_tail == NULL))
    {
-     ERROR ("snmp plugin: csnmp_read_table: malloc failed.");
+     ERROR ("snmp plugin: csnmp_read_table: calloc failed.");
      sfree (oid_list);
+     sfree (value_list_head);
+     sfree (value_list_tail);
      return (-1);
    }
-   memset (value_table, '\0', sizeof (csnmp_table_values_t *) * 2 * data->values_len);
-   value_table_ptr = value_table + data->values_len;
-   
-   instance_list = NULL;
-   instance_list_ptr = NULL;
+   instance_list_head = NULL;
+   instance_list_tail = NULL;
  
    status = 0;
    while (status == 0)
        snmp_sess_error (host->sess_handle, NULL, NULL, &errstr);
  
        c_complain (LOG_ERR, &host->complaint,
-         "snmp plugin: host %s: snmp_sess_synch_response failed: %s",
-         host->name, (errstr == NULL) ? "Unknown problem" : errstr);
+           "snmp plugin: host %s: snmp_sess_synch_response failed: %s",
+           host->name, (errstr == NULL) ? "Unknown problem" : errstr);
  
        if (res != NULL)
-       snmp_free_pdu (res);
+         snmp_free_pdu (res);
        res = NULL;
  
        sfree (errstr);
      status = 0;
      assert (res != NULL);
      c_release (LOG_INFO, &host->complaint,
-       "snmp plugin: host %s: snmp_sess_synch_response successful.",
-       host->name);
+         "snmp plugin: host %s: snmp_sess_synch_response successful.",
+         host->name);
  
      vb = res->variables;
      if (vb == NULL)
        break;
      }
  
-     /* if an instance-OID is configured.. */
+     /* Copy the OID of the value used as instance to oid_list, if an instance
+      * is configured. */
      if (data->instance.oid.oid_len > 0)
      {
        /* Allocate a new `csnmp_list_instances_t', insert the instance name and
         * add it to the list */
-       if (csnmp_instance_list_add (&instance_list, &instance_list_ptr,
-           res) != 0)
+       if (csnmp_instance_list_add (&instance_list_head, &instance_list_tail,
+             res, &data->instance.oid) != 0)
        {
-       ERROR ("snmp plugin: csnmp_instance_list_add failed.");
-       status = -1;
-       break;
+         ERROR ("snmp plugin: csnmp_instance_list_add failed.");
+         status = -1;
+         break;
        }
  
-       /* Set vb on the last variable */
+       /* The instance OID is added to the list of OIDs to GET from the
+        * snmp agent last, so set vb on the last variable returned and copy
+        * that OID. */
        for (vb = res->variables;
-         (vb != NULL) && (vb->next_variable != NULL);
-         vb = vb->next_variable)
-       /* do nothing */;
+           (vb != NULL) && (vb->next_variable != NULL);
+           vb = vb->next_variable)
+         /* do nothing */;
        assert (vb != NULL);
  
-       /* Copy OID to oid_list[data->values_len] */
+       /* Copy the OID of the instance value to oid_list[data->values_len].
+        * "oid_list" is used for the next GETNEXT request. */
        memcpy (oid_list[data->values_len].oid, vb->name,
-         sizeof (oid) * vb->name_length);
+           sizeof (oid) * vb->name_length);
        oid_list[data->values_len].oid_len = vb->name_length;
      }
  
+     /* Iterate over all the (non-instance) values returned by the agent. The
+      * (i < value_len) check will make sure we're not handling the instance OID
+      * twice. */
      for (vb = res->variables, i = 0;
-       (vb != NULL) && (i < data->values_len);
-       vb = vb->next_variable, i++)
+         (vb != NULL) && (i < data->values_len);
+         vb = vb->next_variable, i++)
      {
        csnmp_table_values_t *vt;
+       oid_t vb_name;
+       oid_t suffix;
  
-       /* Check if we left the subtree */
-       if (snmp_oid_ncompare (data->values[i].oid,
-           data->values[i].oid_len,
-           vb->name, vb->name_length,
-           data->values[i].oid_len) != 0)
+       csnmp_oid_init (&vb_name, vb->name, vb->name_length);
+       /* Calculate the current suffix. This is later used to check that the
+        * suffix is increasing. This also checks if we left the subtree */
+       status = csnmp_oid_suffix (&suffix, &vb_name, data->values + i);
+       if (status != 0)
        {
-       DEBUG ("snmp plugin: host = %s; data = %s; Value %i left its subtree.",
-           host->name, data->name, i);
-       continue;
+         DEBUG ("snmp plugin: host = %s; data = %s; Value %i failed. "
+             "It probably left its subtree.",
+             host->name, data->name, i);
+         continue;
        }
  
-       if ((value_table_ptr[i] != NULL)
-         && (vb->name[vb->name_length - 1] <= value_table_ptr[i]->subid))
+       /* Make sure the OIDs returned by the agent are increasing. Otherwise our
+        * table matching algorithm will get confused. */
+       if ((value_list_tail[i] != NULL)
+           && (csnmp_oid_compare (&suffix, &value_list_tail[i]->suffix) <= 0))
        {
-       DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
-           "SUBID is not increasing.",
-           host->name, data->name, i);
-       continue;
+         DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
+             "Suffix is not increasing.",
+             host->name, data->name, i);
+         continue;
        }
  
-       vt = (csnmp_table_values_t *) malloc (sizeof (csnmp_table_values_t));
+       vt = malloc (sizeof (*vt));
        if (vt == NULL)
        {
-       ERROR ("snmp plugin: malloc failed.");
-       status = -1;
-       break;
+         ERROR ("snmp plugin: malloc failed.");
+         status = -1;
+         break;
        }
+       memset (vt, 0, sizeof (*vt));
  
-       vt->subid = vb->name[vb->name_length - 1];
        vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type,
-         data->scale, data->shift);
+           data->scale, data->shift);
+       memcpy (&vt->suffix, &suffix, sizeof (vt->suffix));
        vt->next = NULL;
  
-       if (value_table_ptr[i] == NULL)
-       value_table[i] = vt;
+       if (value_list_tail[i] == NULL)
+         value_list_head[i] = vt;
        else
-       value_table_ptr[i]->next = vt;
-       value_table_ptr[i] = vt;
+         value_list_tail[i]->next = vt;
+       value_list_tail[i] = vt;
  
        /* Copy OID to oid_list[i + 1] */
        memcpy (oid_list[i].oid, vb->name, sizeof (oid) * vb->name_length);
    res = NULL;
  
    if (status == 0)
-     csnmp_dispatch_table (host, data, instance_list, value_table);
+     csnmp_dispatch_table (host, data, instance_list_head, value_list_head);
  
    /* Free all allocated variables here */
-   while (instance_list != NULL)
+   while (instance_list_head != NULL)
    {
-     instance_list_ptr = instance_list->next;
-     sfree (instance_list);
-     instance_list = instance_list_ptr;
+     csnmp_list_instances_t *next = instance_list_head->next;
+     sfree (instance_list_head);
+     instance_list_head = next;
    }
  
    for (i = 0; i < data->values_len; i++)
    {
-     csnmp_table_values_t *tmp;
-     while (value_table[i] != NULL)
+     while (value_list_head[i] != NULL)
      {
-       tmp = value_table[i]->next;
-       sfree (value_table[i]);
-       value_table[i] = tmp;
+       csnmp_table_values_t *next = value_list_head[i]->next;
+       sfree (value_list_head[i]);
+       value_list_head[i] = next;
      }
    }
  
-   sfree (value_table);
+   sfree (value_list_head);
+   sfree (value_list_tail);
    sfree (oid_list);
  
    return (0);
@@@ -1443,7 -1562,7 +1543,7 @@@ static int csnmp_read_value (host_defin
    if (ds->ds_num != data->values_len)
    {
      ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
-       data->type, ds->ds_num, data->values_len);
+         data->type, ds->ds_num, data->values_len);
      return (-1);
    }
  
  
      snmp_sess_error (host->sess_handle, NULL, NULL, &errstr);
      ERROR ("snmp plugin: host %s: snmp_sess_synch_response failed: %s",
-       host->name, (errstr == NULL) ? "Unknown problem" : errstr);
+         host->name, (errstr == NULL) ? "Unknown problem" : errstr);
  
      if (res != NULL)
        snmp_free_pdu (res);
  #if COLLECT_DEBUG
      char buffer[1024];
      snprint_variable (buffer, sizeof (buffer),
-       vb->name, vb->name_length, vb);
+         vb->name, vb->name_length, vb);
      DEBUG ("snmp plugin: Got this variable: %s", buffer);
  #endif /* COLLECT_DEBUG */
  
      for (i = 0; i < data->values_len; i++)
        if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len,
-           vb->name, vb->name_length) == 0)
-       vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type,
-           data->scale, data->shift);
+             vb->name, vb->name_length) == 0)
+         vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type,
+             data->scale, data->shift);
    } /* for (res->variables) */
  
    if (res != NULL)
  static int csnmp_read_host (user_data_t *ud)
  {
    host_definition_t *host;
 -  time_t time_start;
 -  time_t time_end;
 +  cdtime_t time_start;
 +  cdtime_t time_end;
    int status;
    int success;
    int i;
    if (host->interval == 0)
      host->interval = interval_g;
  
 -  time_start = time (NULL);
 -  DEBUG ("snmp plugin: csnmp_read_host (%s) started at %u;", host->name,
 -      (unsigned int) time_start);
 +  time_start = cdtime ();
  
    if (host->sess_handle == NULL)
      csnmp_host_open_session (host);
        success++;
    }
  
 -  time_end = time (NULL);
 -  DEBUG ("snmp plugin: csnmp_read_host (%s) finished at %u;", host->name,
 -      (unsigned int) time_end);
 -  if ((uint32_t) (time_end - time_start) > host->interval)
 +  time_end = cdtime ();
 +  if ((time_end - time_start) > host->interval)
    {
 -    WARNING ("snmp plugin: Host `%s' should be queried every %"PRIu32
 -        " seconds, but reading all values takes %u seconds.",
 -        host->name, host->interval, (unsigned int) (time_end - time_start));
 +    WARNING ("snmp plugin: Host `%s' should be queried every %.3f "
 +      "seconds, but reading all values takes %.3f seconds.",
 +      host->name,
 +      CDTIME_T_TO_DOUBLE (host->interval),
 +      CDTIME_T_TO_DOUBLE (time_end - time_start));
    }
  
    if (success == 0)