Merge branch 'collectd-5.0'
authorFlorian Forster <octo@collectd.org>
Sun, 1 Apr 2012 10:07:20 +0000 (12:07 +0200)
committerFlorian Forster <octo@collectd.org>
Sun, 1 Apr 2012 10:07:20 +0000 (12:07 +0200)
1  2 
ChangeLog
configure.in
src/Makefile.am
src/collectd.conf.pod
src/libcollectdclient/client.c
src/processes.c
src/snmp.c
src/tcpconns.c
version-gen.sh

diff --combined ChangeLog
+++ b/ChangeLog
@@@ -1,3 -1,32 +1,32 @@@
+ 2012-04-01, Version 5.0.4
+       * Build system: Fix the use of a libltdl macro. Thanks to Clemens Lang
+         for fixing this. Adresses some issues with building the iptables
+         plugin under Gentoo.
+       * libcollectdclient: A memory leak in the lcc_getval() function has
+         been fixed. Thanks to Jason Schmidlapp for finding and fixing this
+         issue.
+       * bind plugin: The use of 'QType" types has been fixed.
+       * df plugin: Fixed compiler issue under Mac OS X 10.7.
+       * conntrack plugin: Support zero as legitimate value. Thanks to Louis
+         Opter for his patch.
+       * memcached plugin: Increased the size of a static buffer, which was
+         truncating status messages form memcached. Thanks to Timon for the
+         patch.
+       * network plugin: Forwarding of notifications has been disabled. This
+         was a contition not checked for before, which may retult in an
+         endless loop.
+       * processes plugin: Support for process names with spaces has been
+         added to the Linux implementation. Thanks to Darrell Bishop for his
+         patch.
+       * perl plugin: A race condition in several callbacks, including log and
+         write callbacks, has been fixed. Thanks to "Rrpv" for reporting this
+         bug.
+       * snmp plugin: A bug when casting unsigned integers to gauge values has
+         been fixed: Unsigned integers would be cast to a signed integer and
+         then to a gauge, possibly resulting in a negative value.
+       * tcpconns plugin: Compilation with newer versions of the FreeBSD
+         runtime has been fixed.
  2012-02-19, Version 5.0.3
        * Build system: Fix problems when building the ipvs and iptables
          plugins. Thanks to Sebastian Harl for his patch. A bashism in the
          technique of POWER CPUs. Thanks to AurĂ©lien Reynaud for his code and
          patience.
        * modbus plugin: Support for libmodbus 2.9.2 has been added and the
 -        license has been changes to LGPLv2.1.
 +        license has been changed to LGPLv2.1.
        * mysql plugin: Backwards compatibility code has been removed. The
          data sets used have been improved.
        * network plugin: The default buffer size has been increased to
        * v5upgrade target: Target for converting v4 data sets to the v5
          schema.
  
+ 2012-04-01, Version 4.10.7
+       * Build system: Fix the use of a libltdl macro. Thanks to Clemens Lang
+         for fixing this. Adresses some issues with building the iptables
+         plugin under Gentoo.
+       * libcollectdclient: A memory leak in the lcc_getval() function has
+         been fixed. Thanks to Jason Schmidlapp for finding and fixing this
+         issue.
+       * bind plugin: The use of 'QType" types has been fixed.
+       * df plugin: Fixed compiler issue under Mac OS X 10.7.
+       * conntrack plugin: Support zero as legitimate value. Thanks to Louis
+         Opter for his patch.
+       * memcached plugin: Increased the size of a static buffer, which was
+         truncating status messages form memcached. Thanks to Timon for the
+         patch.
+       * network plugin: Forwarding of notifications has been disabled. This
+         was a contition not checked for before, which may retult in an
+         endless loop.
+       * processes plugin: Support for process names with spaces has been
+         added to the Linux implementation. Thanks to Darrell Bishop for his
+         patch.
+       * perl plugin: A race condition in several callbacks, including log and
+         write callbacks, has been fixed. Thanks to "Rrpv" for reporting this
+         bug.
+       * snmp plugin: A bug when casting unsigned integers to gauge values has
+         been fixed: Unsigned integers would be cast to a signed integer and
+         then to a gauge, possibly resulting in a negative value.
+       * tcpconns plugin: Compilation with newer versions of the FreeBSD
+         runtime has been fixed.
  2012-02-19, Version 4.10.6
        * Build system: Fix problems when building the ipvs and iptables
          plugins. Thanks to Sebastian Harl for his patch. A bashism in the
diff --combined configure.in
@@@ -1,5 -1,5 +1,5 @@@
  dnl Process this file with autoconf to produce a configure script.
 -AC_INIT(collectd, m4_esyscmd(./version-gen.sh))
 +AC_INIT(collectd, [m4_esyscmd(./version-gen.sh)])
  AC_CONFIG_SRCDIR(src/collectd.c)
  AC_CONFIG_HEADERS(src/config.h)
  AC_CONFIG_AUX_DIR([libltdl/config])
  # For hddtemp module
  AC_CHECK_HEADERS(linux/major.h libgen.h)
  
 +# For md module (Linux only)
 +if test "x$ac_system" = "xLinux"
 +then
 +      AC_CHECK_HEADERS(linux/raid/md_u.h,
 +                       [have_linux_raid_md_u_h="yes"],
 +                       [have_linux_raid_md_u_h="no"],
 +[
 +#include <sys/ioctl.h>
 +#include <linux/major.h>
 +#include <linux/types.h>
 +])
 +else
 +      have_linux_raid_md_u_h="no"
 +fi
 +
  # For the battery plugin
  AC_CHECK_HEADERS(IOKit/ps/IOPowerSources.h, [], [],
  [
@@@ -403,33 -388,6 +403,33 @@@ AC_CHECK_HEADERS(linux/netdevice.h, []
  #endif
  ])
  
 +# For ethstat module
 +AC_CHECK_HEADERS(linux/sockios.h,
 +    [have_linux_sockios_h="yes"],
 +    [have_linux_sockios_h="no"],
 +    [
 +#if HAVE_SYS_IOCTL_H
 +# include <sys/ioctl.h>
 +#endif
 +#if HAVE_NET_IF_H
 +# include <net/if.h>
 +#endif
 +    ])
 +AC_CHECK_HEADERS(linux/ethtool.h,
 +    [have_linux_ethtool_h="yes"],
 +    [have_linux_ethtool_h="no"],
 +    [
 +#if HAVE_SYS_IOCTL_H
 +# include <sys/ioctl.h>
 +#endif
 +#if HAVE_NET_IF_H
 +# include <net/if.h>
 +#endif
 +#if HAVE_LINUX_SOCKIOS_H
 +# include <linux/sockios.h>
 +#endif
 +    ])
 +
  # For ipvs module
  have_linux_ip_vs_h="no"
  have_net_ip_vs_h="no"
@@@ -1301,7 -1259,6 +1301,7 @@@ AC_CHECK_MEMBERS([kstat_io_t.nwritten, 
  #
  # Checks for libraries begin here
  #
 +
  with_libresolv="yes"
  AC_CHECK_LIB(resolv, res_search,
  [
@@@ -1423,6 -1380,7 +1423,7 @@@ AM_CONDITIONAL(BUILD_WITH_LIBKVM_GETSWA
  AC_CHECK_LIB(kvm, kvm_nlist, [with_kvm_nlist="yes"], [with_kvm_nlist="no"])
  if test "x$with_kvm_nlist" = "xyes"
  then
+       AC_CHECK_HEADERS(bsd/nlist.h nlist.h)
        AC_DEFINE(HAVE_LIBKVM_NLIST, 1,
                  [Define to 1 if you have the 'kvm' library with the 'kvm_nlist' symbol (-lkvm)])
        with_libkvm="yes"
        AC_CHECK_TYPES([iptc_handle_t, ip6tc_handle_t], [], [])
  fi
  # Check for the iptc_init symbol in the library.
+ # This could be in iptc or ip4tc
  if test "x$with_libiptc" = "xpkgconfig"
  then
-       AC_CHECK_LIB(iptc, iptc_init,
+       AC_SEARCH_LIBS(iptc_init, [iptc ip4tc],
                        [with_libiptc="pkgconfig"],
                        [with_libiptc="no"],
                        [$with_libiptc_libs])
  fi
  if test "x$with_libmodbus" = "xuse_pkgconfig"
  then
 -      AC_MSG_NOTICE([Checking for modbus using $PKG_CONFIG])
 -      $PKG_CONFIG --exists 'modbus' 2>/dev/null
 +      AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG])
 +      $PKG_CONFIG --exists 'libmodbus' 2>/dev/null
        if test $? -ne 0
        then
 -              with_libmodbus="no (pkg-config doesn't know modbus)"
 +              with_libmodbus="no (pkg-config doesn't know libmodbus)"
        fi
  fi
  if test "x$with_libmodbus" = "xuse_pkgconfig"
  then
 -      with_libmodbus_cflags="`$PKG_CONFIG --cflags 'modbus'`"
 +      with_libmodbus_cflags="`$PKG_CONFIG --cflags 'libmodbus'`"
        if test $? -ne 0
        then
                with_libmodbus="no ($PKG_CONFIG failed)"
        fi
 -      with_libmodbus_libs="`$PKG_CONFIG --libs 'modbus'`"
 +      with_libmodbus_libs="`$PKG_CONFIG --libs 'libmodbus'`"
        if test $? -ne 0
        then
                with_libmodbus="no ($PKG_CONFIG failed)"
  fi
  # }}}
  
 +# --with-libmongoc {{{
 +AC_ARG_WITH(libmongoc, [AS_HELP_STRING([--with-libmongoc@<:@=PREFIX@:>@], [Path to libmongoc.])],
 +[
 + if test "x$withval" = "xyes"
 + then
 +       with_libmongoc="yes"
 + else if test "x$withval" = "xno"
 + then
 +       with_libmongoc="no"
 + else
 +       with_libmongoc="yes"
 +       LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS -I$withval/include"
 +       LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS -L$withval/lib"
 + fi; fi
 +],
 +[with_libmongoc="yes"])
 +
 +SAVE_CPPFLAGS="$CPPFLAGS"
 +SAVE_LDFLAGS="$LDFLAGS"
 +
 +CPPFLAGS="$CPPFLAGS $LIBMONGOC_CPPFLAGS"
 +LDFLAGS="$LDFLAGS $LIBMONGOC_LDFLAGS"
 +
 +if test "x$with_libmongoc" = "xyes"
 +then
 +      if test "x$LIBMONGOC_CPPFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([libmongoc CPPFLAGS: $LIBMONGOC_CPPFLAGS])
 +      fi
 +      AC_CHECK_HEADERS(mongo.h,
 +      [with_libmongoc="yes"],
 +      [with_libmongoc="no ('mongo.h' not found)"],
 +[#if HAVE_STDINT_H
 +# define MONGO_HAVE_STDINT 1
 +#else
 +# define MONGO_USE_LONG_LONG_INT 1
 +#endif
 +])
 +fi
 +if test "x$with_libmongoc" = "xyes"
 +then
 +      if test "x$LIBMONGOC_LDFLAGS" != "x"
 +      then
 +              AC_MSG_NOTICE([libmongoc LDFLAGS: $LIBMONGOC_LDFLAGS])
 +      fi
 +      AC_CHECK_LIB(mongoc, mongo_run_command,
 +      [with_libmongoc="yes"],
 +      [with_libmongoc="no (symbol 'mongo_run_command' not found)"])
 +fi
 +
 +CPPFLAGS="$SAVE_CPPFLAGS"
 +LDFLAGS="$SAVE_LDFLAGS"
 +
 +if test "x$with_libmongoc" = "xyes"
 +then
 +      BUILD_WITH_LIBMONGOC_CPPFLAGS="$LIBMONGOC_CPPFLAGS"
 +      BUILD_WITH_LIBMONGOC_LDFLAGS="$LIBMONGOC_LDFLAGS"
 +      AC_SUBST(BUILD_WITH_LIBMONGOC_CPPFLAGS)
 +      AC_SUBST(BUILD_WITH_LIBMONGOC_LDFLAGS)
 +fi
 +AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
 +# }}}
 +
  # --with-libmysql {{{
  with_mysql_config="mysql_config"
  with_mysql_cflags=""
@@@ -3350,26 -3246,39 +3352,39 @@@ AC_ARG_WITH(librabbitmq, [AS_HELP_STRIN
  [
        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
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
        AC_CHECK_HEADERS(amqp.h, [with_librabbitmq="yes"], [with_librabbitmq="no (amqp.h not found)"])
-       CPPFLAGS="$SAVE_CPPFLAGS"
  fi
  if test "x$with_librabbitmq" = "xyes"
  then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_librabbitmq_cppflags"
-       LDFLAGS="$LDFLAGS $with_librabbitmq_ldflags"
+       # 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)"])
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
  fi
  if test "x$with_librabbitmq" = "xyes"
  then
        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")
  # }}}
  
@@@ -4099,9 -4010,10 +4116,9 @@@ the
        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])
 +    AC_CHECK_HEADERS(varnish/vsc.h,
 +        [AC_DEFINE([HAVE_VARNISH_V3], [1], [Varnish 3 API support])],
 +        [AC_DEFINE([HAVE_VARNISH_V2], [1], [Varnish 2 API support])])
  
        CPPFLAGS="$SAVE_CPPFLAGS"
        #LDFLAGS="$SAVE_LDFLAGS"
@@@ -4459,8 -4371,6 +4476,8 @@@ plugin_curl_xml="no
  plugin_df="no"
  plugin_disk="no"
  plugin_entropy="no"
 +plugin_ethstat="no"
 +plugin_fscache="no"
  plugin_interface="no"
  plugin_ipmi="no"
  plugin_ipvs="no"
@@@ -4470,7 -4380,7 +4487,7 @@@ plugin_load="no
  plugin_memory="no"
  plugin_multimeter="no"
  plugin_nfs="no"
 -plugin_fscache="no"
 +plugin_numa="no"
  plugin_perl="no"
  plugin_processes="no"
  plugin_protocols="no"
        plugin_cpufreq="yes"
        plugin_disk="yes"
        plugin_entropy="yes"
 +      plugin_fscache="yes"
        plugin_interface="yes"
        plugin_irq="yes"
        plugin_load="yes"
        plugin_memory="yes"
        plugin_nfs="yes"
 -      plugin_fscache="yes"
 +      plugin_numa="yes"
        plugin_processes="yes"
        plugin_protocols="yes"
        plugin_serial="yes"
  fi
  
  # AIX
 +
 +if test "x$ac_system" = "xAIX"
 +then
 +        plugin_tcpconns="yes"
 +fi
 +
  if test "x$with_perfstat" = "xyes"
  then
        plugin_cpu="yes"
  # Solaris
  if test "x$with_kstat" = "xyes"
  then
 +      plugin_nfs="yes"
        plugin_uptime="yes"
        plugin_zfs_arc="yes"
  fi
        fi
  fi
  
 +if test "x$have_linux_sockios_h$have_linux_ethtool_h" = "xyesyes"
 +then
 +      plugin_ethstat="yes"
 +fi
 +
  if test "x$have_getifaddrs" = "xyes"
  then
        plugin_interface="yes"
@@@ -4778,7 -4675,6 +4795,7 @@@ AC_PLUGIN([disk],        [$plugin_disk]
  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([filecount],   [yes],                [Count files in directories])
  AC_PLUGIN([fscache],     [$plugin_fscache],    [fscache statistics])
@@@ -4801,7 -4697,6 +4818,7 @@@ AC_PLUGIN([match_regex], [yes]
  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])
@@@ -4816,7 -4711,6 +4833,7 @@@ AC_PLUGIN([nginx],       [$with_libcurl
  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])
@@@ -4862,10 -4756,8 +4879,10 @@@ AC_PLUGIN([varnish],     [$with_libvarn
  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_redis], [$with_libcredis],    [Redis output plugin])
 +AC_PLUGIN([write_mongodb], [$with_libmongoc],  [MongoDB output plugin])
  AC_PLUGIN([xmms],        [$with_libxmms],      [XMMS statistics])
  AC_PLUGIN([zfs_arc],     [$plugin_zfs_arc],    [ZFS ARC statistics])
  
@@@ -5008,7 -4900,7 +5025,7 @@@ AC_SUBST(LCC_VERSION_STRING
  
  AC_CONFIG_FILES(src/libcollectdclient/lcc_features.h)
  
 -AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/owniptc/Makefile src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile)
 +AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile)
  
  if test "x$with_librrd" = "xyes" \
        && test "x$librrd_threadsafe" != "xyes"
@@@ -5110,7 -5002,6 +5127,7 @@@ Configuration
      dns . . . . . . . . . $enable_dns
      email . . . . . . . . $enable_email
      entropy . . . . . . . $enable_entropy
 +    ethstat . . . . . . . $enable_ethstat
      exec  . . . . . . . . $enable_exec
      filecount . . . . . . $enable_filecount
      fscache . . . . . . . $enable_fscache
      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
      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
      vmem  . . . . . . . . $enable_vmem
      vserver . . . . . . . $enable_vserver
      wireless  . . . . . . $enable_wireless
 +    write_graphite  . . . $enable_write_graphite
      write_http  . . . . . $enable_write_http
      write_redis . . . . . $enable_write_redis
 +    write_mongodb . . . . $enable_write_mongodb
      xmms  . . . . . . . . $enable_xmms
      zfs_arc . . . . . . . $enable_zfs_arc
  
diff --combined src/Makefile.am
@@@ -1,4 -1,7 +1,4 @@@
  SUBDIRS = libcollectdclient
 -if BUILD_WITH_OWN_LIBIPTC
 -SUBDIRS += owniptc
 -endif
  if BUILD_WITH_OWN_LIBOCONFIG
  SUBDIRS += liboconfig
  endif
@@@ -82,7 -85,7 +82,7 @@@ endi
  
  if BUILD_WITH_OWN_LIBOCONFIG
  collectd_LDADD += $(LIBLTDL) liboconfig/liboconfig.la
- collectd_DEPENDENCIES += $(LIBLTDL) liboconfig/liboconfig.la
+ collectd_DEPENDENCIES += liboconfig/liboconfig.la
  else
  collectd_LDADD += -loconfig
  endif
@@@ -378,14 -381,6 +378,14 @@@ collectd_LDADD += "-dlopen" exec.l
  collectd_DEPENDENCIES += exec.la
  endif
  
 +if BUILD_PLUGIN_ETHSTAT
 +pkglib_LTLIBRARIES += ethstat.la
 +ethstat_la_SOURCES = ethstat.c
 +ethstat_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" ethstat.la
 +collectd_DEPENDENCIES += ethstat.la
 +endif
 +
  if BUILD_PLUGIN_FILECOUNT
  pkglib_LTLIBRARIES += filecount.la
  filecount_la_SOURCES = filecount.c
@@@ -445,7 -440,12 +445,7 @@@ pkglib_LTLIBRARIES += iptables.l
  iptables_la_SOURCES = iptables.c
  iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS)
  iptables_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBIPTC_LDFLAGS)
 -if BUILD_WITH_OWN_LIBIPTC
 -iptables_la_LIBADD  = owniptc/libiptc.la
 -iptables_la_DEPENDENCIES = owniptc/libiptc.la
 -else
  iptables_la_LIBADD = -liptc
 -endif
  collectd_LDADD += "-dlopen" iptables.la
  collectd_DEPENDENCIES += iptables.la
  endif
@@@ -595,14 -595,6 +595,14 @@@ collectd_LDADD += "-dlopen" mbmon.l
  collectd_DEPENDENCIES += mbmon.la
  endif
  
 +if BUILD_PLUGIN_MD
 +pkglib_LTLIBRARIES += md.la
 +md_la_SOURCES = md.c
 +md_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" md.la
 +collectd_DEPENDENCIES += md.la
 +endif
 +
  if BUILD_PLUGIN_MEMCACHEC
  pkglib_LTLIBRARIES += memcachec.la
  memcachec_la_SOURCES = memcachec.c
@@@ -780,14 -772,6 +780,14 @@@ collectd_LDADD += "-dlopen" ntpd.l
  collectd_DEPENDENCIES += ntpd.la
  endif
  
 +if BUILD_PLUGIN_NUMA
 +pkglib_LTLIBRARIES += numa.la
 +numa_la_SOURCES = numa.c
 +numa_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" numa.la
 +collectd_DEPENDENCIES += numa.la
 +endif
 +
  if BUILD_PLUGIN_NUT
  pkglib_LTLIBRARIES += nut.la
  nut_la_SOURCES = nut.c
@@@ -1254,15 -1238,6 +1254,15 @@@ collectd_LDADD += "-dlopen" wireless.l
  collectd_DEPENDENCIES += wireless.la
  endif
  
 +if BUILD_PLUGIN_WRITE_GRAPHITE
 +pkglib_LTLIBRARIES += write_graphite.la
 +write_graphite_la_SOURCES = write_graphite.c \
 +                      utils_format_json.c utils_format_json.h
 +write_graphite_la_LDFLAGS = -module -avoid-version
 +collectd_LDADD += "-dlopen" write_graphite.la
 +collectd_DEPENDENCIES += write_graphite.la
 +endif
 +
  if BUILD_PLUGIN_WRITE_HTTP
  pkglib_LTLIBRARIES += write_http.la
  write_http_la_SOURCES = write_http.c \
@@@ -1278,16 -1253,6 +1278,16 @@@ endi
  collectd_DEPENDENCIES += write_http.la
  endif
  
 +if BUILD_PLUGIN_WRITE_MONGODB
 +pkglib_LTLIBRARIES += write_mongodb.la
 +write_mongodb_la_SOURCES = write_mongodb.c
 +write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS)
 +write_mongodb_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBMONGOC_LDFLAGS)
 +write_mongodb_la_LIBADD = -lmongoc
 +collectd_LDADD += "-dlopen" write_mongodb.la
 +collectd_DEPENDENCIES += write_mongodb.la
 +endif
 +
  if BUILD_PLUGIN_WRITE_REDIS
  pkglib_LTLIBRARIES += write_redis.la
  write_redis_la_SOURCES = write_redis.c
diff --combined src/collectd.conf.pod
@@@ -483,7 -483,6 +483,7 @@@ Synopsis
  
   <Plugin "bind">
     URL "http://localhost:8053/"
 +   ParseTime       false
     OpCodes         true
     QTypes          true
   
@@@ -510,44 -509,35 +510,44 @@@ The bind plugin accepts the following c
  URL from which to retrieve the XML data. If not specified,
  C<http://localhost:8053/> will be used.
  
 -=item B<OpCodes> I<true>|I<false>
 +=item B<ParseTime> B<true>|B<false>
 +
 +When set to B<true>, the time provided by BIND will be parsed and used to
 +dispatch the values. When set to B<false>, the local time source is queried.
 +
 +This setting is set to B<true> by default for backwards compatibility; setting
 +this to B<false> is I<recommended> to avoid problems with timezones and
 +localization.
 +
 +=item B<OpCodes> B<true>|B<false>
  
  When enabled, statistics about the I<"OpCodes">, for example the number of
  C<QUERY> packets, are collected.
  
  Default: Enabled.
  
 -=item B<QTypes> I<true>|I<false>
 +=item B<QTypes> B<true>|B<false>
  
  When enabled, the number of I<incoming> queries by query types (for example
  C<A>, C<MX>, C<AAAA>) is collected.
  
  Default: Enabled.
  
 -=item B<ServerStats> I<true>|I<false>
 +=item B<ServerStats> B<true>|B<false>
  
  Collect global server statistics, such as requests received over IPv4 and IPv6,
  successful queries, and failed updates.
  
  Default: Enabled.
  
 -=item B<ZoneMaintStats> I<true>|I<false>
 +=item B<ZoneMaintStats> B<true>|B<false>
  
  Collect zone maintenance statistics, mostly information about notifications
  (zone updates) and zone transfers.
  
  Default: Enabled.
  
 -=item B<ResolverStats> I<true>|I<false>
 +=item B<ResolverStats> B<true>|B<false>
  
  Collect resolver statistics, i.E<nbsp>e. statistics about outgoing requests
  (e.E<nbsp>g. queries over IPv4, lame servers). Since the global resolver
@@@ -576,21 -566,21 +576,21 @@@ configured, no detailed view statistic
  
  =over 4
  
 -=item B<QTypes> I<true>|I<false>
 +=item B<QTypes> B<true>|B<false>
  
  If enabled, the number of I<outgoing> queries by query type (e.E<nbsp>g. C<A>,
  C<MX>) is collected.
  
  Default: Enabled.
  
 -=item B<ResolverStats> I<true>|I<false>
 +=item B<ResolverStats> B<true>|B<false>
  
  Collect resolver statistics, i.E<nbsp>e. statistics about outgoing requests
  (e.E<nbsp>g. queries over IPv4, lame servers).
  
  Default: Enabled.
  
 -=item B<CacheRRSets> I<true>|I<false>
 +=item B<CacheRRSets> B<true>|B<false>
  
  If enabled, the number of entries (I<"RR sets">) in the view's cache by query
  type is collected. Negative entries (queries which resulted in an error, for
@@@ -1272,41 -1262,6 +1272,41 @@@ at most B<16384> to prevent typos and d
  
  =back
  
 +=head2 Plugin C<ethstat>
 +
 +The I<ethstat plugin> collects information about network interface cards (NICs)
 +by talking directly with the underlying kernel driver using L<ioctl(2)>.
 +
 +B<Synopsis:>
 +
 + <Plugin "ethstat">
 +   Interface "eth0"
 +   Map "rx_csum_offload_errors" "if_rx_errors" "checksum_offload"
 +   Map "multicast" "if_multicast"
 + </Plugin>
 +
 +B<Options:>
 +
 +=over 4
 +
 +=item B<Interface> I<Name>
 +
 +Collect statistical information about interface I<Name>.
 +
 +=item B<Map> I<Name> I<Type> [I<TypeInstance>]
 +
 +By default, the plugin will submit values as type C<derive> and I<type
 +instance> set to I<Name>, the name of the metric as reported by the driver. If
 +an appropriate B<Map> option exists, the given I<Type> and, optionally,
 +I<TypeInstance> will be used.
 +
 +=item B<MappedOnly> B<true>|B<false>
 +
 +When set to B<true>, only metrics that can be mapped to to a I<type> will be
 +collected, all other metrics will be ignored. Defaults to B<false>.
 +
 +=back
 +
  =head2 Plugin C<exec>
  
  Please make sure to read L<collectd-exec(5)> before using this plugin. It
@@@ -1857,31 -1812,6 +1857,31 @@@ TCP-Port to connect to. Defaults to B<4
  
  =back
  
 +=head2 Plugin C<md>
 +
 +The C<md plugin> collects information from Linux Software-RAID devices (md).
 +
 +All reported values are of the type C<md_disks>. Reported type instances are
 +I<active>, I<failed> (present but not operational), I<spare> (hot stand-by) and
 +I<missing> (physically absent) disks.
 +
 +=over 4
 +
 +=item B<Device> I<Device>
 +
 +Select md devices based on device name. The I<device name> is the basename of
 +the device, i.e. the name of the block device without the leading C</dev/>.
 +See B<IgnoreSelected> for more details.
 +
 +=item B<IgnoreSelected> B<true>|B<false>
 +
 +Invert device selection: If set to B<true>, all md devices B<except> those
 +listed using B<Device> are collected. If B<false> (the default), only those
 +listed are collected. If no configuration is given, the B<md> plugin will
 +collect data from all md devices.
 +
 +=back
 +
  =head2 Plugin C<memcachec>
  
  The C<memcachec plugin> connects to a memcached server, queries one or more
@@@ -2003,11 -1933,11 +2003,11 @@@ Configures the base register to read fr
  B<RegisterType> has been set to B<Uint32> or B<Float>, this and the next
  register will be read (the register number is increased by one).
  
 -=item B<RegisterType> B<Uint16>|B<Uint32>|B<Float>
 +=item B<RegisterType> B<Int16>|B<Int32>|B<Uint16>|B<Uint32>|B<Float>
  
 -Specifies what kind of data is returned by the device. If the type is B<Uint32>
 -or B<Float>, two 16E<nbsp>bit registers will be read and the data is combined
 -into one value. Defaults to B<Uint16>.
 +Specifies what kind of data is returned by the device. If the type is B<Int32>,
 +B<Uint32> or B<Float>, two 16E<nbsp>bit registers will be read and the data is
 +combined into one value. Defaults to B<Uint16>.
  
  =item B<Type> I<Type>
  
@@@ -2724,10 -2654,18 +2724,18 @@@ The default IPv6 multicast group is C<f
  multicast group is C<239.192.74.66>. The default I<UDP> port is B<25826>.
  
  Both, B<Server> and B<Listen> can be used as single option or as block. When
- used as block, given options are valid for this socket only. For example:
+ used as block, given options are valid for this socket only. The following
+ example will export the metrics twice: Once to an "internal" server (without
+ encryption and signing) and one to an external server (with cryptographic
+ signature):
  
   <Plugin "network">
+    # Export to an internal server
+    # (demonstrates usage without additional options)
     Server "collectd.internal.tld"
+    
+    # Export to an external server
+    # (demonstrates usage with signature options)
     <Server "collectd.external.tld">
       SecurityLevel "sign"
       Username "myhostname"
@@@ -4230,11 -4168,6 +4238,11 @@@ L<http://secure.netroedge.com/~lm78/>
  
  =over 4
  
 +=item B<SensorConfigFile> I<File>
 +
 +Read the I<lm_sensors> configuration from I<File>. When unset (recommended),
 +the library's default will be used.
 +
  =item B<Sensor> I<chip-bus-address/type-feature>
  
  Selects the name of the sensor which you want to collect or ignore, depending
@@@ -4263,19 -4196,19 +4271,19 @@@ L<collectd-snmp(5)>. Please see there f
  =head2 Plugin C<swap>
  
  The I<Swap plugin> collects information about used and available swap space. On
 -I<Solaris>, the following options are available:
 +I<Linux> and I<Solaris>, the following options are available:
  
  =over 4
  
  =item B<ReportByDevice> B<false>|B<true>
  
 -Configures how to report physical swap devices. If set to B<false> is used (the
 +Configures how to report physical swap devices. If set to B<false> (the
  default), the summary over all swap devices is reported only, i.e. the globally
  used and available space over all devices. If B<true> is configured, the used
  and available space of each device will be reported separately.
  
 -This option is only available if the I<Swap plugin> can use the L<swapctl(2)>
 -mechanism under I<Solaris>.
 +This option is only available if the I<Swap plugin> can read C</proc/swaps>
 +(under Linux) or use the L<swapctl(2)> mechanism (under I<Solaris>).
  
  =back
  
@@@ -4292,15 -4225,6 +4300,15 @@@ syslog-daemon
  Please note that B<debug> is only available if collectd has been compiled with
  debugging support.
  
 +=item B<NotifyLevel> B<OKAY>|B<WARNING>|B<FAILURE>
 +
 +Controls which notifications should be sent to syslog. The default behaviour is
 +not to send any. Less severe notifications always imply logging more severe
 +notifications: Setting this to B<OKAY> means all notifications will be sent to
 +syslog, setting this to B<WARNING> will send B<WARNING> and B<FAILURE>
 +notifications but will dismiss B<OKAY> notifications. Setting this option to
 +B<FAILURE> will only send failures to syslog.
 +
  =back
  
  =head2 Plugin C<table>
@@@ -4851,115 -4775,6 +4859,115 @@@ traffic (e.E<nbsp>g. due to headers an
  collect on-wire traffic you could, for example, use the logging facilities of
  iptables to feed data for the guest IPs into the iptables plugin.
  
 +=head2 Plugin C<write_graphite>
 +
 +The C<write_graphite> plugin writes data to I<Graphite>, an open-source metrics
 +storage and graphing project. The plugin connects to I<Carbon>, the data layer
 +of I<Graphite>, and sends data via the "line based" protocol (per default using
 +portE<nbsp>2003). The data will be sent in blocks of at most 1428 bytes to
 +minimize the number of network packets.
 +
 +Synopsis:
 +
 + <Plugin write_graphite>
 +   <Carbon>
 +     Host "localhost"
 +     Port "2003"
 +     Prefix "collectd"
 +   </Carbon>
 + </Plugin>
 +
 +=over 4
 +
 +=item B<Host> I<Address>
 +
 +Hostname or address to connect to. Defaults to C<localhost>.
 +
 +=item B<Port> I<Service>
 +
 +Service name or port number to connect to. Defaults to C<2003>.
 +
 +=item B<Prefix> I<String>
 +
 +When set, I<String> is added in front of the host name. Dots and whitespace are
 +I<not> escaped in this string (see B<EscapeCharacter> below).
 +
 +=item B<Postfix> I<String>
 +
 +When set, I<String> is appended to the host name. Dots and whitespace are
 +I<not> escaped in this string (see B<EscapeCharacter> below).
 +
 +=item B<EscapeCharacter> I<Char>
 +
 +I<Carbon> uses the dot (C<.>) as escape character and doesn't allow whitespace
 +in the identifier. The B<EscapeCharacter> option determines which character
 +dots, whitespace and control characters are replaced with. Defaults to
 +underscore (C<_>).
 +
 +=item B<StoreRates> B<false>|B<true>
 +
 +If set to B<true> (the default), convert counter values to rates. If set to
 +B<false> counter values are stored as is, i.E<nbsp>e. as an increasing integer
 +number.
 +
 +=item B<SeparateInstances> B<false>|B<true>
 +
 +If set to B<true>, the plugin instance and type instance will be in their own
 +path component, for example C<host.cpu.0.cpu.idle>. If set to B<false> (the
 +default), the plugin and plugin instance (and likewise the type and type
 +instance) are put into once component, for example C<host.cpu-0.cpu-idle>.
 +
 +=item B<AlwaysAppendDS> B<false>|B<true>
 +
 +If set the B<true>, append the name of the I<Data Source> (DS) to the "metric"
 +identifier. If set to B<false> (the default), this is only done when there is
 +more than one DS.
 +
 +=back
 +
 +=head2 Plugin C<write_mongodb>
 +
 +The I<write_mongodb plugin> will send values to I<MongoDB>, a schema-less
 +NoSQL database.
 +
 +B<Synopsis:>
 +
 + <Plugin "write_mongodb">
 +   <Node "default">
 +     Host "localhost"
 +     Port "27017"
 +     Timeout 1000
 +     StoreRates true
 +   </Node>
 + </Plugin>
 +
 +The plugin can send values to multiple instances of I<MongoDB> by specifying
 +one B<Node> block for each instance. Within the B<Node> blocks, the following
 +options are available:
 +
 +=over 4
 +
 +=item B<Host> I<Address>
 +
 +Hostname or address to connect to. Defaults to C<localhost>.
 +
 +=item B<Port> I<Service>
 +
 +Service name or port number to connect to. Defaults to C<27017>.
 +
 +=item B<Timeout> I<Timeout>
 +
 +Set the timeout for each operation on I<MongoDB> to I<Timeout> milliseconds.
 +Setting this option to zero means no timeout, which is the default.
 +
 +=item B<StoreRates> B<false>|B<true>
 +
 +If set to B<true> (the default), convert counter values to rates. If set to
 +B<false> counter values are stored as is, i.e. as an increasing integer
 +number.
 +
 +=back
 +
  =head2 Plugin C<write_http>
  
  This output plugin submits values to an http server by POST them using the
@@@ -5024,6 -4839,170 +5032,170 @@@ number
  
  =back
  
+ =head1 THRESHOLD CONFIGURATION
+ Starting with version C<4.3.0> collectd has support for B<monitoring>. By that
+ we mean that the values are not only stored or sent somewhere, but that they
+ are judged and, if a problem is recognized, acted upon. The only action
+ collectd takes itself is to generate and dispatch a "notification". Plugins can
+ register to receive notifications and perform appropriate further actions.
+ Since systems and what you expect them to do differ a lot, you can configure
+ B<thresholds> for your values freely. This gives you a lot of flexibility but
+ also a lot of responsibility.
+ Every time a value is out of range a notification is dispatched. This means
+ that the idle percentage of your CPU needs to be less then the configured
+ threshold only once for a notification to be generated. There's no such thing
+ as a moving average or similar - at least not now.
+ Also, all values that match a threshold are considered to be relevant or
+ "interesting". As a consequence collectd will issue a notification if they are
+ not received for B<Timeout> iterations. The B<Timeout> configuration option is
+ explained in section L<"GLOBAL OPTIONS">. If, for example, B<Timeout> is set to
+ "2" (the default) and some hosts sends it's CPU statistics to the server every
+ 60 seconds, a notification will be dispatched after about 120 seconds. It may
+ take a little longer because the timeout is checked only once each B<Interval>
+ on the server.
+ When a value comes within range again or is received after it was missing, an
+ "OKAY-notification" is dispatched.
+ Here is a configuration example to get you started. Read below for more
+ information.
+  <Threshold>
+    <Type "foo">
+      WarningMin    0.00
+      WarningMax 1000.00
+      FailureMin    0.00
+      FailureMax 1200.00
+      Invert false
+      Instance "bar"
+    </Type>
+    <Plugin "interface">
+      Instance "eth0"
+      <Type "if_octets">
+        FailureMax 10000000
+        DataSource "rx"
+      </Type>
+    </Plugin>
+    <Host "hostname">
+      <Type "cpu">
+        Instance "idle"
+        FailureMin 10
+      </Type>
+      <Plugin "memory">
+        <Type "memory">
+          Instance "cached"
+          WarningMin 100000000
+        </Type>
+      </Plugin>
+    </Host>
+  </Threshold>
+ There are basically two types of configuration statements: The C<Host>,
+ C<Plugin>, and C<Type> blocks select the value for which a threshold should be
+ configured. The C<Plugin> and C<Type> blocks may be specified further using the
+ C<Instance> option. You can combine the block by nesting the blocks, though
+ they must be nested in the above order, i.E<nbsp>e. C<Host> may contain either
+ C<Plugin> and C<Type> blocks, C<Plugin> may only contain C<Type> blocks and
+ C<Type> may not contain other blocks. If multiple blocks apply to the same
+ value the most specific block is used.
+ The other statements specify the threshold to configure. They B<must> be
+ included in a C<Type> block. Currently the following statements are recognized:
+ =over 4
+ =item B<FailureMax> I<Value>
+ =item B<WarningMax> I<Value>
+ Sets the upper bound of acceptable values. If unset defaults to positive
+ infinity. If a value is greater than B<FailureMax> a B<FAILURE> notification
+ will be created. If the value is greater than B<WarningMax> but less than (or
+ equal to) B<FailureMax> a B<WARNING> notification will be created.
+ =item B<FailureMin> I<Value>
+ =item B<WarningMin> I<Value>
+ Sets the lower bound of acceptable values. If unset defaults to negative
+ infinity. If a value is less than B<FailureMin> a B<FAILURE> notification will
+ be created. If the value is less than B<WarningMin> but greater than (or equal
+ to) B<FailureMin> a B<WARNING> notification will be created.
+ =item B<DataSource> I<DSName>
+ Some data sets have more than one "data source". Interesting examples are the
+ C<if_octets> data set, which has received (C<rx>) and sent (C<tx>) bytes and
+ the C<disk_ops> data set, which holds C<read> and C<write> operations. The
+ system load data set, C<load>, even has three data sources: C<shortterm>,
+ C<midterm>, and C<longterm>.
+ Normally, all data sources are checked against a configured threshold. If this
+ is undesirable, or if you want to specify different limits for each data
+ source, you can use the B<DataSource> option to have a threshold apply only to
+ one data source.
+ =item B<Invert> B<true>|B<false>
+ If set to B<true> the range of acceptable values is inverted, i.E<nbsp>e.
+ values between B<FailureMin> and B<FailureMax> (B<WarningMin> and
+ B<WarningMax>) are not okay. Defaults to B<false>.
+ =item B<Persist> B<true>|B<false>
+ Sets how often notifications are generated. If set to B<true> one notification
+ will be generated for each value that is out of the acceptable range. If set to
+ B<false> (the default) then a notification is only generated if a value is out
+ of range but the previous value was okay.
+ This applies to missing values, too: If set to B<true> a notification about a
+ missing value is generated once every B<Interval> seconds. If set to B<false>
+ only one such notification is generated until the value appears again.
+ =item B<Percentage> B<true>|B<false>
+ If set to B<true>, the minimum and maximum values given are interpreted as
+ percentage value, relative to the other data sources. This is helpful for
+ example for the "df" type, where you may want to issue a warning when less than
+ 5E<nbsp>% of the total space is available. Defaults to B<false>.
+ =item B<Hits> I<Number>
+ Delay creating the notification until the threshold has been passed I<Number>
+ times. When a notification has been generated, or when a subsequent value is
+ inside the threshold, the counter is reset. If, for example, a value is
+ collected once every 10E<nbsp>seconds and B<Hits> is set to 3, a notification
+ will be dispatched at most once every 30E<nbsp>seconds.
+ This is useful when short bursts are not a problem. If, for example, 100% CPU
+ usage for up to a minute is normal (and data is collected every
+ 10E<nbsp>seconds), you could set B<Hits> to B<6> to account for this.
+ =item B<Hysteresis> I<Number>
+ When set to non-zero, a hysteresis value is applied when checking minimum and
+ maximum bounds. This is useful for values that increase slowly and fluctuate a
+ bit while doing so. When these values come close to the threshold, they may
+ "flap", i.e. switch between failure / warning case and okay case repeatedly.
+ If, for example, the threshold is configures as
+   WarningMax 100.0
+   Hysteresis 1.0
+ then a I<Warning> notification is created when the value exceeds I<101> and the
+ corresponding I<Okay> notification is only created once the value falls below
+ I<99>, thus avoiding the "flapping".
+ =back
  =head1 FILTER CONFIGURATION
  
  Starting with collectd 4.6 there is a powerful filtering infrastructure
@@@ -5649,7 -5628,7 +5821,7 @@@ convert counter values to rates
  
  Please note that these placeholders are B<case sensitive>!
  
 -=item B<Severity> B<"FATAL">|B<"WARNING">|B<"OKAY">
 +=item B<Severity> B<"FAILURE">|B<"WARNING">|B<"OKAY">
  
  Sets the severity of the message. If omitted, the severity B<"WARNING"> is
  used.
@@@ -228,53 -228,6 +228,53 @@@ static void lcc_chomp (char *str) /* {{
    }
  } /* }}} void lcc_chomp */
  
 +static int lcc_identifier_cmp (const void *a, const void *b)
 +{
 +  const lcc_identifier_t *ident_a, *ident_b;
 +
 +  int status;
 +
 +  ident_a = a;
 +  ident_b = b;
 +
 +  status = strcasecmp (ident_a->host, ident_b->host);
 +  if (status != 0)
 +    return (status);
 +
 +  status = strcmp (ident_a->plugin, ident_b->plugin);
 +  if (status != 0)
 +    return (status);
 +
 +  if ((*ident_a->plugin_instance != '\0') || (*ident_b->plugin_instance != '\0'))
 +  {
 +    if (*ident_a->plugin_instance == '\0')
 +      return (-1);
 +    else if (*ident_b->plugin_instance == '\0')
 +      return (1);
 +
 +    status = strcmp (ident_a->plugin_instance, ident_b->plugin_instance);
 +    if (status != 0)
 +      return (status);
 +  }
 +
 +  status = strcmp (ident_a->type, ident_b->type);
 +  if (status != 0)
 +    return (status);
 +
 +  if ((*ident_a->type_instance != '\0') || (*ident_b->type_instance != '\0'))
 +  {
 +    if (*ident_a->type_instance == '\0')
 +      return (-1);
 +    else if (*ident_b->type_instance == '\0')
 +      return (1);
 +
 +    status = strcmp (ident_a->type_instance, ident_b->type_instance);
 +    if (status != 0)
 +      return (status);
 +  }
 +  return (0);
 +} /* }}} int lcc_identifier_cmp */
 +
  static void lcc_response_free (lcc_response_t *res) /* {{{ */
  {
    size_t i;
@@@ -780,6 -733,8 +780,8 @@@ int lcc_getval (lcc_connection_t *c, lc
    if (ret_values_names != NULL)
      *ret_values_names = values_names;
  
+   lcc_response_free (&res);
    return (0);
  } /* }}} int lcc_getval */
  
@@@ -1103,17 -1058,4 +1105,17 @@@ int lcc_string_to_identifier (lcc_conne
    return (0);
  } /* }}} int lcc_string_to_identifier */
  
 +int lcc_sort_identifiers (lcc_connection_t *c, /* {{{ */
 +    lcc_identifier_t *idents, size_t idents_num)
 +{
 +  if (idents == NULL)
 +  {
 +    lcc_set_errno (c, EINVAL);
 +    return (-1);
 +  }
 +
 +  qsort (idents, idents_num, sizeof (*idents), lcc_identifier_cmp);
 +  return (0);
 +} /* }}} int lcc_sort_identifiers */
 +
  /* vim: set sw=2 sts=2 et fdm=marker : */
diff --combined src/processes.c
@@@ -200,7 -200,7 +200,7 @@@ static long pagesize_g
  /* #endif KERNEL_LINUX */
  
  #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
 -/* no global variables */
 +static int pagesize;
  /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
  
  #elif HAVE_PROCINFO_H
@@@ -609,7 -609,7 +609,7 @@@ static int ps_init (void
  /* #endif KERNEL_LINUX */
  
  #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
 -/* no initialization */
 +      pagesize = getpagesize();
  /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
  
  #elif HAVE_PROCINFO_H
@@@ -790,7 -790,7 +790,7 @@@ static procstat_t *ps_read_vmem (int pi
                tmp = strtoll (fields[1], &endptr, /* base = */ 10);
                if ((errno == 0) && (endptr != fields[1]))
                {
 -                      if (strncmp (buffer, "VmData", 6) == 0) 
 +                      if (strncmp (buffer, "VmData", 6) == 0)
                        {
                                data = tmp;
                        }
@@@ -881,9 -881,12 +881,12 @@@ int ps_read_process (int pid, procstat_
        char *fields[64];
        char  fields_len;
  
-       int   i;
+       int   buffer_len;
  
-       int   name_len;
+       char *buffer_ptr;
+       size_t name_start_pos;
+       size_t name_end_pos;
+       size_t name_len;
  
        derive_t cpu_user_counter;
        derive_t cpu_system_counter;
  
        ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid);
  
-       i = read_file_contents (filename, buffer, sizeof(buffer) - 1);
-       if (i <= 0)
+       buffer_len = read_file_contents (filename,
+                       buffer, sizeof(buffer) - 1);
+       if (buffer_len <= 0)
                return (-1);
-       buffer[i] = 0;
-       fields_len = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
-       if (fields_len < 24)
+       buffer[buffer_len] = 0;
+       /* The name of the process is enclosed in parens. Since the name can
+        * contain parens itself, spaces, numbers and pretty much everything
+        * else, use these to determine the process name. We don't use
+        * strchr(3) and strrchr(3) to avoid pointer arithmetic which would
+        * otherwise be required to determine name_len. */
+       name_start_pos = 0;
+       while ((buffer[name_start_pos] != '(')
+                       && (name_start_pos < buffer_len))
+               name_start_pos++;
+       name_end_pos = buffer_len;
+       while ((buffer[name_end_pos] != ')')
+                       && (name_end_pos > 0))
+               name_end_pos--;
+       /* Either '(' or ')' is not found or they are in the wrong order.
+        * Anyway, something weird that shouldn't happen ever. */
+       if (name_start_pos >= name_end_pos)
        {
-               DEBUG ("processes plugin: ps_read_process (pid = %i):"
-                               " `%s' has only %i fields..",
-                               (int) pid, filename, fields_len);
+               ERROR ("processes plugin: name_start_pos = %zu >= name_end_pos = %zu",
+                               name_start_pos, name_end_pos);
                return (-1);
        }
  
-       /* copy the name, strip brackets in the process */
-       name_len = strlen (fields[1]) - 2;
-       if ((fields[1][0] != '(') || (fields[1][name_len + 1] != ')'))
+       name_len = (name_end_pos - name_start_pos) - 1;
+       if (name_len >= sizeof (ps->name))
+               name_len = sizeof (ps->name) - 1;
+       sstrncpy (ps->name, &buffer[name_start_pos + 1], name_len + 1);
+       if ((buffer_len - name_end_pos) < 2)
+               return (-1);
+       buffer_ptr = &buffer[name_end_pos + 2];
+       fields_len = strsplit (buffer_ptr, fields, STATIC_ARRAY_SIZE (fields));
+       if (fields_len < 22)
        {
-               DEBUG ("No brackets found in process name: `%s'", fields[1]);
+               DEBUG ("processes plugin: ps_read_process (pid = %i):"
+                               " `%s' has only %i fields..",
+                               (int) pid, filename, fields_len);
                return (-1);
        }
-       fields[1] = fields[1] + 1;
-       fields[1][name_len] = '\0';
-       strncpy (ps->name, fields[1], PROCSTAT_NAME_LEN);
  
-       *state = fields[2][0];
+       *state = fields[0][0];
  
        if (*state == 'Z')
        {
                return (0);
        }
  
-       cpu_user_counter   = atoll (fields[13]);
-       cpu_system_counter = atoll (fields[14]);
-       vmem_size          = atoll (fields[22]);
-       vmem_rss           = atoll (fields[23]);
-       ps->vmem_minflt_counter = atoll (fields[9]);
-       ps->vmem_majflt_counter = atoll (fields[11]);
+       cpu_user_counter   = atoll (fields[11]);
+       cpu_system_counter = atoll (fields[12]);
+       vmem_size          = atoll (fields[20]);
+       vmem_rss           = atoll (fields[21]);
+       ps->vmem_minflt_counter = atol (fields[7]);
+       ps->vmem_majflt_counter = atol (fields[9]);
  
        {
-               unsigned long long stack_start = atoll (fields[27]);
-               unsigned long long stack_ptr   = atoll (fields[28]);
+               unsigned long long stack_start = atoll (fields[25]);
+               unsigned long long stack_ptr   = atoll (fields[26]);
  
                stack_size = (stack_start > stack_ptr)
                        ? stack_start - stack_ptr
@@@ -1579,8 -1605,10 +1605,8 @@@ static int ps_read (void
  
        kvm_t *kd;
        char errbuf[1024];
 -      char cmdline[ARG_MAX];
 -      char *cmdline_ptr;
        struct kinfo_proc *procs;          /* array of processes */
 -      char **argv;
 +      struct kinfo_proc *proc_ptr = NULL;
        int count;                         /* returns number of processes */
        int i;
  
        /* Iterate through the processes in kinfo_proc */
        for (i = 0; i < count; i++)
        {
 -              /* retrieve the arguments */
 -              cmdline[0] = 0;
 -              cmdline_ptr = NULL;
 -
 -              argv = kvm_getargv (kd, (const struct kinfo_proc *) &(procs[i]), 0);
 -              if (argv != NULL)
 +              /* Create only one process list entry per _process_, i.e.
 +               * filter out threads (duplicate PID entries). */
 +              if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid))
                {
 -                      int status;
 -                      int argc;
 -
 -                      argc = 0;
 -                      while (argv[argc] != NULL)
 -                              argc++;
 -
 -                      status = strjoin (cmdline, sizeof (cmdline),
 -                                      argv, argc, " ");
 +                      char cmdline[ARG_MAX] = "";
 +                      _Bool have_cmdline = 0;
  
 -                      if (status < 0)
 +                      proc_ptr = &(procs[i]);
 +                      /* Don't probe system processes and processes without arguments */
 +                      if (((procs[i].ki_flag & P_SYSTEM) == 0)
 +                                      && (procs[i].ki_args != NULL))
                        {
 -                              WARNING ("processes plugin: Command line did "
 -                                              "not fit into buffer.");
 -                      }
 -                      else
 +                              char **argv;
 +                              int argc;
 +                              int status;
 +
 +                              /* retrieve the arguments */
 +                              argv = kvm_getargv (kd, proc_ptr, /* nchr = */ 0);
 +                              argc = 0;
 +                              if ((argv != NULL) && (argv[0] != NULL))
 +                              {
 +                                      while (argv[argc] != NULL)
 +                                              argc++;
 +
 +                                      status = strjoin (cmdline, sizeof (cmdline), argv, argc, " ");
 +                                      if (status < 0)
 +                                              WARNING ("processes plugin: Command line did not fit into buffer.");
 +                                      else
 +                                              have_cmdline = 1;
 +                              }
 +                      } /* if (process has argument list) */
 +
 +                      pse.id       = procs[i].ki_pid;
 +                      pse.age      = 0;
 +
 +                      pse.num_proc = 1;
 +                      pse.num_lwp  = procs[i].ki_numthreads;
 +
 +                      pse.vmem_size = procs[i].ki_size;
 +                      pse.vmem_rss = procs[i].ki_rssize * pagesize;
 +                      pse.vmem_data = procs[i].ki_dsize * pagesize;
 +                      pse.vmem_code = procs[i].ki_tsize * pagesize;
 +                      pse.stack_size = procs[i].ki_ssize * pagesize;
 +                      pse.vmem_minflt = 0;
 +                      pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt;
 +                      pse.vmem_majflt = 0;
 +                      pse.vmem_majflt_counter = procs[i].ki_rusage.ru_majflt;
 +
 +                      pse.cpu_user = 0;
 +                      pse.cpu_system = 0;
 +                      pse.cpu_user_counter = 0;
 +                      pse.cpu_system_counter = 0;
 +                      /*
 +                       * The u-area might be swapped out, and we can't get
 +                       * at it because we have a crashdump and no swap.
 +                       * If it's here fill in these fields, otherwise, just
 +                       * leave them 0.
 +                       */
 +                      if (procs[i].ki_flag & P_INMEM)
                        {
 -                              cmdline_ptr = &cmdline[0];
 +                              pse.cpu_user_counter = procs[i].ki_rusage.ru_utime.tv_usec
 +                                      + (1000000lu * procs[i].ki_rusage.ru_utime.tv_sec);
 +                              pse.cpu_system_counter = procs[i].ki_rusage.ru_stime.tv_usec
 +                                      + (1000000lu * procs[i].ki_rusage.ru_stime.tv_sec);
                        }
 -              }
  
 -              pse.id       = procs[i].ki_pid;
 -              pse.age      = 0;
 -
 -              pse.num_proc = 1;
 -              pse.num_lwp  = procs[i].ki_numthreads;
 -
 -              pse.vmem_size = procs[i].ki_size;
 -              pse.vmem_rss = procs[i].ki_rssize * getpagesize();
 -              pse.vmem_data = procs[i].ki_dsize * getpagesize();
 -              pse.vmem_code = procs[i].ki_tsize * getpagesize();
 -              pse.stack_size = procs[i].ki_ssize * getpagesize();
 -              pse.vmem_minflt = 0;
 -              pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt;
 -              pse.vmem_majflt = 0;
 -              pse.vmem_majflt_counter = procs[i].ki_rusage.ru_majflt;
 +                      /* no I/O data */
 +                      pse.io_rchar = -1;
 +                      pse.io_wchar = -1;
 +                      pse.io_syscr = -1;
 +                      pse.io_syscw = -1;
  
 -              pse.cpu_user = 0;
 -              pse.cpu_user_counter = procs[i].ki_rusage.ru_utime.tv_sec
 -                      * 1000
 -                      + procs[i].ki_rusage.ru_utime.tv_usec;
 -              pse.cpu_system = 0;
 -              pse.cpu_system_counter = procs[i].ki_rusage.ru_stime.tv_sec
 -                      * 1000
 -                      + procs[i].ki_rusage.ru_stime.tv_usec;
 -
 -              /* no io data */
 -              pse.io_rchar = -1;
 -              pse.io_wchar = -1;
 -              pse.io_syscr = -1;
 -              pse.io_syscw = -1;
 +                      ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse);
 +              } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
  
                switch (procs[i].ki_stat)
                {
                        case SLOCK:     blocked++;      break;
                        case SZOMB:     zombies++;      break;
                }
 -
 -              ps_list_add (procs[i].ki_comm, cmdline_ptr, &pse);
        }
  
        kvm_close(kd);
diff --combined src/snmp.c
@@@ -703,13 -703,14 +703,15 @@@ static void csnmp_host_open_session (ho
  
  /* TODO: Check if negative values wrap around. Problem: negative temperatures. */
  static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
 -    double scale, double shift)
 +    double scale, double shift,
 +    const char *host_name, const char *data_name)
  {
    value_t ret;
    uint64_t tmp_unsigned = 0;
    int64_t tmp_signed = 0;
-   int defined = 1;
+   _Bool defined = 1;
+   /* Set to true when the original SNMP type appears to have been signed. */
+   _Bool prefer_signed = 0;
  
    if ((vl->type == ASN_INTEGER)
        || (vl->type == ASN_UINTEGER)
    {
      tmp_unsigned = (uint32_t) *vl->val.integer;
      tmp_signed = (int32_t) *vl->val.integer;
-     DEBUG ("snmp plugin: Parsed int32 value is %"PRIi64".", tmp_signed);
+     if ((vl->type == ASN_INTEGER)
+         || (vl->type == ASN_GAUGE))
+       prefer_signed = 1;
+     DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
    }
    else if (vl->type == ASN_COUNTER64)
    {
          oid_buffer);
      else
  #endif
 -      WARNING ("snmp plugin: I don't know the ASN type \"%i\" (OID: %s)",
 -        (int) vl->type, oid_buffer);
 +      WARNING ("snmp plugin: I don't know the ASN type #%i "
 +               "(OID: \"%s\", data block \"%s\", host block \"%s\")",
 +          (int) vl->type, oid_buffer,
 +          (data_name != NULL) ? data_name : "UNKNOWN",
 +          (host_name != NULL) ? host_name : "UNKNOWN");
  
      defined = 0;
    }
    }
    else if (type == DS_TYPE_GAUGE)
    {
-     ret.gauge = NAN;
-     if (defined != 0)
+     if (!defined)
+       ret.gauge = NAN;
+     else if (prefer_signed)
        ret.gauge = (scale * tmp_signed) + shift;
+     else
+       ret.gauge = (scale * tmp_unsigned) + shift;
    }
    else if (type == DS_TYPE_DERIVE)
-     ret.derive = (derive_t) tmp_signed;
+   {
+     if (prefer_signed)
+       ret.derive = (derive_t) tmp_signed;
+     else
+       ret.derive = (derive_t) tmp_unsigned;
+   }
    else if (type == DS_TYPE_ABSOLUTE)
+   {
      ret.absolute = (absolute_t) tmp_unsigned;
+   }
    else
    {
      ERROR ("snmp plugin: csnmp_value_list_to_value: Unknown data source "
@@@ -962,8 -975,7 +979,8 @@@ 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)
 +    const struct snmp_pdu *res,
 +    const host_definition_t *hd, const data_definition_t *dd)
  {
    csnmp_list_instances_t *il;
    struct variable_list *vb;
    }
    else
    {
 -    value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, 1.0, 0.0);
 +    value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER,
 +        /* scale = */ 1.0, /* shift = */ 0.0, hd->name, dd->name);
      ssnprintf (il->instance, sizeof (il->instance),
        "%llu", val.counter);
    }
@@@ -1292,7 -1303,7 +1309,7 @@@ static int csnmp_read_table (host_defin
        /* 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)
 +          res, host, data) != 0)
        {
        ERROR ("snmp plugin: csnmp_instance_list_add failed.");
        status = -1;
  
        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, host->name, data->name);
        vt->next = NULL;
  
        if (value_table_ptr[i] == NULL)
@@@ -1498,8 -1509,8 +1515,8 @@@ static int csnmp_read_value (host_defin
      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);
 +        vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type,
 +            data->scale, data->shift, host->name, data->name);
    } /* for (res->variables) */
  
    if (res != NULL)
diff --combined src/tcpconns.c
@@@ -65,7 -65,7 +65,7 @@@
  #undef HAVE_SYSCTLBYNAME /* force HAVE_LIBKVM_NLIST path */
  #endif
  
 -#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST
 +#if !KERNEL_LINUX && !HAVE_SYSCTLBYNAME && !HAVE_LIBKVM_NLIST && !KERNEL_AIX
  # error "No applicable input method."
  #endif
  
  # include <netinet/tcp_var.h>
  # include <netdb.h>
  # include <arpa/inet.h>
- # include <nlist.h>
+ # if !defined(HAVE_BSD_NLIST_H) || !HAVE_BSD_NLIST_H
+ #  include <nlist.h>
+ # else /* HAVE_BSD_NLIST_H */
+ #  include <bsd/nlist.h>
+ # endif
  # include <kvm.h>
 -#endif /* HAVE_LIBKVM_NLIST */
 +/* #endif HAVE_LIBKVM_NLIST */
 +
 +#elif KERNEL_AIX
 +# include <arpa/inet.h>
 +# include <sys/socketvar.h>
 +#endif /* KERNEL_AIX */
  
  #if KERNEL_LINUX
  static const char *tcp_state[] =
@@@ -191,49 -190,7 +195,49 @@@ struct inpcbtable *inpcbtable_ptr = NUL
  # define TCP_STATE_LISTEN 1
  # define TCP_STATE_MIN 1
  # define TCP_STATE_MAX 10
 -#endif /* HAVE_LIBKVM_NLIST */
 +/* #endif HAVE_LIBKVM_NLIST */
 +
 +#elif KERNEL_AIX
 +static const char *tcp_state[] =
 +{
 +  "CLOSED",
 +  "LISTEN",
 +  "SYN_SENT",
 +  "SYN_RCVD",
 +  "ESTABLISHED",
 +  "CLOSE_WAIT",
 +  "FIN_WAIT_1",
 +  "CLOSING",
 +  "LAST_ACK",
 +  "FIN_WAIT_2",
 +  "TIME_WAIT"
 +};
 +
 +# define TCP_STATE_LISTEN 1
 +# define TCP_STATE_MIN 0
 +# define TCP_STATE_MAX 10
 +
 +struct netinfo_conn {
 +  uint32_t unknow1[2];
 +  uint16_t dstport;
 +  uint16_t unknow2;
 +  struct in6_addr dstaddr;
 +  uint16_t srcport;
 +  uint16_t unknow3;
 +  struct in6_addr srcaddr;
 +  uint32_t unknow4[36];
 +  uint16_t tcp_state;
 +  uint16_t unknow5[7];
 +};
 +
 +struct netinfo_header {
 +  unsigned int proto;
 +  unsigned int size;
 +};
 +
 +# define NETINFO_TCP 3
 +extern int netinfo (int proto, void *data, int *size,  int n);
 +#endif /* KERNEL_AIX */
  
  #define PORT_COLLECT_LOCAL  0x01
  #define PORT_COLLECT_REMOTE 0x02
@@@ -753,67 -710,7 +757,67 @@@ static int conn_read (void
  
    return (0);
  }
 -#endif /* HAVE_LIBKVM_NLIST */
 +/* #endif HAVE_LIBKVM_NLIST */
 +
 +#elif KERNEL_AIX
 +
 +static int conn_read (void)
 +{
 +  int size;
 +  int i;
 +  int nconn;
 +  void *data;
 +  struct netinfo_header *header;
 +  struct netinfo_conn *conn;
 +
 +  conn_reset_port_entry ();
 +
 +  size = netinfo(NETINFO_TCP, 0, 0, 0);
 +  if (size < 0)
 +  {
 +    ERROR ("tcpconns plugin: netinfo failed return: %i", size);
 +    return (-1);
 +  }
 +
 +  if (size == 0)
 +    return (0);
 +
 +  if ((size - sizeof (struct netinfo_header)) % sizeof (struct netinfo_conn))
 +  {
 +    ERROR ("tcpconns plugin: invalid buffer size");
 +    return (-1);
 +  }
 +
 +  data = malloc(size);
 +  if (data == NULL)
 +  {
 +    ERROR ("tcpconns plugin: malloc failed");
 +    return (-1);
 +  }
 +
 +  if (netinfo(NETINFO_TCP, data, &size, 0) < 0)
 +  {
 +    ERROR ("tcpconns plugin: netinfo failed");
 +    free(data);
 +    return (-1);
 +  }
 +
 +  header = (struct netinfo_header *)data;
 +  nconn = header->size;
 +  conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header));
 +
 +  for (i=0; i < nconn; conn++, i++)
 +  {
 +    conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state);
 +  }
 +
 +  free(data);
 +
 +  conn_submit_all ();
 +
 +  return (0);
 +}
 +#endif /* KERNEL_AIX */
  
  void module_register (void)
  {
        /* no initialization */
  #elif HAVE_LIBKVM_NLIST
        plugin_register_init ("tcpconns", conn_init);
 +#elif KERNEL_AIX
 +      /* no initialization */
  #endif
        plugin_register_read ("tcpconns", conn_read);
  } /* void module_register */
diff --combined version-gen.sh
@@@ -1,6 -1,6 +1,6 @@@
  #!/usr/bin/env bash
  
- DEFAULT_VERSION="5.0.3.git"
+ DEFAULT_VERSION="5.0.4.git"
  
  VERSION="`git describe 2> /dev/null | sed -e 's/^collectd-//'`"
  
@@@ -10,7 -10,7 +10,7 @@@ f
  
  VERSION="`echo \"$VERSION\" | sed -e 's/-/./g'`"
  
 -if test "x`uname -s`" = "xAIX" || test "x`uname -s`" = "xSunOS" ; then
 +if test "x`uname -s`" = "xAIX" ; then
        echo "$VERSION\c"
  else 
        echo -n "$VERSION"