Merge pull request #1308 from mfournier/openldap-persistent-connection
authorMarc Fournier <marc.fournier@camptocamp.com>
Tue, 10 May 2016 08:24:29 +0000 (10:24 +0200)
committerMarc Fournier <marc.fournier@camptocamp.com>
Tue, 10 May 2016 08:24:29 +0000 (10:24 +0200)
Openldap: persistent connection + sane default timeout

220 files changed:
.gitignore
.travis.yml
CONTRIBUTING.md [new file with mode: 0644]
ChangeLog
README
bindings/java/org/collectd/java/GenericJMXConfConnection.java
bindings/java/org/collectd/java/GenericJMXConfValue.java
bindings/perl/lib/Collectd/Unixsock.pm
build.sh
configure.ac
contrib/collection3/lib/Collectd/Graph/Common.pm
contrib/redhat/collectd.spec
contrib/systemd.collectd.service
contrib/wiki2changelog.pl
src/Makefile.am
src/aggregation.c
src/amqp.c
src/apache.c
src/apcups.c
src/apple_sensors.c
src/ascent.c
src/barometer.c
src/battery.c
src/bind.c
src/ceph.c
src/ceph_test.c [new file with mode: 0644]
src/collectd-exec.pod
src/collectd-java.pod
src/collectd-nagios.c
src/collectd-tg.c
src/collectd.conf.in
src/collectd.conf.pod
src/collectdctl.c
src/collectdmon.c
src/cpu.c
src/cpython.h
src/csv.c
src/curl.c
src/curl_json.c
src/curl_xml.c
src/daemon/Makefile.am
src/daemon/collectd.c
src/daemon/collectd.h
src/daemon/common.c
src/daemon/common.h
src/daemon/common_test.c
src/daemon/configfile.c
src/daemon/configfile.h
src/daemon/filter_chain.c
src/daemon/filter_chain.h
src/daemon/meta_data.c
src/daemon/meta_data.h
src/daemon/meta_data_test.c
src/daemon/plugin.c
src/daemon/plugin.h
src/daemon/plugin_mock.c
src/daemon/types_list.c
src/daemon/utils_avltree.c
src/daemon/utils_avltree_test.c
src/daemon/utils_cache.c
src/daemon/utils_cache.h
src/daemon/utils_complain.c
src/daemon/utils_complain.h
src/daemon/utils_heap.c
src/daemon/utils_heap_test.c
src/daemon/utils_ignorelist.c [new file with mode: 0644]
src/daemon/utils_ignorelist.h [new file with mode: 0644]
src/daemon/utils_llist.c
src/daemon/utils_match.c
src/daemon/utils_random.c
src/daemon/utils_subst.c
src/daemon/utils_subst.h
src/daemon/utils_subst_test.c
src/daemon/utils_tail.c
src/daemon/utils_tail_match.c
src/daemon/utils_threshold.h
src/daemon/utils_time.c
src/daemon/utils_time.h
src/daemon/utils_time_mock.c [deleted file]
src/daemon/utils_time_test.c
src/dbi.c
src/df.c
src/disk.c
src/dns.c
src/drbd.c
src/email.c
src/ethstat.c
src/exec.c [changed mode: 0755->0644]
src/fhcount.c
src/filecount.c
src/gmond.c
src/interface.c
src/ipc.c
src/ipmi.c
src/iptables.c
src/ipvs.c
src/irq.c
src/java.c
src/libcollectdclient/client.c
src/libcollectdclient/collectd/network.h
src/libcollectdclient/network.c
src/libcollectdclient/network_buffer.c
src/liboconfig/Makefile.am
src/liboconfig/oconfig.c
src/liboconfig/parser.y
src/liboconfig/scanner.l
src/logfile.c
src/madwifi.c
src/match_empty_counter.c
src/match_hashed.c
src/match_regex.c
src/match_timediff.c
src/match_value.c
src/mbmon.c
src/memcachec.c
src/memcached.c
src/memory.c
src/modbus.c
src/mqtt.c
src/multimeter.c
src/mysql.c
src/netapp.c
src/netlink.c
src/network.c
src/nfs.c
src/nginx.c
src/notify_email.c
src/notify_nagios.c [new file with mode: 0644]
src/ntpd.c
src/nut.c
src/olsrd.c
src/onewire.c
src/openldap.c
src/openvpn.c
src/oracle.c
src/perl.c
src/pf.c
src/pinba.c
src/ping.c
src/postgresql.c
src/powerdns.c
src/processes.c
src/protocols.c
src/pyconfig.c
src/python.c
src/pyvalues.c
src/redis.c
src/riemann.proto [deleted file]
src/routeros.c
src/rrdcached.c
src/rrdtool.c
src/sensors.c
src/sigrok.c
src/smart.c
src/snmp.c
src/statsd.c
src/swap.c
src/syslog.c
src/table.c
src/tail.c
src/tail_csv.c
src/target_notification.c
src/target_replace.c
src/target_scale.c
src/target_set.c
src/tcpconns.c
src/teamspeak2.c
src/ted.c
src/testing.h
src/thermal.c
src/threshold.c
src/tokyotyrant.c
src/turbostat.c
src/types.db
src/unixsock.c
src/users.c
src/utils_cmd_flush.c
src/utils_cmd_getval.c
src/utils_cmd_putnotif.c
src/utils_cmd_putval.c
src/utils_db_query.c
src/utils_db_query.h
src/utils_dns.c
src/utils_dns.h
src/utils_fbhash.c
src/utils_format_json.c
src/utils_ignorelist.c [deleted file]
src/utils_ignorelist.h [deleted file]
src/utils_latency.c
src/utils_latency.h
src/utils_latency_test.c
src/utils_mount.c
src/utils_mount.h
src/utils_mount_test.c
src/utils_parse_option.c
src/utils_rrdcreate.c
src/utils_vl_lookup.c
src/utils_vl_lookup_test.c
src/uuid.c
src/varnish.c
src/virt.c
src/vmem.c
src/vserver.c
src/wireless.c
src/write_graphite.c
src/write_http.c
src/write_kafka.c
src/write_mongodb.c
src/write_redis.c
src/write_riemann.c
src/write_riemann_threshold.c
src/write_riemann_threshold.h [new file with mode: 0644]
src/write_sensu.c
src/write_tsdb.c
src/xencpu.c [new file with mode: 0644]
src/xmms.c
src/zfs_arc.c
src/zone.c
src/zookeeper.c
version-gen.sh

index cf4ad15..b14cc7a 100644 (file)
@@ -20,7 +20,6 @@ Makefile
 config.log
 config.status
 libtool
-src/.deps
 src/collectd.conf
 src/config.h
 src/libcollectdclient/libcollectdclient.pc
@@ -31,7 +30,7 @@ src/stamp-h1
 *.lo
 *.o
 .libs/
-src/collectd
+.deps/
 src/collectd-nagios
 src/collectd-tg
 src/collectdctl
@@ -73,28 +72,11 @@ bindings/java/org/collectd/java/*.class
 # python stuff
 *.pyc
 
-# tag stuff
-src/tags
-
 # backup stuff
 *~
-# tests stuff
-src/tests/.deps/
-src/tests/mock/.deps/
-src/tests/.dirstamp
-src/tests/mock/.dirstamp
-src/test_utils_latency
-src/test_utils_mount
-src/test_utils_vl_lookup
-test*.log
-*.trs
+# Unit tests
+src/tests/
+test_*
 
-# new daemon repo
-src/daemon/.deps/
-src/daemon/.dirstamp
+# src/daemon/...
 src/daemon/collectd
-src/daemon/test_common
-src/daemon/test_meta_data
-src/daemon/test_utils_avltree
-src/daemon/test_utils_heap
-src/daemon/test_utils_subst
index 09adb4d..03d9dde 100644 (file)
@@ -1,25 +1,56 @@
-sudo: false
+sudo: required
+dist: trusty
 compiler:
   - gcc
   - clang
-addons:
-  apt:
-    packages:
-      - iptables-dev
-      - libcap-dev
-      - libdbi-dev
-      - libhiredis-dev
-      - libnfnetlink-dev
-      - libnotify-dev
-      - libpcap-dev
-      - libperl-dev
-      - libprotobuf-c0-dev
-      - librrd-dev
-      - libsnmp-dev
-      - libudev-dev
-      - libvarnishapi-dev
-      - libyajl-dev
-      - linux-libc-dev
-      - protobuf-c-compiler
 language: c
-script: sh build.sh && ./configure && make distcheck
+before_install:
+  - sudo apt-get update -qq
+  - sudo apt-get install -qq --no-install-recommends
+      iptables-dev
+      libatasmart-dev
+      libcap-dev
+      libcurl4-gnutls-dev
+      libdbi0-dev
+      libesmtp-dev
+      libganglia1-dev
+      libgcrypt11-dev
+      libglib2.0-dev
+      libhiredis-dev
+      libi2c-dev
+      libldap2-dev
+      libltdl-dev
+      liblvm2-dev
+      libmemcached-dev
+      libmnl-dev
+      libmodbus-dev
+      libmosquitto0-dev
+      libmysqlclient-dev
+      libnotify-dev
+      libopenipmi-dev
+      liboping-dev
+      libow-dev
+      libpcap-dev
+      libperl-dev
+      libpq-dev
+      libprotobuf-c0-dev
+      librabbitmq-dev
+      librdkafka-dev
+      librrd-dev
+      libsensors4-dev
+      libsigrok-dev
+      libsnmp-dev
+      libstatgrab-dev
+      libtokyocabinet-dev
+      libtokyotyrant-dev
+      libudev-dev
+      libupsclient-dev
+      libvarnish-dev
+      libvirt-dev
+      libxml2-dev
+      libyajl-dev
+      linux-libc-dev
+      perl
+      protobuf-c-compiler
+      python-dev
+script: sh build.sh && ./configure --with-python=/usr/bin/python && make distcheck DISTCHECK_CONFIGURE_FLAGS="--with-python=/usr/bin/python"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..befb76e
--- /dev/null
@@ -0,0 +1,38 @@
+# Thanks !
+
+Thanks for your feedback & contributions to the
+[collectd project](https://collectd.org/) !
+
+## Need help using collectd ?
+
+Please use the
+[collectd mailing list](http://mailman.verplant.org/listinfo/collectd) or the
+[#collectd IRC channel](https://webchat.freenode.net/?channels=#collectd).
+We'd like to keep the github issue tracker for bugreports and patch reviews.
+
+## Found a bug ?
+
+Please mention the exact collectd version you're using, how it was installed
+(built from source, or installed from packages. Where was it downloaded
+from). Which operating system/architecture, distribution and version are you
+running collectd on.
+
+If collectd crashes, try to get a
+[stack trace](https://collectd.org/wiki/index.php/Core_file).
+
+## Fixed a bug ? Want to add a feature ?
+
+Using git/github to submit changes is not mandatory. Sending patches to the
+[mailing-list](http://mailman.verplant.org/listinfo/collectd) is also fine.
+In both cases, take a quick look at the
+[submission guidelines](https://collectd.org/wiki/index.php/Submitting_patches)
+and the [coding style recommendations](https://collectd.org/wiki/index.php/Coding_style).
+
+Please try to submit **bugfixes** to the
+[oldest release branch](https://github.com/collectd/collectd/milestones) on
+which the bug is found, so that it gets included in every future **bugfix
+release**.
+
+Please try to submit **new features** to the master branch (which will become
+the next **feature release**).
+
index b0a997c..48dc6ca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,76 @@
+2016-01-22, Version 5.5.1
+       * Build system: Compilation errors have been avoided by correctly
+         defining package name and version used by autoconf. Thanks to Nathan
+         Berkley. #1063
+       * Build system: Dependency ordering was fixed to ensure parallel builds
+         work reliably. Thanks to Gustavo Zacarias. #1125
+       * Build system: Error messages have been improved and building the unit
+         tests has been fixed on Solaris. Thanks to Florian Forster and
+         Dagobert Michelsen. #1077
+       * Build system: The move of the "utils_ignorelist" functions has been
+         reverted. This fixes build issues of numerous plugins. Thanks to
+         Benjamin Drung;. #1323
+       * Build system: The fhcount plugin has been restricted to Linux. Thanks
+         to Ruben Kerkhof. #1195
+       * Build system: Detection of header files for the turbostat plugin has
+         been fixed. Thanks to Marc Fournier. #1075
+       * collectd: The "LC_NUMERIC" locale is now forced, to prevent issues
+         with some plugins on environments using a comma as decimal separator.
+         Thanks to Florian Forster. #1237
+       * Documentation: Some precisions related to the virt plugin have beed
+         added. Thanks to Wojtek Bocer and Ruben Kerkhof.
+       * Documentation: The CollectdInternalStats documentation has been
+         improved. Thanks to Yves Mettier and Florian Forster.
+       * Battery plugin: A missing Type has been added. Thanks to Marc
+         Fournier. #1338
+       * Bind plugin: An off-by-one error has been fixed: an index was checked
+         against a wrong variable, which may lead to an out-of-bounds read.
+         Thanks to Michal Humpula. #1123
+       * Ceph plugin: JSON parsing has been refactored to support ceph 10.0.0
+         and fixes several buffer overflows. Thanks to Florian Forster. #1350
+       * CPU plugin: A Mac OS X specific bug has been fixed: the plugin
+         expected an incorrect number of CPU states, resulting in failing read
+         callbacks. This regression was introduced in 5.5.0. Thanks to Robert
+         Viduya.
+       * Disk plugin: Support for Mac OS X 10.10 has been added. Thanks to
+         Robert Viduya. #1065
+       * IPC plugin: Support for building with musl-libc has been added. Thanks
+         to Natanael Copa. #1147
+       * Log Logstash plugin: A segfault when using libyajl, version 1 was
+         fixed. Thanks to Vincent Bernat. #1190
+       * Log Logstash plugin: The timestamp is now ISO 8601 compliant. Thanks
+         to Marc Fournier. #1132
+       * memcached plugin: The Type of the listen-disabled metric was fixed.
+         Thanks to Florian Forster. #1356
+       * MySQL plugin: The Type used by Innodb_buffer_pool_pages_flushed was
+         fixed. Thanks to Marek Becka. #1085
+       * OpenLDAP plugin: A crash when using LDAPI (LDAP-over-IPC) got fixed.
+         Thanks to Marek Becka. #1080
+       * OpenLDAP plugin: Support for Mac OS X has been added. Thanks to Ruben
+         Kerkhof. #1489
+       * SMART plugin: A memory leak has been fixed. Thanks to Florian
+         Schüller and Pierre-Yves Ritschard. #1076
+       * Swap plugin: A regression that would lead to swap usage being reported
+         in kilobytes (instead of bytes) has been fixed. Thanks to Marek Becka.
+         #1071
+       * Varnish plugin: Support for FreeBSD has been added. Thanks to Ruben
+         Kerkhof. #1182
+       * Varnish plugin: Support for versions 3 and 4 has been made more
+         tolerant to minor changes in Varnish point releases. Thanks to Marc
+         Fournier. #1302
+       * virt plugin: A copy-and-paste mistake in an error message has been
+         fixed. Thanks to Ruben Kerkhof. #1101
+       * Write Kafka plugin: Support for Solaris has been added. Thanks to
+         Shahul Hameed. #1171
+       * Write Redis plugin: Dead code has been removed. Thanks to Brian Kelly.
+         #1143
+       * 27 patches have been applied to numerous plugins and core components,
+         fixing various programming errors which were reported by scan-build,
+         libasan, FBInfer, coverity-scan and clang: Thanks to Ruben Kerkhof,
+         Florian Forster and Marek Becka.
+       * Collectd::Unixsock: A Perl error got corrected. Thanks to Ciaran Mac
+         An Iomaire. #1295
+
 2015-05-27, Version 5.5.0
        * Build system: Ability to make out-of-tree builds has been fixed.
          Thanks to Vincent Bernat. #792
diff --git a/README b/README
index ad5b667..5f24945 100644 (file)
--- a/README
+++ b/README
@@ -767,8 +767,7 @@ Prerequisites
 
   * libprotobuf-c, protoc-c (optional)
     Used by the `pinba' plugin to generate a parser for the network packets
-    sent by the Pinba PHP extension, and by the `write_riemann' plugin to
-    generate events to be sent to a Riemann server.
+    sent by the Pinba PHP extension.
     <http://code.google.com/p/protobuf-c/>
 
   * libpython (optional)
@@ -843,6 +842,10 @@ Prerequisites
      `varnish' plugin.
      <http://varnish-cache.org>
 
+  * riemann-c-client (optional)
+     For the `write_riemann' plugin.
+     <https://github.com/algernon/riemann-c-client>
+
 Configuring / Compiling / Installing
 ------------------------------------
 
@@ -896,18 +899,19 @@ Configuring with libjvm
   library checks succeed.
 
   If this doesn't work for you, you have the possibility to specify CPP-flags,
-  C-flags and LD-flags for the â€˜Java’ plugin by hand, using the following three
-  (environment) variables:
+  C-flags, LD-flags and LIBS for the â€˜Java’ plugin by hand, using the
+  following environment variables:
 
     - JAVA_CPPFLAGS
     - JAVA_CFLAGS
     - JAVA_LDFLAGS
+    - JAVA_LIBS
 
   For example (shortened for demonstration purposes):
 
     ./configure JAVA_CPPFLAGS="-I$JAVA_HOME/include -I$JAVA_HOME/include/linux"
 
-  Adding "-ljvm" to the JAVA_LDFLAGS is done automatically, you don't have to
+  Adding "-ljvm" to JAVA_LIBS is done automatically, you don't have to
   do that.
 
 Generating the configure script
@@ -924,6 +928,7 @@ To generate the `configure` script, you'll need the following dependencies:
 - bison
 - libtool
 - libtool-ltdl
+- pkg-config
 
 The `build.sh' script takes no arguments.
 
index ea0f2fa..887c289 100644 (file)
@@ -52,7 +52,8 @@ class GenericJMXConfConnection
   private String _host = null;
   private String _instance_prefix = null;
   private String _service_url = null;
-  private MBeanServerConnection _jmx_connection = null;
+  private JMXConnector _jmx_connector = null;
+  private MBeanServerConnection _mbean_connection = null;
   private List<GenericJMXConfMBean> _mbeans = null;
 
   /*
@@ -92,55 +93,74 @@ class GenericJMXConfConnection
     return Collectd.getHostname();
   } /* }}} String getHost */
 
-private void connect () /* {{{ */
-{
-  JMXServiceURL service_url;
-  JMXConnector connector;
-  Map environment;
+  private void connect () /* {{{ */
+  {
+    JMXServiceURL service_url;
+    Map<String,Object> environment;
 
-  if (_jmx_connection != null)
-    return;
+    // already connected
+    if (this._jmx_connector != null) {
+      return;
+    }
 
-  environment = null;
-  if (this._password != null)
-  {
-    String[] credentials;
+    environment = null;
+    if (this._password != null)
+    {
+      String[] credentials;
 
-    if (this._username == null)
-      this._username = new String ("monitorRole");
+      if (this._username == null)
+        this._username = new String ("monitorRole");
 
-    credentials = new String[] { this._username, this._password };
+      credentials = new String[] { this._username, this._password };
 
-    environment = new HashMap ();
-    environment.put (JMXConnector.CREDENTIALS, credentials);
-    environment.put(JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, this.getClass().getClassLoader());
-  }
+      environment = new HashMap<String,Object> ();
+      environment.put (JMXConnector.CREDENTIALS, credentials);
+      environment.put (JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, this.getClass().getClassLoader());
+    }
 
-  try
-  {
-    service_url = new JMXServiceURL (this._service_url);
-    connector = JMXConnectorFactory.connect (service_url, environment);
-    _jmx_connection = connector.getMBeanServerConnection ();
-  }
-  catch (Exception e)
+    try
+    {
+      service_url = new JMXServiceURL (this._service_url);
+      this._jmx_connector = JMXConnectorFactory.connect (service_url, environment);
+      this._mbean_connection = _jmx_connector.getMBeanServerConnection ();
+    }
+    catch (Exception e)
+    {
+      Collectd.logError ("GenericJMXConfConnection: "
+          + "Creating MBean server connection failed: " + e);
+      disconnect ();
+      return;
+    }
+  } /* }}} void connect */
+
+  private void disconnect () /* {{{ */
   {
-    Collectd.logError ("GenericJMXConfConnection: "
-        + "Creating MBean server connection failed: " + e);
-    return;
-  }
-} /* }}} void connect */
+    try
+    {
+      if (this._jmx_connector != null) {
+        this._jmx_connector.close();
+      }
+    }
+    catch (Exception e)
+    {
+      // It's fine if close throws an exception
+    }
 
-/*
- * public methods
- *
- * <Connection>
- *   Host "tomcat0.mycompany"
- *   ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi"
- *   Collect "java.lang:type=GarbageCollector,name=Copy"
- *   Collect "java.lang:type=Memory"
- * </Connection>
- *
- */
+    this._jmx_connector = null;
+    this._mbean_connection = null;
+  } /* }}} void disconnect */
+
+  /*
+   * public methods
+   *
+   * <Connection>
+   *   Host "tomcat0.mycompany"
+   *   ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi"
+   *   Collect "java.lang:type=GarbageCollector,name=Copy"
+   *   Collect "java.lang:type=Memory"
+   * </Connection>
+   *
+   */
   public GenericJMXConfConnection (OConfigItem ci) /* {{{ */
     throws IllegalArgumentException
   {
@@ -217,9 +237,10 @@ private void connect () /* {{{ */
   {
     PluginData pd;
 
+    // try to connect
     connect ();
 
-    if (this._jmx_connection == null)
+    if (this._mbean_connection == null)
       return;
 
     Collectd.logDebug ("GenericJMXConfConnection.query: "
@@ -234,11 +255,11 @@ private void connect () /* {{{ */
     {
       int status;
 
-      status = this._mbeans.get (i).query (this._jmx_connection, pd,
+      status = this._mbeans.get (i).query (this._mbean_connection, pd,
           this._instance_prefix);
       if (status != 0)
       {
-        this._jmx_connection = null;
+        disconnect ();
         return;
       }
     } /* for */
index 4b42c91..25b70d4 100644 (file)
@@ -28,6 +28,7 @@ package org.collectd.java;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Collection;
 import java.util.Set;
 import java.util.Iterator;
 import java.util.ArrayList;
@@ -39,6 +40,7 @@ import javax.management.MBeanServerConnection;
 import javax.management.ObjectName;
 import javax.management.openmbean.OpenType;
 import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
 import javax.management.openmbean.InvalidKeyException;
 
 import org.collectd.api.Collectd;
@@ -68,6 +70,7 @@ class GenericJMXConfValue
   private List<String> _attributes;
   private String _instance_prefix;
   private List<String> _instance_from;
+  private String _plugin_name;
   private boolean _is_table;
 
   /**
@@ -295,6 +298,46 @@ class GenericJMXConfValue
     {
       if (value instanceof CompositeData)
         return (queryAttributeRecursive ((CompositeData) value, attrName));
+      else if (value instanceof TabularData)
+        return (queryAttributeRecursive ((TabularData) value, attrName));
+      else
+        return (null);
+    }
+  } /* }}} queryAttributeRecursive */
+
+  private Object queryAttributeRecursive (TabularData parent, /* {{{ */
+      List<String> attrName)
+  {
+    String key;
+    Object value = null;
+
+    key = attrName.remove (0);
+
+    TabularData tabularData = (TabularData) parent;
+    Collection<CompositeData> table =
+        (Collection<CompositeData>)tabularData.values();
+    for (CompositeData compositeData : table)
+    {
+      if (key.equals(compositeData.get("key")))
+      {
+        value = compositeData.get("value");
+      }
+    }
+    if (null == value)
+    {
+      return (null);
+    }
+
+    if (attrName.size () == 0)
+    {
+      return (value);
+    }
+    else
+    {
+      if (value instanceof CompositeData)
+        return (queryAttributeRecursive ((CompositeData) value, attrName));
+      else if (value instanceof TabularData)
+        return (queryAttributeRecursive ((TabularData) value, attrName));
       else
         return (null);
     }
@@ -341,6 +384,8 @@ class GenericJMXConfValue
     {
       if (value instanceof CompositeData)
         return (queryAttributeRecursive((CompositeData) value, attrNameList));
+      else if (value instanceof TabularData)
+        return (queryAttributeRecursive((TabularData) value, attrNameList));
       else if (value instanceof OpenType)
       {
         OpenType ot = (OpenType) value;
@@ -351,7 +396,7 @@ class GenericJMXConfValue
       else
       {
         Collectd.logError ("GenericJMXConfValue: Received object of "
-            + "unknown class.");
+            + "unknown class. " + attrName + " " + ((value == null)?"null":value.getClass().getName()));
         return (null);
       }
     }
@@ -436,6 +481,7 @@ class GenericJMXConfValue
     this._attributes = new ArrayList<String> ();
     this._instance_prefix = null;
     this._instance_from = new ArrayList<String> ();
+    this._plugin_name = null;
     this._is_table = false;
 
     /*
@@ -485,6 +531,12 @@ class GenericJMXConfValue
         if (tmp != null)
           this._instance_from.add (tmp);
       }
+      else if (child.getKey ().equalsIgnoreCase ("PluginName"))
+      {
+        String tmp = getConfigString (child);
+        if (tmp != null)
+          this._plugin_name = tmp;
+      }
       else
         throw (new IllegalArgumentException ("Unknown option: "
               + child.getKey ()));
@@ -538,6 +590,10 @@ class GenericJMXConfValue
 
     vl = new ValueList (pd);
     vl.setType (this._ds_name);
+    if (this._plugin_name != null)
+    {
+      vl.setPlugin (this._plugin_name);
+    }
 
     /*
      * Build the instnace prefix from the fixed string prefix and the
index d927d13..304bbbc 100644 (file)
@@ -193,6 +193,32 @@ sub _socket_chat
        return $cbdata;
 }
 
+# Send a raw message on a socket.
+# Returns true upon success and false otherwise.
+sub _send_message
+{
+       my ($self, $msg) = @_;
+       
+       my $fh = $self->{'sock'} or confess ('object has no filehandle');
+       
+       $msg .= "\n" unless $msg =~/\n$/;
+       
+       #1024 is default buffer size at unixsock.c us_handle_client()
+       warn "Collectd::Unixsock->_send_message(\$msg): message is too long!" if length($msg) > 1024;
+       
+       _debug "-> $msg";
+       $fh->print($msg);
+
+       $msg = <$fh>;
+       chomp ($msg);
+       _debug "<- $msg\n";
+
+       my ($status, $error) = split / /, $msg, 2;
+       return 1 if $status == 0;
+
+       $self->{error} = $error;
+       return;
+}
 
 =head1 PUBLIC METHODS
 
@@ -330,18 +356,8 @@ sub putval
        . _escape_argument ($identifier)
        . $interval
        . ' ' . _escape_argument ($values) . "\n";
-       _debug "-> $msg";
-       $fh->print($msg);
 
-       $msg = <$fh>;
-       chomp $msg;
-       _debug "<- $msg\n";
-
-       ($status, $msg) = split / /, $msg, 2;
-       return 1 if $status == 0;
-
-       $self->{error} = $msg;
-       return;
+       return $self->_send_message($msg);
 } # putval
 
 =item I<$res> = I<$self>-E<gt>B<listval_filter> ( C<%identifier> )
@@ -500,18 +516,7 @@ sub putnotif
        . join (' ', map { $_ . '=' . _escape_argument ($args{$_}) } keys %args)
        . "\n";
 
-       _debug "-> $msg";
-       $fh->print($msg);
-
-       $msg = <$fh>;
-       chomp $msg;
-       _debug "<- $msg\n";
-
-       ($status, $msg) = split / /, $msg, 2;
-       return 1 if $status == 0;
-
-       $self->{error} = $msg;
-       return;
+       return $self->_send_message($msg);
 } # putnotif
 
 =item I<$self>-E<gt>B<flush> (B<timeout> =E<gt> I<$timeout>, B<plugins> =E<gt> [...], B<identifier>  =E<gt> [...]);
@@ -549,7 +554,6 @@ sub flush
 
        my $fh = $self->{sock} or confess;
 
-       my $status = 0;
        my $msg    = "FLUSH";
 
     $msg .= " timeout=$args{timeout}" if defined $args{timeout};
@@ -564,6 +568,7 @@ sub flush
 
        if ($args{identifier})
        {
+               my $pre = $msg;
                for my $identifier (@{$args{identifier}})
                {
                        my $ident_str;
@@ -576,24 +581,18 @@ sub flush
                        }
 
                        $ident_str = _create_identifier ($identifier) or return;
-                       $msg .= ' identifier=' . _escape_argument ($ident_str);
+                       $ident_str = ' identifier=' . _escape_argument ($ident_str);
+
+                       if (length($msg)+length($ident_str) >= 1023) { #1024 - 1 byte for \n
+                               $self->_send_message($msg) or return;
+                               $msg = $pre;
+                       }
+            
+                       $msg .= $ident_str;
                }
        }
-
-       $msg .= "\n";
-
-       _debug "-> $msg";
-       $fh->print($msg);
-
-       $msg = <$fh>;
-       chomp ($msg);
-       _debug "<- $msg\n";
-
-       ($status, $msg) = split / /, $msg, 2;
-       return 1 if $status == 0;
-
-       $self->{error} = $msg;
-       return;
+    
+       return $self->_send_message($msg);
 }
 
 sub error
index 20854b1..57f3d44 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -18,7 +18,7 @@ EOF
        done
 }
 
-check_for_application lex yacc autoheader aclocal automake autoconf
+check_for_application lex bison autoheader aclocal automake autoconf
 
 # Actually we don't need the pkg-config executable, but we need the M4 macros.
 # We check for `pkg-config' here and hope that M4 macros will then be
index 3f5f2d8..c3bd6ca 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)])
-AC_CONFIG_SRCDIR(src/)
+AC_CONFIG_SRCDIR(src/target_set.c)
 AC_CONFIG_HEADERS(src/config.h)
 AC_CONFIG_AUX_DIR([libltdl/config])
 
@@ -44,6 +44,7 @@ AC_SYS_LARGEFILE
 #
 AC_PROG_CC
 AC_PROG_CPP
+AC_PROG_EGREP
 AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
@@ -54,15 +55,42 @@ AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 AC_PROG_LEX
 AC_PROG_YACC
+
+# Warn when pkg.m4 is missing
+m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config])
+
 PKG_PROG_PKG_CONFIG
 
+AC_CACHE_CHECK([if bison is the parser generator],
+       [collectd_cv_prog_bison],
+       [AS_IF([$YACC --version 2>/dev/null | $EGREP -q '^bison '],
+               [collectd_cv_prog_bison=yes], [collectd_cv_prog_bison=no]
+       )]
+)
+
+if test "x$collectd_cv_prog_bison" = "xno" && test ! -f "${srcdir}/src/liboconfig/parser.c"
+then
+       AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison])
+fi
+
 AC_CHECK_PROG([have_protoc_c], [protoc-c], [yes], [no])
-AC_CHECK_HEADERS([google/protobuf-c/protobuf-c.h],
-                 [have_protobuf_c_h="yes"],
-                 [have_protobuf_c_h="no"])
-if test "x$have_protoc_c" = "xyes" && test "x$have_protobuf_c_h" != "xyes"
+if test "x$have_protoc_c" = "xno"
+then
+       have_protoc_c="no (protoc-c compiler not found)"
+fi
+
+if test "x$have_protoc_c" = "xyes"
+then
+       AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h],
+                        [have_protoc_c="yes"; break],
+                        [have_protoc_c="no (<google/protobuf-c/protobuf-c.h> not found)"])
+fi
+if test "x$have_protoc_c" = "xyes"
 then
-       have_protoc_c="no (unable to find <google/protobuf-c/protobuf-c.h>)"
+       AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack],
+                    [have_protoc_c="yes"],
+                    [have_protoc_c="no (libprotobuf-c not found)"])
+
 fi
 AM_CONDITIONAL(HAVE_PROTOC_C, test "x$have_protoc_c" = "xyes")
 
@@ -84,6 +112,10 @@ case $host_os in
        AC_DEFINE([KERNEL_OPENBSD], 1, [True if program is to be compiled for an OpenBSD kernel])
        ac_system="OpenBSD"
        ;;
+       *netbsd*)
+       AC_DEFINE([KERNEL_NETBSD], 1, [True if program is to be compiled for a NetBSD kernel])
+       ac_system="NetBSD"
+       ;;
        *aix*)
        AC_DEFINE([KERNEL_AIX], 1, [True if program is to be compiled for a AIX kernel])
        ac_system="AIX"
@@ -171,6 +203,19 @@ AC_HEADER_STDBOOL
 
 AC_CHECK_HEADERS(stdio.h errno.h math.h stdarg.h syslog.h fcntl.h signal.h assert.h sys/types.h sys/socket.h sys/select.h poll.h netdb.h arpa/inet.h sys/resource.h sys/param.h kstat.h regex.h sys/ioctl.h endian.h sys/isa_defs.h fnmatch.h libgen.h)
 
+# For entropy plugin on newer NetBSD
+AC_CHECK_HEADERS(sys/rndio.h, [], [],
+[#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+])
+
 # For ping library
 AC_CHECK_HEADERS(netinet/in_systm.h, [], [],
 [#if HAVE_STDINT_H
@@ -385,7 +430,7 @@ AC_CHECK_HEADERS(sys/sysctl.h, [], [],
 AC_MSG_CHECKING([for sysctl kern.cp_times])
 if test -x /sbin/sysctl
 then
-       /sbin/sysctl kern.cp_times 2>/dev/null
+       /sbin/sysctl kern.cp_times >/dev/null 2>&1
        if test $? -eq 0
        then
                AC_MSG_RESULT([yes])
@@ -398,6 +443,22 @@ else
        AC_MSG_RESULT([no])
 fi
 
+AC_MSG_CHECKING([for sysctl kern.cp_time])
+if test -x /sbin/sysctl
+then
+       /sbin/sysctl kern.cp_time >/dev/null 2>&1
+       if test $? -eq 0
+       then
+               AC_MSG_RESULT([yes])
+               AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIME, 1,
+                       [Define if sysctl supports kern.cp_time])
+       else
+               AC_MSG_RESULT([no])
+       fi
+else
+       AC_MSG_RESULT([no])
+fi
+
 # For hddtemp module
 AC_CHECK_HEADERS(linux/major.h)
 
@@ -416,7 +477,7 @@ else
        have_linux_raid_md_u_h="no"
 fi
 
-# For the swap module
+# For the wireless module
 have_linux_wireless_h="no"
 if test "x$ac_system" = "xLinux"
 then
@@ -583,7 +644,35 @@ AC_CHECK_HEADERS(linux/un.h, [], [],
 #endif
 ])
 
-AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h sys/vmmeter.h kvm.h wordexp.h locale.h)
+AC_CHECK_HEADERS([ \
+  ctype.h \
+  fs_info.h \
+  fshelp.h \
+  grp.h \
+  kvm.h \
+  limits.h \
+  locale.h \
+  mntent.h \
+  mnttab.h \
+  paths.h \
+  pwd.h \
+  sys/fs_types.h \
+  sys/fstyp.h \
+  sys/mntent.h \
+  sys/mnttab.h \
+  sys/statfs.h \
+  sys/statvfs.h \
+  sys/un.h \
+  sys/vfs.h \
+  sys/vfstab.h \
+  sys/vmmeter.h \
+  wordexp.h \
+])
+
+AC_CHECK_HEADERS([xfs/xqm.h], [], [],
+[
+#define _GNU_SOURCE
+])
 
 # For the dns plugin
 AC_CHECK_HEADERS(arpa/nameser.h)
@@ -623,8 +712,6 @@ AC_CHECK_HEADERS(netinet/if_ether.h, [], [],
 #endif
 ])
 
-AC_CHECK_HEADERS(netinet/ip_compat.h)
-
 have_net_pfvar_h="no"
 AC_CHECK_HEADERS(net/pfvar.h,
                [have_net_pfvar_h="yes"],
@@ -679,13 +766,9 @@ AC_CHECK_HEADERS(sys/capability.h)
 # Checks for typedefs, structures, and compiler characteristics.
 #
 AC_C_CONST
-AC_C_INLINE
-AC_TYPE_OFF_T
 AC_TYPE_PID_T
 AC_TYPE_SIZE_T
-AC_TYPE_SSIZE_T
 AC_TYPE_UID_T
-AC_TYPE_UINT32_T
 AC_HEADER_TIME
 
 #
@@ -795,8 +878,6 @@ 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"
@@ -1254,6 +1335,8 @@ have_getvfsstat="no"
 AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"])
 have_listmntent="no"
 AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"])
+have_getmntent_r="no"
+AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"])
 
 have_getmntent="no"
 AC_CHECK_FUNCS(getmntent, [have_getmntent="c"])
@@ -1422,6 +1505,24 @@ AC_CHECK_MEMBERS([struct kinfo_proc.p_pid, struct kinfo_proc.p_vm_rssize],
 #include <kvm.h>
        ])
 
+
+AC_CHECK_MEMBERS([struct kinfo_proc2.p_pid, struct kinfo_proc2.p_uru_maxrss],
+       [
+               AC_DEFINE(HAVE_STRUCT_KINFO_PROC2_NETBSD, 1,
+                       [Define if struct kinfo_proc2 exists in the NetBSD variant.])
+               have_struct_kinfo_proc2_netbsd="yes"
+       ],
+       [
+               have_struct_kinfo_proc2_netbsd="no"
+       ],
+       [
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <kvm.h>
+       ])
+
+
+
 AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [],
 [#define _BSD_SOURCE
 #define _DEFAULT_SOURCE
@@ -1502,6 +1603,46 @@ if test "x$with_libhal" = "xyes"; then
        fi
 fi
 
+# --with-libpthread {{{
+AC_ARG_WITH(libpthread, [AS_HELP_STRING([--with-libpthread=@<:@=PREFIX@:>@], [Path to libpthread.])],
+[      if test "x$withval" != "xno" \
+               && test "x$withval" != "xyes"
+       then
+               LDFLAGS="$LDFLAGS -L$withval/lib"
+               CPPFLAGS="$CPPFLAGS -I$withval/include"
+               with_libpthread="yes"
+       else
+               if test "x$withval" = "xno"
+               then
+                       with_libpthread="no (disabled)"
+               fi
+       fi
+], [with_libpthread="yes"])
+
+AC_SUBST([PTHREAD_LIBS])
+if test "x$with_libpthread" = "xyes"
+then
+       SAVE_LIBS="$LIBS"
+       AC_CHECK_LIB(pthread, pthread_create, [], [with_libpthread="no (Symbol 'pthread_create' not found)"], [])
+       PTHREAD_LIBS="$LIBS"
+       LIBS="$SAVE_LIBS"
+fi
+
+if test "x$with_libpthread" = "xyes"
+then
+       AC_CHECK_HEADERS(pthread.h,, [with_libpthread="no (pthread.h not found)"])
+fi
+if test "x$with_libpthread" = "xyes"
+then
+       collect_pthread=1
+else
+       collect_pthread=0
+fi
+AC_DEFINE_UNQUOTED(HAVE_LIBPTHREAD, [$collect_pthread],
+       [Wether or not to use pthread (POSIX threads) library])
+AM_CONDITIONAL(BUILD_WITH_LIBPTHREAD, test "x$with_libpthread" = "xyes")
+# }}}
+
 m4_divert_once([HELP_WITH], [
 collectd additional packages:])
 
@@ -2023,12 +2164,6 @@ then
                GCRYPT_CPPFLAGS=`"$with_libgcrypt_config" --cflags 2>/dev/null`
        fi
 
-       if test "x$GCRYPT_LDFLAGS" = "x"
-       then
-               gcrypt_exec_prefix=`"$with_libgcrypt_config" --exec-prefix 2>/dev/null`
-               GCRYPT_LDFLAGS="-L$gcrypt_exec_prefix/lib"
-       fi
-
        if test "x$GCRYPT_LIBS" = "x"
        then
                GCRYPT_LIBS=`"$with_libgcrypt_config" --libs 2>/dev/null`
@@ -2037,8 +2172,10 @@ fi
 
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
+SAVE_LIBS="$LIBS"
 CPPFLAGS="$CPPFLAGS $GCRYPT_CPPFLAGS"
 LDFLAGS="$LDFLAGS $GCRYPT_LDFLAGS"
+LIBS="$LIBS $GCRYPT_LIBS"
 
 if test "x$with_libgcrypt" = "xyes"
 then
@@ -2053,23 +2190,14 @@ fi
 
 if test "x$with_libgcrypt" = "xyes"
 then
-       if test "x$GCRYPT_LDFLAGS" != "x"
-       then
-               AC_MSG_NOTICE([gcrypt LDFLAGS: $GCRYPT_LDFLAGS])
-       fi
        AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer,
                [with_libgcrypt="yes"],
                [with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"])
-
-       if test "$with_libgcrypt" != "no"; then
-               m4_ifdef([AM_PATH_LIBGCRYPT],[AM_PATH_LIBGCRYPT(1:1.2.0,,with_libgcrypt="no (version 1.2.0+ required)")])
-               GCRYPT_CPPFLAGS="$LIBGCRYPT_CPPFLAGS $LIBGCRYPT_CFLAGS"
-               GCRYPT_LIBS="$LIBGCRYPT_LIBS"
-       fi
 fi
 
 CPPFLAGS="$SAVE_CPPFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
+LIBS="$SAVE_LIBS"
 
 if test "x$with_libgcrypt" = "xyes"
 then
@@ -2183,9 +2311,6 @@ if test "x$with_java_home" = "x"
 then
        with_java_home="/usr/lib/jvm"
 fi
-with_java_vmtype="client"
-with_java_cflags=""
-with_java_libs=""
 JAVAC="$JAVAC"
 JAR="$JAR"
 AC_ARG_WITH(java, [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])],
@@ -2227,7 +2352,7 @@ then
                fi
 
                AC_MSG_CHECKING([for libjvm.so])
-               TMPVAR=`find -L "$with_java_home" -name libjvm.so -type f -exec 'dirname' '{}' ';' 2>/dev/null | head -n 1`
+               TMPVAR=`find -L "$with_java_home" -type f \( -name libjvm.so -o -name libjvm.dylib \) -exec 'dirname' '{}' ';' 2>/dev/null | head -n 1`
                if test "x$TMPVAR" != "x"
                then
                        AC_MSG_RESULT([found in $TMPVAR])
@@ -2278,6 +2403,10 @@ if test "x$JAVA_LDFLAGS" != "x"
 then
        AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
 fi
+if test "x$JAVA_LIBS" != "x"
+then
+       AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
+fi
 if test "x$JAVAC" = "x"
 then
        with_javac_path="$PATH"
@@ -2318,9 +2447,11 @@ fi
 SAVE_CPPFLAGS="$CPPFLAGS"
 SAVE_CFLAGS="$CFLAGS"
 SAVE_LDFLAGS="$LDFLAGS"
+SAVE_LIBS="$LIBS"
 CPPFLAGS="$CPPFLAGS $JAVA_CPPFLAGS"
 CFLAGS="$CFLAGS $JAVA_CFLAGS"
 LDFLAGS="$LDFLAGS $JAVA_LDFLAGS"
+LIBS="$LIBS $JAVA_LIBS"
 
 if test "x$with_java" = "xyes"
 then
@@ -2330,8 +2461,8 @@ if test "x$with_java" = "xyes"
 then
        AC_CHECK_LIB(jvm, JNI_CreateJavaVM,
        [with_java="yes"],
-       [with_java="no (libjvm not found)"],
-       [$JAVA_LIBS])
+       [with_java="no (Symbol 'JNI_CreateJavaVM' not found)"],
+       [$JAVA_LIBS $PTHREAD_LIBS])
 fi
 if test "x$with_java" = "xyes"
 then
@@ -2342,6 +2473,7 @@ fi
 CPPFLAGS="$SAVE_CPPFLAGS"
 CFLAGS="$SAVE_CFLAGS"
 LDFLAGS="$SAVE_LDFLAGS"
+LIBS="$SAVE_LIBS"
 
 AC_SUBST(JAVA_CPPFLAGS)
 AC_SUBST(JAVA_CFLAGS)
@@ -2413,17 +2545,25 @@ with_liblvm2app_cppflags=""
 with_liblvm2app_ldflags=""
 AC_ARG_WITH(liblvm2app, [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])],
 [
-        if test "x$withval" != "xno" && test "x$withval" != "xyes"
-        then
-                with_liblvm2app_cppflags="-I$withval/include"
-                with_liblvm2app_ldflags="-L$withval/lib"
-                with_liblvm2app="yes"
-        else
-                with_liblvm2app="$withval"
+       if test "x$withval" = "xno"
+       then
+               with_liblvm2app="no"
+       else
+               with_liblvm2app="yes"
+               if test "x$withval" != "xyes"
+               then
+                       with_liblvm2app_cppflags="-I$withval/include"
+                       with_liblvm2app_ldflags="-L$withval/lib"
+               fi
         fi
 ],
 [
-        with_liblvm2app="yes"
+       if test "x$ac_system" = "xLinux"
+       then
+               with_liblvm2app="yes"
+       else
+               with_liblvm2app="no (Linux only library)"
+       fi
 ])
 if test "x$with_liblvm2app" = "xyes"
 then
@@ -2668,13 +2808,13 @@ AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
 
 # --with-libmosquitto {{{
 with_libmosquitto_cppflags=""
-with_libmosquitto_libs="-lmosquitto"
+with_libmosquitto_ldflags=""
 AC_ARG_WITH(libmosquitto, [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@], [Path to libmosquitto.])],
 [
        if test "x$withval" != "xno" && test "x$withval" != "xyes"
        then
                with_libmosquitto_cppflags="-I$withval/include"
-               with_libmosquitto_libs="-L$withval/lib -lmosquitto"
+               with_libmosquitto_ldflags="-L$withval/lib"
                with_libmosquitto="yes"
        else
                with_libmosquitto="$withval"
@@ -2686,7 +2826,7 @@ AC_ARG_WITH(libmosquitto, [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@],
 if test "x$with_libmosquitto" = "xyes"
 then
        SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$with_libmosquitto_cppflags"
+       CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
 
        AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"])
 
@@ -2696,8 +2836,8 @@ if test "x$with_libmosquitto" = "xyes"
 then
        SAVE_LDFLAGS="$LDFLAGS"
        SAVE_CPPFLAGS="$CPPFLAGS"
-       LDFLAGS="$with_libmosquitto_libs"
-       CPPFLAGS="$with_libmosquitto_cppflags"
+       LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags"
+       CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
 
        AC_CHECK_LIB(mosquitto, mosquitto_connect, [with_libmosquitto="yes"], [with_libmosquitto="no (libmosquitto not found)"])
 
@@ -2707,8 +2847,10 @@ fi
 if test "x$with_libmosquitto" = "xyes"
 then
        BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
-       BUILD_WITH_LIBMOSQUITTO_LIBS="$with_libmosquitto_libs"
+       BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags"
+       BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto"
        AC_SUBST(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
+       AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
        AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LIBS)
 fi
 # }}}
@@ -2965,7 +3107,7 @@ then
 
        if test "x$LIBNETAPP_LIBS" = "x"
        then
-               LIBNETAPP_LIBS="-lpthread -lxml -ladt -lssl -lm -lcrypto -lz"
+               LIBNETAPP_LIBS="$PTHREAD_LIBS -lxml -ladt -lssl -lm -lcrypto -lz"
        fi
        AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS])
 
@@ -3233,13 +3375,13 @@ fi
 
 # --with-libowcapi {{{
 with_libowcapi_cppflags=""
-with_libowcapi_libs="-lowcapi"
+with_libowcapi_ldflags=""
 AC_ARG_WITH(libowcapi, [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])],
 [
        if test "x$withval" != "xno" && test "x$withval" != "xyes"
        then
                with_libowcapi_cppflags="-I$withval/include"
-               with_libowcapi_libs="-L$withval/lib -lowcapi"
+               with_libowcapi_ldflags="-L$withval/lib"
                with_libowcapi="yes"
        else
                with_libowcapi="$withval"
@@ -3251,7 +3393,7 @@ AC_ARG_WITH(libowcapi, [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path
 if test "x$with_libowcapi" = "xyes"
 then
        SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$with_libowcapi_cppflags"
+       CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags"
 
        AC_CHECK_HEADERS(owcapi.h, [with_libowcapi="yes"], [with_libowcapi="no (owcapi.h not found)"])
 
@@ -3261,7 +3403,7 @@ if test "x$with_libowcapi" = "xyes"
 then
        SAVE_LDFLAGS="$LDFLAGS"
        SAVE_CPPFLAGS="$CPPFLAGS"
-       LDFLAGS="$with_libowcapi_libs"
+       LDFLAGS="$LDFLAGS $with_libowcapi_ldflags"
        CPPFLAGS="$with_libowcapi_cppflags"
 
        AC_CHECK_LIB(owcapi, OW_get, [with_libowcapi="yes"], [with_libowcapi="no (libowcapi not found)"])
@@ -3272,8 +3414,10 @@ fi
 if test "x$with_libowcapi" = "xyes"
 then
        BUILD_WITH_LIBOWCAPI_CPPFLAGS="$with_libowcapi_cppflags"
-       BUILD_WITH_LIBOWCAPI_LIBS="$with_libowcapi_libs"
+       BUILD_WITH_LIBOWCAPI_LDFLAGS="$with_libowcapi_ldflags"
+       BUILD_WITH_LIBOWCAPI_LIBS="-lowcapi"
        AC_SUBST(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
+       AC_SUBST(BUILD_WITH_LIBOWCAPI_LDFLAGS)
        AC_SUBST(BUILD_WITH_LIBOWCAPI_LIBS)
 fi
 # }}}
@@ -3602,41 +3746,6 @@ fi
 AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes")
 # }}}
 
-# --with-libpthread {{{
-AC_ARG_WITH(libpthread, [AS_HELP_STRING([--with-libpthread=@<:@=PREFIX@:>@], [Path to libpthread.])],
-[      if test "x$withval" != "xno" \
-               && test "x$withval" != "xyes"
-       then
-               LDFLAGS="$LDFLAGS -L$withval/lib"
-               CPPFLAGS="$CPPFLAGS -I$withval/include"
-               with_libpthread="yes"
-       else
-               if test "x$withval" = "xno"
-               then
-                       with_libpthread="no (disabled)"
-               fi
-       fi
-], [with_libpthread="yes"])
-if test "x$with_libpthread" = "xyes"
-then
-       AC_CHECK_LIB(pthread, pthread_create, [with_libpthread="yes"], [with_libpthread="no (libpthread not found)"], [])
-fi
-
-if test "x$with_libpthread" = "xyes"
-then
-       AC_CHECK_HEADERS(pthread.h,, [with_libpthread="no (pthread.h not found)"])
-fi
-if test "x$with_libpthread" = "xyes"
-then
-       collect_pthread=1
-else
-       collect_pthread=0
-fi
-AC_DEFINE_UNQUOTED(HAVE_LIBPTHREAD, [$collect_pthread],
-       [Wether or not to use pthread (POSIX threads) library])
-AM_CONDITIONAL(BUILD_WITH_LIBPTHREAD, test "x$with_libpthread" = "xyes")
-# }}}
-
 # --with-python {{{
 with_python_prog=""
 with_python_path="$PATH"
@@ -3979,76 +4088,102 @@ AM_CONDITIONAL(BUILD_WITH_LIBROUTEROS, test "x$with_librouteros" = "xyes")
 # }}}
 
 # --with-librrd {{{
-# AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])
 librrd_cflags=""
 librrd_ldflags=""
-librrd_threadsafe="yes"
+librrd_threadsafe="no"
 librrd_rrdc_update="no"
-AC_ARG_WITH(librrd, [AS_HELP_STRING([--with-librrd@<:@=PREFIX@:>@], [Path to rrdtool.])],
-[      if test "x$withval" != "xno" && test "x$withval" != "xyes"
-       then
-               librrd_cflags="-I$withval/include"
-               librrd_ldflags="-L$withval/lib"
-               with_librrd="yes"
-       else
-               with_librrd="$withval"
-       fi
-], [with_librrd="yes"])
+AC_ARG_WITH(librrd,
+  [AS_HELP_STRING([--with-librrd@<:@=PREFIX@:>@], [Path to rrdtool.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"
+    then
+      librrd_cflags="-I$withval/include"
+      librrd_ldflags="-L$withval/lib"
+      with_librrd="yes"
+    else
+      with_librrd="$withval"
+    fi
+  ],
+  [with_librrd="yes"]
+)
+
 if test "x$with_librrd" = "xyes"
 then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $librrd_ldflags"
+  PKG_CHECK_MODULES([RRD], [librrd >= 1.6.0],
+    [
+      AC_CHECK_LIB([rrd], [rrd_update_r],
+        [librrd_threadsafe="yes"],
+        [:]
+      )
+      AC_CHECK_LIB([rrd], [rrdc_update],
+        [librrd_rrdc_update="yes"],
+        [:]
+      )
+    ],[:]
+  )
+  LDFLAGS="$SAVE_LDFLAGS"
 
-       CPPFLAGS="$CPPFLAGS $librrd_cflags"
-       LDFLAGS="$LDFLAGS $librrd_ldflags"
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="$CPPFLAGS $RRD_CFLAGS $librrd_cflags"
 
-       AC_CHECK_HEADERS(rrd.h,, [with_librrd="no (rrd.h not found)"])
+  AC_CHECK_HEADERS([rrd.h],, [with_librrd="no (rrd.h not found)"])
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  CPPFLAGS="$SAVE_CPPFLAGS"
 fi
-if test "x$with_librrd" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
 
-       CPPFLAGS="$CPPFLAGS $librrd_cflags"
-       LDFLAGS="$LDFLAGS $librrd_ldflags"
+if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"
+then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $librrd_ldflags"
 
-       AC_CHECK_LIB(rrd_th, rrd_update_r,
-       [with_librrd="yes"
-        librrd_ldflags="$librrd_ldflags -lrrd_th -lm"
-       ],
-       [librrd_threadsafe="no"
-        AC_CHECK_LIB(rrd, rrd_update,
-        [with_librrd="yes"
-         librrd_ldflags="$librrd_ldflags -lrrd -lm"
-        ],
-        [with_librrd="no (symbol 'rrd_update' not found)"],
-        [-lm])
-       ],
-       [-lm])
+  AC_CHECK_LIB([rrd_th], [rrd_update_r],
+    [
+      librrd_ldflags="$librrd_ldflags -lrrd_th"
+      librrd_threadsafe="yes"
+      AC_CHECK_LIB([rrd_th], [rrdc_update],
+        [librrd_rrdc_update="yes"],
+        [:],
+      )
+    ],
+    [:]
+  )
+  LDFLAGS="$SAVE_LDFLAGS"
+fi
 
-       if test "x$librrd_threadsafe" = "xyes"
-       then
-               AC_CHECK_LIB(rrd_th, rrdc_update, [librrd_rrdc_update="yes"], [librrd_rrdc_update="no"])
-       else
-               AC_CHECK_LIB(rrd, rrdc_update, [librrd_rrdc_update="yes"], [librrd_rrdc_update="no"])
-       fi
+if test "x$with_librrd" = "xyes" && test "x$librrd_threadsafe" = "xno"
+then
+  SAVE_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $librrd_ldflags"
 
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
+  AC_CHECK_LIB([rrd], [rrd_update],
+    [
+      librrd_ldflags="$librrd_ldflags -lrrd"
+      AC_CHECK_LIB([rrd], [rrdc_update],
+        [librrd_rrdc_update="yes"],
+        [:]
+      )
+    ],
+    [with_librrd="no (symbol 'rrd_update' not found)"]
+  )
+  LDFLAGS="$SAVE_LDFLAGS"
 fi
+
 if test "x$with_librrd" = "xyes"
 then
-       BUILD_WITH_LIBRRD_CFLAGS="$librrd_cflags"
-       BUILD_WITH_LIBRRD_LDFLAGS="$librrd_ldflags"
-       AC_SUBST(BUILD_WITH_LIBRRD_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBRRD_LDFLAGS)
+  BUILD_WITH_LIBRRD_CFLAGS="$RRD_CFLAGS $librrd_cflags"
+  BUILD_WITH_LIBRRD_LDFLAGS="$librrd_ldflags"
+  BUILD_WITH_LIBRRD_LIBS="$RRD_LIBS"
+  AC_SUBST(BUILD_WITH_LIBRRD_CFLAGS)
+  AC_SUBST(BUILD_WITH_LIBRRD_LDFLAGS)
+  AC_SUBST(BUILD_WITH_LIBRRD_LIBS)
 fi
 if test "x$librrd_threadsafe" = "xyes"
 then
-       AC_DEFINE(HAVE_THREADSAFE_LIBRRD, 1, [Define to 1 if you have the threadsafe rrd library (-lrrd_th).])
+  AC_DEFINE([HAVE_THREADSAFE_LIBRRD], [1],
+    [Define to 1 if the rrd library is thread-safe]
+  )
 fi
 # }}}
 
@@ -4083,11 +4218,6 @@ then
        SAVE_CPPFLAGS="$CPPFLAGS"
        CPPFLAGS="$CPPFLAGS $with_sensors_cflags"
 
-#      AC_CHECK_HEADERS(sensors/sensors.h,
-#      [
-#              AC_DEFINE(HAVE_SENSORS_SENSORS_H, 1, [Define to 1 if you have the <sensors/sensors.h> header file.])
-#      ],
-#      [with_libsensors="no (sensors/sensors.h not found)"])
        AC_CHECK_HEADERS(sensors/sensors.h, [], [with_libsensors="no (sensors/sensors.h not found)"])
 
        CPPFLAGS="$SAVE_CPPFLAGS"
@@ -4295,6 +4425,7 @@ fi
 if test "x$with_libstatgrab" = "xyes"
 then
   SAVE_CFLAGS="$CFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
   SAVE_LIBS="$LIBS"
 
   CFLAGS="$CFLAGS $with_libstatgrab_cflags"
@@ -4604,6 +4735,46 @@ then
 fi
 # }}}
 
+# --with-libxenctrl {{{
+with_libxenctrl_cppflags=""
+with_libxenctrl_ldflags=""
+AC_ARG_WITH(libxenctrl, [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])],
+[
+       if test "x$withval" != "xno" && test "x$withval" != "xyes"
+       then
+               with_libxenctrl_cppflags="-I$withval/include"
+               with_libxenctrl_ldflags="-L$withval/lib"
+               with_libxenctrl="yes"
+       else
+               with_libxenctrl="$withval"
+       fi
+],
+[
+       with_libxenctrl="yes"
+])
+if test "x$with_libxenctrl" = "xyes"
+then
+       SAVE_CPPFLAGS="$CPPFLAGS"
+       CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
+
+       AC_CHECK_HEADERS(xenctrl.h, [with_libxenctrl="yes"], [with_libxenctrl="no (xenctrl.h not found)"])
+
+       CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libxenctrl" = "xyes"
+then
+       SAVE_CPPFLAGS="$CPPFLAGS"
+       SAVE_LDFLAGS="$LDFLAGS"
+       CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
+       LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags"
+
+       #Xen versions older than 3.4 has no xc_getcpuinfo()
+       AC_CHECK_LIB(xenctrl, xc_getcpuinfo, [with_libxenctrl="yes"], [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"], [])
+
+       CPPFLAGS="$SAVE_CPPFLAGS"
+       LDFLAGS="$SAVE_LDFLAGS"
+fi
+
 # --with-libxmms {{{
 with_xmms_config="xmms-config"
 with_xmms_cflags=""
@@ -4743,7 +4914,7 @@ AC_ARG_WITH(mic,[AS_HELP_STRING([--with-mic@<:@=PREFIX@:>@], [Path to Intel MIC
                AC_MSG_NOTICE([Not checking for Intel Mic: Manually configured])
                with_mic_cflags="-I$withval/include"
                with_mic_ldpath="-L$withval/lib/Linux"
-               with_mic_libs="-lMicAccessSDK -lscif -lpthread"
+               with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"
                with_mic="yes"
        fi; fi; fi
 ],
@@ -4765,8 +4936,8 @@ then
 
        AC_CHECK_LIB(MicAccessSDK, MicInitAPI,
                        [with_mic_ldpath="$with_mic_ldpath"
-                       with_mic_libs="-lMicAccessSDK -lscif -lpthread"],
-                       [with_mic="no (symbol MicInitAPI not found)"],[-lscif -lpthread])
+                       with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"],
+                       [with_mic="no (symbol MicInitAPI not found)"],[$PTHREAD_LIBS -lscif])
 
        CPPFLAGS="$SAVE_CPPFLAGS"
        LDFLAGS="$SAVE_LDFLAGS"
@@ -5123,11 +5294,12 @@ AM_CONDITIONAL(BUILD_WITH_LIBATASMART, test "x$with_libatasmart" = "xyes")
 
 PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
                [with_libnotify="yes"],
-               [if test "x$LIBNOTIFY_PKG_ERRORS" = "x"; then
-                        with_libnotify="no"
-                else
-                        with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"
-                fi])
+               [with_libnotify="no (pkg-config doesn't know libnotify)"]
+)
+
+PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.8.0],
+ [with_libriemann_client="yes"],
+ [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"])
 
 # Check for enabled/disabled features
 #
@@ -5301,6 +5473,7 @@ plugin_virt="no"
 plugin_vmem="no"
 plugin_vserver="no"
 plugin_wireless="no"
+plugin_xencpu="no"
 plugin_zfs_arc="no"
 plugin_zone="no"
 plugin_zookeeper="no"
@@ -5309,9 +5482,9 @@ plugin_zookeeper="no"
 if test "x$ac_system" = "xLinux"
 then
        plugin_battery="yes"
+       plugin_cgroups="yes"
        plugin_conntrack="yes"
        plugin_contextswitch="yes"
-       plugin_cgroups="yes"
        plugin_cpu="yes"
        plugin_cpufreq="yes"
        plugin_disk="yes"
@@ -5354,6 +5527,14 @@ then
        plugin_tcpconns="yes"
 fi
 
+if test "x$ac_system" = "xNetBSD"
+then
+       plugin_disk="yes"
+       plugin_entropy="yes"
+       plugin_irq="yes"
+       plugin_processes="yes"
+fi
+
 # Mac OS X devices
 if test "x$with_libiokit" = "xyes"
 then
@@ -5365,8 +5546,8 @@ fi
 
 if test "x$ac_system" = "xAIX"
 then
-       plugin_tcpconns="yes"
        plugin_ipc="yes"
+       plugin_tcpconns="yes"
 fi
 
 # FreeBSD
@@ -5380,13 +5561,13 @@ fi
 
 if test "x$with_perfstat" = "xyes"
 then
-       plugin_cpu="yes"
        plugin_contextswitch="yes"
+       plugin_cpu="yes"
        plugin_disk="yes"
-       plugin_memory="yes"
-       plugin_swap="yes"
        plugin_interface="yes"
        plugin_load="yes"
+       plugin_memory="yes"
+       plugin_swap="yes"
        plugin_uptime="yes"
 fi
 
@@ -5415,7 +5596,6 @@ then
 fi
 
 # libi2c-dev
-with_libi2c="no"
 if test "x$ac_system" = "xLinux"
 then
 AC_CHECK_DECL(i2c_smbus_read_i2c_block_data,
@@ -5423,6 +5603,8 @@ AC_CHECK_DECL(i2c_smbus_read_i2c_block_data,
        [with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
        [[#include <stdlib.h>
        #include <linux/i2c-dev.h>]])
+else
+       with_libi2c="no (Linux only)"
 fi
 
 if test "x$with_libi2c" = "xyes"
@@ -5515,6 +5697,11 @@ then
        plugin_df="yes"
 fi
 
+if test "x$c_cv_have_getmntent_r" = "xyes"
+then
+       plugin_df="yes"
+fi
+
 # Df plugin: Check if we have either `statfs' or `statvfs' second.
 if test "x$plugin_df" = "xyes"
 then
@@ -5594,6 +5781,11 @@ then
        plugin_swap="yes"
 fi
 
+if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_three_args" = "xyes"
+then
+       plugin_swap="yes"
+fi
+
 if test "x$with_kvm_openfiles$with_kvm_nlist" = "xyesyes"
 then
        plugin_tcpconns="yes"
@@ -5613,6 +5805,10 @@ then
        plugin_virt="yes"
 fi
 
+if test "x$with_libxenctrl" = "xyes"
+then
+  plugin_xencpu="yes"
+fi
 
 m4_divert_once([HELP_ENABLE], [
 collectd plugins:])
@@ -5634,143 +5830,145 @@ AC_ARG_ENABLE([all-plugins],
 
 m4_divert_once([HELP_ENABLE], [])
 
-AC_PLUGIN([aggregation], [yes],                [Aggregation plugin])
-AC_PLUGIN([amqp],        [$with_librabbitmq],  [AMQP output plugin])
-AC_PLUGIN([apache],      [$with_libcurl],      [Apache httpd statistics])
-AC_PLUGIN([apcups],      [yes],                [Statistics of UPSes by APC])
-AC_PLUGIN([apple_sensors], [$with_libiokit],   [Apple's hardware sensors])
-AC_PLUGIN([aquaero],     [$with_libaquaero5],  [Aquaero's hardware sensors])
-AC_PLUGIN([ascent],      [$plugin_ascent],     [AscentEmu player statistics])
-AC_PLUGIN([barometer],   [$plugin_barometer],  [Barometer sensor on I2C])
-AC_PLUGIN([battery],     [$plugin_battery],    [Battery statistics])
-AC_PLUGIN([bind],        [$plugin_bind],       [ISC Bind nameserver statistics])
-AC_PLUGIN([ceph],        [$plugin_ceph],       [Ceph daemon statistics])
-AC_PLUGIN([conntrack],   [$plugin_conntrack],  [nf_conntrack statistics])
-AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
-AC_PLUGIN([cpufreq],     [$plugin_cpufreq],    [CPU frequency statistics])
-AC_PLUGIN([cpu],         [$plugin_cpu],        [CPU usage statistics])
-AC_PLUGIN([csv],         [yes],                [CSV output plugin])
-AC_PLUGIN([curl],        [$with_libcurl],      [CURL generic web statistics])
-AC_PLUGIN([curl_json],   [$plugin_curl_json],    [CouchDB statistics])
-AC_PLUGIN([curl_xml],   [$plugin_curl_xml],    [CURL generic xml statistics])
-AC_PLUGIN([cgroups],     [$plugin_cgroups],    [CGroups CPU usage accounting])
-AC_PLUGIN([dbi],         [$with_libdbi],       [General database statistics])
-AC_PLUGIN([df],          [$plugin_df],         [Filesystem usage statistics])
-AC_PLUGIN([disk],        [$plugin_disk],       [Disk usage statistics])
-AC_PLUGIN([drbd],        [$plugin_drbd],       [DRBD statistics])
-AC_PLUGIN([dns],         [$with_libpcap],      [DNS traffic analysis])
-AC_PLUGIN([email],       [yes],                [EMail statistics])
-AC_PLUGIN([entropy],     [$plugin_entropy],    [Entropy statistics])
-AC_PLUGIN([ethstat],     [$plugin_ethstat],    [Stats from NIC driver])
-AC_PLUGIN([exec],        [yes],                [Execution of external programs])
-AC_PLUGIN([fhcount],     [$plugin_fhcount],    [File handles statistics])
-AC_PLUGIN([filecount],   [yes],                [Count files in directories])
-AC_PLUGIN([fscache],     [$plugin_fscache],    [fscache statistics])
-AC_PLUGIN([gmond],       [$with_libganglia],   [Ganglia plugin])
-AC_PLUGIN([hddtemp],     [yes],                [Query hddtempd])
-AC_PLUGIN([interface],   [$plugin_interface],  [Interface traffic statistics])
-AC_PLUGIN([ipc],         [$plugin_ipc],        [IPC statistics])
-AC_PLUGIN([ipmi],        [$plugin_ipmi],       [IPMI sensor statistics])
-AC_PLUGIN([iptables],    [$with_libiptc],      [IPTables rule counters])
-AC_PLUGIN([ipvs],        [$plugin_ipvs],       [IPVS connection statistics])
-AC_PLUGIN([irq],         [$plugin_irq],        [IRQ statistics])
-AC_PLUGIN([java],        [$with_java],         [Embed the Java Virtual Machine])
-AC_PLUGIN([load],        [$plugin_load],       [System load])
-AC_PLUGIN([logfile],     [yes],                [File logging plugin])
-AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging])
-AC_PLUGIN([lpar],        [$with_perfstat],     [AIX logical partitions statistics])
-AC_PLUGIN([lvm],         [$with_liblvm2app],   [LVM statistics])
-AC_PLUGIN([madwifi],     [$have_linux_wireless_h], [Madwifi wireless statistics])
-AC_PLUGIN([match_empty_counter], [yes],        [The empty counter match])
-AC_PLUGIN([match_hashed], [yes],               [The hashed match])
-AC_PLUGIN([match_regex], [yes],                [The regex match])
-AC_PLUGIN([match_timediff], [yes],             [The timediff match])
-AC_PLUGIN([match_value], [yes],                [The value match])
-AC_PLUGIN([mbmon],       [yes],                [Query mbmond])
-AC_PLUGIN([md],          [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
-AC_PLUGIN([memcachec],   [$with_libmemcached], [memcachec statistics])
-AC_PLUGIN([memcached],   [yes],                [memcached statistics])
-AC_PLUGIN([memory],      [$plugin_memory],     [Memory usage])
-AC_PLUGIN([mic],         [$with_mic],          [Intel Many Integrated Core stats])
-AC_PLUGIN([modbus],      [$with_libmodbus],    [Modbus plugin])
-AC_PLUGIN([mqtt],        [$with_libmosquitto], [MQTT output plugin])
-AC_PLUGIN([multimeter],  [$plugin_multimeter], [Read multimeter values])
-AC_PLUGIN([mysql],       [$with_libmysql],     [MySQL statistics])
-AC_PLUGIN([netapp],      [$with_libnetapp],    [NetApp plugin])
-AC_PLUGIN([netlink],     [$with_libmnl],       [Enhanced Linux network statistics])
-AC_PLUGIN([network],     [yes],                [Network communication plugin])
-AC_PLUGIN([nfs],         [$plugin_nfs],        [NFS statistics])
-AC_PLUGIN([nginx],       [$with_libcurl],      [nginx statistics])
-AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
-AC_PLUGIN([notify_email], [$with_libesmtp],    [Email notifier])
-AC_PLUGIN([ntpd],        [yes],                [NTPd statistics])
-AC_PLUGIN([numa],        [$plugin_numa],       [NUMA virtual memory statistics])
-AC_PLUGIN([nut],         [$with_libupsclient], [Network UPS tools statistics])
-AC_PLUGIN([olsrd],       [yes],                [olsrd statistics])
-AC_PLUGIN([onewire],     [$with_libowcapi],    [OneWire sensor statistics])
-AC_PLUGIN([openldap],    [$with_libldap],      [OpenLDAP statistics])
-AC_PLUGIN([openvpn],     [yes],                [OpenVPN client statistics])
-AC_PLUGIN([oracle],      [$with_oracle],       [Oracle plugin])
-AC_PLUGIN([perl],        [$plugin_perl],       [Embed a Perl interpreter])
-AC_PLUGIN([pf],          [$have_net_pfvar_h],  [BSD packet filter (PF) statistics])
+AC_PLUGIN([aggregation],         [yes],                     [Aggregation plugin])
+AC_PLUGIN([amqp],                [$with_librabbitmq],       [AMQP output plugin])
+AC_PLUGIN([apache],              [$with_libcurl],           [Apache httpd statistics])
+AC_PLUGIN([apcups],              [yes],                     [Statistics of UPSes by APC])
+AC_PLUGIN([apple_sensors],       [$with_libiokit],          [Apple hardware sensors])
+AC_PLUGIN([aquaero],             [$with_libaquaero5],       [Aquaero hardware sensors])
+AC_PLUGIN([ascent],              [$plugin_ascent],          [AscentEmu player statistics])
+AC_PLUGIN([barometer],           [$plugin_barometer],       [Barometer sensor on I2C])
+AC_PLUGIN([battery],             [$plugin_battery],         [Battery statistics])
+AC_PLUGIN([bind],                [$plugin_bind],            [ISC Bind nameserver statistics])
+AC_PLUGIN([ceph],                [$plugin_ceph],            [Ceph daemon statistics])
+AC_PLUGIN([cgroups],             [$plugin_cgroups],         [CGroups CPU usage accounting])
+AC_PLUGIN([conntrack],           [$plugin_conntrack],       [nf_conntrack statistics])
+AC_PLUGIN([contextswitch],       [$plugin_contextswitch],   [context switch statistics])
+AC_PLUGIN([cpu],                 [$plugin_cpu],             [CPU usage statistics])
+AC_PLUGIN([cpufreq],             [$plugin_cpufreq],         [CPU frequency statistics])
+AC_PLUGIN([csv],                 [yes],                     [CSV output plugin])
+AC_PLUGIN([curl],                [$with_libcurl],           [CURL generic web statistics])
+AC_PLUGIN([curl_json],           [$plugin_curl_json],       [CouchDB statistics])
+AC_PLUGIN([curl_xml],            [$plugin_curl_xml],        [CURL generic xml statistics])
+AC_PLUGIN([dbi],                 [$with_libdbi],            [General database statistics])
+AC_PLUGIN([df],                  [$plugin_df],              [Filesystem usage statistics])
+AC_PLUGIN([disk],                [$plugin_disk],            [Disk usage statistics])
+AC_PLUGIN([dns],                 [$with_libpcap],           [DNS traffic analysis])
+AC_PLUGIN([drbd],                [$plugin_drbd],            [DRBD statistics])
+AC_PLUGIN([email],               [yes],                     [EMail statistics])
+AC_PLUGIN([entropy],             [$plugin_entropy],         [Entropy statistics])
+AC_PLUGIN([ethstat],             [$plugin_ethstat],         [Stats from NIC driver])
+AC_PLUGIN([exec],                [yes],                     [Execution of external programs])
+AC_PLUGIN([fhcount],             [$plugin_fhcount],         [File handles statistics])
+AC_PLUGIN([filecount],           [yes],                     [Count files in directories])
+AC_PLUGIN([fscache],             [$plugin_fscache],         [fscache statistics])
+AC_PLUGIN([gmond],               [$with_libganglia],        [Ganglia plugin])
+AC_PLUGIN([hddtemp],             [yes],                     [Query hddtempd])
+AC_PLUGIN([interface],           [$plugin_interface],       [Interface traffic statistics])
+AC_PLUGIN([ipc],                 [$plugin_ipc],             [IPC statistics])
+AC_PLUGIN([ipmi],                [$plugin_ipmi],            [IPMI sensor statistics])
+AC_PLUGIN([iptables],            [$with_libiptc],           [IPTables rule counters])
+AC_PLUGIN([ipvs],                [$plugin_ipvs],            [IPVS connection statistics])
+AC_PLUGIN([irq],                 [$plugin_irq],             [IRQ statistics])
+AC_PLUGIN([java],                [$with_java],              [Embed the Java Virtual Machine])
+AC_PLUGIN([load],                [$plugin_load],            [System load])
+AC_PLUGIN([log_logstash],        [$plugin_log_logstash],    [Logstash json_event compatible logging])
+AC_PLUGIN([logfile],             [yes],                     [File logging plugin])
+AC_PLUGIN([lpar],                [$with_perfstat],          [AIX logical partitions statistics])
+AC_PLUGIN([lvm],                 [$with_liblvm2app],        [LVM statistics])
+AC_PLUGIN([madwifi],             [$have_linux_wireless_h],  [Madwifi wireless statistics])
+AC_PLUGIN([match_empty_counter], [yes],                     [The empty counter match])
+AC_PLUGIN([match_hashed],        [yes],                     [The hashed match])
+AC_PLUGIN([match_regex],         [yes],                     [The regex match])
+AC_PLUGIN([match_timediff],      [yes],                     [The timediff match])
+AC_PLUGIN([match_value],         [yes],                     [The value match])
+AC_PLUGIN([mbmon],               [yes],                     [Query mbmond])
+AC_PLUGIN([md],                  [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
+AC_PLUGIN([memcachec],           [$with_libmemcached],      [memcachec statistics])
+AC_PLUGIN([memcached],           [yes],                     [memcached statistics])
+AC_PLUGIN([memory],              [$plugin_memory],          [Memory usage])
+AC_PLUGIN([mic],                 [$with_mic],               [Intel Many Integrated Core stats])
+AC_PLUGIN([modbus],              [$with_libmodbus],         [Modbus plugin])
+AC_PLUGIN([mqtt],                [$with_libmosquitto],      [MQTT output plugin])
+AC_PLUGIN([multimeter],          [$plugin_multimeter],      [Read multimeter values])
+AC_PLUGIN([mysql],               [$with_libmysql],          [MySQL statistics])
+AC_PLUGIN([netapp],              [$with_libnetapp],         [NetApp plugin])
+AC_PLUGIN([netlink],             [$with_libmnl],            [Enhanced Linux network statistics])
+AC_PLUGIN([network],             [yes],                     [Network communication plugin])
+AC_PLUGIN([nfs],                 [$plugin_nfs],             [NFS statistics])
+AC_PLUGIN([nginx],               [$with_libcurl],           [nginx statistics])
+AC_PLUGIN([notify_desktop],      [$with_libnotify],         [Desktop notifications])
+AC_PLUGIN([notify_email],        [$with_libesmtp],          [Email notifier])
+AC_PLUGIN([notify_nagios],       [yes],                     [Nagios notification plugin])
+AC_PLUGIN([ntpd],                [yes],                     [NTPd statistics])
+AC_PLUGIN([numa],                [$plugin_numa],            [NUMA virtual memory statistics])
+AC_PLUGIN([nut],                 [$with_libupsclient],      [Network UPS tools statistics])
+AC_PLUGIN([olsrd],               [yes],                     [olsrd statistics])
+AC_PLUGIN([onewire],             [$with_libowcapi],         [OneWire sensor statistics])
+AC_PLUGIN([openldap],            [$with_libldap],           [OpenLDAP statistics])
+AC_PLUGIN([openvpn],             [yes],                     [OpenVPN client statistics])
+AC_PLUGIN([oracle],              [$with_oracle],            [Oracle plugin])
+AC_PLUGIN([perl],                [$plugin_perl],            [Embed a Perl interpreter])
+AC_PLUGIN([pf],                  [$have_net_pfvar_h],       [BSD packet filter (PF) statistics])
 # FIXME: Check for libevent, too.
-AC_PLUGIN([pinba],       [$have_protoc_c],     [Pinba statistics])
-AC_PLUGIN([ping],        [$with_liboping],     [Network latency statistics])
-AC_PLUGIN([postgresql],  [$with_libpq],        [PostgreSQL database statistics])
-AC_PLUGIN([powerdns],    [yes],                [PowerDNS statistics])
-AC_PLUGIN([processes],   [$plugin_processes],  [Process statistics])
-AC_PLUGIN([protocols],   [$plugin_protocols],  [Protocol (IP, TCP, ...) statistics])
-AC_PLUGIN([python],      [$with_python],       [Embed a Python interpreter])
-AC_PLUGIN([redis],       [$with_libhiredis],    [Redis plugin])
-AC_PLUGIN([routeros],    [$with_librouteros],  [RouterOS plugin])
-AC_PLUGIN([rrdcached],   [$librrd_rrdc_update], [RRDTool output plugin])
-AC_PLUGIN([rrdtool],     [$with_librrd],       [RRDTool output plugin])
-AC_PLUGIN([sensors],     [$with_libsensors],   [lm_sensors statistics])
-AC_PLUGIN([serial],      [$plugin_serial],     [serial port traffic])
-AC_PLUGIN([sigrok],      [$with_libsigrok],    [sigrok acquisition sources])
-AC_PLUGIN([smart],       [$with_libatasmart],  [SMART statistics])
-AC_PLUGIN([snmp],        [$with_libnetsnmp],   [SNMP querying plugin])
-AC_PLUGIN([statsd],      [yes],                [StatsD plugin])
-AC_PLUGIN([swap],        [$plugin_swap],       [Swap usage statistics])
-AC_PLUGIN([syslog],      [$have_syslog],       [Syslog logging plugin])
-AC_PLUGIN([table],       [yes],                [Parsing of tabular data])
-AC_PLUGIN([tail],        [yes],                [Parsing of logfiles])
-AC_PLUGIN([tail_csv],    [yes],                [Parsing of CSV files])
-AC_PLUGIN([tape],        [$plugin_tape],       [Tape drive statistics])
-AC_PLUGIN([target_notification], [yes],        [The notification target])
-AC_PLUGIN([target_replace], [yes],             [The replace target])
-AC_PLUGIN([target_scale],[yes],                [The scale target])
-AC_PLUGIN([target_set],  [yes],                [The set target])
-AC_PLUGIN([target_v5upgrade], [yes],           [The v5upgrade target])
-AC_PLUGIN([tcpconns],    [$plugin_tcpconns],   [TCP connection statistics])
-AC_PLUGIN([teamspeak2],  [yes],                [TeamSpeak2 server statistics])
-AC_PLUGIN([ted],         [$plugin_ted],        [Read The Energy Detective values])
-AC_PLUGIN([thermal],     [$plugin_thermal],    [Linux ACPI thermal zone statistics])
-AC_PLUGIN([threshold],   [yes],                [Threshold checking plugin])
-AC_PLUGIN([tokyotyrant], [$with_libtokyotyrant],  [TokyoTyrant database statistics])
-AC_PLUGIN([turbostat],   [$plugin_turbostat],  [Advanced statistic on Intel cpu states])
-AC_PLUGIN([unixsock],    [yes],                [Unixsock communication plugin])
-AC_PLUGIN([uptime],      [$plugin_uptime],     [Uptime statistics])
-AC_PLUGIN([users],       [$plugin_users],      [User statistics])
-AC_PLUGIN([uuid],        [yes],                [UUID as hostname plugin])
-AC_PLUGIN([varnish],     [$with_libvarnish],   [Varnish cache statistics])
-AC_PLUGIN([virt],        [$plugin_virt],       [Virtual machine statistics])
-AC_PLUGIN([vmem],        [$plugin_vmem],       [Virtual memory statistics])
-AC_PLUGIN([vserver],     [$plugin_vserver],    [Linux VServer statistics])
-AC_PLUGIN([wireless],    [$plugin_wireless],   [Wireless statistics])
-AC_PLUGIN([write_graphite], [yes],             [Graphite / Carbon output plugin])
-AC_PLUGIN([write_http],  [$with_libcurl],      [HTTP output plugin])
-AC_PLUGIN([write_kafka],  [$with_librdkafka],  [Kafka output plugin])
-AC_PLUGIN([write_log], [yes],                  [Log output plugin])
-AC_PLUGIN([write_mongodb], [$with_libmongoc],  [MongoDB output plugin])
-AC_PLUGIN([write_redis], [$with_libhiredis],    [Redis output plugin])
-AC_PLUGIN([write_riemann], [$have_protoc_c],   [Riemann output plugin])
-AC_PLUGIN([write_sensu], [yes],                [Sensu output plugin])
-AC_PLUGIN([write_tsdb],  [yes],                [TSDB output plugin])
-AC_PLUGIN([xmms],        [$with_libxmms],      [XMMS statistics])
-AC_PLUGIN([zfs_arc],     [$plugin_zfs_arc],    [ZFS ARC statistics])
-AC_PLUGIN([zone],        [$plugin_zone],       [Solaris container statistics])
-AC_PLUGIN([zookeeper],   [yes],               [Zookeeper statistics])
+AC_PLUGIN([pinba],               [$have_protoc_c],          [Pinba statistics])
+AC_PLUGIN([ping],                [$with_liboping],          [Network latency statistics])
+AC_PLUGIN([postgresql],          [$with_libpq],             [PostgreSQL database statistics])
+AC_PLUGIN([powerdns],            [yes],                     [PowerDNS statistics])
+AC_PLUGIN([processes],           [$plugin_processes],       [Process statistics])
+AC_PLUGIN([protocols],           [$plugin_protocols],       [Protocol (IP, TCP, ...) statistics])
+AC_PLUGIN([python],              [$with_python],            [Embed a Python interpreter])
+AC_PLUGIN([redis],               [$with_libhiredis],        [Redis plugin])
+AC_PLUGIN([routeros],            [$with_librouteros],       [RouterOS plugin])
+AC_PLUGIN([rrdcached],           [$librrd_rrdc_update],     [RRDTool output plugin])
+AC_PLUGIN([rrdtool],             [$with_librrd],            [RRDTool output plugin])
+AC_PLUGIN([sensors],             [$with_libsensors],        [lm_sensors statistics])
+AC_PLUGIN([serial],              [$plugin_serial],          [serial port traffic])
+AC_PLUGIN([sigrok],              [$with_libsigrok],         [sigrok acquisition sources])
+AC_PLUGIN([smart],               [$with_libatasmart],       [SMART statistics])
+AC_PLUGIN([snmp],                [$with_libnetsnmp],        [SNMP querying plugin])
+AC_PLUGIN([statsd],              [yes],                     [StatsD plugin])
+AC_PLUGIN([swap],                [$plugin_swap],            [Swap usage statistics])
+AC_PLUGIN([syslog],              [$have_syslog],            [Syslog logging plugin])
+AC_PLUGIN([table],               [yes],                     [Parsing of tabular data])
+AC_PLUGIN([tail],                [yes],                     [Parsing of logfiles])
+AC_PLUGIN([tail_csv],            [yes],                     [Parsing of CSV files])
+AC_PLUGIN([tape],                [$plugin_tape],            [Tape drive statistics])
+AC_PLUGIN([target_notification], [yes],                     [The notification target])
+AC_PLUGIN([target_replace],      [yes],                     [The replace target])
+AC_PLUGIN([target_scale],        [yes],                     [The scale target])
+AC_PLUGIN([target_set],          [yes],                     [The set target])
+AC_PLUGIN([target_v5upgrade],    [yes],                     [The v5upgrade target])
+AC_PLUGIN([tcpconns],            [$plugin_tcpconns],        [TCP connection statistics])
+AC_PLUGIN([teamspeak2],          [yes],                     [TeamSpeak2 server statistics])
+AC_PLUGIN([ted],                 [$plugin_ted],             [Read The Energy Detective values])
+AC_PLUGIN([thermal],             [$plugin_thermal],         [Linux ACPI thermal zone statistics])
+AC_PLUGIN([threshold],           [yes],                     [Threshold checking plugin])
+AC_PLUGIN([tokyotyrant],         [$with_libtokyotyrant],    [TokyoTyrant database statistics])
+AC_PLUGIN([turbostat],           [$plugin_turbostat],       [Advanced statistic on Intel cpu states])
+AC_PLUGIN([unixsock],            [yes],                     [Unixsock communication plugin])
+AC_PLUGIN([uptime],              [$plugin_uptime],          [Uptime statistics])
+AC_PLUGIN([users],               [$plugin_users],           [User statistics])
+AC_PLUGIN([uuid],                [yes],                     [UUID as hostname plugin])
+AC_PLUGIN([varnish],             [$with_libvarnish],        [Varnish cache statistics])
+AC_PLUGIN([virt],                [$plugin_virt],            [Virtual machine statistics])
+AC_PLUGIN([vmem],                [$plugin_vmem],            [Virtual memory statistics])
+AC_PLUGIN([vserver],             [$plugin_vserver],         [Linux VServer statistics])
+AC_PLUGIN([wireless],            [$plugin_wireless],        [Wireless statistics])
+AC_PLUGIN([write_graphite],      [yes],                     [Graphite / Carbon output plugin])
+AC_PLUGIN([write_http],          [$with_libcurl],           [HTTP output plugin])
+AC_PLUGIN([write_kafka],         [$with_librdkafka],        [Kafka output plugin])
+AC_PLUGIN([write_log],           [yes],                     [Log output plugin])
+AC_PLUGIN([write_mongodb],       [$with_libmongoc],         [MongoDB output plugin])
+AC_PLUGIN([write_redis],         [$with_libhiredis],        [Redis output plugin])
+AC_PLUGIN([write_riemann],       [$with_libriemann_client], [Riemann output plugin])
+AC_PLUGIN([write_sensu],         [yes],                     [Sensu output plugin])
+AC_PLUGIN([write_tsdb],          [yes],                     [TSDB output plugin])
+AC_PLUGIN([xencpu],              [$plugin_xencpu],          [Xen Host CPU usage])
+AC_PLUGIN([xmms],                [$with_libxmms],           [XMMS statistics])
+AC_PLUGIN([zfs_arc],             [$plugin_zfs_arc],         [ZFS ARC statistics])
+AC_PLUGIN([zone],                [$plugin_zone],            [Solaris container statistics])
+AC_PLUGIN([zookeeper],           [yes],                     [Zookeeper statistics])
 
 dnl Default configuration file
 # Load either syslog or logfile
@@ -6007,6 +6205,7 @@ Configuration:
     libpq . . . . . . . . $with_libpq
     libpthread  . . . . . $with_libpthread
     librabbitmq . . . . . $with_librabbitmq
+    libriemann-client . . $with_libriemann_client
     librdkafka  . . . . . $with_librdkafka
     librouteros . . . . . $with_librouteros
     librrd  . . . . . . . $with_librrd
@@ -6018,6 +6217,7 @@ Configuration:
     libupsclient  . . . . $with_libupsclient
     libvarnish  . . . . . $with_libvarnish
     libvirt . . . . . . . $with_libvirt
+    libxenctrl  . . . . . $with_libxenctrl
     libxml2 . . . . . . . $with_libxml2
     libxmms . . . . . . . $with_libxmms
     libyajl . . . . . . . $with_libyajl
@@ -6102,6 +6302,7 @@ Configuration:
     nginx . . . . . . . . $enable_nginx
     notify_desktop  . . . $enable_notify_desktop
     notify_email  . . . . $enable_notify_email
+    notify_nagios . . . . $enable_notify_nagios
     ntpd  . . . . . . . . $enable_ntpd
     numa  . . . . . . . . $enable_numa
     nut . . . . . . . . . $enable_nut
@@ -6165,6 +6366,7 @@ Configuration:
     write_riemann . . . . $enable_write_riemann
     write_sensu . . . . . $enable_write_sensu
     write_tsdb  . . . . . $enable_write_tsdb
+    xencpu  . . . . . . . $enable_xencpu
     xmms  . . . . . . . . $enable_xmms
     zfs_arc . . . . . . . $enable_zfs_arc
     zone  . . . . . . . . $enable_zone
index cc7e141..31c530f 100644 (file)
@@ -487,6 +487,8 @@ sub get_files_by_ident
   my $ident = shift;
   my $all_files;
   my @ret = ();
+  my $temp;
+  my $hosts;
 
   my $cache_key = ident_to_string ($ident);
   if (defined ($Cache->{'get_files_by_ident'}{$cache_key}))
@@ -496,7 +498,20 @@ sub get_files_by_ident
     return ($ret)
   }
 
-  $all_files = _get_all_files ();
+  if ($ident->{'hostname'})
+  {
+    $all_files = [];
+    $hosts = $ident->{'hostname'};
+    foreach (@$hosts)
+    {
+      $temp = get_files_for_host ($_);
+      push (@$all_files, @$temp);
+    }
+  }
+  else
+  {
+    $all_files = _get_all_files ();
+  }
 
   @ret = grep { _filter_ident ($ident, $_) == 0 } (@$all_files);
 
index 2252181..b3fe2bf 100644 (file)
 %{?el7:%global _has_lvm2app_h 1}
 %{?el7:%global _has_libudev 1}
 %{?el7:%global _has_recent_librrd 1}
-%{?el7:%global _has_varnish4 1}
-%{?el7:%global _has_broken_libmemcached 1}
 %{?el7:%global _has_iproute 1}
 %{?el7:%global _has_atasmart 1}
 %{?el7:%global _has_hiredis 1}
 %{?el7:%global _has_asm_msr_index 1}
 %{?el7:%global _has_libmosquitto 1}
+%{?el7:%global _has_libmodbus 1}
+%{?el7:%global _has_xmms 1}
 
 # plugins enabled by default
 %define with_aggregation 0%{!?_without_aggregation:1}
 %define with_madwifi 0%{!?_without_madwifi:1}
 %define with_mbmon 0%{!?_without_mbmon:1}
 %define with_md 0%{!?_without_md:1}
-%define with_memcachec 0%{!?_without_memcachec:0%{!?_has_broken_libmemcached:1}}
+%define with_memcachec 0%{!?_without_memcachec:1}
 %define with_memcached 0%{!?_without_memcached:1}
 %define with_memory 0%{!?_without_memory:1}
 %define with_multimeter 0%{!?_without_multimeter:1}
 %define with_nginx 0%{!?_without_nginx:1}
 %define with_notify_desktop 0%{!?_without_notify_desktop:1}
 %define with_notify_email 0%{!?_without_notify_email:1}
+%define with_notify_nagios 0%{!?_without_notify_nagios:1}
 %define with_ntpd 0%{!?_without_ntpd:1}
 %define with_numa 0%{!?_without_numa:1}
 %define with_nut 0%{!?_without_nut:1}
 %define with_uptime 0%{!?_without_uptime:1}
 %define with_users 0%{!?_without_users:1}
 %define with_uuid 0%{!?_without_uuid:1}
-%define with_varnish 0%{!?_without_varnish:0%{!?_has_varnish4:1}}
+%define with_varnish 0%{!?_without_varnish:1}
 %define with_vmem 0%{!?_without_vmem:1}
 %define with_vserver 0%{!?_without_vserver:1}
 %define with_wireless 0%{!?_without_wireless:1}
 %define with_write_http 0%{!?_without_write_http:1}
 %define with_write_log 0%{!?_without_write_log:1}
 %define with_write_redis 0%{!?_without_write_redis:0%{?_has_hiredis}}
-%define with_write_riemann 0%{!?_without_write_riemann:1}
+%define with_write_riemann 0%{!?_without_write_riemann:0%{?_has_recent_riemann_c_client}}
 %define with_write_sensu 0%{!?_without_write_sensu:1}
 %define with_write_tsdb 0%{!?_without_write_tsdb:1}
+%define with_xmms 0%{!?_without_xmms:0%{?_has_xmms}}
 %define with_zfs_arc 0%{!?_without_zfs_arc:1}
 %define with_zookeeper 0%{!?_without_zookeeper:1}
 
 %define with_write_kafka 0%{!?_without_write_kafka:0}
 # plugin write_mongodb disabled, requires libmongoc
 %define with_write_mongodb 0%{!?_without_write_mongodb:0}
-# plugin xmms disabled, requires xmms
-%define with_xmms 0%{!?_without_xmms:0}
+# plugin xencpu disabled, requires xen-devel from non-default repo
+%define with_xencpu 0%{!?_without_xencpu:0}
 # plugin zone disabled, requires Solaris
 %define with_zone 0%{!?_without_zone:0}
 
 Summary:       statistics collection and monitoring daemon
 Name:          collectd
-Version:       5.5.0
+Version:       5.5.1
 Release:       1%{?dist}
 URL:           http://collectd.org
 Source:                http://collectd.org/files/%{name}-%{version}.tar.bz2
@@ -789,6 +791,26 @@ BuildRequires:     protobuf-c-devel
 The riemann plugin submits values to Riemann, an event stream processor.
 %endif
 
+%if %{with_xencpu}
+%package xencpu
+Summary:       xencpu plugin for collectd
+Group:         System Environment/Daemons
+Requires:      %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: xen-devel
+%description xencpu
+The xencpu plugin collects CPU statistics from Xen.
+%endif
+
+%if %{with_xmms}
+%package xmms
+Summary:       XMMS plugin for collectd
+Group:         System Environment/Daemons
+Requires:      %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: xmms-devel
+%description xmms
+The xmms plugin collects information from the XMMS music player.
+%endif
+
 %package collection3
 Summary:       Web-based viewer for collectd
 Group:         System Environment/Daemons
@@ -1233,6 +1255,12 @@ Collectd utilities
 %define _with_notify_email --disable-notify_email
 %endif
 
+%if %{with_notify_nagios}
+%define _with_notify_nagios --enable-notify_nagios
+%else
+%define _with_notify_nagios --disable-notify_nagios
+%endif
+
 %if %{with_ntpd}
 %define _with_ntpd --enable-ntpd
 %else
@@ -1579,6 +1607,12 @@ Collectd utilities
 %define _with_write_tsdb --disable-write_tsdb
 %endif
 
+%if %{with_xencpu}
+%define _with_xencpu --enable-xencpu
+%else
+%define _with_xencpu --disable-xencpu
+%endif
+
 %if %{with_xmms}
 %define _with_xmms --enable-xmms
 %else
@@ -1697,6 +1731,7 @@ Collectd utilities
        %{?_with_write_kafka} \
        %{?_with_write_mongodb} \
        %{?_with_write_redis} \
+       %{?_with_xencpu} \
        %{?_with_xmms} \
        %{?_with_zfs_arc} \
        %{?_with_zone} \
@@ -1711,6 +1746,7 @@ Collectd utilities
        %{?_with_memory} \
        %{?_with_network} \
        %{?_with_nfs} \
+       %{?_with_notify_nagios} \
        %{?_with_ntpd} \
        %{?_with_numa} \
        %{?_with_olsrd} \
@@ -1977,6 +2013,9 @@ fi
 %if %{with_nfs}
 %{_libdir}/%{name}/nfs.so
 %endif
+%if %{with_notify_nagios}
+%{_libdir}/%{name}/notify_nagios.so
+%endif
 %if %{with_ntpd}
 %{_libdir}/%{name}/ntpd.so
 %endif
@@ -2083,9 +2122,9 @@ fi
 %{_includedir}/collectd/network_buffer.h
 %{_includedir}/collectd/lcc_features.h
 %{_libdir}/pkgconfig/libcollectdclient.pc
+%{_libdir}/libcollectdclient.so
 
 %files -n libcollectdclient
-%{_libdir}/libcollectdclient.so
 %{_libdir}/libcollectdclient.so.*
 
 %files -n collectd-utils
@@ -2356,6 +2395,16 @@ fi
 %{_libdir}/%{name}/write_riemann.so
 %endif
 
+%if %{with_xencpu}
+%files xencpu
+%{_libdir}/%{name}/xencpu.so
+%endif
+
+%if %{with_xmms}
+%files xmms
+%{_libdir}/%{name}/xmms.so
+%endif
+
 %files collection3
 %{_localstatedir}/www/collection3
 %{_sysconfdir}/httpd/conf.d/collection3.conf
@@ -2370,8 +2419,8 @@ fi
 %changelog
 #* TODO: next feature release changelog
 #- New upstream version
-#- New plugins enabled by default: mqtt
-#- New plugins disabled by default: zone
+#- New plugins enabled by default: mqtt, notify_nagios
+#- New plugins disabled by default: zone, xencpu
 #
 * Wed May 27 2015 Marc Fournier <marc.fournier@camptocamp.com> 5.5.0-1
 - New upstream version
@@ -2385,11 +2434,12 @@ fi
 - Install collectdctl, collectd-tg and collectd-nagios in collectd-utils.rpm
 - Add build-dependency on libcap-devel
 
-* Mon Aug 19 2013 Marc Fournier <marc.fournier@camptocamp.com> 5.4.0-1
+* Mon Aug 19 2013 Marc Fournier <marc.fournier@camptocamp.com> 5.4.2-1
 - New upstream version
 - Build netlink plugin by default
 - Enable cgroups, lvm and statsd plugins
 - Enable (but don't build by default) mic, aquaero and sigrok plugins
+- Enable modbus, memcachec and xmms plugins on RHEL7
 
 * Tue Aug 06 2013 Marc Fournier <marc.fournier@camptocamp.com> 5.3.1-1
 - New upstream version
index 0e758e4..d0f1bde 100644 (file)
@@ -1,7 +1,8 @@
 [Unit]
-Description=Collectd
-After=local-fs.target network.target
-Requires=local-fs.target network.target
+Description=Collectd statistics daemon
+Documentation=man:collectd(1) man:collectd.conf(5)
+After=local-fs.target network-online.target
+Requires=local-fs.target network-online.target
 
 [Service]
 ExecStart=/usr/sbin/collectd
@@ -10,12 +11,22 @@ EnvironmentFile=-/etc/default/collectd
 ProtectSystem=full
 ProtectHome=true
 
-# drop all capabilities:
-CapabilityBoundingSet=
-# use this instead if you use the dns or ping plugin
-#CapabilityBoundingSet=CAP_NET_RAW
-# turn this on if you use the iptables next to the dns or ping plugin
+# A few plugins won't work without some privileges, which you'll have to
+# specify using the CapabilityBoundingSet directive below.
+#
+# Here's a (incomplete) list of the plugins known capability requirements:
+#   ceph            CAP_DAC_OVERRIDE
+#   dns             CAP_NET_RAW
+#   exec            CAP_SETUID CAP_SETGID
+#   iptables        CAP_NET_ADMIN
+#   ping            CAP_NET_RAW
+#   turbostat       CAP_SYS_RAWIO
+#
+# Example, if you use the iptables plugin alongside the dns or ping plugin:
 #CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
+#
+# By default, drop all capabilities:
+CapabilityBoundingSet=
 
 NoNewPrivileges=true
 
@@ -23,7 +34,7 @@ NoNewPrivileges=true
 # socket once the daemon is ready. See systemd.service(5) for more details.
 Type=notify
 
-# Restart the collectd daemon after a 10 seconds delay, in case it crashes.
+# Restart the collectd daemon when it fails.
 Restart=on-failure
 
 [Install]
index b8fc965..e6affa5 100755 (executable)
@@ -64,8 +64,8 @@ while (<>)
 
        $line =~ s#\{\{Plugin\|([^}]+)\}\}#$1 plugin#g;
        $line =~ s@\{\{Issue\|([^}]+)\}\}@#$1@g;
-       $line =~ s#\[\[[^|]+\|([^\]]+)\]\]#$1#g;
-       $line =~ s#\[\[([^|]+)\]\]#$1#g;
+       $line =~ s#\[\[[^|\]]+\|([^\]]+)\]\]#$1#g;
+       $line =~ s#\[\[([^|\]]+)\]\]#$1#g;
 
        $line =~ s#'''(.*?)'''#*$1*#g;
        $line =~ s#''(.*?)''#$1#g;
index d0bf546..23c3a2f 100644 (file)
@@ -28,7 +28,7 @@ liblatency_la_SOURCES = utils_latency.c utils_latency.h
 check_PROGRAMS += test_utils_latency
 TESTS += test_utils_latency
 test_utils_latency_SOURCES = utils_latency_test.c testing.h
-test_utils_latency_LDADD = liblatency.la daemon/libcommon.la daemon/libplugin_mock.la -lm
+test_utils_latency_LDADD = liblatency.la daemon/libplugin_mock.la -lm
 
 noinst_LTLIBRARIES += liblookup.la
 liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h
@@ -36,7 +36,7 @@ liblookup_la_LIBADD = daemon/libavltree.la
 check_PROGRAMS += test_utils_vl_lookup
 TESTS += test_utils_vl_lookup
 test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
-test_utils_vl_lookup_LDADD = liblookup.la daemon/libcommon.la daemon/libplugin_mock.la
+test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
 if BUILD_WITH_LIBKSTAT
 test_utils_vl_lookup_LDADD += -lkstat
 endif
@@ -46,7 +46,7 @@ libmount_la_SOURCES = utils_mount.c utils_mount.h
 check_PROGRAMS += test_utils_mount
 TESTS += test_utils_mount
 test_utils_mount_SOURCES = utils_mount_test.c testing.h
-test_utils_mount_LDADD = libmount.la daemon/libcommon.la daemon/libplugin_mock.la
+test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
 if BUILD_WITH_LIBKSTAT
 test_utils_mount_LDADD += -lkstat
 endif
@@ -97,7 +97,7 @@ if BUILD_AIX
 collectd_tg_LDADD += -lm
 endif
 if BUILD_WITH_LIBPTHREAD
-collectd_tg_LDADD += -lpthread
+collectd_tg_LDADD += $(PTHREAD_LIBS)
 endif
 collectd_tg_LDADD += libcollectdclient/libcollectdclient.la
 collectd_tg_DEPENDENCIES = libcollectdclient/libcollectdclient.la
@@ -120,7 +120,7 @@ if BUILD_PLUGIN_AMQP
 pkglib_LTLIBRARIES += amqp.la
 amqp_la_SOURCES = amqp.c \
                  utils_cmd_putval.c utils_cmd_putval.h \
-                 utils_parse_option.c utils_parse_option.h \
+                 utils_parse_option.c utils_parse_option.h \
                  utils_format_graphite.c utils_format_graphite.h \
                  utils_format_json.c utils_format_json.h
 amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
@@ -211,8 +211,7 @@ endif
 
 if BUILD_PLUGIN_CGROUPS
 pkglib_LTLIBRARIES += cgroups.la
-cgroups_la_SOURCES = cgroups.c \
-                    utils_ignorelist.c utils_ignorelist.h
+cgroups_la_SOURCES = cgroups.c
 cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 cgroups_la_LIBADD = libmount.la
 endif
@@ -311,16 +310,14 @@ endif
 
 if BUILD_PLUGIN_DF
 pkglib_LTLIBRARIES += df.la
-df_la_SOURCES = df.c \
-               utils_ignorelist.c utils_ignorelist.h
+df_la_SOURCES = df.c
 df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 df_la_LIBADD = libmount.la
 endif
 
 if BUILD_PLUGIN_DISK
 pkglib_LTLIBRARIES += disk.la
-disk_la_SOURCES = disk.c \
-                 utils_ignorelist.c utils_ignorelist.h
+disk_la_SOURCES = disk.c
 disk_la_CFLAGS = $(AM_CFLAGS)
 disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 disk_la_LIBADD =
@@ -352,21 +349,20 @@ if BUILD_PLUGIN_DNS
 pkglib_LTLIBRARIES += dns.la
 dns_la_SOURCES = dns.c utils_dns.c utils_dns.h
 dns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-dns_la_LIBADD = -lpcap -lpthread
+dns_la_LIBADD = $(PTHREAD_LIBS) -lpcap
 endif
 
 if BUILD_PLUGIN_DRBD
 pkglib_LTLIBRARIES += drbd.la
 drbd_la_SOURCES = drbd.c
 drbd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-drbd_la_LIBADD = -lpthread
 endif
 
 if BUILD_PLUGIN_EMAIL
 pkglib_LTLIBRARIES += email.la
 email_la_SOURCES = email.c
 email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-email_la_LIBADD = -lpthread
+email_la_LIBADD = $(PTHREAD_LIBS)
 endif
 
 if BUILD_PLUGIN_ENTROPY
@@ -382,7 +378,7 @@ exec_la_SOURCES = exec.c \
                  utils_cmd_putval.c utils_cmd_putval.h \
                  utils_parse_option.h utils_parse_option.c
 exec_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-exec_la_LIBADD = -lpthread
+exec_la_LIBADD = $(PTHREAD_LIBS)
 endif
 
 if BUILD_PLUGIN_ETHSTAT
@@ -423,8 +419,7 @@ endif
 
 if BUILD_PLUGIN_INTERFACE
 pkglib_LTLIBRARIES += interface.la
-interface_la_SOURCES = interface.c \
-                      utils_ignorelist.c utils_ignorelist.h
+interface_la_SOURCES = interface.c
 interface_la_CFLAGS = $(AM_CFLAGS)
 interface_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 interface_la_LIBADD =
@@ -461,8 +456,7 @@ endif
 
 if BUILD_PLUGIN_IPMI
 pkglib_LTLIBRARIES += ipmi.la
-ipmi_la_SOURCES = ipmi.c \
-                 utils_ignorelist.c utils_ignorelist.h
+ipmi_la_SOURCES = ipmi.c
 ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS)
 ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS)
@@ -481,8 +475,7 @@ endif
 
 if BUILD_PLUGIN_IRQ
 pkglib_LTLIBRARIES += irq.la
-irq_la_SOURCES = irq.c \
-                utils_ignorelist.c utils_ignorelist.h
+irq_la_SOURCES = irq.c
 irq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -492,7 +485,7 @@ java_la_SOURCES = java.c
 java_la_CPPFLAGS = $(AM_CPPFLAGS) $(JAVA_CPPFLAGS)
 java_la_CFLAGS = $(AM_CFLAGS) $(JAVA_CFLAGS)
 java_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(JAVA_LDFLAGS)
-java_la_LIBADD = $(JAVA_LIBS)
+java_la_LIBADD = $(PTHREAD_LIBS) $(JAVA_LIBS)
 endif
 
 if BUILD_PLUGIN_LOAD
@@ -541,8 +534,7 @@ endif
 
 if BUILD_PLUGIN_MADWIFI
 pkglib_LTLIBRARIES += madwifi.la
-madwifi_la_SOURCES = madwifi.c madwifi.h \
-                    utils_ignorelist.c utils_ignorelist.h
+madwifi_la_SOURCES = madwifi.c madwifi.h
 madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -588,8 +580,7 @@ endif
 
 if BUILD_PLUGIN_MD
 pkglib_LTLIBRARIES += md.la
-md_la_SOURCES = md.c \
-               utils_ignorelist.c utils_ignorelist.h
+md_la_SOURCES = md.c
 md_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -634,8 +625,7 @@ endif
 
 if BUILD_PLUGIN_MIC
 pkglib_LTLIBRARIES += mic.la
-mic_la_SOURCES = mic.c \
-                utils_ignorelist.c utils_ignorelist.h
+mic_la_SOURCES = mic.c
 mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LIBPATH)
 mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS)
 mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD)
@@ -652,8 +642,8 @@ endif
 if BUILD_PLUGIN_MQTT
 pkglib_LTLIBRARIES += mqtt.la
 mqtt_la_SOURCES = mqtt.c
-mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 mqtt_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
+mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
 mqtt_la_LIBADD = $(BUILD_WITH_LIBMOSQUITTO_LIBS)
 endif
 
@@ -677,8 +667,7 @@ endif
 
 if BUILD_PLUGIN_NETAPP
 pkglib_LTLIBRARIES += netapp.la
-netapp_la_SOURCES = netapp.c \
-                   utils_ignorelist.c utils_ignorelist.h
+netapp_la_SOURCES = netapp.c
 netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS)
 netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS)
 netapp_la_LIBADD = $(LIBNETAPP_LIBS)
@@ -698,7 +687,7 @@ network_la_SOURCES = network.c network.h \
                     utils_fbhash.c utils_fbhash.h
 network_la_CPPFLAGS = $(AM_CPPFLAGS)
 network_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-network_la_LIBADD = -lpthread
+network_la_LIBADD = $(PTHREAD_LIBS)
 if BUILD_WITH_LIBSOCKET
 network_la_LIBADD += -lsocket
 endif
@@ -745,7 +734,13 @@ if BUILD_PLUGIN_NOTIFY_EMAIL
 pkglib_LTLIBRARIES += notify_email.la
 notify_email_la_SOURCES = notify_email.c
 notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-notify_email_la_LIBADD = -lesmtp -lssl -lcrypto -lpthread
+notify_email_la_LIBADD = $(PTHREAD_LIBS) -lesmtp -lssl -lcrypto
+endif
+
+if BUILD_PLUGIN_NOTIFY_NAGIOS
+pkglib_LTLIBRARIES += notify_nagios.la
+notify_nagios_la_SOURCES = notify_nagios.c
+notify_nagios_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
 if BUILD_PLUGIN_NTPD
@@ -769,7 +764,7 @@ pkglib_LTLIBRARIES += nut.la
 nut_la_SOURCES = nut.c
 nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS)
 nut_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-nut_la_LIBADD = -lpthread $(BUILD_WITH_LIBUPSCLIENT_LIBS)
+nut_la_LIBADD = $(PTHREAD_LIBS) $(BUILD_WITH_LIBUPSCLIENT_LIBS)
 endif
 
 if BUILD_PLUGIN_OLSRD
@@ -784,12 +779,11 @@ endif
 
 if BUILD_PLUGIN_ONEWIRE
 pkglib_LTLIBRARIES += onewire.la
-onewire_la_SOURCES = onewire.c \
-                    utils_ignorelist.c utils_ignorelist.h
+onewire_la_SOURCES = onewire.c
 onewire_la_CFLAGS = $(AM_CFLAGS)
 onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
 onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS)
-onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOWCAPI_LDFLAGS)
 endif
 
 if BUILD_PLUGIN_OPENLDAP
@@ -898,8 +892,7 @@ endif
 
 if BUILD_PLUGIN_PROTOCOLS
 pkglib_LTLIBRARIES += protocols.la
-protocols_la_SOURCES = protocols.c \
-                      utils_ignorelist.c utils_ignorelist.h
+protocols_la_SOURCES = protocols.c
 protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -922,23 +915,22 @@ endif
 if BUILD_PLUGIN_RRDCACHED
 pkglib_LTLIBRARIES += rrdcached.la
 rrdcached_la_SOURCES = rrdcached.c utils_rrdcreate.c utils_rrdcreate.h
-rrdcached_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+rrdcached_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS)
 rrdcached_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS)
-rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LDFLAGS)
+rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS)
 endif
 
 if BUILD_PLUGIN_RRDTOOL
 pkglib_LTLIBRARIES += rrdtool.la
 rrdtool_la_SOURCES = rrdtool.c utils_rrdcreate.c utils_rrdcreate.h
-rrdtool_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+rrdtool_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS)
 rrdtool_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS)
-rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LDFLAGS)
+rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS)
 endif
 
 if BUILD_PLUGIN_SENSORS
 pkglib_LTLIBRARIES += sensors.la
-sensors_la_SOURCES = sensors.c \
-                    utils_ignorelist.c utils_ignorelist.h
+sensors_la_SOURCES = sensors.c
 sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS)
 sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS)
 sensors_la_LIBADD = -lsensors
@@ -961,8 +953,7 @@ endif
 if BUILD_PLUGIN_SMART
 if BUILD_WITH_LIBUDEV
 pkglib_LTLIBRARIES += smart.la
-smart_la_SOURCES = smart.c \
-                  utils_ignorelist.c utils_ignorelist.h
+smart_la_SOURCES = smart.c
 smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS)
 smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS)
 smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) -ludev
@@ -980,7 +971,7 @@ snmp_la_CFLAGS += $(BUILD_WITH_LIBSNMP_CFLAGS)
 snmp_la_LIBADD += $(BUILD_WITH_LIBSNMP_LIBS)
 endif
 if BUILD_WITH_LIBPTHREAD
-snmp_la_LIBADD += -lpthread
+snmp_la_LIBADD += $(PTHREAD_LIBS)
 endif
 endif
 
@@ -988,7 +979,7 @@ if BUILD_PLUGIN_STATSD
 pkglib_LTLIBRARIES += statsd.la
 statsd_la_SOURCES = statsd.c
 statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-statsd_la_LIBADD = liblatency.la -lpthread -lm
+statsd_la_LIBADD = $(PTHREAD_LIBS) liblatency.la -lm
 endif
 
 if BUILD_PLUGIN_SWAP
@@ -1101,8 +1092,7 @@ endif
 
 if BUILD_PLUGIN_THERMAL
 pkglib_LTLIBRARIES += thermal.la
-thermal_la_SOURCES = thermal.c \
-                    utils_ignorelist.c utils_ignorelist.h
+thermal_la_SOURCES = thermal.c
 thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
@@ -1140,7 +1130,7 @@ unixsock_la_SOURCES = unixsock.c \
                      utils_cmd_putnotif.h utils_cmd_putnotif.c \
                      utils_parse_option.h utils_parse_option.c
 unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-unixsock_la_LIBADD = -lpthread
+unixsock_la_LIBADD = $(PTHREAD_LIBS)
 endif
 
 if BUILD_PLUGIN_UPTIME
@@ -1187,8 +1177,7 @@ endif
 
 if BUILD_PLUGIN_VIRT
 pkglib_LTLIBRARIES += virt.la
-virt_la_SOURCES = virt.c \
-                 utils_ignorelist.c utils_ignorelist.h
+virt_la_SOURCES = virt.c
 virt_la_CFLAGS = $(AM_CFLAGS) \
                $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
 virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
@@ -1271,10 +1260,9 @@ endif
 
 if BUILD_PLUGIN_WRITE_RIEMANN
 pkglib_LTLIBRARIES += write_riemann.la
-write_riemann_la_SOURCES = write_riemann.c write_riemann_threshold.c
-nodist_write_riemann_la_SOURCES = riemann.pb-c.c riemann.pb-c.h
-write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_riemann_la_LIBADD = -lprotobuf-c
+write_riemann_la_SOURCES = write_riemann.c write_riemann_threshold.c write_riemann_threshold.h
+write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBRIEMANN_CLIENT_LIBS)
+write_riemann_la_CFLAGS = $(AM_CFLAGS) $(LIBRIEMANN_CLIENT_CFLAGS)
 endif
 
 if BUILD_PLUGIN_WRITE_SENSU
@@ -1289,6 +1277,13 @@ write_tsdb_la_SOURCES = write_tsdb.c
 write_tsdb_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
+if BUILD_PLUGIN_XENCPU
+pkglib_LTLIBRARIES += xencpu.la
+xencpu_la_SOURCES = xencpu.c
+xencpu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+xencpu_la_LIBADD = -lxenctrl
+endif
+
 if BUILD_PLUGIN_XMMS
 pkglib_LTLIBRARIES += xmms.la
 xmms_la_SOURCES = xmms.c
@@ -1382,25 +1377,19 @@ EXTRA_DIST +=   collectd.conf.pod \
                echo "$@ has some POD errors!"; false; \
        fi
 
+AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@)
+am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@)
+am__v_PROTOC_C_0 = @echo "  PROTOC-C    " $@;
+am__v_PROTOC_C_1 =
+
 # Protocol buffer for the "pinba" plugin.
 EXTRA_DIST += pinba.proto
-if HAVE_PROTOC_C
+if BUILD_PLUGIN_PINBA
 CLEANFILES += pinba.pb-c.c pinba.pb-c.h
 BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h
 
 pinba.pb-c.c pinba.pb-c.h: pinba.proto
-       protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto
-endif
-
-# Protocol buffer for the "write_riemann" plugin.
-EXTRA_DIST += riemann.proto
-if HAVE_PROTOC_C
-CLEANFILES += riemann.pb-c.c riemann.pb-c.h
-
-BUILT_SOURCES += riemann.pb-c.c riemann.pb-c.h
-
-riemann.pb-c.c riemann.pb-c.h: riemann.proto
-       protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto
+       $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto
 endif
 
 install-exec-hook:
@@ -1421,4 +1410,11 @@ uninstall-hook:
        rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
        rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
 
-
+if BUILD_PLUGIN_CEPH
+test_plugin_ceph_SOURCES = ceph_test.c
+test_plugin_ceph_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+test_plugin_ceph_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+test_plugin_ceph_LDADD = daemon/libcommon.la daemon/libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS)
+check_PROGRAMS += test_plugin_ceph
+TESTS += test_plugin_ceph
+endif
index 8175c66..3d5f396 100644 (file)
@@ -240,13 +240,12 @@ static agg_instance_t *agg_instance_create (data_set_t const *ds, /* {{{ */
 
   DEBUG ("aggregation plugin: Creating new instance.");
 
-  inst = malloc (sizeof (*inst));
+  inst = calloc (1, sizeof (*inst));
   if (inst == NULL)
   {
-    ERROR ("aggregation plugin: malloc() failed.");
+    ERROR ("aggregation plugin: calloc() failed.");
     return (NULL);
   }
-  memset (inst, 0, sizeof (*inst));
   pthread_mutex_init (&inst->lock, /* attr = */ NULL);
 
   inst->ds_type = ds->ds[0].type;
@@ -259,13 +258,13 @@ static agg_instance_t *agg_instance_create (data_set_t const *ds, /* {{{ */
 #define INIT_STATE(field) do { \
   inst->state_ ## field = NULL; \
   if (agg->calc_ ## field) { \
-    inst->state_ ## field = malloc (sizeof (*inst->state_ ## field)); \
+    inst->state_ ## field = calloc (1, sizeof (*inst->state_ ## field)); \
     if (inst->state_ ## field == NULL) { \
       agg_instance_destroy (inst); \
-      ERROR ("aggregation plugin: malloc() failed."); \
+      free (inst); \
+      ERROR ("aggregation plugin: calloc() failed."); \
       return (NULL); \
     } \
-    memset (inst->state_ ## field, 0, sizeof (*inst->state_ ## field)); \
   } \
 } while (0)
 
@@ -527,13 +526,12 @@ static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */
   int status;
   int i;
 
-  agg = malloc (sizeof (*agg));
+  agg = calloc (1, sizeof (*agg));
   if (agg == NULL)
   {
-    ERROR ("aggregation plugin: malloc failed.");
+    ERROR ("aggregation plugin: calloc failed.");
     return (-1);
   }
-  memset (agg, 0, sizeof (*agg));
 
   sstrncpy (agg->ident.host, "/.*/", sizeof (agg->ident.host));
   sstrncpy (agg->ident.plugin, "/.*/", sizeof (agg->ident.plugin));
index aba4f01..fc69e93 100644 (file)
@@ -199,11 +199,11 @@ static char *camqp_strerror (camqp_config_t *conf, /* {{{ */
     switch (r.reply_type)
     {
         case AMQP_RESPONSE_NORMAL:
-            sstrncpy (buffer, "Success", sizeof (buffer));
+            sstrncpy (buffer, "Success", buffer_size);
             break;
 
         case AMQP_RESPONSE_NONE:
-            sstrncpy (buffer, "Missing RPC reply type", sizeof (buffer));
+            sstrncpy (buffer, "Missing RPC reply type", buffer_size);
             break;
 
         case AMQP_RESPONSE_LIBRARY_EXCEPTION:
@@ -215,7 +215,7 @@ static char *camqp_strerror (camqp_config_t *conf, /* {{{ */
                 return (sstrerror (r.library_error, buffer, buffer_size));
 #endif
             else
-                sstrncpy (buffer, "End of stream", sizeof (buffer));
+                sstrncpy (buffer, "End of stream", buffer_size);
             break;
 
         case AMQP_RESPONSE_SERVER_EXCEPTION:
@@ -736,7 +736,7 @@ static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */
     if (tmp == NULL)
     {
         ERROR ("amqp plugin: realloc failed.");
-        camqp_config_free (conf);
+        sfree (subscriber_threads);
         return (ENOMEM);
     }
     subscriber_threads = tmp;
@@ -750,7 +750,6 @@ static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */
         char errbuf[1024];
         ERROR ("amqp plugin: pthread_create failed: %s",
                 sstrerror (status, errbuf, sizeof (errbuf)));
-        camqp_config_free (conf);
         return (status);
     }
 
@@ -925,15 +924,14 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
     int status;
     int i;
 
-    conf = malloc (sizeof (*conf));
+    conf = calloc (1, sizeof (*conf));
     if (conf == NULL)
     {
-        ERROR ("amqp plugin: malloc failed.");
+        ERROR ("amqp plugin: calloc failed.");
         return (ENOMEM);
     }
 
     /* Initialize "conf" {{{ */
-    memset (conf, 0, sizeof (*conf));
     conf->publish = publish;
     conf->name = NULL;
     conf->format = CAMQP_FORMAT_COMMAND;
index 41b807a..2e91a1b 100644 (file)
@@ -98,14 +98,14 @@ static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb,
                return (0);
        }
 
-       if (len <= 0)
+       if (len == 0)
                return (len);
 
        if ((st->apache_buffer_fill + len) >= st->apache_buffer_size)
        {
                char *temp;
 
-               temp = (char *) realloc (st->apache_buffer,
+               temp = realloc (st->apache_buffer,
                                st->apache_buffer_fill + len + 1);
                if (temp == NULL)
                {
@@ -137,7 +137,7 @@ static size_t apache_header_callback (void *buf, size_t size, size_t nmemb,
                return (0);
        }
 
-       if (len <= 0)
+       if (len == 0)
                return (len);
 
        /* look for the Server header */
@@ -175,13 +175,12 @@ static int config_add (oconfig_item_t *ci)
        int i;
        int status;
 
-       st = malloc (sizeof (*st));
+       st = calloc (1, sizeof (*st));
        if (st == NULL)
        {
-               ERROR ("apache plugin: malloc failed.");
+               ERROR ("apache plugin: calloc failed.");
                return (-1);
        }
-       memset (st, 0, sizeof (*st));
 
        st->timeout = -1;
 
@@ -519,12 +518,9 @@ static void submit_scoreboard (char *buf, apache_t *st)
 
 static int apache_read_host (user_data_t *user_data) /* {{{ */
 {
-       int i;
-
        char *ptr;
        char *saveptr;
-       char *lines[16];
-       int   lines_num = 0;
+       char *line;
 
        char *fields[4];
        int   fields_num;
@@ -533,13 +529,16 @@ static int apache_read_host (user_data_t *user_data) /* {{{ */
 
        st = user_data->data;
 
+       int status;
+
+       char *content_type;
+       static const char *text_plain = "text/plain";
+
        assert (st->url != NULL);
        /* (Assured by `config_add') */
 
        if (st->curl == NULL)
        {
-               int status;
-
                status = init_host (st);
                if (status != 0)
                        return (-1);
@@ -562,31 +561,29 @@ static int apache_read_host (user_data_t *user_data) /* {{{ */
                st->server_type = APACHE;
        }
 
-       ptr = st->apache_buffer;
-       saveptr = NULL;
-       while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
+       status = curl_easy_getinfo (st->curl, CURLINFO_CONTENT_TYPE, &content_type);
+       if ((status == CURLE_OK) && (content_type != NULL) &&
+           (strncasecmp (content_type, text_plain, strlen (text_plain)) != 0))
        {
-               ptr = NULL;
-               lines_num++;
-
-               if (lines_num >= 16)
-                       break;
+               WARNING ("apache plugin: `Content-Type' response header is not `%s' "
+                       "(received: `%s'). Expecting unparseable data. Please check `URL' "
+                       "parameter (missing `?auto' suffix ?)",
+                       text_plain, content_type);
        }
 
-       for (i = 0; i < lines_num; i++)
+       ptr = st->apache_buffer;
+       saveptr = NULL;
+       while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
        {
-               fields_num = strsplit (lines[i], fields, 4);
+               ptr = NULL;
+               fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields));
 
                if (fields_num == 3)
                {
-                       if ((strcmp (fields[0], "Total") == 0)
-                                       && (strcmp (fields[1], "Accesses:") == 0))
-                               submit_derive ("apache_requests", "",
-                                               atoll (fields[2]), st);
-                       else if ((strcmp (fields[0], "Total") == 0)
-                                       && (strcmp (fields[1], "kBytes:") == 0))
-                               submit_derive ("apache_bytes", "",
-                                               1024LL * atoll (fields[2]), st);
+                       if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "Accesses:") == 0))
+                               submit_derive ("apache_requests", "", atoll (fields[2]), st);
+                       else if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "kBytes:") == 0))
+                               submit_derive ("apache_bytes", "", 1024LL * atoll (fields[2]), st);
                }
                else if (fields_num == 2)
                {
index 718061a..2d1c16b 100644 (file)
 # include <netinet/in.h>
 #endif
 
+#ifndef APCUPS_SERVER_TIMEOUT
+# define APCUPS_SERVER_TIMEOUT 15.0
+#endif
+
 #ifndef APCUPS_DEFAULT_NODE
 # define APCUPS_DEFAULT_NODE "localhost"
 #endif
@@ -125,7 +129,7 @@ static int net_open (char const *node, char const *service)
        if (status != 0)
        {
                char errbuf[1024];
-               INFO ("getaddrinfo failed: %s",
+               INFO ("apcups plugin: getaddrinfo failed: %s",
                                (status == EAI_SYSTEM)
                                ? sstrerror (errno, errbuf, sizeof (errbuf))
                                : gai_strerror (status));
@@ -144,7 +148,7 @@ static int net_open (char const *node, char const *service)
 
        if (sd < 0)
        {
-               DEBUG ("Unable to open a socket");
+               DEBUG ("apcups plugin: Unable to open a socket");
                freeaddrinfo (ai_return);
                return (-1);
        }
@@ -156,13 +160,13 @@ static int net_open (char const *node, char const *service)
        if (status != 0) /* `connect(2)' failed */
        {
                char errbuf[1024];
-               INFO ("connect failed: %s",
+               INFO ("apcups plugin: connect failed: %s",
                                sstrerror (errno, errbuf, sizeof (errbuf)));
                close (sd);
                return (-1);
        }
 
-       DEBUG ("Done opening a socket %i", sd);
+       DEBUG ("apcups plugin: Done opening a socket %i", sd);
 
        return (sd);
 } /* int net_open */
@@ -220,7 +224,7 @@ static int net_recv (int *sockfd, char *buf, int buflen)
  * Returns zero on success
  * Returns non-zero on error
  */
-static int net_send (int *sockfd, char *buff, int len)
+static int net_send (int *sockfd, const char *buff, int len)
 {
        uint16_t packet_size;
 
@@ -322,9 +326,6 @@ static int apc_query_server (char const *node, char const *service,
                printf ("net_recv = `%s';\n", recvline);
 #endif /* if APCMAIN */
 
-               if (strncmp ("END APC", recvline, strlen ("END APC")) == 0)
-                       break;
-
                toksaveptr = NULL;
                tokptr = strtok_r (recvline, " :\t", &toksaveptr);
                while (tokptr != NULL)
@@ -381,6 +382,7 @@ static int apc_query_server (char const *node, char const *service,
 static int apcups_config (oconfig_item_t *ci)
 {
        int i;
+       _Bool persistent_conn_set = 0;
 
        for (i = 0; i < ci->children_num; i++)
        {
@@ -392,16 +394,29 @@ static int apcups_config (oconfig_item_t *ci)
                        cf_util_get_service (child, &conf_service);
                else if (strcasecmp (child->key, "ReportSeconds") == 0)
                        cf_util_get_boolean (child, &conf_report_seconds);
-               else if (strcasecmp (child->key, "PersistentConnection") == 0)
+               else if (strcasecmp (child->key, "PersistentConnection") == 0) {
                        cf_util_get_boolean (child, &conf_persistent_conn);
+                       persistent_conn_set = 1;
+               }
                else
                        ERROR ("apcups plugin: Unknown config option \"%s\".", child->key);
        }
 
+       if (!persistent_conn_set) {
+               double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval());
+               if (interval > APCUPS_SERVER_TIMEOUT) {
+                       NOTICE ("apcups plugin: Plugin poll interval set to %.3f seconds. "
+                               "Apcupsd NIS socket timeout is %.3f seconds, "
+                               "PersistentConnection disabled by default.",
+                               interval, APCUPS_SERVER_TIMEOUT);
+                       conf_persistent_conn = 0;
+               }
+       }
+
        return (0);
 } /* int apcups_config */
 
-static void apc_submit_generic (char *type, char *type_inst, double value)
+static void apc_submit_generic (const char *type, const char *type_inst, double value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
@@ -455,7 +470,7 @@ static int apcups_read (void)
         */
        if (status != 0)
        {
-               DEBUG ("apc_query_server (%s, %s) = %i",
+               DEBUG ("apcups plugin: apc_query_server (%s, %s) = %i",
                                (conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
                                (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
                                status);
index 19d5a49..7ed2016 100644 (file)
@@ -59,7 +59,7 @@ static mach_port_t io_master_port = MACH_PORT_NULL;
 static int as_init (void)
 {
        kern_return_t status;
-       
+
        if (io_master_port != MACH_PORT_NULL)
        {
                mach_port_deallocate (mach_task_self (),
index 2ba3c77..9124c26 100644 (file)
@@ -32,7 +32,7 @@
 #include <curl/curl.h>
 #include <libxml/parser.h>
 
-static char *races_list[] = /* {{{ */
+static const char *races_list[] = /* {{{ */
 {
   NULL,
   "Human",    /*  1 */
@@ -49,7 +49,7 @@ static char *races_list[] = /* {{{ */
 }; /* }}} */
 #define RACES_LIST_LENGTH STATIC_ARRAY_SIZE (races_list)
 
-static char *classes_list[] = /* {{{ */
+static const char *classes_list[] = /* {{{ */
 {
   NULL,
   "Warrior", /*  1 */
@@ -66,7 +66,7 @@ static char *classes_list[] = /* {{{ */
 }; /* }}} */
 #define CLASSES_LIST_LENGTH STATIC_ARRAY_SIZE (classes_list)
 
-static char *genders_list[] = /* {{{ */
+static const char *genders_list[] = /* {{{ */
 {
   "Male",
   "Female"
@@ -154,14 +154,14 @@ static size_t ascent_curl_callback (void *buf, size_t size, size_t nmemb, /* {{{
 {
   size_t len = size * nmemb;
 
-  if (len <= 0)
+  if (len == 0)
     return (len);
 
   if ((ascent_buffer_fill + len) >= ascent_buffer_size)
   {
     char *temp;
 
-    temp = (char *) realloc (ascent_buffer,
+    temp = realloc (ascent_buffer,
         ascent_buffer_fill + len + 1);
     if (temp == NULL)
     {
index c5e7f77..f14ac04 100644 (file)
 /* ------------ MPL115 defines ------------ */
 /* I2C address of the MPL115 sensor */
 #define MPL115_I2C_ADDRESS          0x60
-                                    
-/* register addresses */            
+
+/* register addresses */
 #define MPL115_ADDR_CONV            0x00
 #define MPL115_ADDR_COEFFS          0x04
-                                    
-/* register sizes */                
+
+/* register sizes */
 #define MPL115_NUM_CONV             4
 #define MPL115_NUM_COEFFS           12
-                                    
-/* commands / addresses */          
+
+/* commands / addresses */
 #define MPL115_CMD_CONVERT_PRESS    0x10
 #define MPL115_CMD_CONVERT_TEMP     0x11
 #define MPL115_CMD_CONVERT_BOTH     0x12
-                                    
+
 #define MPL115_CONVERSION_RETRIES   5
 
 
 #define MPL3115_PT_DATA_DREM        0x04
 #define MPL3115_PT_DATA_PDEF        0x02
 #define MPL3115_PT_DATA_TDEF        0x01
-                                    
+
 #define MPL3115_DR_STATUS_TDR       0x02
 #define MPL3115_DR_STATUS_PDR       0x04
 #define MPL3115_DR_STATUS_PTDR      0x08
 #define MPL3115_DR_STATUS_DR        (MPL3115_DR_STATUS_TDR | MPL3115_DR_STATUS_PDR | MPL3115_DR_STATUS_PTDR)
-                                    
+
 #define MPL3115_DR_STATUS_TOW       0x20
 #define MPL3115_DR_STATUS_POW       0x40
 #define MPL3115_DR_STATUS_PTOW      0x80
 /* I2C address of the BMP085 sensor */
 #define BMP085_I2C_ADDRESS          0x77
 
-/* register addresses */            
+/* register addresses */
 #define BMP085_ADDR_ID_REG          0xD0
 #define BMP085_ADDR_VERSION         0xD1
 
 #define BMP085_ADDR_CTRL_REG        0xF4
 #define BMP085_ADDR_COEFFS          0xAA
 
-/* register sizes */                
+/* register sizes */
 #define BMP085_NUM_COEFFS           22
 
 /* commands, values */
@@ -178,7 +178,7 @@ static const char *config_keys[] =
 };
 
 static int    config_keys_num     = STATIC_ARRAY_SIZE(config_keys);
-                                  
+
 static char * config_device       = NULL;  /**< I2C bus device */
 static int    config_oversample   = 1;     /**< averaging window */
 
@@ -187,9 +187,9 @@ static double config_temp_offset  = 0.0;   /**< temperature offset */
 
 static double config_altitude     = NAN;   /**< altitude */
 static int    config_normalize    = 0;     /**< normalization method */
-                                  
+
 static _Bool  configured          = 0;     /**< the whole plugin config status */
-                                  
+
 static int    i2c_bus_fd          = -1;    /**< I2C bus device FD */
 
 static enum Sensor_type sensor_type = Sensor_none; /**< detected/used sensor type */
@@ -243,7 +243,7 @@ static averaging_t pressure_averaging    = { NULL, 0, 0L, 0 };
 static averaging_t temperature_averaging = { NULL, 0, 0L, 0 };
 
 
-/** 
+/**
  * Create / allocate averaging buffer
  *
  * The buffer is initialized with zeros.
@@ -309,9 +309,9 @@ static double averaging_add_sample(averaging_t * avg, long int sample)
     avg->ring_buffer[avg->ring_buffer_head] = sample;
     avg->ring_buffer_head = (avg->ring_buffer_head+1) % avg->ring_buffer_size;
     result = (double)(avg->ring_buffer_sum) / (double)(avg->ring_buffer_size);
-    
-    DEBUG ("barometer: averaging_add_sample - added %ld, result = %lf", 
-           sample, 
+
+    DEBUG ("barometer: averaging_add_sample - added %ld, result = %lf",
+           sample,
            result);
 
     return result;
@@ -343,9 +343,9 @@ static temperature_list_t * temp_list = NULL;
  */
 static int temp_list_add(temperature_list_t * list, const char * sensor)
 {
-    temperature_list_t * new_temp;
+    temperature_list_t *new_temp;
 
-    new_temp = (temperature_list_t *) malloc(sizeof(*new_temp));
+    new_temp = malloc(sizeof (*new_temp));
     if(new_temp == NULL)
         return -1;
 
@@ -473,7 +473,7 @@ static int get_reference_temperature(double * result)
             list = list->next;
             continue;
         }
-            
+
         for(i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
         {
             DEBUG ("barometer: get_reference_temperature - history %zu: %lf",
@@ -530,7 +530,7 @@ static int get_reference_temperature(double * result)
         }
         list = list->next;
     }  /* while sensor list */
-    
+
     if(*result == NAN)
     {
         ERROR("barometer: get_reference_temperature - no sensor available (yet?)");
@@ -543,7 +543,7 @@ static int get_reference_temperature(double * result)
 
 /* ------------------------ MPL115 access ------------------------ */
 
-/** 
+/**
  * Detect presence of a MPL115 pressure sensor.
  *
  * Unfortunately there seems to be no ID register so we just try to read first
@@ -551,7 +551,7 @@ static int get_reference_temperature(double * result)
  * MPL115. We should use this check as the last resort (which would be the typical
  * case anyway since MPL115 is the least accurate sensor).
  * As a sideeffect will leave set I2C slave address.
- * 
+ *
  * @return 1 if MPL115, 0 otherwise
  */
 static int MPL115_detect(void)
@@ -687,7 +687,7 @@ static void MPL115_convert_adc_to_real(double   adc_pressure,
     Pcomp = mpl115_coeffA0 +                                            \
         (mpl115_coeffB1 + mpl115_coeffC11*adc_pressure + mpl115_coeffC12*adc_temp) * adc_pressure + \
         (mpl115_coeffB2 + mpl115_coeffC22*adc_temp) * adc_temp;
-    
+
     *pressure = ((1150.0-500.0) * Pcomp / 1023.0) + 500.0;
     *temperature = (472.0 - adc_temp) / 5.35 + 25.0;
     DEBUG ("barometer: MPL115_convert_adc_to_real - got %lf hPa, %lf C",
@@ -799,11 +799,11 @@ static int MPL115_read_averaged(double * pressure, double * temperature)
 
 /* ------------------------ MPL3115 access ------------------------ */
 
-/** 
+/**
  * Detect presence of a MPL3115 pressure sensor by checking register "WHO AM I"
  *
  * As a sideeffect will leave set I2C slave address.
- * 
+ *
  * @return 1 if MPL3115, 0 otherwise
  */
 static int MPL3115_detect(void)
@@ -830,10 +830,10 @@ static int MPL3115_detect(void)
     return 0;
 }
 
-/** 
+/**
  * Adjusts oversampling to values supported by MPL3115
  *
- * MPL3115 supports only power of 2 in the range 1 to 128. 
+ * MPL3115 supports only power of 2 in the range 1 to 128.
  */
 static void MPL3115_adjust_oversampling(void)
 {
@@ -881,13 +881,13 @@ static void MPL3115_adjust_oversampling(void)
     }
 
     DEBUG("barometer: MPL3115_adjust_oversampling - correcting oversampling from %d to %d",
-          config_oversample, 
+          config_oversample,
           new_val);
     config_oversample = new_val;
 }
 
-/** 
- * Read sensor averegaed measurements
+/**
+ * Read sensor averaged measurements
  *
  * @param pressure    averaged measured pressure
  * @param temperature averaged measured temperature
@@ -901,7 +901,7 @@ static int MPL3115_read(double * pressure, double * temperature)
     __u8 data[MPL3115_NUM_CONV_VALS];
     long int tmp_value = 0;
     char errbuf[1024];
-    
+
     /* Set Active - activate the device from standby */
     res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1);
     if (res < 0)
@@ -911,8 +911,8 @@ static int MPL3115_read(double * pressure, double * temperature)
         return 1;
     }
     ctrl = res;
-    res = i2c_smbus_write_byte_data(i2c_bus_fd, 
-                                    MPL3115_REG_CTRL_REG1, 
+    res = i2c_smbus_write_byte_data(i2c_bus_fd,
+                                    MPL3115_REG_CTRL_REG1,
                                     ctrl | MPL3115_CTRL_REG1_SBYB);
     if (res < 0)
     {
@@ -920,10 +920,10 @@ static int MPL3115_read(double * pressure, double * temperature)
                sstrerror (errno, errbuf, sizeof (errbuf)));
         return 1;
     }
-    
+
     /* base sleep is 5ms x OST */
     usleep(5000 * config_oversample);
-      
+
     /* check the flags/status if ready */
     res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS);
     if (res < 0)
@@ -932,12 +932,12 @@ static int MPL3115_read(double * pressure, double * temperature)
                sstrerror (errno, errbuf, sizeof (errbuf)));
         return 1;
     }
-    
+
     while ((res & MPL3115_DR_STATUS_DR) != MPL3115_DR_STATUS_DR)
     {
         /* try some extra sleep... */
         usleep(10000);
-        
+
         /* ... and repeat the check. The conversion has to finish sooner or later. */
         res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS);
         if (res < 0)
@@ -947,10 +947,10 @@ static int MPL3115_read(double * pressure, double * temperature)
             return 1;
         }
     }
-    
+
     /* Now read all the data in one block. There is address autoincrement. */
-    res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, 
-                                        MPL3115_REG_OUT_P_MSB, 
+    res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
+                                        MPL3115_REG_OUT_P_MSB,
                                         MPL3115_NUM_CONV_VALS,
                                         data);
     if (res < 0)
@@ -959,11 +959,11 @@ static int MPL3115_read(double * pressure, double * temperature)
                sstrerror (errno, errbuf, sizeof (errbuf)));
         return 1;
     }
-    
+
     tmp_value = (data[0] << 16) | (data[1] << 8) | data[2];
     *pressure = ((double) tmp_value) / 4.0 / 16.0 / 100.0;
     DEBUG ("barometer: MPL3115_read - absolute pressure = %lf hPa", *pressure);
-    
+
     if(data[3] > 0x7F)
     {
         data[3] = ~data[3] + 1;
@@ -974,16 +974,16 @@ static int MPL3115_read(double * pressure, double * temperature)
     {
         *temperature = data[3];
     }
-    
+
     *temperature += (double)(data[4]) / 256.0;
     DEBUG ("barometer: MPL3115_read - temperature = %lf C", *temperature);
-    
+
     return 0;
 }
 
-/** 
+/**
  * Initialize MPL3115 for barometeric measurements
- * 
+ *
  * @return 0 if successful
  */
 static int MPL3115_init_sensor(void)
@@ -991,18 +991,18 @@ static int MPL3115_init_sensor(void)
     __s32 res;
     __s8 offset;
     char errbuf[1024];
-    
+
     /* Reset the sensor. It will reset immediately without ACKing */
     /* the transaction, so no error handling here. */
-    i2c_smbus_write_byte_data(i2c_bus_fd, 
-                              MPL3115_REG_CTRL_REG1, 
+    i2c_smbus_write_byte_data(i2c_bus_fd,
+                              MPL3115_REG_CTRL_REG1,
                               MPL3115_CTRL_REG1_RST);
-    
+
     /* wait some time for the reset to finish */
     usleep(100000);
 
     /* now it should be in standby already so we can go and configure it */
-    
+
     /*  Set temperature offset. */
     /*  result = ADCtemp + offset [C] */
     offset = (__s8) (config_temp_offset * 16.0);
@@ -1013,7 +1013,7 @@ static int MPL3115_init_sensor(void)
                sstrerror (errno, errbuf, sizeof (errbuf)));
         return -1;
     }
-    
+
     /*  Set pressure offset. */
     /*  result = ADCpress + offset [hPa] */
     offset = (__s8) (config_press_offset * 100.0 / 4.0);
@@ -1026,7 +1026,7 @@ static int MPL3115_init_sensor(void)
     }
 
     /* Enable Data Flags in PT_DATA_CFG - flags on both pressure and temp */
-    res = i2c_smbus_write_byte_data(i2c_bus_fd, 
+    res = i2c_smbus_write_byte_data(i2c_bus_fd,
                                     MPL3115_REG_PT_DATA_CFG,
                                     MPL3115_PT_DATA_DREM        \
                                     | MPL3115_PT_DATA_PDEF      \
@@ -1038,9 +1038,9 @@ static int MPL3115_init_sensor(void)
         return -1;
     }
 
-    /* Set to barometer with an OSR */ 
-    res = i2c_smbus_write_byte_data(i2c_bus_fd, 
-                                    MPL3115_REG_CTRL_REG1, 
+    /* Set to barometer with an OSR */
+    res = i2c_smbus_write_byte_data(i2c_bus_fd,
+                                    MPL3115_REG_CTRL_REG1,
                                     mpl3115_oversample);
     if (res < 0)
     {
@@ -1054,11 +1054,11 @@ static int MPL3115_init_sensor(void)
 
 /* ------------------------ BMP085 access ------------------------ */
 
-/** 
+/**
  * Detect presence of a BMP085 pressure sensor by checking its ID register
  *
  * As a sideeffect will leave set I2C slave address.
- * 
+ *
  * @return 1 if BMP085, 0 otherwise
  */
 static int BMP085_detect(void)
@@ -1098,10 +1098,10 @@ static int BMP085_detect(void)
 }
 
 
-/** 
+/**
  * Adjusts oversampling settings to values supported by BMP085
  *
- * BMP085 supports only 1,2,4 or 8 samples. 
+ * BMP085 supports only 1,2,4 or 8 samples.
  */
 static void BMP085_adjust_oversampling(void)
 {
@@ -1137,13 +1137,13 @@ static void BMP085_adjust_oversampling(void)
     }
 
     DEBUG("barometer: BMP085_adjust_oversampling - correcting oversampling from %d to %d",
-          config_oversample, 
+          config_oversample,
           new_val);
     config_oversample = new_val;
 }
 
 
-/** 
+/**
  * Read the BMP085 sensor conversion coefficients.
  *
  * These are (device specific) constants so we can read them just once.
@@ -1153,12 +1153,12 @@ static void BMP085_adjust_oversampling(void)
 static int BMP085_read_coeffs(void)
 {
     __s32 res;
-    __u8 coeffs[BMP085_NUM_COEFFS]; 
+    __u8 coeffs[BMP085_NUM_COEFFS];
     char errbuf[1024];
 
-    res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, 
+    res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
                                         BMP085_ADDR_COEFFS,
-                                        BMP085_NUM_COEFFS, 
+                                        BMP085_NUM_COEFFS,
                                         coeffs);
     if (res < 0)
     {
@@ -1166,7 +1166,7 @@ static int BMP085_read_coeffs(void)
                sstrerror (errno, errbuf, sizeof (errbuf)));
         return -1;
     }
-    
+
     bmp085_AC1 = ((int16_t)  coeffs[0]  <<8) | (int16_t)  coeffs[1];
     bmp085_AC2 = ((int16_t)  coeffs[2]  <<8) | (int16_t)  coeffs[3];
     bmp085_AC3 = ((int16_t)  coeffs[4]  <<8) | (int16_t)  coeffs[5];
@@ -1237,13 +1237,13 @@ static void BMP085_convert_adc_to_real(long adc_pressure,
     X2 = (((long)bmp085_AC2 * B6) >> 11);
     X3 = X1 + X2;
     B3 = (((((long)bmp085_AC1 * 4) + X3) << bmp085_oversampling) + 2) >> 2;
-    
+
     /* B4 */
     X1 = (((long)bmp085_AC3*B6) >> 13);
     X2 = (bmp085_B1*((B6*B6) >> 12) ) >> 16;
     X3 = ((X1 + X2) + 2 ) >> 2;
     B4 = ((long)bmp085_AC4* (unsigned long)(X3 + 32768)) >> 15;
-    
+
     /* B7, P */
     B7 =  (unsigned long)(adc_pressure - B3)*(50000>>bmp085_oversampling);
     if( B7 < 0x80000000 )
@@ -1258,15 +1258,15 @@ static void BMP085_convert_adc_to_real(long adc_pressure,
     X1 = (X1 * 3038) >> 16;
     X2 = ((-7357) * P) >> 16;
     P = P + ( ( X1 + X2 + 3791 ) >> 4);
-    
-    *pressure = P / 100.0; // in [hPa] 
+
+    *pressure = P / 100.0; // in [hPa]
     DEBUG ("barometer: BMP085_convert_adc_to_real - got %lf hPa, %lf C",
            *pressure,
            *temperature);
 }
 
-    
-/** 
+
+/**
  * Read compensated sensor measurements
  *
  * @param pressure    averaged measured pressure
@@ -1298,9 +1298,9 @@ static int BMP085_read(double * pressure, double * temperature)
     usleep(BMP085_TIME_CNV_TEMP); /* wait for the conversion */
 
     res = i2c_smbus_read_i2c_block_data( i2c_bus_fd,
-                                         BMP085_ADDR_CONV, 
+                                         BMP085_ADDR_CONV,
                                          2,
-                                         measBuff); 
+                                         measBuff);
     if (res < 0)
     {
         ERROR ("barometer: BMP085_read - problem reading temperature data: %s",
@@ -1308,12 +1308,12 @@ static int BMP085_read(double * pressure, double * temperature)
         return 1;
     }
 
-    adc_temperature = ( (unsigned short)measBuff[0] << 8 ) + measBuff[1]; 
-    
+    adc_temperature = ( (unsigned short)measBuff[0] << 8 ) + measBuff[1];
+
 
     /* get presure */
     res = i2c_smbus_write_byte_data( i2c_bus_fd,
-                                     BMP085_ADDR_CTRL_REG, 
+                                     BMP085_ADDR_CTRL_REG,
                                      bmp085_cmdCnvPress );
     if (res < 0)
     {
@@ -1325,7 +1325,7 @@ static int BMP085_read(double * pressure, double * temperature)
     usleep(bmp085_timeCnvPress); /* wait for the conversion */
 
     res = i2c_smbus_read_i2c_block_data( i2c_bus_fd,
-                                         BMP085_ADDR_CONV, 
+                                         BMP085_ADDR_CONV,
                                          3,
                                          measBuff );
     if (res < 0)
@@ -1336,7 +1336,7 @@ static int BMP085_read(double * pressure, double * temperature)
     }
 
     adc_pressure = (long)((((ulong)measBuff[0]<<16) | ((ulong)measBuff[1]<<8) | (ulong)measBuff[2] ) >> (8 - bmp085_oversampling));
-    
+
 
     DEBUG ("barometer: BMP085_read - raw pressure ADC value = %ld, " \
            "raw temperature ADC value = %ld",
@@ -1351,16 +1351,16 @@ static int BMP085_read(double * pressure, double * temperature)
 
 
 /* ------------------------ Sensor detection ------------------------ */
-/** 
+/**
  * Detect presence of a supported sensor.
  *
  * As a sideeffect will leave set I2C slave address.
  * The detection is done in the order BMP085, MPL3115, MPL115 and stops after
  * first sensor beeing found.
- * 
+ *
  * @return detected sensor type
  */
-enum Sensor_type Detect_sensor_type(void)
+static enum Sensor_type detect_sensor_type(void)
 {
     if(BMP085_detect())
         return Sensor_BMP085;
@@ -1385,7 +1385,7 @@ enum Sensor_type Detect_sensor_type(void)
  * - MSLP_INTERNATIONAL - see http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation
  *           Requires #config_altitude
  *
- * - MSLP_DEU_WETT - formula as recommended by the Deutsche Wetterdienst. See 
+ * - MSLP_DEU_WETT - formula as recommended by the Deutsche Wetterdienst. See
  *                http://de.wikipedia.org/wiki/Barometrische_H%C3%B6henformel#Theorie
  *           Requires both #config_altitude and temperature reference(s).
  *
@@ -1413,12 +1413,12 @@ static double abs_to_mean_sea_level_pressure(double abs_pressure)
     case MSLP_NONE:
         mean = abs_pressure;
         break;
-        
+
     case MSLP_INTERNATIONAL:
         mean = abs_pressure / \
             pow(1.0 - 0.0065*config_altitude/288.15, 9.80665*0.0289644/(8.31447*0.0065));
         break;
-        
+
     case MSLP_DEU_WETT:
     {
         double E; /* humidity */
@@ -1433,7 +1433,7 @@ static double abs_to_mean_sea_level_pressure(double abs_pressure)
     break;
 
     default:
-        ERROR ("barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d", 
+        ERROR ("barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d",
                config_normalize);
         mean = abs_pressure;
         break;
@@ -1444,17 +1444,17 @@ static double abs_to_mean_sea_level_pressure(double abs_pressure)
            config_normalize,
            mean);
 
-    return mean; 
+    return mean;
 }
 
 /* ------------------------ main plugin callbacks ------------------------ */
 
-/** 
+/**
  * Main plugin configuration callback (using simple config)
- * 
+ *
  * @param key   configuration key we should process
  * @param value configuration value we should process
- * 
+ *
  * @return Zero when successful.
  */
 static int collectd_barometer_config (const char *key, const char *value)
@@ -1508,7 +1508,7 @@ static int collectd_barometer_config (const char *key, const char *value)
     {
         config_temp_offset = atof(value);
     }
-    else 
+    else
     {
         return -1;
     }
@@ -1517,11 +1517,11 @@ static int collectd_barometer_config (const char *key, const char *value)
 }
 
 
-/** 
+/**
  * Shutdown callback.
- * 
+ *
  * Close I2C and delete all the buffers.
- * 
+ *
  * @return Zero when successful (at the moment the only possible outcome)
  */
 static int collectd_barometer_shutdown(void)
@@ -1547,9 +1547,9 @@ static int collectd_barometer_shutdown(void)
 }
 
 
-/** 
+/**
  * Plugin read callback for MPL115.
- * 
+ *
  *  Dispatching will create values:
  *  - <hostname>/barometer-mpl115/pressure-normalized
  *  - <hostname>/barometer-mpl115/pressure-absolute
@@ -1567,7 +1567,7 @@ static int MPL115_collectd_barometer_read (void)
 
     value_list_t vl = VALUE_LIST_INIT;
     value_t      values[1];
-    
+
     DEBUG("barometer: MPL115_collectd_barometer_read");
 
     if (!configured)
@@ -1629,9 +1629,9 @@ static int MPL115_collectd_barometer_read (void)
 }
 
 
-/** 
+/**
  * Plugin read callback for MPL3115.
- * 
+ *
  *  Dispatching will create values:
  *  - <hostname>/barometer-mpl3115/pressure-normalized
  *  - <hostname>/barometer-mpl3115/pressure-absolute
@@ -1642,21 +1642,21 @@ static int MPL115_collectd_barometer_read (void)
 static int MPL3115_collectd_barometer_read (void)
 {
     int result = 0;
-    
+
     double pressure        = 0.0;
     double temperature     = 0.0;
     double norm_pressure   = 0.0;
-    
+
     value_list_t vl = VALUE_LIST_INIT;
     value_t      values[1];
-    
+
     DEBUG("barometer: MPL3115_collectd_barometer_read");
-    
+
     if (!configured)
     {
         return -1;
     }
-    
+
     result = MPL3115_read(&pressure, &temperature);
     if(result)
         return result;
@@ -1692,9 +1692,9 @@ static int MPL3115_collectd_barometer_read (void)
 }
 
 
-/** 
+/**
  * Plugin read callback for BMP085.
- * 
+ *
  *  Dispatching will create values:
  *  - <hostname>/barometer-bmp085/pressure-normalized
  *  - <hostname>/barometer-bmp085/pressure-absolute
@@ -1705,21 +1705,21 @@ static int MPL3115_collectd_barometer_read (void)
 static int BMP085_collectd_barometer_read (void)
 {
     int result = 0;
-    
+
     double pressure        = 0.0;
     double temperature     = 0.0;
     double norm_pressure   = 0.0;
-    
+
     value_list_t vl = VALUE_LIST_INIT;
     value_t      values[1];
-    
+
     DEBUG("barometer: BMP085_collectd_barometer_read");
-    
+
     if (!configured)
     {
         return -1;
     }
-    
+
     result = BMP085_read(&pressure, &temperature);
     if(result)
         return result;
@@ -1755,12 +1755,12 @@ static int BMP085_collectd_barometer_read (void)
 }
 
 
-/** 
+/**
  * Initialization callback
- * 
+ *
  * Check config, initialize I2C bus access, conversion coefficients and averaging
  * ring buffers
- * 
+ *
  * @return Zero when successful.
  */
 static int collectd_barometer_init (void)
@@ -1802,7 +1802,7 @@ static int collectd_barometer_init (void)
     }
 
     /* detect sensor type - this will also set slave address */
-    sensor_type = Detect_sensor_type();
+    sensor_type = detect_sensor_type();
 
     /* init correct sensor type */
     switch(sensor_type)
@@ -1811,10 +1811,10 @@ static int collectd_barometer_init (void)
     case Sensor_MPL3115:
     {
         MPL3115_adjust_oversampling();
-        
+
         if(MPL3115_init_sensor())
             return -1;
-        
+
         plugin_register_read ("barometer", MPL3115_collectd_barometer_read);
     }
     break;
@@ -1827,16 +1827,16 @@ static int collectd_barometer_init (void)
             ERROR("barometer: collectd_barometer_init pressure averaging init failed");
             return -1;
         }
-        
+
         if (averaging_create (&temperature_averaging, config_oversample))
         {
             ERROR("barometer: collectd_barometer_init temperature averaging init failed");
             return -1;
         }
-        
+
         if (MPL115_read_coeffs() < 0)
             return -1;
-        
+
         plugin_register_read ("barometer", MPL115_collectd_barometer_read);
     }
     break;
@@ -1858,7 +1858,7 @@ static int collectd_barometer_init (void)
         ERROR("barometer: collectd_barometer_init - no supported sensor found");
         return -1;
     }
-        
+
 
     configured = 1;
     return 0;
@@ -1866,15 +1866,15 @@ static int collectd_barometer_init (void)
 
 /* ------------------------ plugin register / entry point ------------------------ */
 
-/** 
+/**
  * Plugin "entry" - register all callback.
- * 
+ *
  */
 void module_register (void)
 {
-    plugin_register_config ("barometer", 
-                            collectd_barometer_config, 
-                            config_keys, 
+    plugin_register_config ("barometer",
+                            collectd_barometer_config,
+                            config_keys,
                             config_keys_num);
     plugin_register_init ("barometer", collectd_barometer_init);
     plugin_register_shutdown ("barometer", collectd_barometer_shutdown);
index c4c050d..8a96e89 100644 (file)
@@ -143,7 +143,7 @@ static void submit_capacity (char const *plugin_instance, /* {{{ */
 } /* }}} void submit_capacity */
 
 #if HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H
-static double dict_get_double (CFDictionaryRef dict, char *key_string) /* {{{ */
+static double dict_get_double (CFDictionaryRef dict, const char *key_string) /* {{{ */
 {
        double      val_double;
        long long   val_int;
@@ -341,7 +341,7 @@ static void get_via_generic_iokit (double *ret_capacity_full, /* {{{ */
                                *ret_voltage = temp_double / 1000.0;
                        }
                }
-               
+
                CFRelease (bat_root_dict);
        }
 
@@ -358,7 +358,7 @@ static int battery_read (void) /* {{{ */
         * IOPowerSources. IOKit, on the other hand, only reports the full
         * capacity. We use the two to calculate the current charged capacity. */
        gauge_t charge_rel = NAN; /* Current charge in percent */
-       gauge_t capacity_charged = NAN; /* Charged capacity */
+       gauge_t capacity_charged; /* Charged capacity */
        gauge_t capacity_full = NAN; /* Total capacity */
        gauge_t capacity_design = NAN; /* Full design capacity */
 
index 06b4ace..7d26208 100644 (file)
@@ -54,7 +54,7 @@
 # define BIND_DEFAULT_URL "http://localhost:8053/"
 #endif
 
-/* 
+/*
  * Some types used for the callback functions. `translation_table_ptr_t' and
  * `list_info_ptr_t' are passed to the callbacks in the `void *user_data'
  * pointer.
@@ -277,14 +277,14 @@ static size_t bind_curl_callback (void *buf, size_t size, /* {{{ */
 {
   size_t len = size * nmemb;
 
-  if (len <= 0)
+  if (len == 0)
     return (len);
 
   if ((bind_buffer_fill + len) >= bind_buffer_size)
   {
     char *temp;
 
-    temp = realloc(bind_buffer, bind_buffer_fill + len + 1);
+    temp = realloc (bind_buffer, bind_buffer_fill + len + 1);
     if (temp == NULL)
     {
       ERROR ("bind plugin: realloc failed.");
@@ -474,7 +474,7 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */
   return (0);
 } /* }}} int bind_xml_read_timestamp */
 
-/* 
+/*
  * bind_parse_generic_name_value
  *
  * Reads statistics in the form:
@@ -559,7 +559,7 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ *
   return (0);
 } /* }}} int bind_parse_generic_name_value */
 
-/* 
+/*
  * bind_parse_generic_value_list
  *
  * Reads statistics in the form:
@@ -774,7 +774,7 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */
   { /* Parse the <counters> tag {{{ */
     char plugin_instance[DATA_MAX_NAME_LEN];
     translation_table_ptr_t table_ptr =
-    { 
+    {
       nsstats_translation_table,
       nsstats_translation_table_length,
       plugin_instance
@@ -836,8 +836,6 @@ static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */
 
   for (i = 0; i < zone_nodes->nodesetval->nodeNr; i++)
   {
-    xmlNode *node;
-
     node = zone_nodes->nodesetval->nodeTab[i];
     assert (node != NULL);
 
@@ -957,7 +955,7 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */
   {
     char plugin_instance[DATA_MAX_NAME_LEN];
     translation_table_ptr_t table_ptr =
-    { 
+    {
       resstats_translation_table,
       resstats_translation_table_length,
       plugin_instance
@@ -1615,7 +1613,7 @@ static int bind_config_add_view_zone (cb_view_t *view, /* {{{ */
     return (-1);
   }
 
-  tmp = (char **) realloc (view->zones,
+  tmp = realloc (view->zones,
       sizeof (char *) * (view->zones_num + 1));
   if (tmp == NULL)
   {
@@ -1646,7 +1644,7 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  tmp = (cb_view_t *) realloc (views, sizeof (*views) * (views_num + 1));
+  tmp = realloc (views, sizeof (*views) * (views_num + 1));
   if (tmp == NULL)
   {
     ERROR ("bind plugin: realloc failed.");
@@ -1666,7 +1664,7 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */
   if (tmp->name == NULL)
   {
     ERROR ("bind plugin: strdup failed.");
-    free (tmp);
+    sfree (views);
     return (-1);
   }
 
@@ -1709,6 +1707,7 @@ static int bind_config (oconfig_item_t *ci) /* {{{ */
         return (-1);
       }
 
+      sfree (url);
       url = strdup (child->values[0].value.string);
     } else if (strcasecmp ("OpCodes", child->key) == 0)
       bind_config_set_bool ("OpCodes", &global_opcodes, child);
index 419ca6e..04a3974 100644 (file)
@@ -1,6 +1,7 @@
 /**
  * collectd - src/ceph.c
  * Copyright (C) 2011  New Dream Network
+ * Copyright (C) 2015  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
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Authors:
- *   Colin McCabe <cmccabe@alumni.cmu.edu>
- *   Dennis Zou <yunzou@cisco.com>
- *   Dan Ryder <daryder@cisco.com>
+ *   Colin McCabe <cmccabe at alumni.cmu.edu>
+ *   Dennis Zou <yunzou at cisco.com>
+ *   Dan Ryder <daryder at cisco.com>
+ *   Florian octo Forster <octo at collectd.org>
  **/
 
 #define _DEFAULT_SOURCE
@@ -94,7 +96,7 @@ enum ceph_dset_type_d
 };
 
 /** Valid types for ceph defined in types.db */
-const char * ceph_dset_types [CEPH_DSET_TYPES_NUM] =
+static const char * const ceph_dset_types [CEPH_DSET_TYPES_NUM] =
                                    {"ceph_latency", "ceph_bytes", "ceph_rate"};
 
 /******* ceph_daemon *******/
@@ -132,11 +134,10 @@ struct yajl_struct
 {
     node_handler_t handler;
     void * handler_arg;
-    struct {
-      char key[DATA_MAX_NAME_LEN];
-      int key_len;
-    } state[YAJL_MAX_DEPTH];
-    int depth;
+
+    char *key;
+    char *stack[YAJL_MAX_DEPTH];
+    size_t depth;
 };
 typedef struct yajl_struct yajl_struct;
 
@@ -255,68 +256,81 @@ static int ceph_cb_boolean(void *ctx, int bool_val)
     return CEPH_CB_CONTINUE;
 }
 
+#define BUFFER_ADD(dest, src) do { \
+    size_t dest_size = sizeof (dest); \
+    strncat ((dest), (src), dest_size - strlen (dest)); \
+    (dest)[dest_size - 1] = 0; \
+} while (0)
+
 static int
 ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len)
 {
-    yajl_struct *yajl = (yajl_struct*)ctx;
+    yajl_struct *state = (yajl_struct*) ctx;
     char buffer[number_len+1];
-    int i, latency_type = 0, result;
-    char key[128];
+    char key[2 * DATA_MAX_NAME_LEN];
+    _Bool latency_type = 0;
+    size_t i;
+    int status;
 
     memcpy(buffer, number_val, number_len);
     buffer[sizeof(buffer) - 1] = 0;
 
-    ssnprintf(key, yajl->state[0].key_len, "%s", yajl->state[0].key);
-    for(i = 1; i < yajl->depth; i++)
+    memset (key, 0, sizeof (key));
+    for (i = 0; i < state->depth; i++)
+    {
+        if (state->stack[i] == NULL)
+            continue;
+
+        if (strlen (key) != 0)
+            BUFFER_ADD (key, ".");
+        BUFFER_ADD (key, state->stack[i]);
+    }
+
+    /* Special case for latency metrics. */
+    if ((strcmp ("avgcount", state->key) == 0)
+        || (strcmp ("sum", state->key) == 0))
     {
-        if((i == yajl->depth-1) && ((strcmp(yajl->state[i].key,"avgcount") == 0)
-                || (strcmp(yajl->state[i].key,"sum") == 0)))
+        latency_type = 1;
+
+        /* Super-special case for filestore.journal_wr_bytes.avgcount: For
+         * some reason, Ceph schema encodes this as a count/sum pair while all
+         * other "Bytes" data (excluding used/capacity bytes for OSD space) uses
+         * a single "Derive" type. To spare further confusion, keep this KPI as
+         * the same type of other "Bytes". Instead of keeping an "average" or
+         * "rate", use the "sum" in the pair and assign that to the derive
+         * value. */
+        if (convert_special_metrics && (state->depth >= 2)
+            && (strcmp("filestore", state->stack[state->depth - 2]) == 0)
+            && (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0)
+            && (strcmp("avgcount", state->key) == 0))
         {
-            if(convert_special_metrics)
-            {
-                /**
-                 * Special case for filestore:JournalWrBytes. For some reason,
-                 * Ceph schema encodes this as a count/sum pair while all
-                 * other "Bytes" data (excluding used/capacity bytes for OSD
-                 * space) uses a single "Derive" type. To spare further
-                 * confusion, keep this KPI as the same type of other "Bytes".
-                 * Instead of keeping an "average" or "rate", use the "sum" in
-                 * the pair and assign that to the derive value.
-                 */
-                if((strcmp(yajl->state[i-1].key, "journal_wr_bytes") == 0) &&
-                        (strcmp(yajl->state[i-2].key,"filestore") == 0) &&
-                        (strcmp(yajl->state[i].key,"avgcount") == 0))
-                {
-                    DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes");
-                    yajl->depth = (yajl->depth - 1);
-                    return CEPH_CB_CONTINUE;
-                }
-            }
-            //probably a avgcount/sum pair. if not - we'll try full key later
-            latency_type = 1;
-            break;
+            DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes");
+            return CEPH_CB_CONTINUE;
         }
-        strncat(key, ".", 1);
-        strncat(key, yajl->state[i].key, yajl->state[i].key_len+1);
+    }
+    else /* not a latency type */
+    {
+        BUFFER_ADD (key, ".");
+        BUFFER_ADD (key, state->key);
     }
 
-    result = yajl->handler(yajl->handler_arg, buffer, key);
-
-    if((result == RETRY_AVGCOUNT) && latency_type)
+    status = state->handler(state->handler_arg, buffer, key);
+    if((status == RETRY_AVGCOUNT) && latency_type)
     {
-        strncat(key, ".", 1);
-        strncat(key, yajl->state[yajl->depth-1].key,
-                yajl->state[yajl->depth-1].key_len+1);
-        result = yajl->handler(yajl->handler_arg, buffer, key);
+        /* Add previously skipped part of the key, either "avgcount" or "sum",
+         * and try again. */
+        BUFFER_ADD (key, ".");
+        BUFFER_ADD (key, state->key);
+
+        status = state->handler(state->handler_arg, buffer, key);
     }
 
-    if(result == -ENOMEM)
+    if (status != 0)
     {
-        ERROR("ceph plugin: memory allocation failed");
+        ERROR("ceph plugin: JSON handler failed with status %d.", status);
         return CEPH_CB_ABORT;
     }
 
-    yajl->depth = (yajl->depth - 1);
     return CEPH_CB_CONTINUE;
 }
 
@@ -328,37 +342,52 @@ static int ceph_cb_string(void *ctx, const unsigned char *string_val,
 
 static int ceph_cb_start_map(void *ctx)
 {
+    yajl_struct *state = (yajl_struct*) ctx;
+
+    /* Push key to the stack */
+    if (state->depth == YAJL_MAX_DEPTH)
+        return CEPH_CB_ABORT;
+
+    state->stack[state->depth] = state->key;
+    state->depth++;
+    state->key = NULL;
+
     return CEPH_CB_CONTINUE;
 }
 
-static int
-ceph_cb_map_key(void *ctx, const unsigned char *key, yajl_len_t string_len)
+static int ceph_cb_end_map(void *ctx)
 {
-    yajl_struct *yajl = (yajl_struct*)ctx;
+    yajl_struct *state = (yajl_struct*) ctx;
 
-    if((yajl->depth+1)  >= YAJL_MAX_DEPTH)
-    {
-        ERROR("ceph plugin: depth exceeds max, aborting.");
+    /* Pop key from the stack */
+    if (state->depth == 0)
         return CEPH_CB_ABORT;
-    }
-
-    char buffer[string_len+1];
-
-    memcpy(buffer, key, string_len);
-    buffer[sizeof(buffer) - 1] = 0;
 
-    snprintf(yajl->state[yajl->depth].key, sizeof(buffer), "%s", buffer);
-    yajl->state[yajl->depth].key_len = sizeof(buffer);
-    yajl->depth = (yajl->depth + 1);
+    sfree (state->key);
+    state->depth--;
+    state->key = state->stack[state->depth];
+    state->stack[state->depth] = NULL;
 
     return CEPH_CB_CONTINUE;
 }
 
-static int ceph_cb_end_map(void *ctx)
+static int
+ceph_cb_map_key(void *ctx, const unsigned char *key, yajl_len_t string_len)
 {
-    yajl_struct *yajl = (yajl_struct*)ctx;
+    yajl_struct *state = (yajl_struct*) ctx;
+    size_t sz = ((size_t) string_len) + 1;
+
+    sfree (state->key);
+    state->key = malloc (sz);
+    if (state->key == NULL)
+    {
+        ERROR ("ceph plugin: malloc failed.");
+        return CEPH_CB_ABORT;
+    }
+
+    memmove (state->key, key, sz - 1);
+    state->key[sz - 1] = 0;
 
-    yajl->depth = (yajl->depth - 1);
     return CEPH_CB_CONTINUE;
 }
 
@@ -419,140 +448,140 @@ static void ceph_daemon_free(struct ceph_daemon *d)
     sfree(d);
 }
 
-/**
- * Compact ds name by removing special characters and trimming length to
- * DATA_MAX_NAME_LEN if necessary
- */
-static void compact_ds_name(char *source, char *dest)
+/* compact_ds_name removed the special characters ":", "_", "-" and "+" from the
+ * intput string. Characters following these special characters are capitalized.
+ * Trailing "+" and "-" characters are replaces with the strings "Plus" and
+ * "Minus". */
+static int compact_ds_name (char *buffer, size_t buffer_size, char const *src)
 {
-    int keys_num = 0, i;
-    char *save_ptr = NULL, *tmp_ptr = source;
-    char *keys[16];
-    char len_str[3];
-    char tmp[DATA_MAX_NAME_LEN];
-    size_t key_chars_remaining = (DATA_MAX_NAME_LEN-1);
-    int reserved = 0;
-    int offset = 0;
-    memset(tmp, 0, sizeof(tmp));
-    if(source == NULL || dest == NULL || source[0] == '\0' || dest[0] != '\0')
-    {
-        return;
-    }
-    size_t src_len = strlen(source);
-    snprintf(len_str, sizeof(len_str), "%zu", src_len);
-    unsigned char append_status = 0x0;
-    append_status |= (source[src_len - 1] == '-') ? 0x1 : 0x0;
-    append_status |= (source[src_len - 1] == '+') ? 0x2 : 0x0;
-    while ((keys[keys_num] = strtok_r(tmp_ptr, ":_-+", &save_ptr)) != NULL)
-    {
-        tmp_ptr = NULL;
-        /** capitalize 1st char **/
-        keys[keys_num][0] = toupper(keys[keys_num][0]);
-        keys_num++;
-        if(keys_num >= 16)
-        {
-            break;
-        }
-    }
-    /** concatenate each part of source string **/
-    for(i = 0; i < keys_num; i++)
-    {
-        strncat(tmp, keys[i], key_chars_remaining);
-        key_chars_remaining -= strlen(keys[i]);
-    }
-    tmp[DATA_MAX_NAME_LEN - 1] = '\0';
-    /** to coordinate limitation of length of type_instance
-     *  we will truncate ds_name
-     *  when the its length is more than
-     *  DATA_MAX_NAME_LEN
-     */
-    if(strlen(tmp) > DATA_MAX_NAME_LEN - 1)
+    char *src_copy;
+    size_t src_len;
+    char *ptr = buffer;
+    size_t ptr_size = buffer_size;
+    _Bool append_plus = 0;
+    _Bool append_minus = 0;
+
+    if ((buffer == NULL) || (buffer_size <= strlen ("Minus")) || (src == NULL))
+      return EINVAL;
+
+    src_copy = strdup (src);
+    src_len = strlen(src);
+
+    /* Remove trailing "+" and "-". */
+    if (src_copy[src_len - 1] == '+')
     {
-        append_status |= 0x4;
-        /** we should reserve space for
-         * len_str
-         */
-        reserved += 2;
+        append_plus = 1;
+        src_len--;
+        src_copy[src_len] = 0;
     }
-    if(append_status & 0x1)
+    else if (src_copy[src_len - 1] == '-')
     {
-        /** we should reserve space for
-         * "Minus"
-         */
-        reserved += 5;
+        append_minus = 1;
+        src_len--;
+        src_copy[src_len] = 0;
     }
-    if(append_status & 0x2)
+
+    /* Split at special chars, capitalize first character, append to buffer. */
+    char *dummy = src_copy;
+    char *token;
+    char *save_ptr = NULL;
+    while ((token = strtok_r (dummy, ":_-+", &save_ptr)) != NULL)
     {
-        /** we should reserve space for
-         * "Plus"
-         */
-        reserved += 4;
+        size_t len;
+
+        dummy = NULL;
+
+        token[0] = toupper ((int) token[0]);
+
+        assert (ptr_size > 1);
+
+        len = strlen (token);
+        if (len >= ptr_size)
+            len = ptr_size - 1;
+
+        assert (len > 0);
+        assert (len < ptr_size);
+
+        sstrncpy (ptr, token, len + 1);
+        ptr += len;
+        ptr_size -= len;
+
+        assert (*ptr == 0);
+        if (ptr_size <= 1)
+            break;
     }
-    snprintf(dest, DATA_MAX_NAME_LEN - reserved, "%s", tmp);
-    offset = strlen(dest);
-    switch (append_status)
+
+    /* Append "Plus" or "Minus" if "+" or "-" has been stripped above. */
+    if (append_plus || append_minus)
     {
-        case 0x1:
-            memcpy(dest + offset, "Minus", 5);
-            break;
-        case 0x2:
-            memcpy(dest + offset, "Plus", 5);
-            break;
-        case 0x4:
-            memcpy(dest + offset, len_str, 2);
-            break;
-        case 0x5:
-            memcpy(dest + offset, "Minus", 5);
-            memcpy(dest + offset + 5, len_str, 2);
-            break;
-        case 0x6:
-            memcpy(dest + offset, "Plus", 4);
-            memcpy(dest + offset + 4, len_str, 2);
-            break;
-        default:
-            break;
+        char const *append = "Plus";
+        if (append_minus)
+            append = "Minus";
+
+        size_t offset = buffer_size - (strlen (append) + 1);
+        if (offset > strlen (buffer))
+            offset = strlen (buffer);
+
+        sstrncpy (buffer + offset, append, buffer_size - offset);
     }
+
+    sfree (src_copy);
+    return 0;
+}
+
+static _Bool has_suffix (char const *str, char const *suffix)
+{
+    size_t str_len = strlen (str);
+    size_t suffix_len = strlen (suffix);
+    size_t offset;
+
+    if (suffix_len > str_len)
+        return 0;
+    offset = str_len - suffix_len;
+
+    if (strcmp (str + offset, suffix) == 0)
+        return 1;
+
+    return 0;
+}
+
+/* count_parts returns the number of elements a "foo.bar.baz" style key has. */
+static size_t count_parts (char const *key)
+{
+    char const *ptr;
+    size_t parts_num = 0;
+
+    for (ptr = key; ptr != NULL; ptr = strchr (ptr + 1, '.'))
+        parts_num++;
+
+    return parts_num;
 }
 
 /**
  * Parse key to remove "type" if this is for schema and initiate compaction
  */
-static int parse_keys(const char *key_str, char *ds_name)
+static int parse_keys (char *buffer, size_t buffer_size, const char *key_str)
 {
-    char *ptr, *rptr;
-    size_t ds_name_len = 0;
-    /**
-     * allow up to 100 characters before compaction - compact_ds_name will not
-     * allow more than DATA_MAX_NAME_LEN chars
-     */
-    int max_str_len = 100;
-    char tmp_ds_name[max_str_len];
-    memset(tmp_ds_name, 0, sizeof(tmp_ds_name));
-    if(ds_name == NULL || key_str == NULL ||  key_str[0] == '\0' ||
-                                                            ds_name[0] != '\0')
-    {
-        return -1;
-    }
-    if((ptr = strchr(key_str, '.')) == NULL
-            || (rptr = strrchr(key_str, '.')) == NULL)
+    char tmp[2 * buffer_size];
+
+    if (buffer == NULL || buffer_size == 0 || key_str == NULL || strlen (key_str) == 0)
+        return EINVAL;
+
+    if ((count_parts (key_str) > 2) && has_suffix (key_str, ".type"))
     {
-        memcpy(tmp_ds_name, key_str, max_str_len - 1);
-        goto compact;
-    }
+        /* strip ".type" suffix iff the key has more than two parts. */
+        size_t sz = strlen (key_str) - strlen (".type") + 1;
 
-    ds_name_len = (rptr - ptr) > max_str_len ? max_str_len : (rptr - ptr);
-    if((ds_name_len == 0) || strncmp(rptr + 1, "type", 4))
-    { /** copy whole key **/
-        memcpy(tmp_ds_name, key_str, max_str_len - 1);
+        if (sz > sizeof (tmp))
+            sz = sizeof (tmp);
+        sstrncpy (tmp, key_str, sz);
     }
     else
-    {/** more than two keys **/
-        memcpy(tmp_ds_name, key_str, ((rptr - key_str) > (max_str_len - 1) ?
-                (max_str_len - 1) : (rptr - key_str)));
+    {
+        sstrncpy (tmp, key_str, sizeof (tmp));
     }
 
-    compact: compact_ds_name(tmp_ds_name, ds_name);
-    return 0;
+    return compact_ds_name (buffer, buffer_size, tmp);
 }
 
 /**
@@ -594,7 +623,7 @@ static int ceph_daemon_add_ds_entry(struct ceph_daemon *d, const char *name,
         return -ENOMEM;
     }
 
-    d->ds_names[d->ds_num] = malloc(sizeof(char) * DATA_MAX_NAME_LEN);
+    d->ds_names[d->ds_num] = malloc(DATA_MAX_NAME_LEN);
     if(!d->ds_names[d->ds_num])
     {
         return -ENOMEM;
@@ -604,7 +633,7 @@ static int ceph_daemon_add_ds_entry(struct ceph_daemon *d, const char *name,
             ((pc_type & PERFCOUNTER_LATENCY) ? DSET_LATENCY : DSET_BYTES);
     d->ds_types[d->ds_num] = type;
 
-    if(parse_keys(name, ds_name))
+    if (parse_keys(ds_name, sizeof (ds_name), name))
     {
         return 1;
     }
@@ -718,7 +747,7 @@ static int cc_add_daemon_config(oconfig_item_t *ci)
     }
     g_daemons = tmp;
 
-    nd = malloc(sizeof(*nd));
+    nd = malloc(sizeof (*nd));
     if(!nd)
     {
         return ENOMEM;
@@ -816,7 +845,7 @@ node_handler_define_schema(void *arg, const char *val, const char *key)
 static int add_last(struct ceph_daemon *d, const char *ds_n, double cur_sum,
         uint64_t cur_count)
 {
-    d->last_poll_data[d->last_idx] = malloc(1 * sizeof(struct last_data));
+    d->last_poll_data[d->last_idx] = malloc(sizeof (*d->last_poll_data[d->last_idx]));
     if(!d->last_poll_data[d->last_idx])
     {
         return -ENOMEM;
@@ -844,7 +873,7 @@ static int update_last(struct ceph_daemon *d, const char *ds_n, int index,
 
     if(!d->last_poll_data)
     {
-        d->last_poll_data = malloc(1 * sizeof(struct last_data *));
+        d->last_poll_data = malloc(sizeof (*d->last_poll_data));
         if(!d->last_poll_data)
         {
             return -ENOMEM;
@@ -956,7 +985,7 @@ static int node_handler_fetch_data(void *arg, const char *val, const char *key)
     char ds_name[DATA_MAX_NAME_LEN];
     memset(ds_name, 0, sizeof(ds_name));
 
-    if(parse_keys(key, ds_name))
+    if (parse_keys (ds_name, sizeof (ds_name), key))
     {
         return 1;
     }
@@ -1067,7 +1096,7 @@ static int cconn_connect(struct cconn *io)
     fd = socket(PF_UNIX, SOCK_STREAM, 0);
     if(fd < 0)
     {
-        int err = -errno;
+        err = -errno;
         ERROR("ceph plugin: cconn_connect: socket(PF_UNIX, SOCK_STREAM, 0) "
             "failed: error %d", err);
         return err;
@@ -1082,6 +1111,7 @@ static int cconn_connect(struct cconn *io)
     {
         ERROR("ceph plugin: cconn_connect: connect(%d) failed: error %d",
             fd, err);
+        close(fd);
         return err;
     }
 
@@ -1091,6 +1121,7 @@ static int cconn_connect(struct cconn *io)
         err = -errno;
         ERROR("ceph plugin: cconn_connect: fcntl(%d, O_NONBLOCK) error %d",
             fd, err);
+        close(fd);
         return err;
     }
     io->asok = fd;
@@ -1514,7 +1545,7 @@ static int cconn_main_loop(uint32_t request_type)
             }
             else
             {
-                int ret = cconn_handle_event(io);
+                ret = cconn_handle_event(io);
                 if(ret)
                 {
                     WARNING("ceph plugin: cconn_handle_event(name=%s,"
@@ -1578,3 +1609,4 @@ void module_register(void)
     plugin_register_read("ceph", ceph_read);
     plugin_register_shutdown("ceph", ceph_shutdown);
 }
+/* vim: set sw=4 sts=4 et : */
diff --git a/src/ceph_test.c b/src/ceph_test.c
new file mode 100644 (file)
index 0000000..1141140
--- /dev/null
@@ -0,0 +1,188 @@
+/**
+ * collectd - src/ceph_test.c
+ * Copyright (C) 2015      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
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "ceph.c" /* sic */
+#include "testing.h"
+
+struct case_s
+{
+  const char *key;
+  const char *value;
+};
+typedef struct case_s case_t;
+
+struct test_s
+{
+  case_t *cases;
+  size_t  cases_num;
+};
+typedef struct test_s test_t;
+
+static int test_handler(void *user, char const *val, char const *key)
+{
+  test_t *t = user;
+  size_t i;
+
+  char status[1024];
+  _Bool ok;
+
+  /* special case for latency metrics. */
+  if (strcmp ("filestore.example_latency", key) == 0)
+    return RETRY_AVGCOUNT;
+
+  snprintf (status, sizeof (status), "unexpected call: test_handler(\"%s\") = \"%s\"", key, val);
+  ok = 0;
+
+  for (i = 0; i < t->cases_num; i++)
+  {
+    if (strcmp (key, t->cases[i].key) != 0)
+      continue;
+
+    if (strcmp (val, t->cases[i].value) != 0)
+    {
+      snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\", want \"%s\"", key, val, t->cases[i].value);
+      ok = 0;
+      break;
+    }
+
+    snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\"", key, val);
+    ok = 1;
+    break;
+  }
+
+  OK1(ok, status);
+  return ok ? 0 : -1;
+}
+
+DEF_TEST(traverse_json)
+{
+  char const *json = "{\n"
+      "    \"WBThrottle\": {\n"
+      "        \"bytes_dirtied\": {\n"
+      "            \"type\": 2,\n"
+      "            \"description\": \"Dirty data\",\n"
+      "            \"nick\": \"\"\n"
+      "        },\n"
+      "        \"bytes_wb\": {\n"
+      "            \"type\": 2,\n"
+      "            \"description\": \"Written data\",\n"
+      "            \"nick\": \"\"\n"
+      "        },\n"
+      "        \"ios_dirtied\": {\n"
+      "            \"type\": 2,\n"
+      "            \"description\": \"Dirty operations\",\n"
+      "            \"nick\": \"\"\n"
+      "        },\n"
+      "        \"ios_wb\": {\n"
+      "            \"type\": 2,\n"
+      "            \"description\": \"Written operations\",\n"
+      "            \"nick\": \"\"\n"
+      "        },\n"
+      "        \"inodes_dirtied\": {\n"
+      "            \"type\": 2,\n"
+      "            \"description\": \"Entries waiting for write\",\n"
+      "            \"nick\": \"\"\n"
+      "        },\n"
+      "        \"inodes_wb\": {\n"
+      "            \"type\": 10,\n"
+      "            \"description\": \"Written entries\",\n"
+      "            \"nick\": \"\"\n"
+      "        }\n"
+      "    },\n"
+      "    \"filestore\": {\n"
+      "        \"journal_wr_bytes\": {\n"
+      "            \"avgcount\": 23,\n"
+      "            \"sum\": 3117\n"
+      "        },\n"
+      "        \"example_latency\": {\n"
+      "            \"avgcount\": 42,\n"
+      "            \"sum\": 4711\n"
+      "        }\n"
+      "    }\n"
+      "}\n";
+  case_t cases[] = {
+    {"WBThrottle.bytes_dirtied.type", "2"},
+    {"WBThrottle.bytes_wb.type", "2"},
+    {"WBThrottle.ios_dirtied.type", "2"},
+    {"WBThrottle.ios_wb.type", "2"},
+    {"WBThrottle.inodes_dirtied.type", "2"},
+    {"WBThrottle.inodes_wb.type", "10"},
+    {"filestore.journal_wr_bytes", "3117"},
+    {"filestore.example_latency.avgcount", "42"},
+    {"filestore.example_latency.sum", "4711"},
+  };
+  test_t t = {cases, STATIC_ARRAY_SIZE (cases)};
+
+  yajl_struct ctx = {test_handler, &t};
+
+  yajl_handle hndl;
+#if HAVE_YAJL_V2
+  hndl = yajl_alloc (&callbacks, NULL, &ctx);
+  CHECK_ZERO (traverse_json ((const unsigned char *) json, (uint32_t) strlen (json), hndl));
+  CHECK_ZERO (yajl_complete_parse (hndl));
+#else
+  hndl = yajl_alloc (&callbacks, NULL, NULL, &ctx);
+  CHECK_ZERO (traverse_json ((const unsigned char *) json, (uint32_t) strlen (json), hndl));
+  CHECK_ZERO (yajl_parse_complete (hndl));
+#endif
+
+  return 0;
+}
+
+DEF_TEST(parse_keys)
+{
+  struct {
+    const char *str;
+    const char *want;
+  } cases[] = {
+    {"WBThrottle.bytes_dirtied.description.bytes_wb.description.ios_dirtied.description.ios_wb.type", "WBThrottle.bytesDirtied.description.bytesWb.description.iosDirt"},
+    {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
+    {"foo:bar", "FooBar"},
+    {"foo:bar+", "FooBarPlus"},
+    {"foo:bar-", "FooBarMinus"},
+    {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+", "AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPlus"},
+    {"aa.bb.cc.dd.ee.ff", "Aa.bb.cc.dd.ee.ff"},
+    {"aa.bb.cc.dd.ee.ff.type", "Aa.bb.cc.dd.ee.ff"},
+    {"aa.type", "Aa.type"},
+    {"WBThrottle.bytes_dirtied.type", "WBThrottle.bytesDirtied"},
+  };
+  size_t i;
+
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  {
+    char got[DATA_MAX_NAME_LEN];
+
+    CHECK_ZERO (parse_keys (got, sizeof (got), cases[i].str));
+    EXPECT_EQ_STR (cases[i].want, got);
+  }
+
+  return 0;
+}
+
+int main (void)
+{
+  RUN_TEST(traverse_json);
+  RUN_TEST(parse_keys);
+
+  END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
index 10f9f61..654db40 100644 (file)
@@ -17,7 +17,7 @@ collectd-exec - Documentation of collectd's C<exec plugin>
 
 =head1 DESCRIPTION
 
-The C<exec plugin> forks of an executable either to receive values or to
+The C<exec plugin> forks off an executable either to receive values or to
 dispatch notifications to the outside world. The syntax of the configuration is
 explained in L<collectd.conf(5)> but summarized in the above synopsis.
 
@@ -42,7 +42,7 @@ time and continuously write values to C<STDOUT>.
 See L<EXEC DATA FORMAT> below for a description of the output format expected
 from these programs.
 
-B<Warning:> If the executable only writes one value and then exits I will be
+B<Warning:> If the executable only writes one value and then exits it will be
 executed every I<Interval> seconds. If I<Interval> is short (the default is 10
 seconds) this may result in serious system load.
 
@@ -94,7 +94,7 @@ I<Valuelist> is a colon-separated list of the time and the values, each either
 an integer if the data-source is a counter, or a double if the data-source is
 of type "gauge". You can submit an undefined gauge-value by using B<U>. When
 submitting B<U> to a counter the behavior is undefined. The time is given as
-epoch (i.E<nbsp>e. standard UNIX time).
+epoch (i.E<nbsp>e. standard UNIX time) or B<N> to use the current time.
 
 You can mix options and values, but the order is important: Options only
 effect following values, so specifying an option as last field is allowed, but
index aade08a..afa7e48 100644 (file)
@@ -620,6 +620,11 @@ sets the type instance instead. I<(optional)>
 Works like the option of the same name directly beneath the I<MBean> block, but
 sets the type instance instead. I<(optional)>
 
+=item B<PluginName> I<name>
+
+When set, overrides the default setting for the I<plugin> field
+(C<GenericJMX>).
+
 =item B<Table> B<true>|B<false>
 
 Set this to true if the returned attribute is a I<composite type>. If set to
index b17e47e..fe56d5d 100644 (file)
@@ -136,14 +136,14 @@ static int filter_ds (size_t *values_num,
        new_values = (gauge_t *)calloc (match_ds_num_g, sizeof (*new_values));
        if (new_values == NULL)
        {
-               fprintf (stderr, "malloc failed: %s\n", strerror (errno));
+               fprintf (stderr, "calloc failed: %s\n", strerror (errno));
                return (RET_UNKNOWN);
        }
 
        new_names = (char **)calloc (match_ds_num_g, sizeof (*new_names));
        if (new_names == NULL)
        {
-               fprintf (stderr, "malloc failed: %s\n", strerror (errno));
+               fprintf (stderr, "calloc failed: %s\n", strerror (errno));
                free (new_values);
                return (RET_UNKNOWN);
        }
@@ -245,6 +245,7 @@ static int match_range (range_t *range, double value)
        return (((ret - range->invert) == 0) ? 0 : 1);
 } /* int match_range */
 
+__attribute__((noreturn))
 static void usage (const char *name)
 {
        fprintf (stderr, "Usage: %s <-s socket> <-n value_spec> <-H hostname> [options]\n"
@@ -693,7 +694,7 @@ int main (int argc, char **argv)
                        case 'd':
                        {
                                char **tmp;
-                               tmp = (char **) realloc (match_ds_g,
+                               tmp = realloc (match_ds_g,
                                                (match_ds_num_g + 1)
                                                * sizeof (char *));
                                if (tmp == NULL)
index 9bd65bc..23257fd 100644 (file)
@@ -156,13 +156,12 @@ static lcc_value_list_t *create_value_list (void) /* {{{ */
   lcc_value_list_t *vl;
   int host_num;
 
-  vl = malloc (sizeof (*vl));
+  vl = calloc (1, sizeof (*vl));
   if (vl == NULL)
   {
-    fprintf (stderr, "malloc failed.\n");
+    fprintf (stderr, "calloc failed.\n");
     return (NULL);
   }
-  memset (vl, 0, sizeof (*vl));
 
   vl->values = calloc (/* nmemb = */ 1, sizeof (*vl->values));
   if (vl->values == NULL)
@@ -201,6 +200,7 @@ static lcc_value_list_t *create_value_list (void) /* {{{ */
   strncpy (vl->identifier.type,
       (vl->values_types[0] == LCC_TYPE_GAUGE) ? "gauge" : "derive",
       sizeof (vl->identifier.type));
+  vl->identifier.type[sizeof (vl->identifier.type) - 1] = 0;
   snprintf (vl->identifier.type_instance, sizeof (vl->identifier.type_instance),
       "ti%li", random ());
 
@@ -367,7 +367,7 @@ int main (int argc, char **argv) /* {{{ */
   else
   {
     lcc_server_t *srv;
-    
+
     srv = lcc_server_create (net, conf_destination, conf_service);
     if (srv == NULL)
     {
index 1f4ccf8..80a7db9 100644 (file)
@@ -84,7 +84,7 @@
 # Lines beginning with a single `#' belong to plugins which have been built  #
 # but are disabled by default.                                               #
 #                                                                            #
-# Lines begnning with `##' belong to plugins which have not been built due   #
+# Lines beginning with `##' belong to plugins which have not been built due  #
 # to missing dependencies or because they have been deactivated explicitly.  #
 ##############################################################################
 
 #@BUILD_PLUGIN_NGINX_TRUE@LoadPlugin nginx
 #@BUILD_PLUGIN_NOTIFY_DESKTOP_TRUE@LoadPlugin notify_desktop
 #@BUILD_PLUGIN_NOTIFY_EMAIL_TRUE@LoadPlugin notify_email
+#@BUILD_PLUGIN_NOTIFY_NAGIOS_TRUE@LoadPlugin notify_nagios
 #@BUILD_PLUGIN_NTPD_TRUE@LoadPlugin ntpd
 #@BUILD_PLUGIN_NUMA_TRUE@LoadPlugin numa
 #@BUILD_PLUGIN_NUT_TRUE@LoadPlugin nut
 #@BUILD_PLUGIN_WRITE_RIEMANN_TRUE@LoadPlugin write_riemann
 #@BUILD_PLUGIN_WRITE_SENSU_TRUE@LoadPlugin write_sensu
 #@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb
+#@BUILD_PLUGIN_XENCPU_TRUE@LoadPlugin xencpu
 #@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
 #@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc
 #@BUILD_PLUGIN_ZONE_TRUE@LoadPlugin zone
 
 #<Plugin "battery">
 #  ValuesPercentage false
-#  ReportDegraded
+#  ReportDegraded false
 #</Plugin>
 
 #<Plugin "bind">
 #      FSType "ext3"
 #      IgnoreSelected false
 #      ReportByDevice false
-#      ReportReserved false
 #      ReportInodes false
 #      ValuesAbsolute true
 #      ValuesPercentage false
 #<Plugin interface>
 #      Interface "eth0"
 #      IgnoreSelected false
+#      UniqueName false
 #</Plugin>
 
 #<Plugin ipmi>
 
 #<Plugin iptables>
 #      Chain table chain
+#      Chain6 table chain
 #</Plugin>
 
 #<Plugin irq>
 #              Prefix "collectd"
 #              StoreRates true
 #              Retain false
+#              CACert "/etc/ssl/ca.crt"
+#              CertificateFile "/etc/ssl/client.crt"
+#              CertificateKeyFile "/etc/ssl/client.pem"
+#              TLSProtocol "tlsv1.2"
+#              CipherSuite "ciphers"
 #      </Publish>
 #      <Subscribe "name">
 #              Host "localhost"
 #      Recipient "email2@domain2.com"
 #</Plugin>
 
+#<Plugin notify_nagios>
+#      CommandFile "/usr/local/nagios/var/rw/nagios.cmd"
+#</Plugin>
+
 #<Plugin ntpd>
 #      Host "localhost"
 #      Port 123
 #  DeleteTimers   false
 #  DeleteGauges   false
 #  DeleteSets     false
+#  CounterSum     false
 #  TimerPercentile 90.0
 #  TimerPercentile 95.0
 #  TimerPercentile 99.0
 ##     None of the following option should be set manually
 ##     This plugin automatically detect most optimal options
 ##     Only set values here if:
-##     - The module ask you to
+##     - The module asks you to
 ##     - You want to disable the collection of some data
-##     - Your (intel) CPU is not supported (yet) by the module
-##     - The module generate a lot of errors 'MSR offset 0x... read failed'
+##     - Your (Intel) CPU is not supported (yet) by the module
+##     - The module generates a lot of errors 'MSR offset 0x... read failed'
 ##     In the last two cases, please open a bug request
 #
 #      TCCActivationTemp "100"
 #    Host "localhost"
 #    Port "2003"
 #    Protocol "tcp"
+#    ReconnectInterval 0
 #    LogSendErrors true
 #    Prefix "collectd"
 #    Postfix "collectd"
 #              ClientKey "/etc/ssl/client.pem"
 #              ClientCert "/etc/ssl/client.crt"
 #              ClientKeyPass "secret"
+#              Header "X-Custom-Header: custom_value"
 #              SSLVersion "TLSv1"
 #              Format "Command"
 #              StoreRates false
index 48de6f9..0853fff 100644 (file)
@@ -38,7 +38,7 @@ i.e. a C<E<lt>PluginE<nbsp>...E<gt>> block.
 The syntax of this config file is similar to the config file of the famous
 I<Apache> webserver. Each line contains either an option (a key and a list of
 one or more values) or a section-start or -end. Empty lines and everything
-after a non-quoted hash-symbol (C<#>) is ignored. I<Keys> are unquoted
+after a non-quoted hash-symbol (C<#>) are ignored. I<Keys> are unquoted
 strings, consisting only of alphanumeric characters and the underscore (C<_>)
 character. Keys are handled case insensitive by I<collectd> itself and all
 plugins included with it. I<Values> can either be an I<unquoted string>, a
@@ -70,7 +70,7 @@ C<E<lt>B<Plugin> ...E<gt>> block.
 
 =item B<BaseDir> I<Directory>
 
-Sets the base directory. This is the directory beneath all RRD-files are
+Sets the base directory. This is the directory beneath which all RRD-files are
 created. Possibly more subdirectories are created. This is also the working
 directory for the daemon.
 
@@ -83,7 +83,7 @@ I<collectd> will be mostly useless.
 Only the first B<LoadPlugin> statement or block for a given plugin name has any
 effect. This is useful when you want to split up the configuration into smaller
 files and want each file to be "self contained", i.e. it contains a B<Plugin>
-block I<and> then appropriate B<LoadPlugin> statement. The downside is that if
+block I<and> the appropriate B<LoadPlugin> statement. The downside is that if
 you have multiple conflicting B<LoadPlugin> blocks, e.g. when they specify
 different intervals, only one of them (the first one encountered) will take
 effect and all others will be silently ignored.
@@ -127,13 +127,13 @@ the average user from ever having to deal with this low level linking stuff.
 =item B<Interval> I<Seconds>
 
 Sets a plugin-specific interval for collecting metrics. This overrides the
-global B<Interval> setting. If a plugin provides own support for specifying an
-interval, that setting will take precedence.
+global B<Interval> setting. If a plugin provides its own support for specifying
+an interval, that setting will take precedence.
 
 =item B<FlushInterval> I<Seconds>
 
-Specifies the the interval, in seconds, to call the flush callback if it's
-defined in this plugin. By default, this is disabled
+Specifies the interval, in seconds, to call the flush callback if it's
+defined in this plugin. By default, this is disabled.
 
 =item B<FlushTimeout> I<Seconds>
 
@@ -159,12 +159,27 @@ plugins that don't provide any configuration, e.g. the I<Load plugin>.
 When set to B<true>, various statistics about the I<collectd> daemon will be
 collected, with "collectd" as the I<plugin name>. Defaults to B<false>.
 
-The "write_queue" I<plugin instance> reports the number of elements currently
-queued and the number of elements dropped off the queue by the
-B<WriteQueueLimitLow>/B<WriteQueueLimitHigh> mechanism.
+The following metrics are reported:
 
-The "cache" I<plugin instance> reports the number of elements in the value list
-cache (the cache you can interact with using L<collectd-unixsock(5)>).
+=over 4
+
+=item C<collectd-write_queue/queue_length>
+
+The number of metrics currently in the write queue. You can limit the queue
+length with the B<WriteQueueLimitLow> and B<WriteQueueLimitHigh> options.
+
+=item C<collectd-write_queue/derive-dropped>
+
+The number of metrics dropped due to a queue length limitation.
+If this value is non-zero, your system can't handle all incoming metrics and
+protects itself against overload by dropping metrics.
+
+=item C<collectd-cache/cache_size>
+
+The number of elements in the metric cache (the cache you can interact with
+using L<collectd-unixsock(5)>).
+
+=back
 
 =item B<Include> I<Path> [I<pattern>]
 
@@ -193,13 +208,11 @@ I<pattern> may be specified to filter which files to include. This may be used
 in combination with recursively including a directory to easily be able to
 arbitrarily mix configuration files and other documents (e.g. README files).
 The given example is similar to the first example above but includes all files
-matching C<*.conf> in any subdirectory of C</etc/collectd.d>:
-
-  Include "/etc/collectd.d" "*.conf"
+matching C<*.conf> in any subdirectory of C</etc/collectd.d>.
 
 =back
 
-If more than one files are included by a single B<Include> option, the files
+If more than one file is included by a single B<Include> option, the files
 will be included in lexicographical order (as defined by the C<strcmp>
 function). Thus, you can e.E<nbsp>g. use numbered prefixes to specify the
 order in which the files are loaded.
@@ -240,7 +253,7 @@ magic! (Assuming you're using the I<RRDtool> or I<RRDCacheD> plugin.)
 
 =item B<MaxReadInterval> I<Seconds>
 
-Read plugin doubles interval between queries after each failed attempt
+A read plugin doubles the interval between queries after each failed attempt
 to get data.
 
 This options limits the maximum value of the interval. The default value is
@@ -821,13 +834,15 @@ default for backwards compatibility, the time will be reported in minutes.
 
 =item B<PersistentConnection> B<true>|B<false>
 
-By default, the plugin will try to keep the connection to UPS open between
-reads. Since this appears to be somewhat brittle (I<apcupsd> appears to close
-the connection due to inactivity quite quickly), the plugin will try to detect
-this problem and switch to an open-read-close mode in such cases.
+The plugin is designed to keep the connection to I<apcupsd> open between reads.
+If plugin poll interval is greater than 15 seconds (hardcoded socket close
+timeout in I<apcupsd> NIS), then this option is B<false> by default.
 
 You can instruct the plugin to close the connection after each read by setting
-this option to B<false>.
+this option to B<false> or force keeping the connection by setting it to B<true>.
+
+If I<apcupsd> appears to close the connection due to inactivity quite quickly,
+the plugin will try to detect this problem and switch to an open-read-close mode.
 
 =back
 
@@ -2516,7 +2531,7 @@ a more detailed description see B<IgnoreSelected> below.
 
 =item B<IgnoreSelected> I<true>|I<false>
 
-If no configuration if given, the B<traffic>-plugin will collect data from
+If no configuration if given, the B<interface>-plugin will collect data from
 all interfaces. This may not be practical, especially for loopback- and
 similar interfaces. Thus, you can use the B<Interface>-option to pick the
 interfaces you're interested in. Sometimes, however, it's easier/preferred
@@ -2525,6 +2540,34 @@ do that: By setting B<IgnoreSelected> to I<true> the effect of
 B<Interface> is inverted: All selected interfaces are ignored and all
 other interfaces are collected.
 
+It is possible to use regular expressions to match interface names, if the
+name is surrounded by I</.../> and collectd was compiled with support for
+regexps. This is useful if there's a need to collect (or ignore) data
+for a group of interfaces that are similarly named, without the need to
+explicitly list all of them (especially useful if the list is dynamic).
+Example:
+
+ Interface "lo"
+ Interface "/^veth/"
+ Interface "/^tun[0-9]+/"
+ IgnoreSelected "true"
+
+This will ignore the loopback interface, all interfaces with names starting
+with I<veth> and all interfaces with names starting with I<tun> followed by
+at least one digit.
+
+
+=item B<UniqueName> I<true>|I<false>
+
+Interface name is not unique on Solaris (KSTAT), interface name is unique
+only within a module/instance. Following tuple is considered unique:
+   (ks_module, ks_instance, ks_name)
+If this option is set to true, interface name contains above three fields
+separated by an underscore. For more info on KSTAT, visit
+L<http://docs.oracle.com/cd/E23824_01/html/821-1468/kstat-3kstat.html#REFMAN3Ekstat-3kstat>
+
+This option is only available on Solaris.
+
 =back
 
 =head2 Plugin C<ipmi>
@@ -2565,9 +2608,13 @@ a notification is sent.
 
 =item B<Chain> I<Table> I<Chain> [I<Comment|Number> [I<Name>]]
 
-Select the rules to count. If only I<Table> and I<Chain> are given, this plugin
-will collect the counters of all rules which have a comment-match. The comment
-is then used as type-instance.
+=item B<Chain6> I<Table> I<Chain> [I<Comment|Number> [I<Name>]]
+
+Select the iptables/ip6tables filter rules to count packets and bytes from.
+
+If only I<Table> and I<Chain> are given, this plugin will collect the counters
+of all rules which have a comment-match. The comment is then used as
+type-instance.
 
 If I<Comment> or I<Number> is given, only the rule with the matching comment or
 the I<n>th rule will be collected. Again, the comment (or the number) will be
@@ -3347,6 +3394,38 @@ Configures the topic(s) to subscribe to. You can use the single level C<+> and
 multi level C<#> wildcards. Defaults to B<collectd/#>, i.e. all topics beneath
 the B<collectd> branch.
 
+=item B<CACert> I<file>
+
+Path to the PEM-encoded CA certificate file. Setting this option enables TLS
+communication with the MQTT broker, and as such, B<Port> should be the TLS-enabled
+port of the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateFile> I<file>
+
+Path to the PEM-encoded certificate file to use as client certificate when
+connecting to the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateKeyFile> I<file>
+
+Path to the unencrypted PEM-encoded key file corresponding to B<CertificateFile>.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<TLSProtocol> I<protocol>
+
+If configured, this specifies the string protocol version (e.g. C<tlsv1>,
+C<tlsv1.2>) to use for the TLS connection to the broker. If not set a default
+version is used which depends on the version of OpenSSL the Mosquitto library
+was linked against.
+
+=item B<CipherSuite> I<ciphersuite>
+
+A string describing the ciphers available for use. See L<ciphers(1)> and the
+C<openssl ciphers> utility for more information. If unset, the default ciphers
+will be used.
+
+
 =back
 
 =head2 Plugin C<mysql>
@@ -4404,8 +4483,35 @@ Default: C<Collectd notify: %s@%s>
 
 =back
 
+=head2 Plugin C<notify_nagios>
+
+The I<notify_nagios> plugin writes notifications to Nagios' I<command file> as
+a I<passive service check result>.
+
+Available configuration options:
+
+=over 4
+
+=item B<CommandFile> I<Path>
+
+Sets the I<command file> to write to. Defaults to F</usr/local/nagios/var/rw/nagios.cmd>.
+
+=back
+
 =head2 Plugin C<ntpd>
 
+The C<ntpd> plugin collects per-peer ntpd data such as time offset and time
+dispersion.
+
+For talking to B<ntpd>, it mimics what the B<ntpdc> control program does on
+wire - using B<mode 7> specific requests. This mode is deprecated with
+newer B<ntpd> releases (4.2.7p230 and later). For the C<ntpd> plugin to work
+correctly with them, the ntp daemon must be explicitly configured to
+enable B<mode 7> (which is disabled by default). Refer to the I<ntp.conf(5)>
+manual page for details.
+
+Available configuration options for the C<ntpd> plugin:
+
 =over 4
 
 =item B<Host> I<Hostname>
@@ -4631,12 +4737,12 @@ I<mandatory>.
 
 =item B<BindDN> I<BindDN>
 
-Name in the form of an LDAP distinguished name intended to be used for 
+Name in the form of an LDAP distinguished name intended to be used for
 authentication. Defaults to empty string to establish an anonymous authorization.
 
 =item B<Password> I<Password>
 
-Password for simple bind authentication. If this option is not set, 
+Password for simple bind authentication. If this option is not set,
 unauthenticated bind operation is used.
 
 =item B<StartTLS> B<true|false>
@@ -4911,6 +5017,13 @@ Default: B<0.9>
 
 Sets the Time-To-Live of generated ICMP packets.
 
+=item B<Size> I<size>
+
+Sets the size of the data payload in ICMP packet to specified I<size> (it
+will be filled with regular ASCII pattern). If not set, default 56 byte
+long string is used so that the packet size of an ICMPv4 packet is exactly
+64 bytes, similar to the behaviour of normal ping(1) command.
+
 =item B<SourceAddress> I<host>
 
 Sets the source address to use. I<host> may either be a numerical network
@@ -6038,6 +6151,12 @@ few ones. This option enables you to do that: By setting B<IgnoreSelected> to
 I<true> the effect of B<Sensor> is inverted: All selected sensors are ignored
 and all other sensors are collected.
 
+=item B<UseLabels> I<true>|I<false>
+
+Configures how sensor readings are reported. When set to I<true>, sensor
+readings are reported using their descriptive label (e.g. "VCore"). When set to
+I<false> (the default) the sensor name is used ("in0").
+
 =back
 
 =head2 Plugin C<sigrok>
@@ -6186,6 +6305,12 @@ rate of counters and size of sets will be zero, timers report C<NaN> and gauges
 are unchanged. If set to B<True>, the such metrics are not dispatched and
 removed from the internal cache.
 
+=item B<CounterSum> B<false>|B<true>
+
+When enabled, creates a C<count> metric which reports the change since the last
+read. This option primarily exists for compatibility with the I<statsd>
+implementation by Etsy.
+
 =item B<TimerPercentile> I<Percent>
 
 Calculate and dispatch the configured percentile, i.e. compute the latency, so
@@ -6794,13 +6919,13 @@ fails or if you want to disable this feature.
 =item B<DigitalTemperatureSensor> I<true>|I<false>
 
 Boolean enabling the collection of the temperature of each core.
-This option should only be used if the automated detectionfails or 
+This option should only be used if the automated detectionfails or
 if you want to disable this feature.
 
 =item B<DigitalTemperatureSensor> I<true>|I<false>
 
 Boolean enabling the collection of the temperature of each package.
-This option should only be used if the automated detectionfails or 
+This option should only be used if the automated detectionfails or
 if you want to disable this feature.
 
 =item B<TCCActivationTemp> I<Temperature>
@@ -7225,6 +7350,14 @@ Service name or port number to connect to. Defaults to C<2003>.
 
 Protocol to use when connecting to I<Graphite>. Defaults to C<tcp>.
 
+=item B<ReconnectInterval> I<Seconds>
+
+When set to non-zero, forces the connection to the Graphite backend to be
+closed and re-opend periodically. This behavior is desirable in environments
+where the connection to the Graphite backend is done through load balancers,
+for example. When set to zero, the default, the connetion is kept open for as
+long as possible.
+
 =item B<LogSendErrors> B<false>|B<true>
 
 If set to B<true> (the default), logs errors when sending data to I<Graphite>.
@@ -7451,6 +7584,12 @@ authentication.
 
 Password required to load the private key in B<ClientKey>.
 
+=item B<Header> I<Header>
+
+A HTTP header to add to the request.  Multiple headers are added if this option is specified more than once.  Example:
+
+  Header "X-Custom-Header: custom_value"
+
 =item B<SSLVersion> B<SSLv2>|B<SSLv3>|B<TLSv1>|B<TLSv1_0>|B<TLSv1_1>|B<TLSv1_2>
 
 Define which SSL protocol version must be used. By default C<libcurl> will
@@ -7625,6 +7764,8 @@ Synopsis:
         Timeout 1000
         Prefix "collectd/"
         Database 1
+        MaxSetSize -1
+        StoreRates true
     </Node>
   </Plugin>
 
@@ -7633,7 +7774,7 @@ the timestamp as the score. Retrieving a date range can then be done using the
 C<ZRANGEBYSCORE> I<Redis> command. Additionally, all the identifiers of these
 I<Sorted Sets> are kept in a I<Set> called C<collectd/values> (or
 C<${prefix}/values> if the B<Prefix> option was specified) and can be retrieved
-using the C<SMEMBERS> I<Redis> command. You can specify the database to use 
+using the C<SMEMBERS> I<Redis> command. You can specify the database to use
 with the B<Database> parameter (default is C<0>). See
 L<http://redis.io/commands#sorted_set> and L<http://redis.io/commands#set> for
 details.
@@ -7678,7 +7819,18 @@ is recommended but not required to include a trailing slash in I<Prefix>.
 
 =item B<Database> I<Index>
 
-This index selects the redis database to use for writing operations. Defaults to C<0>.
+This index selects the redis database to use for writing operations. Defaults
+to C<0>.
+
+=item B<MaxSetSize> I<Items>
+
+The B<MaxSetSize> option limits the number of items that the I<Sorted Sets> can
+hold. Negative values for I<Items> sets no limit, which is the default behavior.
+
+=item B<StoreRates> B<true>|B<false>
+
+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
 
@@ -7724,11 +7876,26 @@ Hostname or address to connect to. Defaults to C<localhost>.
 
 Service name or port number to connect to. Defaults to C<5555>.
 
-=item B<Protocol> B<UDP>|B<TCP>
+=item B<Protocol> B<UDP>|B<TCP>|B<TLS>
 
 Specify the protocol to use when communicating with I<Riemann>. Defaults to
 B<TCP>.
 
+=item B<TLSCertFile> I<Path>
+
+When using the B<TLS> protocol, path to a PEM certificate to present
+to remote host.
+
+=item B<TLSCAFile> I<Path>
+
+When using the B<TLS> protocol, path to a PEM CA certificate to
+use to validate the remote hosts's identity.
+
+=item B<TLSKeyFile> I<Path>
+
+When using the B<TLS> protocol, path to a PEM private key associated
+with the certificate defined by B<TLSCertFile>.
+
 =item B<Batch> B<true>|B<false>
 
 If set to B<true> and B<Protocol> is set to B<TCP>,
@@ -7748,6 +7915,11 @@ Defaults to true
 
 Maximum payload size for a riemann packet. Defaults to 8192
 
+=item B<BatchFlushTimeout> I<seconds>
+
+Maximum amount of seconds to wait in between to batch flushes.
+No timeout by default.
+
 =item B<StoreRates> B<true>|B<false>
 
 If set to B<true> (the default), convert counter values to rates. If set to
@@ -7759,7 +7931,7 @@ C<ds_type:derive:rate>.
 
 =item B<AlwaysAppendDS> B<false>|B<true>
 
-If set the B<true>, append the name of the I<Data Source> (DS) to the
+If set to B<true>, append the name of the I<Data Source> (DS) to the
 "service", i.e. the field that, together with the "host" field, uniquely
 identifies a metric in I<Riemann>. If set to B<false> (the default), this is
 only done when there is more than one DS.
@@ -7914,6 +8086,14 @@ attribute for each metric being sent out to I<Sensu>.
 
 =back
 
+=head2 Plugin C<xencpu>
+
+This plugin collects metrics of hardware CPU load for machine running Xen
+hypervisor. Load is calculated from 'idle time' value, provided by Xen.
+Result is reported using the C<percent> type, for each CPU (core).
+
+This plugin doesn't have any options (yet).
+
 =head2 Plugin C<zookeeper>
 
 The I<zookeeper plugin> will collect statistics from a I<Zookeeper> server
@@ -8811,6 +8991,8 @@ Available options:
 
 =item B<TypeInstance> I<String>
 
+=item B<MetaDataSet> I<String> I<String>
+
 Set the appropriate field to the given string. The strings for plugin instance
 and type instance may be empty, the strings for host and plugin may not be
 empty. It's currently not possible to set the type of a value this way.
index febc998..ee11c45 100644 (file)
@@ -72,6 +72,7 @@
 extern char *optarg;
 extern int   optind;
 
+__attribute__((noreturn))
 static void exit_usage (const char *name, int status) {
   fprintf ((status == 0) ? stdout : stderr,
       "Usage: %s [options] <command> [cmd options]\n\n"
@@ -482,7 +483,7 @@ static int putval (lcc_connection_t *c, int argc, char **argv)
 
       values_len = 0;
       value = tmp;
-      while (value != 0) {
+      while (value != NULL) {
         char *dot, *endptr;
 
         tmp = strchr (value, (int)':');
index 33f02b4..13304f2 100644 (file)
 static int loop    = 0;
 static int restart = 0;
 
-static char  *pidfile      = NULL;
-static pid_t  collectd_pid = 0;
+static const char *pidfile      = NULL;
+static pid_t       collectd_pid = 0;
 
-static void exit_usage (char *name)
+__attribute__((noreturn))
+static void exit_usage (const char *name)
 {
        printf ("Usage: %s <options> [-- <collectd options>]\n"
 
@@ -119,6 +120,7 @@ static int pidfile_delete (void)
 static int daemonize (void)
 {
        struct rlimit rl;
+       int dev_null;
 
        pid_t pid = 0;
        int   i   = 0;
@@ -152,26 +154,33 @@ static int daemonize (void)
        for (i = 0; i < (int)rl.rlim_max; ++i)
                close (i);
 
-       errno = 0;
-       if (open ("/dev/null", O_RDWR) != 0) {
-               syslog (LOG_ERR, "Error: couldn't connect STDIN to /dev/null: %s",
-                               strerror (errno));
+       dev_null = open ("/dev/null", O_RDWR);
+       if (dev_null == -1) {
+               syslog (LOG_ERR, "Error: couldn't open /dev/null: %s", strerror (errno));
                return -1;
        }
 
-       errno = 0;
-       if (dup (0) != 1) {
-               syslog (LOG_ERR, "Error: couldn't connect STDOUT to /dev/null: %s",
-                               strerror (errno));
+       if (dup2 (dev_null, STDIN_FILENO) == -1) {
+               close (dev_null);
+               syslog (LOG_ERR, "Error: couldn't connect STDIN to /dev/null: %s", strerror (errno));
                return -1;
        }
 
-       errno = 0;
-       if (dup (0) != 2) {
-               syslog (LOG_ERR, "Error: couldn't connect STDERR to /dev/null: %s",
-                               strerror (errno));
+       if (dup2 (dev_null, STDOUT_FILENO) == -1) {
+               close (dev_null);
+               syslog (LOG_ERR, "Error: couldn't connect STDOUT to /dev/null: %s", strerror (errno));
                return -1;
        }
+
+       if (dup2 (dev_null, STDERR_FILENO) == -1) {
+               close (dev_null);
+               syslog (LOG_ERR, "Error: couldn't connect STDERR to /dev/null: %s", strerror (errno));
+               return -1;
+       }
+
+       if ((dev_null != STDIN_FILENO) && (dev_null != STDOUT_FILENO) && (dev_null != STDERR_FILENO))
+               close (dev_null);
+
        return 0;
 } /* daemonize */
 
index bcaea38..9c432d1 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -221,15 +221,25 @@ static int init (void)
 
        port_host = mach_host_self ();
 
-       /* FIXME: Free `cpu_list' if it's not NULL */
-       if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS)
+       status = host_processors (port_host, &cpu_list, &cpu_list_len);
+       if (status == KERN_INVALID_ARGUMENT)
        {
-               ERROR ("cpu plugin: host_processors returned %i", (int) status);
+               ERROR ("cpu plugin: Don't have a privileged host control port. "
+                               "The most common cause for this problem is "
+                               "that collectd is running without root "
+                               "privileges, which are required to read CPU "
+                               "load information. "
+                               "<https://collectd.org/bugs/22>");
+               cpu_list_len = 0;
+               return (-1);
+       }
+       if (status != KERN_SUCCESS)
+       {
+               ERROR ("cpu plugin: host_processors() failed with status %d.", (int) status);
                cpu_list_len = 0;
                return (-1);
        }
 
-       DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors");
        INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s");
 /* #endif PROCESSOR_CPU_LOAD_INFO */
 
@@ -804,8 +814,7 @@ static int cpu_read (void)
 
        if (pnumcpu != numcpu || perfcpu == NULL)
        {
-               if (perfcpu != NULL)
-                       free(perfcpu);
+               free(perfcpu);
                perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t));
        }
        pnumcpu = numcpu;
index 81e580d..880fa4c 100644 (file)
@@ -21,7 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Sven Trenkel <collectd at semidefinite.de>  
+ *   Sven Trenkel <collectd at semidefinite.de>
  **/
 
 /* Some python versions don't include this by default. */
 } while (0)
 static inline void CPY_STRCAT(PyObject **a, PyObject *b) {
        PyObject *ret;
-       
+
        if (!a || !*a)
                return;
-       
+
        ret = PyUnicode_Concat(*a, b);
        Py_DECREF(*a);
        *a = ret;
@@ -156,7 +156,7 @@ static inline PyObject *cpy_string_to_unicode_or_bytes(const char *buf) {
        return PyBytes_FromString(buf);
 #else
        return PyString_FromString(buf);
-#endif 
+#endif
 }
 
 void cpy_log_exception(const char *context);
index 15494f4..7b513e7 100644 (file)
--- a/src/csv.c
+++ b/src/csv.c
@@ -64,13 +64,16 @@ static int value_list_to_string (char *buffer, int buffer_len,
                                && (ds->ds[i].type != DS_TYPE_GAUGE)
                                && (ds->ds[i].type != DS_TYPE_DERIVE)
                                && (ds->ds[i].type != DS_TYPE_ABSOLUTE))
+               {
+                       sfree (rates);
                        return (-1);
+               }
 
-               if (ds->ds[i].type == DS_TYPE_GAUGE) 
+               if (ds->ds[i].type == DS_TYPE_GAUGE)
                {
                        status = ssnprintf (buffer + offset, buffer_len - offset,
                                        ",%lf", vl->values[i].gauge);
-               } 
+               }
                else if (store_rates != 0)
                {
                        if (rates == NULL)
index 16ae3ab..7f298a2 100644 (file)
@@ -95,7 +95,7 @@ static size_t cc_curl_callback (void *buf, /* {{{ */
   size_t len;
 
   len = size * nmemb;
-  if (len <= 0)
+  if (len == 0)
     return (len);
 
   wp = user_data;
@@ -108,7 +108,7 @@ static size_t cc_curl_callback (void *buf, /* {{{ */
     size_t temp_size;
 
     temp_size = wp->buffer_fill + len + 1;
-    temp = (char *) realloc (wp->buffer, temp_size);
+    temp = realloc (wp->buffer, temp_size);
     if (temp == NULL)
     {
       ERROR ("curl plugin: realloc failed.");
@@ -167,16 +167,19 @@ static void cc_web_page_free (web_page_t *wp) /* {{{ */
 static int cc_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
     oconfig_item_t *ci)
 {
+  struct curl_slist *temp = NULL;
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
     WARNING ("curl plugin: `%s' needs exactly one string argument.", name);
     return (-1);
   }
 
-  *dest = curl_slist_append(*dest, ci->values[0].value.string);
-  if (*dest == NULL)
+  temp = curl_slist_append(*dest, ci->values[0].value.string);
+  if (temp == NULL)
     return (-1);
 
+  *dest = temp;
+
   return (0);
 } /* }}} int cc_config_append_string */
 
@@ -270,13 +273,12 @@ static int cc_config_add_match (web_page_t *page, /* {{{ */
     WARNING ("curl plugin: Ignoring arguments for the `Match' block.");
   }
 
-  match = (web_match_t *) malloc (sizeof (*match));
+  match = calloc (1, sizeof (*match));
   if (match == NULL)
   {
-    ERROR ("curl plugin: malloc failed.");
+    ERROR ("curl plugin: calloc failed.");
     return (-1);
   }
-  memset (match, 0, sizeof (*match));
 
   status = 0;
   for (i = 0; i < ci->children_num; i++)
@@ -388,7 +390,7 @@ static int cc_page_init_curl (web_page_t *wp) /* {{{ */
     if (wp->pass != NULL)
       credentials_size += strlen (wp->pass);
 
-    wp->credentials = (char *) malloc (credentials_size);
+    wp->credentials = malloc (credentials_size);
     if (wp->credentials == NULL)
     {
       ERROR ("curl plugin: malloc failed.");
@@ -436,13 +438,12 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  page = (web_page_t *) malloc (sizeof (*page));
+  page = calloc (1, sizeof (*page));
   if (page == NULL)
   {
-    ERROR ("curl plugin: malloc failed.");
+    ERROR ("curl plugin: calloc failed.");
     return (-1);
   }
-  memset (page, 0, sizeof (*page));
   page->url = NULL;
   page->user = NULL;
   page->pass = NULL;
@@ -542,7 +543,7 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */
     web_page_t *prev;
 
     prev = pages_g;
-    while ((prev != NULL) && (prev->next != NULL))
+    while (prev->next != NULL)
       prev = prev->next;
     prev->next = page;
   }
index 510d9b6..b19730b 100644 (file)
@@ -116,7 +116,7 @@ static size_t cj_curl_callback (void *buf, /* {{{ */
 
   len = size * nmemb;
 
-  if (len <= 0)
+  if (len == 0)
     return (len);
 
   db = user_data;
@@ -131,17 +131,11 @@ static size_t cj_curl_callback (void *buf, /* {{{ */
     return (len);
 #endif
 
-  if (status != yajl_status_ok)
-  {
-    unsigned char *msg =
-      yajl_get_error(db->yajl, /* verbose = */ 1,
-          /* jsonText = */ (unsigned char *) buf, (unsigned int) len);
-    ERROR ("curl_json plugin: yajl_parse failed: %s", msg);
-    yajl_free_error(db->yajl, msg);
-    return (0); /* abort write callback */
-  }
-
-  return (len);
+  unsigned char *msg = yajl_get_error(db->yajl, /* verbose = */ 1,
+        /* jsonText = */ (unsigned char *) buf, (unsigned int) len);
+  ERROR ("curl_json plugin: yajl_parse failed: %s", msg);
+  yajl_free_error(db->yajl, msg);
+  return (0); /* abort write callback */
 } /* }}} size_t cj_curl_callback */
 
 static int cj_get_type (cj_key_t *key)
@@ -452,16 +446,19 @@ static c_avl_tree_t *cj_avl_create(void)
 static int cj_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
     oconfig_item_t *ci)
 {
+  struct curl_slist *temp = NULL;
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
     WARNING ("curl_json plugin: `%s' needs exactly one string argument.", name);
     return (-1);
   }
 
-  *dest = curl_slist_append(*dest, ci->values[0].value.string);
-  if (*dest == NULL)
+  temp = curl_slist_append(*dest, ci->values[0].value.string);
+  if (temp == NULL)
     return (-1);
 
+  *dest = temp;
+
   return (0);
 } /* }}} int cj_config_append_string */
 
@@ -480,13 +477,12 @@ static int cj_config_add_key (cj_t *db, /* {{{ */
     return (-1);
   }
 
-  key = (cj_key_t *) malloc (sizeof (*key));
+  key = calloc (1, sizeof (*key));
   if (key == NULL)
   {
-    ERROR ("curl_json plugin: malloc failed.");
+    ERROR ("curl_json plugin: calloc failed.");
     return (-1);
   }
-  memset (key, 0, sizeof (*key));
   key->magic = CJ_KEY_MAGIC;
 
   if (strcasecmp ("Key", ci->key) == 0)
@@ -525,71 +521,68 @@ static int cj_config_add_key (cj_t *db, /* {{{ */
       break;
   } /* for (i = 0; i < ci->children_num; i++) */
 
-  while (status == 0)
+  if (status != 0)
   {
-    if (key->type == NULL)
-    {
-      WARNING ("curl_json plugin: `Type' missing in `Key' block.");
-      status = -1;
-    }
+    cj_key_free (key);
+    return (-1);
+  }
 
-    break;
-  } /* while (status == 0) */
+  if (key->type == NULL)
+  {
+    WARNING ("curl_json plugin: `Type' missing in `Key' block.");
+    cj_key_free (key);
+    return (-1);
+  }
 
   /* store path in a tree that will match the json map structure, example:
    * "httpd/requests/count",
    * "httpd/requests/current" ->
    * { "httpd": { "requests": { "count": $key, "current": $key } } }
    */
-  if (status == 0)
+  char *ptr;
+  char *name;
+  c_avl_tree_t *tree;
+
+  if (db->tree == NULL)
+    db->tree = cj_avl_create();
+
+  tree = db->tree;
+  ptr = key->path;
+  if (*ptr == '/')
+    ++ptr;
+
+  name = ptr;
+  while ((ptr = strchr (name, '/')) != NULL)
   {
-    char *ptr;
-    char *name;
     char ent[PATH_MAX];
-    c_avl_tree_t *tree;
+    c_avl_tree_t *value;
+    size_t len;
 
-    if (db->tree == NULL)
-      db->tree = cj_avl_create();
+    len = ptr - name;
+    if (len == 0)
+      break;
 
-    tree = db->tree;
-    ptr = key->path;
-    if (*ptr == '/')
-      ++ptr;
+    len = COUCH_MIN(len, sizeof (ent)-1);
+    sstrncpy (ent, name, len+1);
 
-    name = ptr;
-    while (*ptr)
-    {
-      if (*ptr == '/')
-      {
-        c_avl_tree_t *value;
-        size_t len;
-
-        len = ptr-name;
-        if (len == 0)
-          break;
-        len = COUCH_MIN(len, sizeof (ent)-1);
-        sstrncpy (ent, name, len+1);
-
-        if (c_avl_get (tree, ent, (void *) &value) != 0)
-        {
-          value = cj_avl_create ();
-          c_avl_insert (tree, strdup (ent), value);
-        }
-
-        tree = value;
-        name = ptr+1;
-      }
-      ++ptr;
-    }
-    if (*name)
-      c_avl_insert (tree, strdup(name), key);
-    else
+    if (c_avl_get (tree, ent, (void *) &value) != 0)
     {
-      ERROR ("curl_json plugin: invalid key: %s", key->path);
-      status = -1;
+      value = cj_avl_create ();
+      c_avl_insert (tree, strdup (ent), value);
     }
+
+    tree = value;
+    name = ptr + 1;
+  }
+
+  if (strlen (name) == 0)
+  {
+    ERROR ("curl_json plugin: invalid key: %s", key->path);
+    cj_key_free (key);
+    return (-1);
   }
 
+  c_avl_insert (tree, strdup (name), key);
   return (status);
 } /* }}} int cj_config_add_key */
 
@@ -624,7 +617,7 @@ static int cj_init_curl (cj_t *db) /* {{{ */
     if (db->pass != NULL)
       credentials_size += strlen (db->pass);
 
-    db->credentials = (char *) malloc (credentials_size);
+    db->credentials = malloc (credentials_size);
     if (db->credentials == NULL)
     {
       ERROR ("curl_json plugin: malloc failed.");
@@ -676,13 +669,12 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  db = (cj_t *) malloc (sizeof (*db));
+  db = calloc (1, sizeof (*db));
   if (db == NULL)
   {
-    ERROR ("curl_json plugin: malloc failed.");
+    ERROR ("curl_json plugin: calloc failed.");
     return (-1);
   }
-  memset (db, 0, sizeof (*db));
 
   db->timeout = -1;
 
@@ -870,7 +862,7 @@ static void cj_submit (cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
 static int cj_sock_perform (cj_t *db) /* {{{ */
 {
   char errbuf[1024];
-  struct sockaddr_un sa_unix = {};
+  struct sockaddr_un sa_unix = { 0 };
   sa_unix.sun_family = AF_UNIX;
   sstrncpy (sa_unix.sun_path, db->sock, sizeof (sa_unix.sun_path));
 
index 5a1f2ba..0f2b92b 100644 (file)
@@ -114,14 +114,14 @@ static size_t cx_curl_callback (void *buf, /* {{{ */
     return (0);
   }
 
-   if (len <= 0)
+   if (len == 0)
     return (len);
 
   if ((db->buffer_fill + len) >= db->buffer_size)
   {
     char *temp;
 
-    temp = (char *) realloc (db->buffer,
+    temp = realloc (db->buffer,
                     db->buffer_fill + len + 1);
     if (temp == NULL)
     {
@@ -170,7 +170,6 @@ static void cx_list_free (llist_t *list) /* {{{ */
   }
 
   llist_destroy (list);
-  list = NULL;
 } /* }}} void cx_list_free */
 
 static void cx_free (void *arg) /* {{{ */
@@ -217,16 +216,19 @@ static void cx_free (void *arg) /* {{{ */
 static int cx_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
     oconfig_item_t *ci)
 {
+  struct curl_slist *temp = NULL;
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
     WARNING ("curl_xml plugin: `%s' needs exactly one string argument.", name);
     return (-1);
   }
 
-  *dest = curl_slist_append(*dest, ci->values[0].value.string);
-  if (*dest == NULL)
+  temp = curl_slist_append(*dest, ci->values[0].value.string);
+  if (temp == NULL)
     return (-1);
 
+  *dest = temp;
+
   return (0);
 } /* }}} int cx_config_append_string */
 
@@ -248,7 +250,7 @@ static int cx_check_type (const data_set_t *ds, cx_xpath_t *xpath) /* {{{ */
   return (0);
 } /* }}} cx_check_type */
 
-static xmlXPathObjectPtr cx_evaluate_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */ 
+static xmlXPathObjectPtr cx_evaluate_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
            xmlChar *expr)
 {
   xmlXPathObjectPtr xpath_obj;
@@ -315,7 +317,7 @@ static int cx_handle_single_value_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
   {
     WARNING ("curl_xml plugin: "
         "relative xpath expression \"%s\" is expected to return "
-        "only text/attribute node which is not the case. Skipping...", 
+        "only text/attribute node which is not the case. Skipping...",
         xpath->values[index].path);
     xmlXPathFreeObject (values_node_obj);
     return (-1);
@@ -336,7 +338,7 @@ static int cx_handle_single_value_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
       vl->values[index].absolute = (absolute_t) strtoull (node_value,
           /* endptr = */ NULL, /* base = */ 0);
       break;
-    case DS_TYPE_GAUGE: 
+    case DS_TYPE_GAUGE:
       vl->values[index].gauge = (gauge_t) strtod (node_value,
           /* endptr = */ NULL);
   }
@@ -472,7 +474,7 @@ static int cx_handle_instance_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
 
 static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
     char const *host,
-    xmlXPathContextPtr xpath_ctx, const data_set_t *ds, 
+    xmlXPathContextPtr xpath_ctx, const data_set_t *ds,
     char *base_xpath, cx_xpath_t *xpath)
 {
   int total_nodes;
@@ -483,7 +485,7 @@ static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
 
   value_list_t vl = VALUE_LIST_INIT;
 
-  base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath); 
+  base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath);
   if (base_node_obj == NULL)
     return -1; /* error is logged already */
 
@@ -500,7 +502,7 @@ static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
   }
 
   /* If base_xpath returned multiple results, then */
-  /* Instance in the xpath block is required */ 
+  /* Instance in the xpath block is required */
   if (total_nodes > 1 && xpath->instance == NULL)
   {
     ERROR ("curl_xml plugin: "
@@ -515,7 +517,7 @@ static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
   sstrncpy (vl.plugin, "curl_xml", sizeof (vl.plugin));
   sstrncpy (vl.host, (host != NULL) ? host : hostname_g, sizeof (vl.host));
   if (plugin_instance != NULL)
-    sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); 
+    sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
 
   for (i = 0; i < total_nodes; i++)
   {
@@ -534,19 +536,19 @@ static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
   } /* for (i = 0; i < total_nodes; i++) */
 
   /* free up the allocated memory */
-  xmlXPathFreeObject (base_node_obj); 
+  xmlXPathFreeObject (base_node_obj);
 
-  return (0); 
+  return (0);
 } /* }}} cx_handle_base_xpath */
 
-static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */ 
+static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */
                        xmlXPathContextPtr xpath_ctx, cx_t *db)
 {
   llentry_t *le;
   const data_set_t *ds;
   cx_xpath_t *xpath;
   int status=-1;
-  
+
 
   le = llist_head (db->list);
   while (le != NULL)
@@ -620,7 +622,7 @@ static int cx_curl_perform (cx_t *db, CURL *curl) /* {{{ */
   char *url;
   url = db->url;
 
-  db->buffer_fill = 0; 
+  db->buffer_fill = 0;
   status = curl_easy_perform (curl);
   if (status != CURLE_OK)
   {
@@ -686,7 +688,7 @@ static int cx_config_add_values (const char *name, cx_xpath_t *xpath, /* {{{ */
   sfree (xpath->values);
 
   xpath->values_len = 0;
-  xpath->values = (cx_values_t *) malloc (sizeof (cx_values_t) * ci->values_num);
+  xpath->values = malloc (sizeof (cx_values_t) * ci->values_num);
   if (xpath->values == NULL)
     return (-1);
   xpath->values_len = (size_t) ci->values_num;
@@ -698,36 +700,37 @@ static int cx_config_add_values (const char *name, cx_xpath_t *xpath, /* {{{ */
     sstrncpy (xpath->values[i].path, ci->values[i].value.string, sizeof (xpath->values[i].path));
   }
 
-  return (0); 
+  return (0);
 } /* }}} cx_config_add_values */
 
-static int cx_config_add_xpath (cx_t *db, /* {{{ */
-                                   oconfig_item_t *ci)
+static int cx_config_add_xpath (cx_t *db, oconfig_item_t *ci) /* {{{ */
 {
   cx_xpath_t *xpath;
+  char *name;
+  llentry_t *le;
   int status;
   int i;
 
-  xpath = (cx_xpath_t *) malloc (sizeof (*xpath));
+  xpath = calloc (1, sizeof (*xpath));
   if (xpath == NULL)
   {
-    ERROR ("curl_xml plugin: malloc failed.");
+    ERROR ("curl_xml plugin: calloc failed.");
     return (-1);
   }
-  memset (xpath, 0, sizeof (*xpath));
 
   status = cf_util_get_string (ci, &xpath->path);
   if (status != 0)
   {
-    sfree (xpath);
+    cx_xpath_free (xpath);
     return (status);
   }
 
   /* error out if xpath->path is an empty string */
-  if (*xpath->path == 0)
+  if (strlen (xpath->path) == 0)
   {
     ERROR ("curl_xml plugin: invalid xpath. "
            "xpath value can't be an empty string");
+    cx_xpath_free (xpath);
     return (-1);
   }
 
@@ -754,45 +757,49 @@ static int cx_config_add_xpath (cx_t *db, /* {{{ */
       break;
   } /* for (i = 0; i < ci->children_num; i++) */
 
-  if (status == 0 && xpath->type == NULL)
+  if (status != 0)
+  {
+    cx_xpath_free (xpath);
+    return status;
+  }
+
+  if (xpath->type == NULL)
   {
     WARNING ("curl_xml plugin: `Type' missing in `xpath' block.");
-    status = -1;
+    cx_xpath_free (xpath);
+    return -1;
   }
 
-  if (status == 0)
+  if (db->list == NULL)
   {
-    char *name;
-    llentry_t *le;
-
+    db->list = llist_create();
     if (db->list == NULL)
     {
-      db->list = llist_create();
-      if (db->list == NULL)
-      {
-        ERROR ("curl_xml plugin: list creation failed.");
-        return (-1);
-      }
-    }
-
-    name = strdup(xpath->path);
-    if (name == NULL)
-    {
-        ERROR ("curl_xml plugin: strdup failed.");
-        return (-1);
-    }
-
-    le = llentry_create (name, xpath);
-    if (le == NULL)
-    {
-      ERROR ("curl_xml plugin: llentry_create failed.");
+      ERROR ("curl_xml plugin: list creation failed.");
+      cx_xpath_free (xpath);
       return (-1);
     }
+  }
+
+  name = strdup (xpath->path);
+  if (name == NULL)
+  {
+    ERROR ("curl_xml plugin: strdup failed.");
+    cx_xpath_free (xpath);
+    return (-1);
+  }
 
-    llist_append (db->list, le);
+  le = llentry_create (name, xpath);
+  if (le == NULL)
+  {
+    ERROR ("curl_xml plugin: llentry_create failed.");
+    cx_xpath_free (xpath);
+    sfree (name);
+    return (-1);
   }
 
-  return (status);
+  llist_append (db->list, le);
+  return (0);
 } /* }}} int cx_config_add_xpath */
 
 static int cx_config_add_namespace (cx_t *db, /* {{{ */
@@ -867,7 +874,7 @@ static int cx_init_curl (cx_t *db) /* {{{ */
     if (db->pass != NULL)
       credentials_size += strlen (db->pass);
 
-    db->credentials = (char *) malloc (credentials_size);
+    db->credentials = malloc (credentials_size);
     if (db->credentials == NULL)
     {
       ERROR ("curl_xml plugin: malloc failed.");
@@ -917,13 +924,12 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  db = (cx_t *) malloc (sizeof (*db));
+  db = calloc (1, sizeof (*db));
   if (db == NULL)
   {
-    ERROR ("curl_xml plugin: malloc failed.");
+    ERROR ("curl_xml plugin: calloc failed.");
     return (-1);
   }
-  memset (db, 0, sizeof (*db));
 
   db->timeout = -1;
 
index 4e38341..cdd927b 100644 (file)
@@ -48,8 +48,10 @@ libheap_la_SOURCES = utils_heap.c utils_heap.h
 
 libmetadata_la_SOURCES = meta_data.c meta_data.h
 
-libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c utils_time_mock.c
-libplugin_mock_la_LIBADD = $(COMMON_LIBS)
+libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c \
+                           utils_time.c utils_time.h
+libplugin_mock_la_CPPFLAGS = $(AM_CPPFLAGS) -DMOCK_TIME
+libplugin_mock_la_LIBADD = $(COMMON_LIBS) libcommon.la
 
 collectd_SOURCES = collectd.c collectd.h \
                   configfile.c configfile.h \
@@ -58,6 +60,7 @@ collectd_SOURCES = collectd.c collectd.h \
                   plugin.c plugin.h \
                   utils_cache.c utils_cache.h \
                   utils_complain.c utils_complain.h \
+                  utils_ignorelist.c utils_ignorelist.h \
                   utils_llist.c utils_llist.h \
                   utils_random.c utils_random.h \
                   utils_tail_match.c utils_tail_match.h \
@@ -93,7 +96,7 @@ check_PROGRAMS = test_common test_meta_data test_utils_avltree test_utils_heap t
 TESTS          = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst
 
 test_common_SOURCES = common_test.c ../testing.h
-test_common_LDADD = libcommon.la libplugin_mock.la
+test_common_LDADD = libplugin_mock.la
 
 test_meta_data_SOURCES = meta_data_test.c ../testing.h
 test_meta_data_LDADD = libmetadata.la libplugin_mock.la
@@ -108,4 +111,4 @@ test_utils_time_SOURCES = utils_time_test.c ../testing.h
 
 test_utils_subst_SOURCES = utils_subst_test.c ../testing.h \
                           utils_subst.c utils_subst.h
-test_utils_subst_LDADD = libcommon.la libplugin_mock.la
+test_utils_subst_LDADD = libplugin_mock.la
index fc52933..a72ff35 100644 (file)
@@ -196,7 +196,7 @@ static int change_basedir (const char *orig_dir)
        while ((dirlen > 0) && (dir[dirlen - 1] == '/'))
                dir[--dirlen] = '\0';
 
-       if (dirlen <= 0) {
+       if (dirlen == 0) {
                free (dir);
                return (-1);
        }
@@ -269,6 +269,7 @@ static void update_kstat (void)
 /* TODO
  * Remove all settings but `-f' and `-C'
  */
+__attribute__((noreturn))
 static void exit_usage (int status)
 {
        printf ("Usage: "PACKAGE_NAME" [OPTIONS]\n\n"
@@ -301,6 +302,11 @@ static int do_init (void)
 #if HAVE_SETLOCALE
        if (setlocale (LC_NUMERIC, COLLECTD_LOCALE) == NULL)
                WARNING ("setlocale (\"%s\") failed.", COLLECTD_LOCALE);
+
+       /* Update the environment, so that libraries that are calling
+        * setlocale(LC_NUMERIC, "") don't accidentally revert these changes. */
+       unsetenv ("LC_ALL");
+       setenv ("LC_NUMERIC", COLLECTD_LOCALE, /* overwrite = */ 1);
 #endif
 
 #if HAVE_LIBKSTAT
@@ -326,9 +332,7 @@ static int do_init (void)
        }
 #endif
 
-       plugin_init_all ();
-
-       return (0);
+       return plugin_init_all ();
 } /* int do_init () */
 
 
@@ -382,8 +386,7 @@ static int do_loop (void)
 
 static int do_shutdown (void)
 {
-       plugin_shutdown_all ();
-       return (0);
+       return plugin_shutdown_all ();
 } /* int do_shutdown */
 
 #if COLLECT_DAEMON
@@ -417,7 +420,7 @@ static int pidfile_remove (void)
 #endif /* COLLECT_DAEMON */
 
 #ifdef KERNEL_LINUX
-int notify_upstart (void)
+static int notify_upstart (void)
 {
     char const *upstart_job = getenv("UPSTART_JOB");
 
@@ -437,7 +440,7 @@ int notify_upstart (void)
     return 1;
 }
 
-int notify_systemd (void)
+static int notify_systemd (void)
 {
     int                  fd;
     const char          *notifysocket;
@@ -513,7 +516,7 @@ int main (int argc, char **argv)
        struct sigaction sig_term_action;
        struct sigaction sig_usr1_action;
        struct sigaction sig_pipe_action;
-       char *configfile = CONFIGFILE;
+       const char *configfile = CONFIGFILE;
        int test_config  = 0;
        int test_readall = 0;
        const char *basedir;
@@ -633,6 +636,8 @@ int main (int argc, char **argv)
 #endif
        )
        {
+               int status;
+
                if ((pid = fork ()) == -1)
                {
                        /* error */
@@ -661,19 +666,24 @@ int main (int argc, char **argv)
                close (1);
                close (0);
 
-               if (open ("/dev/null", O_RDWR) != 0)
+               status = open ("/dev/null", O_RDWR);
+               if (status != 0)
                {
-                       ERROR ("Error: Could not connect `STDIN' to `/dev/null'");
+                       ERROR ("Error: Could not connect `STDIN' to `/dev/null' (status %d)", status);
                        return (1);
                }
-               if (dup (0) != 1)
+
+               status = dup (0);
+               if (status != 1)
                {
-                       ERROR ("Error: Could not connect `STDOUT' to `/dev/null'");
+                       ERROR ("Error: Could not connect `STDOUT' to `/dev/null' (status %d)", status);
                        return (1);
                }
-               if (dup (0) != 2)
+
+               status = dup (0);
+               if (status != 2)
                {
-                       ERROR ("Error: Could not connect `STDERR' to `/dev/null'");
+                       ERROR ("Error: Could not connect `STDERR' to `/dev/null', (status %d)", status);
                        return (1);
                }
        } /* if (daemonize) */
@@ -716,12 +726,19 @@ int main (int argc, char **argv)
        /*
         * run the actual loops
         */
-       do_init ();
+       if (do_init () != 0)
+       {
+               ERROR ("Error: one or more plugin init callbacks failed.");
+               exit_status = 1;
+       }
 
        if (test_readall)
        {
                if (plugin_read_all_once () != 0)
+               {
+                       ERROR ("Error: one or more plugin read callbacks failed.");
                        exit_status = 1;
+               }
        }
        else
        {
@@ -732,7 +749,11 @@ int main (int argc, char **argv)
        /* close syslog */
        INFO ("Exiting normally.");
 
-       do_shutdown ();
+       if (do_shutdown () != 0)
+       {
+               ERROR ("Error: one or more plugin shutdown callbacks failed.");
+               exit_status = 1;
+       }
 
 #if COLLECT_DAEMON
        if (daemonize)
index 66b4856..9002187 100644 (file)
@@ -294,7 +294,7 @@ typedef int _Bool;
 # pragma GCC poison strcpy strcat strtok
 #endif
 
-/* 
+/*
  * Special hack for the perl plugin: Because the later included perl.h defines
  * a macro which is never used, but contains `sprintf', we cannot poison that
  * identifies just yet. The parl plugin will do that itself once perl.h is
index 8f22011..546da3b 100644 (file)
@@ -48,6 +48,8 @@
 #include <sys/types.h>
 #include <netdb.h>
 
+#include <poll.h>
+
 #if HAVE_NETINET_IN_H
 # include <netinet/in.h>
 #endif
@@ -113,10 +115,9 @@ char *ssnprintf_alloc (char const *format, ...) /* {{{ */
                return (strdup (static_buffer));
 
        /* Allocate a buffer large enough to hold the string. */
-       alloc_buffer = malloc (alloc_buffer_size);
+       alloc_buffer = calloc (1, alloc_buffer_size);
        if (alloc_buffer == NULL)
                return (NULL);
-       memset (alloc_buffer, 0, alloc_buffer_size);
 
        /* Print again into this new buffer. */
        va_start (ap, format);
@@ -142,7 +143,7 @@ char *sstrdup (const char *s)
        /* Do not use `strdup' here, because it's not specified in POSIX. It's
         * ``only'' an XSI extension. */
        sz = strlen (s) + 1;
-       r = (char *) malloc (sizeof (char) * sz);
+       r = malloc (sz);
        if (r == NULL)
        {
                ERROR ("sstrdup: Out of memory.");
@@ -269,9 +270,23 @@ ssize_t swrite (int fd, const void *buf, size_t count)
        const char *ptr;
        size_t      nleft;
        ssize_t     status;
+       struct      pollfd pfd;
 
        ptr   = (const char *) buf;
        nleft = count;
+       
+       /* checking for closed peer connection */
+       pfd.fd = fd;
+       pfd.events = POLLIN | POLLHUP;
+       pfd.revents = 0;
+       if (poll(&pfd, 1, 0) > 0) {
+               char buffer[32];
+               if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
+                       // if recv returns zero (even though poll() said there is data to be read),
+                       // that means the connection has been closed
+                       return -1;
+               }
+       }
 
        while (nleft > 0)
        {
@@ -320,7 +335,7 @@ int strjoin (char *buffer, size_t buffer_size,
        size_t sep_len;
        size_t i;
 
-       if ((buffer_size < 1) || (fields_num <= 0))
+       if ((buffer_size < 1) || (fields_num == 0))
                return (-1);
 
        memset (buffer, 0, buffer_size);
@@ -358,27 +373,6 @@ int strjoin (char *buffer, size_t buffer_size,
        return ((int) strlen (buffer));
 }
 
-int strsubstitute (char *str, char c_from, char c_to)
-{
-       int ret;
-
-       if (str == NULL)
-               return (-1);
-
-       ret = 0;
-       while (*str != '\0')
-       {
-               if (*str == c_from)
-               {
-                       *str = c_to;
-                       ret++;
-               }
-               str++;
-       }
-
-       return (ret);
-} /* int strsubstitute */
-
 int escape_string (char *buffer, size_t buffer_size)
 {
   char *temp;
@@ -393,10 +387,9 @@ int escape_string (char *buffer, size_t buffer_size)
   if (buffer_size < 3)
     return (EINVAL);
 
-  temp = (char *) malloc (buffer_size);
+  temp = calloc (1, buffer_size);
   if (temp == NULL)
     return (ENOMEM);
-  memset (temp, 0, buffer_size);
 
   temp[0] = '"';
   j = 1;
@@ -1153,6 +1146,9 @@ int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds)
        char *ptr;
        char *saveptr;
 
+       if ((buffer == NULL) || (vl == NULL) || (ds == NULL))
+               return EINVAL;
+
        i = 0;
        dummy = buffer;
        saveptr = NULL;
index c3f7f54..6981d21 100644 (file)
@@ -37,9 +37,7 @@
 
 #define sfree(ptr) \
        do { \
-               if((ptr) != NULL) { \
-                       free(ptr); \
-               } \
+               free(ptr); \
                (ptr) = NULL; \
        } while (0)
 
@@ -224,8 +222,6 @@ int escape_string (char *buffer, size_t buffer_size);
  */
 void replace_special (char *buffer, size_t buffer_size);
 
-int strsubstitute (char *str, char c_from, char c_to);
-
 /*
  * NAME
  *   strunescape
index 399f8b5..68958f3 100644 (file)
@@ -24,8 +24,8 @@
  *   Florian octo Forster <octo at collectd.org>
  */
 
-#include "testing.h"
 #include "common.h"
+#include "testing.h"
 
 #if HAVE_LIBKSTAT
 kstat_ctl_t *kc;
@@ -90,7 +90,6 @@ DEF_TEST(sstrdup)
   EXPECT_EQ_STR ("collectd", ptr);
 
   sfree(ptr);
-  OK(ptr == NULL);
 
   ptr = sstrdup (NULL);
   OK(ptr == NULL);
index ae9ab3a..34c23cd 100644 (file)
@@ -72,15 +72,15 @@ typedef struct cf_complex_callback_s
 
 typedef struct cf_value_map_s
 {
-       char *key;
+       const char *key;
        int (*func) (oconfig_item_t *);
 } cf_value_map_t;
 
 typedef struct cf_global_option_s
 {
-       char *key;
+       const char *key;
        char *value;
-       char *def;
+       const char *def;
 } cf_global_option_t;
 
 /*
@@ -257,7 +257,7 @@ static int dispatch_value_typesdb (oconfig_item_t *ci)
 static int dispatch_value_plugindir (oconfig_item_t *ci)
 {
        assert (strcasecmp (ci->key, "PluginDir") == 0);
-       
+
        if (ci->values_num != 1)
                return (-1);
        if (ci->values[0].type != OCONFIG_TYPE_STRING)
@@ -358,7 +358,7 @@ static int dispatch_value_plugin (const char *plugin, oconfig_item_t *ci)
 
 static int dispatch_value (oconfig_item_t *ci)
 {
-       int ret = -2;
+       int ret = 0;
        int i;
 
        for (i = 0; i < cf_value_map_num; i++)
@@ -381,7 +381,7 @@ static int dispatch_value (oconfig_item_t *ci)
 static int dispatch_block_plugin (oconfig_item_t *ci)
 {
        int i;
-       char *name;
+       const char *name;
 
        cf_complex_callback_t *cb;
 
@@ -514,7 +514,7 @@ static int cf_ci_replace_child (oconfig_item_t *dst, oconfig_item_t *src,
                return (0);
        }
 
-       temp = (oconfig_item_t *) realloc (dst->children,
+       temp = realloc (dst->children,
                        sizeof (oconfig_item_t)
                        * (dst->children_num + src->children_num - 1));
        if (temp == NULL)
@@ -562,7 +562,7 @@ static int cf_ci_append_children (oconfig_item_t *dst, oconfig_item_t *src)
        if ((src == NULL) || (src->children_num == 0))
                return (0);
 
-       temp = (oconfig_item_t *) realloc (dst->children,
+       temp = realloc (dst->children,
                        sizeof (oconfig_item_t)
                        * (dst->children_num + src->children_num));
        if (temp == NULL)
@@ -717,13 +717,13 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                return (NULL);
        }
 
-       root = (oconfig_item_t *) malloc (sizeof (oconfig_item_t));
+       root = calloc (1, sizeof (*root));
        if (root == NULL)
        {
-               ERROR ("configfile: malloc failed.");
+               ERROR ("configfile: calloc failed.");
+               closedir (dh);
                return (NULL);
        }
-       memset (root, 0, sizeof (oconfig_item_t));
 
        while ((de = readdir (dh)) != NULL)
        {
@@ -740,6 +740,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                        ERROR ("configfile: Not including `%s/%s' because its"
                                        " name is too long.",
                                        dir, de->d_name);
+                       closedir (dh);
                        for (i = 0; i < filenames_num; ++i)
                                free (filenames[i]);
                        free (filenames);
@@ -748,10 +749,11 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                }
 
                ++filenames_num;
-               tmp = (char **) realloc (filenames,
+               tmp = realloc (filenames,
                                filenames_num * sizeof (*filenames));
                if (tmp == NULL) {
                        ERROR ("configfile: realloc failed.");
+                       closedir (dh);
                        for (i = 0; i < filenames_num - 1; ++i)
                                free (filenames[i]);
                        free (filenames);
@@ -764,7 +766,10 @@ static oconfig_item_t *cf_read_dir (const char *dir,
        }
 
        if (filenames == NULL)
+       {
+               closedir (dh);
                return (root);
+       }
 
        qsort ((void *) filenames, filenames_num, sizeof (*filenames),
                        cf_compare_string);
@@ -789,11 +794,12 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                free (name);
        }
 
+       closedir (dh);
        free(filenames);
        return (root);
 } /* oconfig_item_t *cf_read_dir */
 
-/* 
+/*
  * cf_read_generic
  *
  * Path is stat'ed and either cf_read_file or cf_read_dir is called
@@ -828,13 +834,12 @@ static oconfig_item_t *cf_read_generic (const char *path,
                return (NULL);
        }
 
-       root = (oconfig_item_t *) malloc (sizeof (oconfig_item_t));
+       root = calloc (1, sizeof (*root));
        if (root == NULL)
        {
-               ERROR ("configfile: malloc failed.");
+               ERROR ("configfile: calloc failed.");
                return (NULL);
        }
-       memset (root, '\0', sizeof (oconfig_item_t));
 
        /* wordexp() might return a sorted list already. That's not
         * documented though, so let's make sure we get what we want. */
@@ -919,7 +924,7 @@ static oconfig_item_t *cf_read_generic (const char *path,
 } /* oconfig_item_t *cf_read_generic */
 #endif /* !HAVE_WORDEXP_H */
 
-/* 
+/*
  * Public functions
  */
 int global_option_set (const char *option, const char *value)
@@ -962,7 +967,7 @@ const char *global_option_get (const char *option)
 
        if (i >= cf_global_options_num)
                return (NULL);
-       
+
        return ((cf_global_options[i].value != NULL)
                        ? cf_global_options[i].value
                        : cf_global_options[i].def);
@@ -1060,7 +1065,7 @@ void cf_register (const char *type,
        cf_unregister (type);
 
        /* This pointer will be free'd in `cf_unregister' */
-       if ((cf_cb = (cf_callback_t *) malloc (sizeof (cf_callback_t))) == NULL)
+       if ((cf_cb = malloc (sizeof (*cf_cb))) == NULL)
                return;
 
        cf_cb->type     = type;
@@ -1077,7 +1082,7 @@ int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *))
 {
        cf_complex_callback_t *new;
 
-       new = (cf_complex_callback_t *) malloc (sizeof (cf_complex_callback_t));
+       new = malloc (sizeof (*new));
        if (new == NULL)
                return (-1);
 
@@ -1108,10 +1113,11 @@ int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *))
        return (0);
 } /* int cf_register_complex */
 
-int cf_read (char *filename)
+int cf_read (const char *filename)
 {
        oconfig_item_t *conf;
        int i;
+       int ret = 0;
 
        conf = cf_read_generic (filename, /* pattern = */ NULL, /* depth = */ 0);
        if (conf == NULL)
@@ -1129,18 +1135,27 @@ int cf_read (char *filename)
        for (i = 0; i < conf->children_num; i++)
        {
                if (conf->children[i].children == NULL)
-                       dispatch_value (conf->children + i);
+               {
+                       if (dispatch_value (conf->children + i) != 0)
+                               ret = -1;
+               }
                else
-                       dispatch_block (conf->children + i);
+               {
+                       if (dispatch_block (conf->children + i) != 0)
+                               ret = -1;
+               }
        }
 
        oconfig_free (conf);
 
        /* Read the default types.db if no `TypesDB' option was given. */
        if (cf_default_typesdb)
-               read_types_list (PKGDATADIR"/types.db");
+       {
+               if (read_types_list (PKGDATADIR"/types.db") != 0)
+                       ret = -1;
+       }
 
-       return (0);
+       return ret;
 } /* int cf_read */
 
 /* Assures the config option is a string, duplicates it and returns the copy in
index 5bc9b30..09dbe58 100644 (file)
@@ -34,7 +34,7 @@
 /*
  * DESCRIPTION
  *  Remove a registered plugin from the internal data structures.
- * 
+ *
  * PARAMETERS
  *  `type'      Name of the plugin (must be the same as passed to
  *              `plugin_register'
@@ -87,7 +87,7 @@ int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *));
  *  Returns zero upon success and non-zero otherwise. A error-message will have
  *  been printed in this case.
  */
-int cf_read (char *filename);
+int cf_read (const char *filename);
 
 int global_option_set (const char *option, const char *value);
 const char *global_option_get (const char *option);
index 5042913..a622af9 100644 (file)
@@ -174,7 +174,7 @@ static char *fc_strdup (const char *orig) /* {{{ */
     return (NULL);
 
   sz = strlen (orig) + 1;
-  dest = (char *) malloc (sz);
+  dest = malloc (sz);
   if (dest == NULL)
     return (NULL);
 
@@ -235,13 +235,12 @@ static int fc_config_add_match (fc_match_t **matches_head, /* {{{ */
     return (-1);
   }
 
-  m = (fc_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
   {
-    ERROR ("fc_config_add_match: malloc failed.");
+    ERROR ("fc_config_add_match: calloc failed.");
     return (-1);
   }
-  memset (m, 0, sizeof (*m));
 
   sstrncpy (m->name, ptr->name, sizeof (m->name));
   memcpy (&m->proc, &ptr->proc, sizeof (m->proc));
@@ -307,13 +306,12 @@ static int fc_config_add_target (fc_target_t **targets_head, /* {{{ */
     return (-1);
   }
 
-  t = (fc_target_t *) malloc (sizeof (*t));
+  t = calloc (1, sizeof (*t));
   if (t == NULL)
   {
-    ERROR ("fc_config_add_target: malloc failed.");
+    ERROR ("fc_config_add_target: calloc failed.");
     return (-1);
   }
-  memset (t, 0, sizeof (*t));
 
   sstrncpy (t->name, ptr->name, sizeof (t->name));
   memcpy (&t->proc, &ptr->proc, sizeof (t->proc));
@@ -335,7 +333,7 @@ static int fc_config_add_target (fc_target_t **targets_head, /* {{{ */
   {
     t->user_data = NULL;
   }
-  
+
   if (*targets_head != NULL)
   {
     ptr = *targets_head;
@@ -373,14 +371,12 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */
     return (-1);
   }
 
-  rule = (fc_rule_t *) malloc (sizeof (*rule));
+  rule = calloc (1, sizeof (*rule));
   if (rule == NULL)
   {
-    ERROR ("fc_config_add_rule: malloc failed.");
+    ERROR ("fc_config_add_rule: calloc failed.");
     return (-1);
   }
-  memset (rule, 0, sizeof (*rule));
-  rule->next = NULL;
 
   if (ci->values_num == 1)
   {
@@ -469,17 +465,13 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */
 
   if (chain == NULL)
   {
-    chain = (fc_chain_t *) malloc (sizeof (*chain));
+    chain = calloc (1, sizeof (*chain));
     if (chain == NULL)
     {
-      ERROR ("fc_config_add_chain: malloc failed.");
+      ERROR ("fc_config_add_chain: calloc failed.");
       return (-1);
     }
-    memset (chain, 0, sizeof (*chain));
     sstrncpy (chain->name, ci->values[0].value.string, sizeof (chain->name));
-    chain->rules = NULL;
-    chain->targets = NULL;
-    chain->next = NULL;
   }
 
   for (i = 0; i < ci->children_num; i++)
@@ -663,7 +655,7 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
       }
       plugin = child->values[j].value.string;
 
-      temp = (fc_writer_t *) realloc (plugin_list, (plugin_list_len + 2)
+      temp = realloc (plugin_list, (plugin_list_len + 2)
           * (sizeof (*plugin_list)));
       if (temp == NULL)
       {
@@ -824,14 +816,12 @@ int fc_register_match (const char *name, match_proc_t proc) /* {{{ */
 
   DEBUG ("fc_register_match (%s);", name);
 
-  m = (fc_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
     return (-ENOMEM);
-  memset (m, 0, sizeof (*m));
 
   sstrncpy (m->name, name, sizeof (m->name));
   memcpy (&m->proc, &proc, sizeof (m->proc));
-  m->next = NULL;
 
   if (match_list_head == NULL)
   {
@@ -858,14 +848,12 @@ int fc_register_target (const char *name, target_proc_t proc) /* {{{ */
 
   DEBUG ("fc_register_target (%s);", name);
 
-  t = (fc_target_t *) malloc (sizeof (*t));
+  t = calloc (1, sizeof (*t));
   if (t == NULL)
     return (-ENOMEM);
-  memset (t, 0, sizeof (*t));
 
   sstrncpy (t->name, name, sizeof (t->name));
   memcpy (&t->proc, &proc, sizeof (t->proc));
-  t->next = NULL;
 
   if (target_list_head == NULL)
   {
@@ -904,17 +892,17 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
 {
   fc_rule_t *rule;
   fc_target_t *target;
-  int status;
+  int status = FC_TARGET_CONTINUE;
 
   if (chain == NULL)
     return (-1);
 
   DEBUG ("fc_process_chain (chain = %s);", chain->name);
 
-  status = FC_TARGET_CONTINUE;
   for (rule = chain->rules; rule != NULL; rule = rule->next)
   {
     fc_match_t *match;
+    status = FC_TARGET_CONTINUE;
 
     if (rule->name[0] != 0)
     {
@@ -976,8 +964,7 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
       }
     }
 
-    if ((status == FC_TARGET_STOP)
-        || (status == FC_TARGET_RETURN))
+    if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN))
     {
       if (rule->name[0] != 0)
       {
@@ -988,20 +975,10 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
       }
       break;
     }
-    else
-    {
-      status = FC_TARGET_CONTINUE;
-    }
   } /* for (rule) */
 
-  if (status == FC_TARGET_STOP)
-    return (FC_TARGET_STOP);
-  else if (status == FC_TARGET_RETURN)
-    return (FC_TARGET_CONTINUE);
-
-  /* for-loop has been aborted: A target returned `FC_TARGET_STOP' */
-  if (rule != NULL)
-    return (FC_TARGET_CONTINUE);
+  if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN))
+    return (status);
 
   DEBUG ("fc_process_chain (%s): Executing the default targets.",
       chain->name);
index 2db90db..dbf4b83 100644 (file)
@@ -97,7 +97,7 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl,
 
 int fc_default_action (const data_set_t *ds, value_list_t *vl);
 
-/* 
+/*
  * Shortcut for global configuration
  */
 int fc_configure (const oconfig_item_t *ci);
index 6ee8446..b3f892a 100644 (file)
@@ -71,7 +71,7 @@ static char *md_strdup (const char *orig) /* {{{ */
     return (NULL);
 
   sz = strlen (orig) + 1;
-  dest = (char *) malloc (sz);
+  dest = malloc (sz);
   if (dest == NULL)
     return (NULL);
 
@@ -84,13 +84,12 @@ static meta_entry_t *md_entry_alloc (const char *key) /* {{{ */
 {
   meta_entry_t *e;
 
-  e = (meta_entry_t *) malloc (sizeof (*e));
+  e = calloc (1, sizeof (*e));
   if (e == NULL)
   {
-    ERROR ("md_entry_alloc: malloc failed.");
+    ERROR ("md_entry_alloc: calloc failed.");
     return (NULL);
   }
-  memset (e, 0, sizeof (*e));
 
   e->key = md_strdup (key);
   if (e->key == NULL)
@@ -106,20 +105,37 @@ static meta_entry_t *md_entry_alloc (const char *key) /* {{{ */
   return (e);
 } /* }}} meta_entry_t *md_entry_alloc */
 
-static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */
+/* XXX: The lock on md must be held while calling this function! */
+static meta_entry_t *md_entry_clone_contents (const meta_entry_t *orig) /* {{{ */
 {
   meta_entry_t *copy;
 
-  if (orig == NULL)
-    return (NULL);
+  /* WARNINGS :
+   *  - we do not check that orig != NULL here. You should have done it before.
+   *  - we do not set copy->next. DO NOT FORGET TO SET copy->next IN YOUR FUNCTION
+   */
 
   copy = md_entry_alloc (orig->key);
+  if (copy == NULL)
+    return (NULL);
   copy->type = orig->type;
   if (copy->type == MD_TYPE_STRING)
     copy->value.mv_string = strdup (orig->value.mv_string);
   else
     copy->value = orig->value;
 
+  return (copy);
+} /* }}} meta_entry_t *md_entry_clone_contents */
+
+static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */
+{
+  meta_entry_t *copy;
+
+  if (orig == NULL)
+    return (NULL);
+
+  copy = md_entry_clone_contents(orig);
+
   copy->next = md_entry_clone (orig->next);
   return (copy);
 } /* }}} meta_entry_t *md_entry_clone */
@@ -196,6 +212,63 @@ static int md_entry_insert (meta_data_t *md, meta_entry_t *e) /* {{{ */
 } /* }}} int md_entry_insert */
 
 /* XXX: The lock on md must be held while calling this function! */
+static int md_entry_insert_clone (meta_data_t *md, meta_entry_t *orig) /* {{{ */
+{
+  meta_entry_t *e;
+  meta_entry_t *this;
+  meta_entry_t *prev;
+
+  /* WARNINGS :
+   *  - we do not check that md and e != NULL here. You should have done it before.
+   *  - we do not use the lock. You should have set it before.
+   */
+
+  e = md_entry_clone_contents(orig);
+
+  prev = NULL;
+  this = md->head;
+  while (this != NULL)
+  {
+    if (strcasecmp (e->key, this->key) == 0)
+      break;
+
+    prev = this;
+    this = this->next;
+  }
+
+  if (this == NULL)
+  {
+    /* This key does not exist yet. */
+    if (md->head == NULL)
+      md->head = e;
+    else
+    {
+      assert (prev != NULL);
+      prev->next = e;
+    }
+
+    e->next = NULL;
+  }
+  else /* (this != NULL) */
+  {
+    if (prev == NULL)
+      md->head = e;
+    else
+      prev->next = e;
+
+    e->next = this->next;
+  }
+
+  if (this != NULL)
+  {
+    this->next = NULL;
+    md_entry_free (this);
+  }
+
+  return (0);
+} /* }}} int md_entry_insert_clone */
+
+/* XXX: The lock on md must be held while calling this function! */
 static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */
     const char *key)
 {
@@ -218,15 +291,13 @@ meta_data_t *meta_data_create (void) /* {{{ */
 {
   meta_data_t *md;
 
-  md = (meta_data_t *) malloc (sizeof (*md));
+  md = calloc (1, sizeof (*md));
   if (md == NULL)
   {
-    ERROR ("meta_data_create: malloc failed.");
+    ERROR ("meta_data_create: calloc failed.");
     return (NULL);
   }
-  memset (md, 0, sizeof (*md));
 
-  md->head = NULL;
   pthread_mutex_init (&md->lock, /* attr = */ NULL);
 
   return (md);
@@ -250,12 +321,33 @@ meta_data_t *meta_data_clone (meta_data_t *orig) /* {{{ */
   return (copy);
 } /* }}} meta_data_t *meta_data_clone */
 
+int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig) /* {{{ */
+{
+  meta_entry_t *e;
+
+  if (orig == NULL)
+    return (0);
+
+  if (*dest == NULL) {
+    *dest = meta_data_clone(orig);
+    return(0);
+  }
+
+  pthread_mutex_lock (&orig->lock);
+  for (e=orig->head; e != NULL; e = e->next)
+  {
+    md_entry_insert_clone((*dest), e);
+  }
+  pthread_mutex_unlock (&orig->lock);
+
+  return (0);
+} /* }}} int meta_data_clone_merge */
+
 void meta_data_destroy (meta_data_t *md) /* {{{ */
 {
   if (md == NULL)
     return;
 
-  pthread_mutex_destroy(&md->lock);
   md_entry_free (md->head);
   pthread_mutex_destroy (&md->lock);
   free (md);
@@ -316,7 +408,7 @@ int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */
   pthread_mutex_lock (&md->lock);
 
   for (e = md->head; e != NULL; e = e->next)
-    ++count;    
+    ++count;
 
   if (count == 0)
   {
@@ -327,7 +419,7 @@ int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */
   *toc = calloc(count, sizeof(**toc));
   for (e = md->head; e != NULL; e = e->next)
     (*toc)[i++] = strdup(e->key);
-  
+
   pthread_mutex_unlock (&md->lock);
   return count;
 } /* }}} int meta_data_toc */
@@ -506,7 +598,7 @@ int meta_data_get_string (meta_data_t *md, /* {{{ */
     ERROR ("meta_data_get_string: md_strdup failed.");
     return (-ENOMEM);
   }
+
   pthread_mutex_unlock (&md->lock);
 
   *value = temp;
index fa48df3..9e448e5 100644 (file)
@@ -43,6 +43,7 @@ typedef struct meta_data_s meta_data_t;
 
 meta_data_t *meta_data_create (void);
 meta_data_t *meta_data_clone (meta_data_t *orig);
+int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig);
 void meta_data_destroy (meta_data_t *md);
 
 int meta_data_exists (meta_data_t *md, const char *key);
index b4c0e27..48760d6 100644 (file)
@@ -24,9 +24,9 @@
  *   Florian octo Forster <octo at collectd.org>
  */
 
-#include "testing.h"
-#include "collectd.h"
 #include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
 #include "meta_data.h"
 
 DEF_TEST(base)
index b57dd4a..3a2e287 100644 (file)
@@ -288,7 +288,7 @@ static int register_callback (llist_t **list, /* {{{ */
                {
                        ERROR ("plugin: register_callback: "
                                        "llentry_create failed.");
-                       free (key);
+                       sfree (key);
                        destroy_callback (cf);
                        return (-1);
                }
@@ -358,9 +358,9 @@ static void log_list_callbacks (llist_t **list, /* {{{ */
                *str = '\0';
                strjoin(str, len, keys, n, "', '");
                INFO("%s ['%s']", comment, str);
-               free(str);
+               sfree (str);
        }
-       free(keys);
+       sfree (keys);
 } /* }}} void log_list_callbacks */
 
 static int create_register_callback (llist_t **list, /* {{{ */
@@ -368,13 +368,12 @@ static int create_register_callback (llist_t **list, /* {{{ */
 {
        callback_func_t *cf;
 
-       cf = (callback_func_t *) malloc (sizeof (*cf));
+       cf = calloc (1, sizeof (*cf));
        if (cf == NULL)
        {
-               ERROR ("plugin: create_register_callback: malloc failed.");
+               ERROR ("plugin: create_register_callback: calloc failed.");
                return (-1);
        }
-       memset (cf, 0, sizeof (*cf));
 
        cf->cf_callback = callback;
        if (ud == NULL)
@@ -483,7 +482,9 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
        {
                read_func_t *rf;
                plugin_ctx_t old_ctx;
+               cdtime_t start;
                cdtime_t now;
+               cdtime_t elapsed;
                int status;
                int rf_type;
                int rc;
@@ -562,6 +563,8 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
 
                DEBUG ("plugin_read_thread: Handling `%s'.", rf->rf_name);
 
+               start = cdtime ();
+
                old_ctx = plugin_set_ctx (rf->rf_ctx);
 
                if (rf_type == RF_SIMPLE)
@@ -605,8 +608,22 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
                /* update the ``next read due'' field */
                now = cdtime ();
 
+               /* calculate the time spent in the read function */
+               elapsed = (now - start);
+
+               if (elapsed > rf->rf_effective_interval)
+                       WARNING ("plugin_read_thread: read-function of the `%s' plugin took %.3f "
+                               "seconds, which is above its read interval (%.3f seconds). You might "
+                               "want to adjust the `Interval' or `ReadThreads' settings.",
+                               rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed),
+                               CDTIME_T_TO_DOUBLE(rf->rf_effective_interval));
+
+               DEBUG ("plugin_read_thread: read-function of the `%s' plugin took "
+                               "%.6f seconds.",
+                               rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed));
+
                DEBUG ("plugin_read_thread: Effective interval of the "
-                               "%s plugin is %.3f seconds.",
+                               "`%s' plugin is %.3f seconds.",
                                rf->rf_name,
                                CDTIME_T_TO_DOUBLE (rf->rf_effective_interval));
 
@@ -623,7 +640,7 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
                        rf->rf_next_read = now;
                }
 
-               DEBUG ("plugin_read_thread: Next read of the %s plugin at %.3f.",
+               DEBUG ("plugin_read_thread: Next read of the `%s' plugin at %.3f.",
                                rf->rf_name,
                                CDTIME_T_TO_DOUBLE (rf->rf_next_read));
 
@@ -941,17 +958,17 @@ static void stop_write_threads (void) /* {{{ */
  */
 void plugin_set_dir (const char *dir)
 {
-       if (plugindir != NULL)
-               free (plugindir);
+       sfree (plugindir);
 
        if (dir == NULL)
-               plugindir = NULL;
-       else if ((plugindir = strdup (dir)) == NULL)
        {
-               char errbuf[1024];
-               ERROR ("strdup failed: %s",
-                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               plugindir = NULL;
+               return;
        }
+
+       plugindir = strdup (dir);
+       if (plugindir == NULL)
+               ERROR ("plugin_set_dir: strdup(\"%s\") failed", dir);
 }
 
 static _Bool plugin_is_loaded (char const *name)
@@ -980,7 +997,7 @@ static int plugin_mark_loaded (char const *name)
        return (status);
 }
 
-static void plugin_free_loaded ()
+static void plugin_free_loaded (void)
 {
        void *key;
        void *value;
@@ -1226,14 +1243,13 @@ int plugin_register_read (const char *name,
        read_func_t *rf;
        int status;
 
-       rf = malloc (sizeof (*rf));
+       rf = calloc (1, sizeof (*rf));
        if (rf == NULL)
        {
-               ERROR ("plugin_register_read: malloc failed.");
+               ERROR ("plugin_register_read: calloc failed.");
                return (ENOMEM);
        }
 
-       memset (rf, 0, sizeof (read_func_t));
        rf->rf_callback = (void *) callback;
        rf->rf_udata.data = NULL;
        rf->rf_udata.free_func = NULL;
@@ -1260,14 +1276,13 @@ int plugin_register_complex_read (const char *group, const char *name,
        read_func_t *rf;
        int status;
 
-       rf = malloc (sizeof (*rf));
+       rf = calloc (1,sizeof (*rf));
        if (rf == NULL)
        {
-               ERROR ("plugin_register_complex_read: malloc failed.");
+               ERROR ("plugin_register_complex_read: calloc failed.");
                return (ENOMEM);
        }
 
-       memset (rf, 0, sizeof (read_func_t));
        rf->rf_callback = (void *) callback;
        if (group != NULL)
                sstrncpy (rf->rf_group, group, sizeof (rf->rf_group));
@@ -1319,13 +1334,13 @@ static void plugin_flush_timeout_callback_free (void *data)
 
        if (cb == NULL) return;
 
-       sfree(cb->name);
-       sfree(cb);
+       sfree (cb->name);
+       sfree (cb);
 } /* static void plugin_flush_callback_free */
 
 static char *plugin_flush_callback_name (const char *name)
 {
-       char *flush_prefix = "flush/";
+       const char *flush_prefix = "flush/";
        size_t prefix_size;
        char *flush_name;
        size_t name_size;
@@ -1333,7 +1348,7 @@ static char *plugin_flush_callback_name (const char *name)
        prefix_size = strlen(flush_prefix);
        name_size = strlen(name);
 
-       flush_name = malloc (sizeof(char) * (name_size + prefix_size + 1));
+       flush_name = malloc (name_size + prefix_size + 1);
        if (flush_name == NULL)
        {
                ERROR ("plugin_flush_callback_name: malloc failed.");
@@ -1360,18 +1375,17 @@ int plugin_register_flush (const char *name,
        if (ctx.flush_interval != 0)
        {
                char *flush_name;
-               user_data_t ud;
                flush_callback_t *cb;
 
                flush_name = plugin_flush_callback_name (name);
                if (flush_name == NULL)
                        return (-1);
 
-               cb = malloc(sizeof(flush_callback_t));
+               cb = malloc(sizeof (*cb));
                if (cb == NULL)
                {
                        ERROR ("plugin_register_flush: malloc failed.");
-                       sfree(flush_name);
+                       sfree (flush_name);
                        return (-1);
                }
 
@@ -1379,27 +1393,27 @@ int plugin_register_flush (const char *name,
                if (cb->name == NULL)
                {
                        ERROR ("plugin_register_flush: strdup failed.");
-                       sfree(cb);
-                       sfree(flush_name);
+                       sfree (cb);
+                       sfree (flush_name);
                        return (-1);
                }
                cb->timeout = ctx.flush_timeout;
 
-               ud.data = cb;
-               ud.free_func = plugin_flush_timeout_callback_free;
+               ud->data = cb;
+               ud->free_func = plugin_flush_timeout_callback_free;
 
                status = plugin_register_complex_read (
                        /* group     = */ "flush",
                        /* name      = */ flush_name,
                        /* callback  = */ plugin_flush_timeout_callback,
                        /* interval  = */ ctx.flush_interval,
-                       /* user data = */ &ud);
+                       /* user data = */ ud);
 
-               sfree(flush_name);
+               sfree (flush_name);
                if (status != 0)
                {
-                       sfree(cb->name);
-                       sfree(cb);
+                       sfree (cb->name);
+                       sfree (cb);
                        return status;
                }
        }
@@ -1460,16 +1474,16 @@ int plugin_register_data_set (const data_set_t *ds)
                        return (-1);
        }
 
-       ds_copy = (data_set_t *) malloc (sizeof (data_set_t));
+       ds_copy = malloc (sizeof (*ds_copy));
        if (ds_copy == NULL)
                return (-1);
        memcpy(ds_copy, ds, sizeof (data_set_t));
 
-       ds_copy->ds = (data_source_t *) malloc (sizeof (data_source_t)
+       ds_copy->ds = malloc (sizeof (*ds_copy->ds)
                        * ds->ds_num);
        if (ds_copy->ds == NULL)
        {
-               free (ds_copy);
+               sfree (ds_copy);
                return (-1);
        }
 
@@ -1633,7 +1647,7 @@ int plugin_unregister_flush (const char *name)
                if (flush_name != NULL)
                {
                        plugin_unregister_read(flush_name);
-                       sfree(flush_name);
+                       sfree (flush_name);
                }
        }
 
@@ -1676,12 +1690,12 @@ int plugin_unregister_notification (const char *name)
        return (plugin_unregister (list_notification, name));
 }
 
-void plugin_init_all (void)
+int plugin_init_all (void)
 {
        char const *chain_name;
-       long write_threads_num;
        llentry_t *le;
        int status;
+       int ret = 0;
 
        /* Init the value cache */
        uc_init ();
@@ -1725,10 +1739,8 @@ void plugin_init_all (void)
                write_threads_num = 5;
        }
 
-       start_write_threads ((size_t) write_threads_num);
-
        if ((list_init == NULL) && (read_heap == NULL))
-               return;
+               return ret;
 
        /* Calling all init callbacks before checking if read callbacks
         * are available allows the init callbacks to register the read
@@ -1757,11 +1769,14 @@ void plugin_init_all (void)
                         * handling themselves. */
                        /* FIXME: Unload _all_ functions */
                        plugin_unregister_read (le->key);
+                       ret = -1;
                }
 
                le = le->next;
        }
 
+       start_write_threads ((size_t) write_threads_num);
+
        max_read_interval = global_option_get_time ("MaxReadInterval",
                        DEFAULT_MAX_READ_INTERVAL);
 
@@ -1776,6 +1791,7 @@ void plugin_init_all (void)
                if (num != -1)
                        start_read_threads ((num > 0) ? num : 5);
        }
+       return ret;
 } /* void plugin_init_all */
 
 /* TODO: Rename this function. */
@@ -1959,9 +1975,10 @@ int plugin_flush (const char *plugin, cdtime_t timeout, const char *identifier)
   return (0);
 } /* int plugin_flush */
 
-void plugin_shutdown_all (void)
+int plugin_shutdown_all (void)
 {
        llentry_t *le;
+       int ret = 0;  // Assume success.
 
        stop_read_threads ();
 
@@ -1998,7 +2015,8 @@ void plugin_shutdown_all (void)
                 * after callback returns. */
                le = le->next;
 
-               (*callback) ();
+               if ((*callback) () != 0)
+                       ret = -1;
 
                plugin_set_ctx (old_ctx);
        }
@@ -2020,6 +2038,7 @@ void plugin_shutdown_all (void)
 
        plugin_free_loaded ();
        plugin_free_data_sets ();
+       return (ret);
 } /* void plugin_shutdown_all */
 
 int plugin_dispatch_missing (const value_list_t *vl) /* {{{ */
@@ -2075,8 +2094,10 @@ static int plugin_dispatch_values_internal (value_list_t *vl)
 
        int free_meta_data = 0;
 
-       if ((vl == NULL) || (vl->type[0] == 0)
-                       || (vl->values == NULL) || (vl->values_len < 1))
+       assert(vl);
+       assert(vl->plugin);
+
+       if (vl->type[0] == 0 || vl->values == NULL || vl->values_len < 1)
        {
                ERROR ("plugin_dispatch_values: Invalid value list "
                                "from plugin %s.", vl->plugin);
@@ -2197,7 +2218,7 @@ static int plugin_dispatch_values_internal (value_list_t *vl)
                         * don't get confused.. */
                        if (saved_values != NULL)
                        {
-                               free (vl->values);
+                               sfree (vl->values);
                                vl->values     = saved_values;
                                vl->values_len = saved_values_len;
                        }
@@ -2226,7 +2247,7 @@ static int plugin_dispatch_values_internal (value_list_t *vl)
         * confused.. */
        if (saved_values != NULL)
        {
-               free (vl->values);
+               sfree (vl->values);
                vl->values     = saved_values;
                vl->values_len = saved_values_len;
        }
@@ -2341,7 +2362,7 @@ int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */
 
        assert (template->values_len == 1);
 
-  /* Calculate sum for Gauge to calculate percent if needed */
+       /* Calculate sum for Gauge to calculate percent if needed */
        if (DS_TYPE_GAUGE == store_type)        {
                va_start (ap, store_type);
                while (42)
@@ -2384,7 +2405,7 @@ int plugin_dispatch_multivalue (value_list_t const *template, /* {{{ */
                case DS_TYPE_GAUGE:
                        vl->values[0].gauge = va_arg (ap, gauge_t);
                        if (store_percentage)
-                               vl->values[0].gauge *= 100.0 / sum;
+                               vl->values[0].gauge *= sum ? (100.0 / sum) : 0;
                        break;
                case DS_TYPE_ABSOLUTE:
                        vl->values[0].absolute = va_arg (ap, absolute_t);
@@ -2562,13 +2583,12 @@ static int plugin_notification_meta_add (notification_t *n,
     return (-1);
   }
 
-  meta = (notification_meta_t *) malloc (sizeof (notification_meta_t));
+  meta = calloc (1, sizeof (*meta));
   if (meta == NULL)
   {
-    ERROR ("plugin_notification_meta_add: malloc failed.");
+    ERROR ("plugin_notification_meta_add: calloc failed.");
     return (-1);
   }
-  memset (meta, 0, sizeof (notification_meta_t));
 
   sstrncpy (meta->name, name, sizeof (meta->name));
   meta->type = type;
@@ -2712,7 +2732,11 @@ int plugin_notification_meta_free (notification_meta_t *n)
 
     if (this->type == NM_TYPE_STRING)
     {
-      free ((char *)this->nm_value.nm_string);
+      /* Assign to a temporary variable to work around nm_string's const
+       * modifier. */
+      void *tmp = (void *) this->nm_value.nm_string;
+
+      sfree (tmp);
       this->nm_value.nm_string = NULL;
     }
     sfree (this);
@@ -2819,7 +2843,7 @@ static void *plugin_thread_start (void *arg)
 
        plugin_set_ctx (plugin_thread->ctx);
 
-       free (plugin_thread);
+       sfree (plugin_thread);
 
        return start_routine (plugin_arg);
 } /* void *plugin_thread_start */
index b1adb52..7398227 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * collectd - src/plugin.h
+ * collectd - src/daemon/plugin.h
  * Copyright (C) 2005-2014  Florian octo Forster
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -39,7 +39,9 @@
 
 #define PLUGIN_FLAGS_GLOBAL 0x0001
 
-#define DATA_MAX_NAME_LEN 64
+#ifndef DATA_MAX_NAME_LEN
+# define DATA_MAX_NAME_LEN 64
+#endif
 
 #define DS_TYPE_COUNTER  0
 #define DS_TYPE_GAUGE    1
@@ -240,10 +242,10 @@ void plugin_set_dir (const char *dir);
  */
 int plugin_load (const char *name, uint32_t flags);
 
-void plugin_init_all (void);
+int plugin_init_all (void);
 void plugin_read_all (void);
 int plugin_read_all_once (void);
-void plugin_shutdown_all (void);
+int plugin_shutdown_all (void);
 
 /*
  * NAME
@@ -334,7 +336,7 @@ int plugin_unregister_notification (const char *name);
  *  Since some writers dynamically build their name it can be hard for
  *  the configuring person to know it. This function will fill this gap.
  */
-void plugin_log_available_writers ();
+void plugin_log_available_writers (void);
 
 /*
  * NAME
@@ -459,4 +461,10 @@ cdtime_t plugin_get_interval (void);
 int plugin_thread_create (pthread_t *thread, const pthread_attr_t *attr,
                void *(*start_routine) (void *), void *arg);
 
+/*
+ * Plugins need to implement this
+ */
+
+void module_register (void);
+
 #endif /* PLUGIN_H */
index f7bf1c0..b6efa3a 100644 (file)
 kstat_ctl_t *kc = NULL;
 #endif /* HAVE_LIBKSTAT */
 
+char hostname_g[] = "example.com";
+
+int plugin_register_complex_config (const char *type, int (*callback) (oconfig_item_t *))
+{
+  return ENOTSUP;
+}
+
+int plugin_register_init (const char *name, plugin_init_cb callback)
+{
+  return ENOTSUP;
+}
+
+int plugin_register_read (const char *name, int (*callback) (void))
+{
+  return ENOTSUP;
+}
+
+int plugin_register_shutdown (const char *name, int (*callback) (void))
+{
+  return ENOTSUP;
+}
+
+int plugin_dispatch_values (value_list_t const *vl)
+{
+  return ENOTSUP;
+}
+
 void plugin_log (int level, char const *format, ...)
 {
   char buffer[1024];
@@ -42,4 +69,9 @@ void plugin_log (int level, char const *format, ...)
   printf ("plugin_log (%i, \"%s\");\n", level, buffer);
 }
 
+cdtime_t plugin_get_interval (void)
+{
+  return TIME_T_TO_CDTIME_T (10);
+}
+
 /* vim: set sw=2 sts=2 et : */
index 75a980a..de6fce3 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "plugin.h"
 #include "configfile.h"
+#include "types_list.h"
 
 static int parse_ds (data_source_t *dsrc, char *buf, size_t buf_len)
 {
@@ -111,25 +112,27 @@ static void parse_line (char *buf)
   if (fields[0][0] == '#')
     return;
 
-  ds = (data_set_t *) malloc (sizeof (data_set_t));
+  ds = calloc (1, sizeof (*ds));
   if (ds == NULL)
     return;
 
-  memset (ds, '\0', sizeof (data_set_t));
-
   sstrncpy (ds->type, fields[0], sizeof (ds->type));
 
   ds->ds_num = fields_num - 1;
   ds->ds = (data_source_t *) calloc (ds->ds_num, sizeof (data_source_t));
   if (ds->ds == NULL)
+  {
+    sfree (ds);
     return;
+  }
 
   for (i = 0; i < ds->ds_num; i++)
     if (parse_ds (ds->ds + i, fields[i + 1], strlen (fields[i + 1])) != 0)
     {
-      sfree (ds->ds);
       ERROR ("types_list: parse_line: Cannot parse data source #%zu "
          "of data set %s", i, ds->type);
+      sfree (ds->ds);
+      sfree (ds);
       return;
     }
 
index e251975..1680c41 100644 (file)
@@ -245,7 +245,7 @@ static void rebalance (c_avl_tree_t *t, c_avl_node_t *n)
                {
                        assert (n->right != NULL);
                        b_bottom = BALANCE (n->right);
-                       assert ((b_bottom >= -1) || (b_bottom <= 1));
+                       assert ((b_bottom >= -1) && (b_bottom <= 1));
                        if (b_bottom == 1)
                                n = rotate_right_left (t, n);
                        else
@@ -255,7 +255,7 @@ static void rebalance (c_avl_tree_t *t, c_avl_node_t *n)
                {
                        assert (n->left != NULL);
                        b_bottom = BALANCE (n->left);
-                       assert ((b_bottom >= -1) || (b_bottom <= 1));
+                       assert ((b_bottom >= -1) && (b_bottom <= 1));
                        if (b_bottom == -1)
                                n = rotate_left_right (t, n);
                        else
@@ -485,7 +485,7 @@ c_avl_tree_t *c_avl_create (int (*compare) (const void *, const void *))
        if (compare == NULL)
                return (NULL);
 
-       if ((t = (c_avl_tree_t *) malloc (sizeof (c_avl_tree_t))) == NULL)
+       if ((t = malloc (sizeof (*t))) == NULL)
                return (NULL);
 
        t->root = NULL;
@@ -509,7 +509,7 @@ int c_avl_insert (c_avl_tree_t *t, void *key, void *value)
        c_avl_node_t *nptr;
        int cmp;
 
-       if ((new = (c_avl_node_t *) malloc (sizeof (c_avl_node_t))) == NULL)
+       if ((new = malloc (sizeof (*new))) == NULL)
                return (-1);
 
        new->key = key;
@@ -652,6 +652,7 @@ int c_avl_pick (c_avl_tree_t *t, void **key, void **value)
        *value = n->value;
 
        free_node (n);
+       --t->size;
        rebalance (t, p);
 
        return (0);
@@ -664,10 +665,9 @@ c_avl_iterator_t *c_avl_get_iterator (c_avl_tree_t *t)
        if (t == NULL)
                return (NULL);
 
-       iter = (c_avl_iterator_t *) malloc (sizeof (c_avl_iterator_t));
+       iter = calloc (1, sizeof (*iter));
        if (iter == NULL)
                return (NULL);
-       memset (iter, '\0', sizeof (c_avl_iterator_t));
        iter->tree = t;
 
        return (iter);
index 2a8244c..489d60f 100644 (file)
@@ -24,8 +24,9 @@
  *   Florian octo Forster <octo at collectd.org>
  */
 
-#include "testing.h"
+#include "common.h" /* STATIC_ARRAY_SIZE */
 #include "collectd.h"
+#include "testing.h"
 #include "utils_avltree.h"
 
 static int compare_total_count = 0;
@@ -42,30 +43,99 @@ static int compare_callback (void const *v0, void const *v1)
 
 DEF_TEST(success)
 {
+  struct {
+    char *key;
+    char *value;
+  } cases[] = {
+    {"Eeph7chu", "vai1reiV"},
+    {"igh3Paiz", "teegh1Ee"},
+    {"caip6Uu8", "ooteQu8n"},
+    {"Aech6vah", "AijeeT0l"},
+    {"Xah0et2L", "gah8Taep"},
+    {"BocaeB8n", "oGaig8io"},
+    {"thai8AhM", "ohjeFo3f"},
+    {"ohth6ieC", "hoo8ieWo"},
+    {"aej7Woow", "phahuC2s"},
+    {"Hai8ier2", "Yie6eimi"},
+    {"phuXi3Li", "JaiF7ieb"},
+    {"Shaig5ef", "aihi5Zai"},
+    {"voh6Aith", "Oozaeto0"},
+    {"zaiP5kie", "seep5veM"},
+    {"pae7ba7D", "chie8Ojo"},
+    {"Gou2ril3", "ouVoo0ha"},
+    {"lo3Thee3", "ahDu4Zuj"},
+    {"Rah8kohv", "ieShoc7E"},
+    {"ieN5engi", "Aevou1ah"},
+    {"ooTe4OhP", "aingai5Y"},
+  };
+
   c_avl_tree_t *t;
-  char key_orig[] = "foo";
-  char value_orig[] = "bar";
-  char *key_ret = NULL;
-  char *value_ret = NULL;
+  size_t i;
 
   RESET_COUNTS ();
-  t = c_avl_create (compare_callback);
-  OK (t != NULL);
+  CHECK_NOT_NULL (t = c_avl_create (compare_callback));
+
+  /* insert */
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  {
+    char *key;
+    char *value;
 
-  OK (c_avl_insert (t, key_orig, value_orig) == 0);
-  OK (c_avl_size (t) == 1);
+    CHECK_NOT_NULL (key = strdup (cases[i].key));
+    CHECK_NOT_NULL (value = strdup (cases[i].value));
+
+    CHECK_ZERO (c_avl_insert (t, key, value));
+    EXPECT_EQ_INT ((int) (i + 1), c_avl_size (t));
+  }
 
   /* Key already exists. */
-  OK (c_avl_insert (t, "foo", "qux") > 0);
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+    EXPECT_EQ_INT (1, c_avl_insert (t, cases[i].key, cases[i].value));
+
+  /* get */
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  {
+    char *value_ret = NULL;
+
+    CHECK_ZERO (c_avl_get (t, cases[i].key, (void *) &value_ret));
+    EXPECT_EQ_STR (cases[i].value, value_ret);
+  }
+
+  /* remove half */
+  for (i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
+  {
+    char *key = NULL;
+    char *value = NULL;
+
+    int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+    CHECK_ZERO (c_avl_remove (t, cases[i].key, (void *) &key, (void *) &value));
+
+    EXPECT_EQ_STR (cases[i].key, key);
+    EXPECT_EQ_STR (cases[i].value, value);
+
+    free (key);
+    free (value);
+
+    EXPECT_EQ_INT (expected_size, c_avl_size (t));
+  }
+
+  /* pick the other half */
+  for (i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
+  {
+    char *key = NULL;
+    char *value = NULL;
+
+    int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+    EXPECT_EQ_INT (expected_size + 1, c_avl_size (t));
+    EXPECT_EQ_INT (0, c_avl_pick (t, (void *) &key, (void *) &value));
 
-  OK (c_avl_get (t, "foo", (void *) &value_ret) == 0);
-  OK (value_ret == &value_orig[0]);
+    free (key);
+    free (value);
 
-  key_ret = value_ret = NULL;
-  OK (c_avl_remove (t, "foo", (void *) &key_ret, (void *) &value_ret) == 0);
-  OK (key_ret == &key_orig[0]);
-  OK (value_ret == &value_orig[0]);
-  OK (c_avl_size (t) == 0);
+    EXPECT_EQ_INT (expected_size, c_avl_size (t));
+  }
 
   c_avl_destroy (t);
 
index 3f7a596..9328d7a 100644 (file)
@@ -83,13 +83,12 @@ static cache_entry_t *cache_alloc (size_t values_num)
 {
   cache_entry_t *ce;
 
-  ce = (cache_entry_t *) malloc (sizeof (cache_entry_t));
+  ce = calloc (1, sizeof (*ce));
   if (ce == NULL)
   {
-    ERROR ("utils_cache: cache_alloc: malloc failed.");
+    ERROR ("utils_cache: cache_alloc: calloc failed.");
     return (NULL);
   }
-  memset (ce, '\0', sizeof (cache_entry_t));
   ce->values_num = values_num;
 
   ce->values_gauge = calloc (values_num, sizeof (*ce->values_gauge));
@@ -193,12 +192,13 @@ static int uc_insert (const data_set_t *ds, const value_list_t *vl,
            / CDTIME_T_TO_DOUBLE (vl->interval);
        ce->values_raw[i].absolute = vl->values[i].absolute;
        break;
-       
+
       default:
        /* This shouldn't happen. */
        ERROR ("uc_insert: Don't know how to handle data source type %i.",
            ds->ds[i].type);
        sfree (key_copy);
+       cache_free (ce);
        return (-1);
     } /* switch (ds->ds[i].type) */
   } /* for (i) */
@@ -246,7 +246,7 @@ int uc_check_timeout (void)
 
   int status;
   int i;
-  
+
   pthread_mutex_lock (&cache_lock);
 
   now = cdtime ();
@@ -263,7 +263,7 @@ int uc_check_timeout (void)
       continue;
 
     /* If entry has not been updated, add to `keys' array */
-    tmp = (char **) realloc ((void *) keys,
+    tmp = realloc ((void *) keys,
        (keys_len + 1) * sizeof (char *));
     if (tmp == NULL)
     {
@@ -498,7 +498,7 @@ int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_val
     else
     {
       ret_num = ce->values_num;
-      ret = (gauge_t *) malloc (ret_num * sizeof (gauge_t));
+      ret = malloc (ret_num * sizeof (*ret));
       if (ret == NULL)
       {
         ERROR ("utils_cache: uc_get_rate_by_name: malloc failed.");
@@ -558,7 +558,7 @@ gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
   return (ret);
 } /* gauge_t *uc_get_rate */
 
-size_t uc_get_size() {
+size_t uc_get_size (void) {
   size_t size_arrays = 0;
 
   pthread_mutex_lock (&cache_lock);
@@ -735,7 +735,6 @@ int uc_get_history_by_name (const char *name,
   if (ce->history_length < num_steps)
   {
     gauge_t *tmp;
-    size_t i;
 
     tmp = realloc (ce->history, sizeof (*ce->history)
        * num_steps * ce->values_num);
index ea3eb2f..75bfc42 100644 (file)
@@ -40,7 +40,7 @@ int uc_update (const data_set_t *ds, const value_list_t *vl);
 int uc_get_rate_by_name (const char *name, gauge_t **ret_values, size_t *ret_values_num);
 gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl);
 
-size_t uc_get_size();
+size_t uc_get_size (void);
 int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number);
 
 int uc_get_state (const data_set_t *ds, const value_list_t *vl);
index 6193614..1cf6c3a 100644 (file)
@@ -102,4 +102,3 @@ void c_do_release (int level, c_complain_t *c, const char *format, ...)
 } /* c_release */
 
 /* vim: set sw=4 ts=4 tw=78 noexpandtab : */
-
index 390f961..9d96d35 100644 (file)
@@ -66,6 +66,7 @@ typedef struct
  *   `c'      Identifier for the complaint.
  *   `format' Message format - see the documentation of printf(3).
  */
+__attribute__ ((format(printf,3,4)))
 void c_complain (int level, c_complain_t *c, const char *format, ...);
 
 /*
@@ -80,6 +81,7 @@ void c_complain (int level, c_complain_t *c, const char *format, ...);
  *
  *   See `c_complain' for further details and a description of the parameters.
  */
+__attribute__ ((format(printf,3,4)))
 void c_complain_once (int level, c_complain_t *c, const char *format, ...);
 
 /*
@@ -101,6 +103,7 @@ void c_complain_once (int level, c_complain_t *c, const char *format, ...);
  *
  *   See `c_complain' for a description of the parameters.
  */
+__attribute__ ((format(printf,3,4)))
 void c_do_release (int level, c_complain_t *c, const char *format, ...);
 #define c_release(level, c, ...) \
        do { \
index 1b5dca7..19b1d5b 100644 (file)
@@ -112,14 +112,13 @@ c_heap_t *c_heap_create (int (*compare) (const void *, const void *))
   if (compare == NULL)
     return (NULL);
 
-  h = malloc (sizeof (*h));
+  h = calloc (1, sizeof (*h));
   if (h == NULL)
     return (NULL);
 
-  memset (h, 0, sizeof (*h));
   pthread_mutex_init (&h->lock, /* attr = */ NULL);
   h->compare = compare;
-  
+
   h->list = NULL;
   h->list_len = 0;
   h->list_size = 0;
@@ -174,7 +173,7 @@ int c_heap_insert (c_heap_t *h, void *ptr)
 
   /* Reorganize the heap from bottom up. */
   reheap (h, /* parent of this node = */ (index - 1) / 2, DIR_UP);
-  
+
   pthread_mutex_unlock (&h->lock);
   return (0);
 } /* int c_heap_insert */
index 53d0fba..6ef8047 100644 (file)
@@ -24,8 +24,8 @@
  *   Florian octo Forster <octo at collectd.org>
  */
 
-#include "testing.h"
 #include "collectd.h"
+#include "testing.h"
 #include "utils_heap.h"
 
 static int compare (void const *v0, void const *v1)
diff --git a/src/daemon/utils_ignorelist.c b/src/daemon/utils_ignorelist.c
new file mode 100644 (file)
index 0000000..311cb07
--- /dev/null
@@ -0,0 +1,335 @@
+/**
+ * collectd - src/utils_ignorelist.c
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ * Copyright (C) 2008 Florian Forster <octo at collectd.org>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Lubos Stanek <lubek at users.sourceforge.net>
+ *   Florian Forster <octo at collectd.org>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+/**
+ * Usage:
+ *
+ * Define plugin's global pointer variable of type ignorelist_t:
+ *   ignorelist_t *myconfig_ignore;
+ * If you know the state of the global ignore (IgnoreSelected),
+ * allocate the variable with:
+ *   myconfig_ignore = ignorelist_create (YourKnownIgnore);
+ * If you do not know the state of the global ignore,
+ * initialize the global variable and set the ignore flag later:
+ *   myconfig_ignore = ignorelist_init ();
+ * Append single entries in your cf_register'ed callback function:
+ *   ignorelist_add (myconfig_ignore, newentry);
+ * When you hit the IgnoreSelected config option,
+ * offer it to the list:
+ *   ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
+ * That is all for the ignorelist initialization.
+ * Later during read and write (plugin's registered functions) get
+ * the information whether this entry would be collected or not:
+ *   if (ignorelist_match (myconfig_ignore, thisentry))
+ *     return;
+ **/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "common.h"
+#include "plugin.h"
+#include "utils_ignorelist.h"
+
+/*
+ * private prototypes
+ */
+struct ignorelist_item_s
+{
+#if HAVE_REGEX_H
+       regex_t *rmatch;        /* regular expression entry identification */
+#endif
+       char *smatch;           /* string entry identification */
+       struct ignorelist_item_s *next;
+};
+typedef struct ignorelist_item_s ignorelist_item_t;
+
+struct ignorelist_s
+{
+       int ignore;             /* ignore entries */
+       ignorelist_item_t *head;        /* pointer to the first entry */
+};
+
+/* *** *** *** ********************************************* *** *** *** */
+/* *** *** *** *** *** ***   private functions   *** *** *** *** *** *** */
+/* *** *** *** ********************************************* *** *** *** */
+
+static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
+{
+       assert ((il != NULL) && (item != NULL));
+
+       item->next = il->head;
+       il->head = item;
+}
+
+#if HAVE_REGEX_H
+static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
+{
+       regex_t *re;
+       ignorelist_item_t *entry;
+       int status;
+
+       re = calloc (1, sizeof (*re));
+       if (re == NULL)
+       {
+               ERROR ("ignorelist_append_regex: calloc failed.");
+               return (ENOMEM);
+       }
+
+       status = regcomp (re, re_str, REG_EXTENDED);
+       if (status != 0)
+       {
+               char errbuf[1024];
+               (void) regerror (status, re, errbuf, sizeof (errbuf));
+               ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
+               ERROR ("ignorelist_append_regex: Compiling regular expression \"%s\" failed: %s", re_str, errbuf);
+               sfree (re);
+               return (status);
+       }
+
+       entry = calloc (1, sizeof (*entry));
+       if (entry == NULL)
+       {
+               ERROR ("ignorelist_append_regex: calloc failed.");
+               regfree (re);
+               sfree (re);
+               return (ENOMEM);
+       }
+       entry->rmatch = re;
+
+       ignorelist_append (il, entry);
+       return (0);
+} /* int ignorelist_append_regex */
+#endif
+
+static int ignorelist_append_string(ignorelist_t *il, const char *entry)
+{
+       ignorelist_item_t *new;
+
+       /* create new entry */
+       if ((new = calloc(1, sizeof (*new))) == NULL )
+       {
+               ERROR ("cannot allocate new entry");
+               return (1);
+       }
+       new->smatch = sstrdup(entry);
+
+       /* append new entry */
+       ignorelist_append (il, new);
+
+       return (0);
+} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
+
+#if HAVE_REGEX_H
+/*
+ * check list for entry regex match
+ * return 1 if found
+ */
+static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
+{
+       assert ((item != NULL) && (item->rmatch != NULL)
+                       && (entry != NULL) && (strlen (entry) > 0));
+
+       /* match regex */
+       if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
+               return (1);
+
+       return (0);
+} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
+#endif
+
+/*
+ * check list for entry string match
+ * return 1 if found
+ */
+static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
+{
+       assert ((item != NULL) && (item->smatch != NULL)
+                       && (entry != NULL) && (strlen (entry) > 0));
+
+       if (strcmp (entry, item->smatch) == 0)
+               return (1);
+
+       return (0);
+} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
+
+
+/* *** *** *** ******************************************** *** *** *** */
+/* *** *** *** *** *** ***   public functions   *** *** *** *** *** *** */
+/* *** *** *** ******************************************** *** *** *** */
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert)
+{
+       ignorelist_t *il;
+
+       il = calloc (1, sizeof (*il));
+       if (il == NULL)
+               return NULL;
+
+       /*
+        * ->ignore == 0  =>  collect
+        * ->ignore == 1  =>  ignore
+        */
+       il->ignore = invert ? 0 : 1;
+
+       return (il);
+} /* ignorelist_t *ignorelist_create (int ignore) */
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il)
+{
+       ignorelist_item_t *this;
+       ignorelist_item_t *next;
+
+       if (il == NULL)
+               return;
+
+       for (this = il->head; this != NULL; this = next)
+       {
+               next = this->next;
+#if HAVE_REGEX_H
+               if (this->rmatch != NULL)
+               {
+                       regfree (this->rmatch);
+                       sfree (this->rmatch);
+                       this->rmatch = NULL;
+               }
+#endif
+               if (this->smatch != NULL)
+               {
+                       sfree (this->smatch);
+                       this->smatch = NULL;
+               }
+               sfree (this);
+       }
+
+       sfree (il);
+} /* void ignorelist_destroy (ignorelist_t *il) */
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert)
+{
+       if (il == NULL)
+       {
+               DEBUG("ignore call with ignorelist_t == NULL");
+               return;
+       }
+
+       il->ignore = invert ? 0 : 1;
+} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
+
+/*
+ * append entry into ignorelist_t
+ * return 0 for success
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry)
+{
+       size_t len;
+
+       if (il == NULL)
+       {
+               DEBUG ("add called with ignorelist_t == NULL");
+               return (1);
+       }
+
+       len = strlen (entry);
+
+       /* append nothing */
+       if (len == 0)
+       {
+               DEBUG("not appending: empty entry");
+               return (1);
+       }
+
+#if HAVE_REGEX_H
+       /* regex string is enclosed in "/.../" */
+       if ((len > 2) && (entry[0] == '/') && entry[len - 1] == '/')
+       {
+               char *copy;
+               int status;
+
+               /* skip leading slash */
+               copy = strdup (entry + 1);
+               if (copy == NULL)
+                       return ENOMEM;
+
+               /* trim trailing slash */
+               copy[strlen (copy) - 1] = 0;
+
+               status = ignorelist_append_regex (il, copy);
+               sfree (copy);
+               return status;
+       }
+#endif
+
+       return ignorelist_append_string(il, entry);
+} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry)
+{
+       ignorelist_item_t *traverse;
+
+       /* if no entries, collect all */
+       if ((il == NULL) || (il->head == NULL))
+               return (0);
+
+       if ((entry == NULL) || (strlen (entry) == 0))
+               return (0);
+
+       /* traverse list and check entries */
+       for (traverse = il->head; traverse != NULL; traverse = traverse->next)
+       {
+#if HAVE_REGEX_H
+               if (traverse->rmatch != NULL)
+               {
+                       if (ignorelist_match_regex (traverse, entry))
+                               return (il->ignore);
+               }
+               else
+#endif
+               {
+                       if (ignorelist_match_string (traverse, entry))
+                               return (il->ignore);
+               }
+       } /* for traverse */
+
+       return (1 - il->ignore);
+} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
+
diff --git a/src/daemon/utils_ignorelist.h b/src/daemon/utils_ignorelist.h
new file mode 100644 (file)
index 0000000..db7535f
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * collectd - src/utils_ignorelist.h
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Lubos Stanek <lubek at users.sourceforge.net>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+
+#ifndef UTILS_IGNORELIST_H
+#define UTILS_IGNORELIST_H 1
+
+#include "collectd.h"
+
+#if HAVE_REGEX_H
+# include <regex.h>
+#endif
+
+/* public prototypes */
+
+struct ignorelist_s;
+typedef struct ignorelist_s ignorelist_t;
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert);
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il);
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert);
+
+/*
+ * append entry to ignorelist_t
+ * returns zero on success, non-zero upon failure.
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry);
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry);
+
+#endif /* UTILS_IGNORELIST_H */
index 4265286..1a6188f 100644 (file)
@@ -48,12 +48,10 @@ llist_t *llist_create (void)
 {
        llist_t *ret;
 
-       ret = (llist_t *) malloc (sizeof (llist_t));
+       ret = calloc (1, sizeof (*ret));
        if (ret == NULL)
                return (NULL);
 
-       memset (ret, '\0', sizeof (llist_t));
-
        return (ret);
 }
 
@@ -78,7 +76,7 @@ llentry_t *llentry_create (char *key, void *value)
 {
        llentry_t *e;
 
-       e = (llentry_t *) malloc (sizeof (llentry_t));
+       e = malloc (sizeof (*e));
        if (e)
        {
                e->key   = key;
index 5083b05..cf87b6b 100644 (file)
@@ -63,7 +63,7 @@ static char *match_substr (const char *str, int begin, int end)
   }
 
   ret_len = end - begin;
-  ret = (char *) malloc (sizeof (char) * (ret_len + 1));
+  ret = malloc (ret_len + 1);
   if (ret == NULL)
   {
     ERROR ("utils_match: match_substr: malloc failed.");
@@ -238,10 +238,9 @@ cu_match_t *match_create_callback (const char *regex, const char *excluderegex,
   DEBUG ("utils_match: match_create_callback: regex = %s, excluderegex = %s",
         regex, excluderegex);
 
-  obj = (cu_match_t *) malloc (sizeof (cu_match_t));
+  obj = calloc (1, sizeof (*obj));
   if (obj == NULL)
     return (NULL);
-  memset (obj, '\0', sizeof (cu_match_t));
 
   status = regcomp (&obj->regex, regex, REG_EXTENDED | REG_NEWLINE);
   if (status != 0)
@@ -275,10 +274,9 @@ cu_match_t *match_create_simple (const char *regex,
   cu_match_value_t *user_data;
   cu_match_t *obj;
 
-  user_data = (cu_match_value_t *) malloc (sizeof (cu_match_value_t));
+  user_data = calloc (1, sizeof (*user_data));
   if (user_data == NULL)
     return (NULL);
-  memset (user_data, '\0', sizeof (cu_match_value_t));
   user_data->ds_type = match_ds_type;
 
   obj = match_create_callback (regex, excluderegex,
index b873845..fee0871 100644 (file)
 
 #include "collectd.h"
 #include "utils_time.h"
+#include "utils_random.h"
 
 #include <pthread.h>
 
+
 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 static _Bool have_seed = 0;
 static unsigned short seed[3];
index 43634df..9284f73 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "collectd.h"
 #include "common.h"
+#include "utils_subst.h"
 
 char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t off2,
                const char *replacement)
@@ -101,7 +102,7 @@ char *asubst (const char *string, int off1, int off2, const char *replacement)
 
        len = off1 + strlen (replacement) + strlen (string) - off2 + 1;
 
-       buf = (char *)malloc (len);
+       buf = malloc (len);
        if (NULL == buf)
                return NULL;
 
index 9085286..50df9c7 100644 (file)
@@ -66,7 +66,7 @@
  *
  * The function returns 'buf' on success, NULL else.
  */
-char *subst (char *buf, size_t buflen, const char *string, int off1, int off2,
+char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t off2,
                const char *replacement);
 
 /*
index c12aa10..953ccc4 100644 (file)
@@ -24,9 +24,9 @@
  *   Florian octo Forster <octo at collectd.org>
  */
 
-#include "testing.h"
-#include "collectd.h"
 #include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
 #include "utils_subst.h"
 
 #if HAVE_LIBKSTAT
@@ -36,11 +36,11 @@ kstat_ctl_t *kc;
 DEF_TEST(subst)
 {
   struct {
-    char *str;
+    const char *str;
     int off1;
     int off2;
-    char *rplmt;
-    char *want;
+    const char *rplmt;
+    const char *want;
   } cases[] = {
     {"foo_____bar", 3, 8, " - ", "foo - bar"}, /* documentation example */
     {"foo bar", 0, 2, "m",     "mo bar"},    /* beginning, shorten */
@@ -95,7 +95,10 @@ DEF_TEST(subst)
 DEF_TEST(subst_string)
 {
   struct {
-    char *str;          char *srch; char *rplmt; char *want;
+    const char *str;
+    const char *srch;
+    const char *rplmt;
+    const char *want;
   } cases[] = {
     {"Hello %{name}",    "%{name}", "world", "Hello world"},
     {"abcccccc",         "abc",     "cab",   "ccccccab"},
index fe5dca8..0b0a8fb 100644 (file)
@@ -119,10 +119,9 @@ cu_tail_t *cu_tail_create (const char *file)
 {
        cu_tail_t *obj;
 
-       obj = (cu_tail_t *) malloc (sizeof (cu_tail_t));
+       obj = calloc (1, sizeof (*obj));
        if (obj == NULL)
                return (NULL);
-       memset (obj, '\0', sizeof (cu_tail_t));
 
        obj->file = strdup (file);
        if (obj->file == NULL)
index 8776ad1..1aeb814 100644 (file)
@@ -126,10 +126,9 @@ cu_tail_match_t *tail_match_create (const char *filename)
 {
   cu_tail_match_t *obj;
 
-  obj = (cu_tail_match_t *) malloc (sizeof (cu_tail_match_t));
+  obj = calloc (1, sizeof (*obj));
   if (obj == NULL)
     return (NULL);
-  memset (obj, '\0', sizeof (cu_tail_match_t));
 
   obj->tail = cu_tail_create (filename);
   if (obj->tail == NULL)
@@ -180,7 +179,7 @@ int tail_match_add_match (cu_tail_match_t *obj, cu_match_t *match,
 {
   cu_tail_match_match_t *temp;
 
-  temp = (cu_tail_match_match_t *) realloc (obj->matches,
+  temp = realloc (obj->matches,
       sizeof (cu_tail_match_match_t) * (obj->matches_num + 1));
   if (temp == NULL)
     return (-1);
@@ -212,13 +211,12 @@ int tail_match_add_match_simple (cu_tail_match_t *obj,
   if (match == NULL)
     return (-1);
 
-  user_data = (cu_tail_match_simple_t *) malloc (sizeof (cu_tail_match_simple_t));
+  user_data = calloc (1, sizeof (*user_data));
   if (user_data == NULL)
   {
     match_destroy (match);
     return (-1);
   }
-  memset (user_data, '\0', sizeof (cu_tail_match_simple_t));
 
   sstrncpy (user_data->plugin, plugin, sizeof (user_data->plugin));
   if (plugin_instance != NULL)
index bf097fa..a5c3373 100644 (file)
@@ -59,7 +59,7 @@ threshold_t *threshold_get (const char *hostname,
 
 threshold_t *threshold_search (const value_list_t *vl);
 
-int ut_search_threshold (const value_list_t *vl, 
+int ut_search_threshold (const value_list_t *vl,
   threshold_t *ret_threshold);
 
 #endif /* UTILS_THRESHOLD_H */
index 5d905d9..56c250c 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/utils_time.c
- * Copyright (C) 2010       Florian octo Forster
+ * Copyright (C) 2010-2015  Florian octo Forster
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -21,7 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Florian octo Forster <ff at octo.it>
+ *   Florian octo Forster <octo at collectd.org>
  **/
 
 #include "collectd.h"
 #include "plugin.h"
 #include "common.h"
 
-#if HAVE_CLOCK_GETTIME
+#ifndef DEFAULT_MOCK_TIME
+# define DEFAULT_MOCK_TIME 1542455354518929408ULL
+#endif
+
+#ifdef MOCK_TIME
+cdtime_t cdtime_mock = (cdtime_t) MOCK_TIME;
+
+cdtime_t cdtime (void)
+{
+  return cdtime_mock;
+}
+#else /* !MOCK_TIME */
+# if HAVE_CLOCK_GETTIME
 cdtime_t cdtime (void) /* {{{ */
 {
   int status;
@@ -46,7 +58,7 @@ cdtime_t cdtime (void) /* {{{ */
 
   return (TIMESPEC_TO_CDTIME_T (&ts));
 } /* }}} cdtime_t cdtime */
-#else
+# else /* !HAVE_CLOCK_GETTIME */
 /* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */
 cdtime_t cdtime (void) /* {{{ */
 {
@@ -64,43 +76,95 @@ cdtime_t cdtime (void) /* {{{ */
 
   return (TIMEVAL_TO_CDTIME_T (&tv));
 } /* }}} cdtime_t cdtime */
+# endif
 #endif
 
-size_t cdtime_to_iso8601 (char *s, size_t max, cdtime_t t) /* {{{ */
+/* format_zone reads time zone information from "extern long timezone", exported
+ * by <time.h>, and formats it according to RFC 3339. This differs from
+ * strftime()'s "%z" format by including a colon between hour and minute. */
+static int format_zone (char *buffer, size_t buffer_size, struct tm const *tm) /* {{{ */
+{
+  char tmp[7];
+  size_t sz;
+
+  if ((buffer == NULL) || (buffer_size < 7))
+    return EINVAL;
+
+  sz = strftime (tmp, sizeof (tmp), "%z", tm);
+  if (sz == 0)
+    return ENOMEM;
+  if (sz != 5)
+  {
+    DEBUG ("format_zone: strftime(\"%%z\") = \"%s\", want \"+hhmm\"", tmp);
+    sstrncpy (buffer, tmp, buffer_size);
+    return 0;
+  }
+
+  buffer[0] = tmp[0];
+  buffer[1] = tmp[1];
+  buffer[2] = tmp[2];
+  buffer[3] = ':';
+  buffer[4] = tmp[3];
+  buffer[5] = tmp[4];
+  buffer[6] = 0;
+
+  return 0;
+} /* }}} int format_zone */
+
+static int format_rfc3339 (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */
 {
   struct timespec t_spec;
   struct tm t_tm;
-
+  char base[20]; /* 2006-01-02T15:04:05 */
+  char nano[11]; /* .999999999 */
+  char zone[7];  /* +00:00 */
+  char *fields[] = {base, nano, zone};
   size_t len;
+  int status;
 
   CDTIME_T_TO_TIMESPEC (t, &t_spec);
   NORMALIZE_TIMESPEC (t_spec);
 
-  if (localtime_r ((time_t *)&t_spec.tv_sec, &t_tm) == NULL) {
+  if (localtime_r (&t_spec.tv_sec, &t_tm) == NULL) {
     char errbuf[1024];
-    ERROR ("cdtime_to_iso8601: localtime_r failed: %s",
-        sstrerror (errno, errbuf, sizeof (errbuf)));
-    return (0);
+    status = errno;
+    ERROR ("format_rfc3339: localtime_r failed: %s",
+        sstrerror (status, errbuf, sizeof (errbuf)));
+    return (status);
   }
 
-  len = strftime (s, max, "%Y-%m-%dT%H:%M:%S", &t_tm);
+  len = strftime (base, sizeof (base), "%Y-%m-%dT%H:%M:%S", &t_tm);
   if (len == 0)
-    return 0;
+    return ENOMEM;
 
-  if (max - len > 2) {
-    int n = snprintf (s + len, max - len, ".%09i", (int)t_spec.tv_nsec);
-    len += (n < 0) ? 0
-      : (((size_t) n) < (max - len)) ? ((size_t) n)
-      : (max - len);
-  }
+  if (print_nano)
+    ssnprintf (nano, sizeof (nano), ".%09ld", (long) t_spec.tv_nsec);
+  else
+    sstrncpy (nano, "", sizeof (nano));
 
-  if (max - len > 3) {
-    size_t n = strftime (s + len, max - len, "%z", &t_tm);
-    len += (n < max - len) ? n : max - len;
-  }
+  status = format_zone (zone, sizeof (zone), &t_tm);
+  if (status != 0)
+    return status;
+
+  if (strjoin (buffer, buffer_size, fields, STATIC_ARRAY_SIZE (fields), "") < 0)
+    return ENOMEM;
+  return 0;
+} /* }}} int format_rfc3339 */
+
+int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+  if (buffer_size < RFC3339_SIZE)
+    return ENOMEM;
+
+  return format_rfc3339 (buffer, buffer_size, t, 0);
+} /* }}} size_t cdtime_to_rfc3339 */
+
+int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+  if (buffer_size < RFC3339NANO_SIZE)
+    return ENOMEM;
 
-  s[max - 1] = '\0';
-  return len;
-} /* }}} size_t cdtime_to_iso8601 */
+  return format_rfc3339 (buffer, buffer_size, t, 1);
+} /* }}} size_t cdtime_to_rfc3339nano */
 
 /* vim: set sw=2 sts=2 et fdm=marker : */
index 2cc84b5..4d88dcc 100644 (file)
 
 #include "collectd.h"
 
+#ifdef TESTING_H
+/* cdtime_mock is the time returned by cdtime() when build with
+ * -DMOCK_TIME */
+extern cdtime_t cdtime_mock;
+#endif
+
 /*
  * "cdtime_t" is a 64bit unsigned integer. The time is stored at a 2^-30 second
  * resolution, i.e. the most significant 34 bit are used to store the time in
@@ -37,7 +43,7 @@
  * manner is that comparing times and calculating differences is as simple as
  * it is with "time_t", i.e. a simple integer comparison / subtraction works.
  */
-/* 
+/*
  * cdtime_t is defined in "collectd.h" */
 /* typedef uint64_t cdtime_t; */
 
 #define CDTIME_T_TO_DOUBLE(t) (((double) (t)) / 1073741824.0)
 #define DOUBLE_TO_CDTIME_T(d) ((cdtime_t) ((d) * 1073741824.0))
 
-#define CDTIME_T_TO_TIMEVAL(cdt,tvp) do {                                    \
-        (tvp)->tv_sec = CDTIME_T_TO_TIME_T (cdt);                            \
-        (tvp)->tv_usec = (suseconds_t) CDTIME_T_TO_US ((cdt) & 0x3fffffff);  \
+#define CDTIME_T_TO_TIMEVAL(cdt,tvp) do { \
+  (tvp)->tv_sec = (time_t) ((cdt) >> 30); \
+  (tvp)->tv_usec = (suseconds_t) ((((cdt) & 0x3fffffff) * 1000000 + (1 << 29)) >> 30); \
 } while (0)
 #define TIMEVAL_TO_CDTIME_T(tv) US_TO_CDTIME_T(1000000 * (tv)->tv_sec + (tv)->tv_usec)
 
-#define CDTIME_T_TO_TIMESPEC(cdt,tsp) do {                                   \
-  (tsp)->tv_sec = CDTIME_T_TO_TIME_T (cdt);                                  \
-  (tsp)->tv_nsec = (long) CDTIME_T_TO_NS ((cdt) & 0x3fffffff);               \
+#define CDTIME_T_TO_TIMESPEC(cdt,tsp) do { \
+  (tsp)->tv_sec = (time_t) ((cdt) >> 30); \
+  (tsp)->tv_nsec = (long) ((((cdt) & 0x3fffffff) * 1000000000 + (1 << 29)) >> 30); \
 } while (0)
-#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000 * (ts)->tv_sec + (ts)->tv_nsec)
+#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000ULL * (ts)->tv_sec + (ts)->tv_nsec)
 
 cdtime_t cdtime (void);
 
-/* format a cdtime_t value in ISO 8601 format:
- * returns the number of characters written to the string (not including the
- * terminating null byte or 0 on error; the function ensures that the string
- * is null terminated */
-size_t cdtime_to_iso8601 (char *s, size_t max, cdtime_t t);
+#define RFC3339_SIZE     26
+#define RFC3339NANO_SIZE 36
+
+/* rfc3339 formats a cdtime_t time in RFC 3339 format with second precision. */
+int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t);
+
+/* rfc3339nano formats a cdtime_t time in RFC 3339 format with nanosecond
+ * precision. */
+int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t);
 
 #endif /* UTILS_TIME_H */
 /* vim: set sw=2 sts=2 et : */
diff --git a/src/daemon/utils_time_mock.c b/src/daemon/utils_time_mock.c
deleted file mode 100644 (file)
index 217515e..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * collectd - src/tests/mock/utils_time.c
- * Copyright (C) 2013       Florian octo Forster
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *   Florian octo Forster <octo at collectd.org>
- */
-
-#include "utils_time.h"
-
-cdtime_t cdtime (void)
-{
-  return ((cdtime_t) 1542455354518929408ULL);
-}
-
index 8eac0b6..4d64991 100644 (file)
@@ -26,8 +26,8 @@
 
 #define DBL_PRECISION 1e-3
 
-#include "testing.h"
 #include "collectd.h"
+#include "testing.h"
 #include "utils_time.h"
 
 DEF_TEST(conversion)
@@ -62,7 +62,7 @@ DEF_TEST(conversion)
     // 1546167831554815222 / 2^30 = 1439981005.6712620165...
     {1546167831554815222ULL, 1439981005.671, 1439981006, 1439981005671ULL, {1439981005, 671262}, {1439981005, 671262017}},
     // 1546167986577716567 / 2^30 = 1439981150.0475896215...
-    {1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150,  47590}, {1439981005,  47589622}},
+    {1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150,  47590}, {1439981150,  47589622}},
   };
   size_t i;
 
@@ -78,10 +78,12 @@ DEF_TEST(conversion)
 
     // cdtime -> us
     CDTIME_T_TO_TIMEVAL (cases[i].t, &tv);
+    EXPECT_EQ_UINT64 (cases[i].tv.tv_sec, tv.tv_sec);
     EXPECT_EQ_UINT64 (cases[i].tv.tv_usec, tv.tv_usec);
 
     // cdtime -> ns
     CDTIME_T_TO_TIMESPEC (cases[i].t, &ts);
+    EXPECT_EQ_UINT64 (cases[i].ts.tv_sec, ts.tv_sec);
     EXPECT_EQ_UINT64 (cases[i].ts.tv_nsec, ts.tv_nsec);
 
     // cdtime -> double
index 94d0762..273cce8 100644 (file)
--- a/src/dbi.c
+++ b/src/dbi.c
@@ -148,7 +148,7 @@ static int cdbi_result_get_field (dbi_result res, /* {{{ */
   else if (src_type == DBI_TYPE_STRING)
   {
     const char *value;
-    
+
     value = dbi_result_get_string_idx (res, index);
     if (value == NULL)
       sstrncpy (buffer, "", buffer_size);
@@ -214,7 +214,7 @@ static void cdbi_database_free (cdbi_database_t *db) /* {{{ */
  *     </Result>
  *     ...
  *   </Query>
- *     
+ *
  *   <Database "plugin_instance1">
  *     Driver "mysql"
  *     Interval 120
@@ -240,7 +240,7 @@ static int cdbi_config_add_database_driver_option (cdbi_database_t *db, /* {{{ *
     return (-1);
   }
 
-  option = (cdbi_driver_option_t *) realloc (db->driver_options,
+  option = realloc (db->driver_options,
       sizeof (*option) * (db->driver_options_num + 1));
   if (option == NULL)
   {
@@ -294,13 +294,12 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  db = (cdbi_database_t *) malloc (sizeof (*db));
+  db = calloc (1, sizeof (*db));
   if (db == NULL)
   {
-    ERROR ("dbi plugin: malloc failed.");
+    ERROR ("dbi plugin: calloc failed.");
     return (-1);
   }
-  memset (db, 0, sizeof (*db));
 
   status = cf_util_get_string (ci, &db->name);
   if (status != 0)
@@ -357,12 +356,11 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
   while ((status == 0) && (db->queries_num > 0))
   {
     size_t j;
-    db->q_prep_areas = (udb_query_preparation_area_t **) calloc (
-        db->queries_num, sizeof (*db->q_prep_areas));
 
+    db->q_prep_areas = calloc (db->queries_num, sizeof (*db->q_prep_areas));
     if (db->q_prep_areas == NULL)
     {
-      WARNING ("dbi plugin: malloc failed");
+      WARNING ("dbi plugin: calloc failed");
       status = -1;
       break;
     }
@@ -388,7 +386,7 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
   {
     cdbi_database_t **temp;
 
-    temp = (cdbi_database_t **) realloc (databases,
+    temp = realloc (databases,
         sizeof (*databases) * (databases_num + 1));
     if (temp == NULL)
     {
@@ -512,7 +510,6 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
 
   column_names = NULL;
   column_values = NULL;
-  res = NULL;
 
   statement = udb_query_get_statement (q);
   assert (statement != NULL);
@@ -548,35 +545,33 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
   }
 
   /* Allocate `column_names' and `column_values'. {{{ */
-  column_names = (char **) calloc (column_num, sizeof (char *));
+  column_names = calloc (column_num, sizeof (*column_names));
   if (column_names == NULL)
   {
-    ERROR ("dbi plugin: malloc failed.");
+    ERROR ("dbi plugin: calloc failed.");
     BAIL_OUT (-1);
   }
 
-  column_names[0] = (char *) calloc (column_num,
-      DATA_MAX_NAME_LEN * sizeof (char));
+  column_names[0] = calloc (column_num, DATA_MAX_NAME_LEN);
   if (column_names[0] == NULL)
   {
-    ERROR ("dbi plugin: malloc failed.");
+    ERROR ("dbi plugin: calloc failed.");
     BAIL_OUT (-1);
   }
   for (i = 1; i < column_num; i++)
     column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;
 
-  column_values = (char **) calloc (column_num, sizeof (char *));
+  column_values = calloc (column_num, sizeof (*column_values));
   if (column_values == NULL)
   {
-    ERROR ("dbi plugin: malloc failed.");
+    ERROR ("dbi plugin: calloc failed.");
     BAIL_OUT (-1);
   }
 
-  column_values[0] = (char *) calloc (column_num,
-      DATA_MAX_NAME_LEN * sizeof (char));
+  column_values[0] = calloc (column_num, DATA_MAX_NAME_LEN);
   if (column_values[0] == NULL)
   {
-    ERROR ("dbi plugin: malloc failed.");
+    ERROR ("dbi plugin: calloc failed.");
     BAIL_OUT (-1);
   }
   for (i = 1; i < column_num; i++)
index cb0ff2f..ff70172 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -53,7 +53,6 @@ static const char *config_keys[] =
        "FSType",
        "IgnoreSelected",
        "ReportByDevice",
-       "ReportReserved",
        "ReportInodes",
        "ValuesAbsolute",
        "ValuesPercentage"
@@ -204,6 +203,7 @@ static int df_read (void)
        {
                unsigned long long blocksize;
                char disk_name[256];
+               cu_mount_t *dup_ptr;
                uint64_t blk_free;
                uint64_t blk_reserved;
                uint64_t blk_used;
@@ -219,6 +219,27 @@ static int df_read (void)
                if (ignorelist_match (il_fstype, mnt_ptr->type))
                        continue;
 
+               /* search for duplicates *in front of* the current mnt_ptr. */
+               for (dup_ptr = mnt_list; dup_ptr != NULL; dup_ptr = dup_ptr->next)
+               {
+                       /* No duplicate found: mnt_ptr is the first of its kind. */
+                       if (dup_ptr == mnt_ptr)
+                       {
+                               dup_ptr = NULL;
+                               break;
+                       }
+
+                       /* Duplicate found: leave non-NULL dup_ptr. */
+                       if (by_device && (strcmp (mnt_ptr->spec_device, dup_ptr->spec_device) == 0))
+                               break;
+                       else if (!by_device && (strcmp (mnt_ptr->dir, dup_ptr->dir) == 0))
+                               break;
+               }
+
+               /* ignore duplicates */
+               if (dup_ptr != NULL)
+                       continue;
+
                if (STATANYFS (mnt_ptr->dir, &statbuf) < 0)
                {
                        char errbuf[1024];
@@ -249,11 +270,7 @@ static int df_read (void)
                else
                {
                        if (strcmp (mnt_ptr->dir, "/") == 0)
-                       {
-                               if (strcmp (mnt_ptr->type, "rootfs") == 0)
-                                       continue;
                                sstrncpy (disk_name, "root", sizeof (disk_name));
-                       }
                        else
                        {
                                int i, len;
index 8f8f370..0d62488 100644 (file)
@@ -106,6 +106,10 @@ typedef struct diskstats
        derive_t avg_read_time;
        derive_t avg_write_time;
 
+       _Bool has_merged;
+       _Bool has_in_progress;
+       _Bool has_io_time;
+
        struct diskstats *next;
 } diskstats_t;
 
@@ -275,10 +279,6 @@ static void disk_submit (const char *plugin_instance,
        value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
 
-       /* Both `ignorelist' and `plugin_instance' may be NULL. */
-       if (ignorelist_match (ignorelist, plugin_instance) != 0)
-         return;
-
        values[0].derive = read;
        values[1].derive = write;
 
@@ -293,44 +293,40 @@ static void disk_submit (const char *plugin_instance,
        plugin_dispatch_values (&vl);
 } /* void disk_submit */
 
-#if KERNEL_LINUX
-static void submit_in_progress (char const *disk_name, gauge_t in_progress)
+#if KERNEL_FREEBSD || KERNEL_LINUX
+static void submit_io_time (char const *plugin_instance, derive_t io_time, derive_t weighted_time)
 {
-       value_t v;
+       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
 
-       if (ignorelist_match (ignorelist, disk_name) != 0)
-         return;
-
-       v.gauge = in_progress;
+       values[0].derive = io_time;
+       values[1].derive = weighted_time;
 
-       vl.values = &v;
-       vl.values_len = 1;
+       vl.values = values;
+       vl.values_len = 2;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
-       sstrncpy (vl.plugin_instance, disk_name, sizeof (vl.plugin_instance));
-       sstrncpy (vl.type, "pending_operations", sizeof (vl.type));
+       sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
+       sstrncpy (vl.type, "disk_io_time", sizeof (vl.type));
 
        plugin_dispatch_values (&vl);
-}
+} /* void submit_io_time */
+#endif /* KERNEL_FREEBSD || KERNEL_LINUX */
 
-static void submit_io_time (char const *plugin_instance, derive_t io_time, derive_t weighted_time)
+#if KERNEL_LINUX
+static void submit_in_progress (char const *disk_name, gauge_t in_progress)
 {
-       value_t values[2];
+       value_t v;
        value_list_t vl = VALUE_LIST_INIT;
 
-       if (ignorelist_match (ignorelist, plugin_instance) != 0)
-         return;
-
-       values[0].derive = io_time;
-       values[1].derive = weighted_time;
+       v.gauge = in_progress;
 
-       vl.values = values;
-       vl.values_len = 2;
+       vl.values = &v;
+       vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
-       sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
-       sstrncpy (vl.type, "disk_io_time", sizeof (vl.type));
+       sstrncpy (vl.plugin_instance, disk_name, sizeof (vl.plugin_instance));
+       sstrncpy (vl.type, "pending_operations", sizeof (vl.type));
 
        plugin_dispatch_values (&vl);
 }
@@ -389,7 +385,7 @@ static signed long long dict_get_value (CFDictionaryRef dict, const char *key)
                DEBUG ("CFStringCreateWithCString (%s) failed.", key);
                return (-1LL);
        }
-       
+
        /* get => we don't need to release (== free) the object */
        val_obj = (CFNumberRef) CFDictionaryGetValue (dict, key_obj);
 
@@ -504,6 +500,15 @@ static int disk_read (void)
                else
                        ssnprintf (disk_name, sizeof (disk_name), "%i-%i", disk_major, disk_minor);
 
+               DEBUG ("disk plugin: disk_name = \"%s\"", disk_name);
+
+               /* check the name against ignore list */
+               if (ignorelist_match (ignorelist, disk_name) != 0) {
+                       CFRelease (props_dict);
+                       IOObjectRelease (disk);
+                       continue;
+               }
+
                /* extract the stats */
                read_ops  = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsReadsKey);
                read_byt  = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesReadKey);
@@ -515,7 +520,6 @@ static int disk_read (void)
                IOObjectRelease (disk);
 
                /* and submit */
-               DEBUG ("disk plugin: disk_name = \"%s\"", disk_name);
                if ((read_byt != -1LL) || (write_byt != -1LL))
                        disk_submit (disk_name, "disk_octets", read_byt, write_byt);
                if ((read_ops != -1LL) || (write_ops != -1LL))
@@ -536,7 +540,7 @@ static int disk_read (void)
        struct gident *geom_id;
 
        const char *disk_name;
-       long double read_time, write_time;
+       long double read_time, write_time, busy_time, total_duration;
 
        for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) {
                if (snap != NULL)
@@ -613,6 +617,9 @@ static int disk_read (void)
 
                disk_name = ((struct gprovider *)geom_id->lg_ptr)->lg_name;
 
+               if (ignorelist_match (ignorelist, disk_name) != 0)
+                       continue;
+
                if ((snap_iter->bytes[DEVSTAT_READ] != 0) || (snap_iter->bytes[DEVSTAT_WRITE] != 0)) {
                        disk_submit(disk_name, "disk_octets",
                                        (derive_t)snap_iter->bytes[DEVSTAT_READ],
@@ -631,13 +638,23 @@ static int disk_read (void)
                        disk_submit (disk_name, "disk_time",
                                        (derive_t)(read_time*1000), (derive_t)(write_time*1000));
                }
+               if (devstat_compute_statistics(snap_iter, NULL, 1.0,
+                   DSM_TOTAL_BUSY_TIME, &busy_time,
+                   DSM_TOTAL_DURATION, &total_duration,
+                   DSM_NONE) != 0) {
+                       WARNING("%s", devstat_errbuf);
+               }
+               else
+               {
+                       submit_io_time(disk_name, busy_time, total_duration);
+               }
        }
        geom_stats_snapshot_free(snap);
 
 #elif KERNEL_LINUX
        FILE *fh;
        char buffer[1024];
-       
+
        char *fields[32];
        int numfields;
        int fieldshift = 0;
@@ -681,7 +698,6 @@ static int disk_read (void)
        {
                char *disk_name;
                char *output_name;
-               char *alt_name;
 
                numfields = strsplit (buffer, fields, 32);
 
@@ -819,6 +835,16 @@ static int disk_read (void)
                        ds->read_time = read_time;
                        ds->write_ops = write_ops;
                        ds->write_time = write_time;
+
+                       if (read_merged || write_merged)
+                               ds->has_merged = 1;
+
+                       if (in_progress)
+                               ds->has_in_progress = 1;
+
+                       if (io_time)
+                               ds->has_io_time = 1;
+               
                } /* if (is_disk) */
 
                /* Don't write to the RRDs if we've just started.. */
@@ -841,13 +867,13 @@ static int disk_read (void)
                output_name = disk_name;
 
 #if HAVE_LIBUDEV
-               alt_name = disk_udev_attr_name (handle_udev, disk_name,
-                               conf_udev_name_attr);
-#else
-               alt_name = NULL;
-#endif
+               char *alt_name = disk_udev_attr_name (handle_udev, disk_name, conf_udev_name_attr);
                if (alt_name != NULL)
                        output_name = alt_name;
+#endif
+
+               if (ignorelist_match (ignorelist, output_name) != 0)
+                       continue;
 
                if ((ds->read_bytes != 0) || (ds->write_bytes != 0))
                        disk_submit (output_name, "disk_octets",
@@ -863,14 +889,19 @@ static int disk_read (void)
 
                if (is_disk)
                {
-                       disk_submit (output_name, "disk_merged",
+                       if (ds->has_merged)
+                               disk_submit (output_name, "disk_merged",
                                        read_merged, write_merged);
-                       submit_in_progress (output_name, in_progress);
-                       submit_io_time (output_name, io_time, weighted_time);
+                       if (ds->has_in_progress)
+                               submit_in_progress (output_name, in_progress);
+                       if (ds->has_io_time)
+                               submit_io_time (output_name, io_time, weighted_time);
                } /* if (is_disk) */
 
+#if HAVE_LIBUDEV
                /* release udev-based alternate name, if allocated */
-               free(alt_name);
+               sfree (alt_name);
+#endif
        } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */
 
 #if HAVE_LIBUDEV
@@ -911,6 +942,9 @@ static int disk_read (void)
 
                if (strncmp (ksp[i]->ks_class, "disk", 4) == 0)
                {
+                       if (ignorelist_match (ignorelist, ksp[i]->ks_name) != 0)
+                               continue;
+
                        disk_submit (ksp[i]->ks_name, "disk_octets",
                                        kio.KIO_ROCTETS, kio.KIO_WOCTETS);
                        disk_submit (ksp[i]->ks_name, "disk_ops",
@@ -921,6 +955,9 @@ static int disk_read (void)
                }
                else if (strncmp (ksp[i]->ks_class, "partition", 9) == 0)
                {
+                       if (ignorelist_match (ignorelist, ksp[i]->ks_name) != 0)
+                               continue;
+
                        disk_submit (ksp[i]->ks_name, "disk_octets",
                                        kio.KIO_ROCTETS, kio.KIO_WOCTETS);
                        disk_submit (ksp[i]->ks_name, "disk_ops",
@@ -938,13 +975,19 @@ static int disk_read (void)
 #endif
        int counter;
        char name[DATA_MAX_NAME_LEN];
-       
+
        if ((ds = sg_get_disk_io_stats(&disks)) == NULL)
                return (0);
-               
+
        for (counter=0; counter < disks; counter++) {
                strncpy(name, ds->disk_name, sizeof(name));
                name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
+
+               if (ignorelist_match (ignorelist, name) != 0) {
+                       ds++;
+                       continue;
+               }
+
                disk_submit (name, "disk_octets", ds->read_bytes, ds->write_bytes);
                ds++;
        }
@@ -961,7 +1004,7 @@ static int disk_read (void)
        int rnumdisk;
        int i;
 
-       if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0) 
+       if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0)
        {
                char errbuf[1024];
                WARNING ("disk plugin: perfstat_disk: %s",
@@ -970,14 +1013,14 @@ static int disk_read (void)
        }
 
        if (numdisk != pnumdisk || stat_disk==NULL) {
-               if (stat_disk!=NULL) 
+               if (stat_disk!=NULL)
                        free(stat_disk);
                stat_disk = (perfstat_disk_t *)calloc(numdisk, sizeof(perfstat_disk_t));
-       } 
+       }
        pnumdisk = numdisk;
 
        firstpath.name[0]='\0';
-       if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0) 
+       if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0)
        {
                char errbuf[1024];
                WARNING ("disk plugin: perfstat_disk : %s",
@@ -985,8 +1028,11 @@ static int disk_read (void)
                return (-1);
        }
 
-       for (i = 0; i < rnumdisk; i++) 
+       for (i = 0; i < rnumdisk; i++)
        {
+               if (ignorelist_match (ignorelist, stat_disk[i].name) != 0)
+                       continue;
+
                read_sectors = stat_disk[i].rblks*stat_disk[i].bsize;
                write_sectors = stat_disk[i].wblks*stat_disk[i].bsize;
                disk_submit (stat_disk[i].name, "disk_octets", read_sectors, write_sectors);
index 3421c47..53fa725 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
@@ -94,11 +94,10 @@ static counter_list_t *counter_list_create (counter_list_t **list,
 {
        counter_list_t *entry;
 
-       entry = (counter_list_t *) malloc (sizeof (counter_list_t));
+       entry = calloc (1, sizeof (*entry));
        if (entry == NULL)
                return (NULL);
 
-       memset (entry, 0, sizeof (counter_list_t));
        entry->key = key;
        entry->value = value;
 
index cc306dc..f029894 100644 (file)
@@ -28,7 +28,7 @@
  See: http://www.drbd.org/users-guide/ch-admin.html#s-performance-indicators
 
  version: 8.3.11 (api:88/proto:86-96)
- srcversion: 71955441799F513ACA6DA60 
+ srcversion: 71955441799F513ACA6DA60
   0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r-----
         ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \
                                                pe:0 ua:0 ap:0 ep:1 wo:f oos:0
@@ -142,8 +142,12 @@ static int drbd_read (void)
                                fields, STATIC_ARRAY_SIZE (fields));
 
                /* ignore headers (first two iterations) */
-               if (fields_num < 4)
+               if ((strcmp(fields[0], "version:") == 0) ||
+                               (strcmp(fields[0], "srcversion:") == 0) ||
+                               (strcmp(fields[0], "GIT-hash:") == 0))
+               {
                        continue;
+               }
 
                if (isdigit(fields[0][0]))
                {
index 1bf9add..ea4e785 100644 (file)
@@ -219,7 +219,7 @@ static int email_config (const char *key, const char *value)
 static void type_list_incr (type_list_t *list, char *name, int incr)
 {
        if (NULL == list->head) {
-               list->head = (type_t *)smalloc (sizeof (type_t));
+               list->head = smalloc (sizeof (*list->head));
 
                list->head->name  = sstrdup (name);
                list->head->value = incr;
@@ -236,7 +236,7 @@ static void type_list_incr (type_list_t *list, char *name, int incr)
                }
 
                if (NULL == ptr) {
-                       list->tail->next = (type_t *)smalloc (sizeof (type_t));
+                       list->tail->next = smalloc (sizeof (*list->tail->next));
                        list->tail = list->tail->next;
 
                        list->tail->name  = sstrdup (name);
@@ -305,8 +305,11 @@ static void *collect (void *arg)
                                                break;
                                continue;
                        }
+                       if (len < 3) { /* [a-z] ':' '\n' */
+                               continue;
+                       }
 
-                       line[len - 1] = '\0';
+                       line[len - 1] = 0;
 
                        log_debug ("collect: line = '%s'", line);
 
@@ -329,12 +332,12 @@ static void *collect (void *arg)
                                bytes = atoi (tmp);
 
                                pthread_mutex_lock (&count_mutex);
-                               type_list_incr (&list_count, type, 1);
+                               type_list_incr (&list_count, type, /* increment = */ 1);
                                pthread_mutex_unlock (&count_mutex);
 
                                if (bytes > 0) {
                                        pthread_mutex_lock (&size_mutex);
-                                       type_list_incr (&list_size, type, bytes);
+                                       type_list_incr (&list_size, type, /* increment = */ bytes);
                                        pthread_mutex_unlock (&size_mutex);
                                }
                        }
@@ -346,14 +349,17 @@ static void *collect (void *arg)
                                pthread_mutex_unlock (&score_mutex);
                        }
                        else if ('c' == line[0]) { /* c:<type1>[,<type2>,...] */
-                               char *ptr  = NULL;
-                               char *type = strtok_r (line + 2, ",", &ptr);
-
-                               do {
-                                       pthread_mutex_lock (&check_mutex);
-                                       type_list_incr (&list_check, type, 1);
-                                       pthread_mutex_unlock (&check_mutex);
-                               } while (NULL != (type = strtok_r (NULL, ",", &ptr)));
+                               char *dummy = line + 2;
+                               char *endptr = NULL;
+                               char *type;
+
+                               pthread_mutex_lock (&check_mutex);
+                               while ((type = strtok_r (dummy, ",", &endptr)) != NULL)
+                               {
+                                       dummy = NULL;
+                                       type_list_incr (&list_check, type, /* increment = */ 1);
+                               }
+                               pthread_mutex_unlock (&check_mutex);
                        }
                        else {
                                log_err ("collect: unknown type '%c'", line[0]);
@@ -383,8 +389,8 @@ static void *open_connection (void __attribute__((unused)) *arg)
 {
        struct sockaddr_un addr;
 
-       char *path  = (NULL == sock_file) ? SOCK_PATH : sock_file;
-       char *group = (NULL == sock_group) ? COLLECTD_GRP_NAME : sock_group;
+       const char *path  = (NULL == sock_file) ? SOCK_PATH : sock_file;
+       const char *group = (NULL == sock_group) ? COLLECTD_GRP_NAME : sock_group;
 
        /* create UNIX socket */
        errno = 0;
@@ -476,10 +482,10 @@ static void *open_connection (void __attribute__((unused)) *arg)
                available_collectors = max_conns;
 
                collectors =
-                       (collector_t **)smalloc (max_conns * sizeof (collector_t *));
+                       smalloc (max_conns * sizeof (*collectors));
 
                for (i = 0; i < max_conns; ++i) {
-                       collectors[i] = (collector_t *)smalloc (sizeof (collector_t));
+                       collectors[i] = smalloc (sizeof (*collectors[i]));
                        collectors[i]->socket = NULL;
 
                        if (0 != (err = plugin_thread_create (&collectors[i]->thread,
@@ -509,28 +515,41 @@ static void *open_connection (void __attribute__((unused)) *arg)
 
                pthread_mutex_unlock (&available_mutex);
 
-               do {
+               while (42) {
                        errno = 0;
-                       if (-1 == (remote = accept (connector_socket, NULL, NULL))) {
-                               if (EINTR != errno) {
-                                       char errbuf[1024];
-                                       disabled = 1;
-                                       close (connector_socket);
-                                       connector_socket = -1;
-                                       log_err ("accept() failed: %s",
-                                                       sstrerror (errno, errbuf, sizeof (errbuf)));
-                                       pthread_exit ((void *)1);
-                               }
+
+                       remote = accept (connector_socket, NULL, NULL);
+                       if (remote == -1) {
+                               char errbuf[1024];
+
+                               if (errno == EINTR)
+                                       continue;
+
+                               disabled = 1;
+                               close (connector_socket);
+                               connector_socket = -1;
+                               log_err ("accept() failed: %s",
+                                                sstrerror (errno, errbuf, sizeof (errbuf)));
+                               pthread_exit ((void *)1);
                        }
-               } while (EINTR == errno);
 
-               connection = (conn_t *)smalloc (sizeof (conn_t));
+                       /* access() succeeded. */
+                       break;
+               }
+
+               connection = calloc (1, sizeof (*connection));
+               if (connection == NULL)
+               {
+                       close (remote);
+                       continue;
+               }
 
                connection->socket = fdopen (remote, "r");
                connection->next   = NULL;
 
                if (NULL == connection->socket) {
                        close (remote);
+                       sfree (connection);
                        continue;
                }
 
@@ -675,7 +694,7 @@ static void copy_type_list (type_list_t *l1, type_list_t *l2)
        for (ptr1 = l1->head, ptr2 = l2->head; NULL != ptr1;
                        ptr1 = ptr1->next, last = ptr2, ptr2 = ptr2->next) {
                if (NULL == ptr2) {
-                       ptr2 = (type_t *)smalloc (sizeof (type_t));
+                       ptr2 = smalloc (sizeof (*ptr2));
                        ptr2->name = NULL;
                        ptr2->next = NULL;
 
index dec14f3..8971f4d 100644 (file)
@@ -104,14 +104,13 @@ static int ethstat_add_map (const oconfig_item_t *ci) /* {{{ */
     return (ENOMEM);
   }
 
-  map = malloc (sizeof (*map));
+  map = calloc (1, sizeof (*map));
   if (map == NULL)
   {
     sfree (key);
-    ERROR ("ethstat plugin: malloc(3) failed.");
+    ERROR ("ethstat plugin: calloc failed.");
     return (ENOMEM);
   }
-  memset (map, 0, sizeof (*map));
 
   sstrncpy (map->type, ci->values[1].value.string, sizeof (map->type));
   if (ci->values_num == 3)
@@ -273,7 +272,7 @@ static int ethstat_read_interface (char *device)
     close (fd);
     sfree (strings);
     sfree (stats);
-    ERROR("ethstat plugin: malloc(3) failed.");
+    ERROR("ethstat plugin: malloc failed.");
     return (-1);
   }
 
old mode 100755 (executable)
new mode 100644 (file)
index f080ad6..85f6cb8
@@ -126,13 +126,12 @@ static int exec_config_exec (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  pl = (program_list_t *) malloc (sizeof (program_list_t));
+  pl = calloc (1, sizeof (*pl));
   if (pl == NULL)
   {
-    ERROR ("exec plugin: malloc failed.");
+    ERROR ("exec plugin: calloc failed.");
     return (-1);
   }
-  memset (pl, '\0', sizeof (program_list_t));
 
   if (strcasecmp ("NotificationExec", ci->key) == 0)
     pl->flags |= PL_NOTIF_ACTION;
@@ -163,16 +162,15 @@ static int exec_config_exec (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  pl->argv = (char **) malloc (ci->values_num * sizeof (char *));
+  pl->argv = calloc (ci->values_num, sizeof (*pl->argv));
   if (pl->argv == NULL)
   {
-    ERROR ("exec plugin: malloc failed.");
+    ERROR ("exec plugin: calloc failed.");
     sfree (pl->exec);
     sfree (pl->user);
     sfree (pl);
     return (-1);
   }
-  memset (pl->argv, '\0', ci->values_num * sizeof (char *));
 
   {
     char *tmp = strrchr (ci->values[1].value.string, '/');
@@ -184,7 +182,7 @@ static int exec_config_exec (oconfig_item_t *ci) /* {{{ */
   pl->argv[0] = strdup (buffer);
   if (pl->argv[0] == NULL)
   {
-    ERROR ("exec plugin: malloc failed.");
+    ERROR ("exec plugin: strdup failed.");
     sfree (pl->argv);
     sfree (pl->exec);
     sfree (pl->user);
@@ -869,8 +867,7 @@ static int exec_notification (const notification_t *n, /* {{{ */
     if (pl->pid != 0)
       continue;
 
-    pln = (program_list_and_notification_t *) malloc (sizeof
-        (program_list_and_notification_t));
+    pln = malloc (sizeof (*pln));
     if (pln == NULL)
     {
       ERROR ("exec plugin: malloc failed.");
index 4c409b5..666dacc 100644 (file)
@@ -98,6 +98,7 @@ static int fhcount_read(void) {
   }
   if (fgets(buffer, buffer_len, fp) == NULL) {
     ERROR("fhcount: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+    fclose(fp);
     return(EXIT_FAILURE);
   }
   fclose(fp);
index 47caf93..c81fdc2 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "collectd.h"
 #include "common.h"
-#include "plugin.h"       
+#include "plugin.h"
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -344,18 +344,18 @@ static int fc_config_add_dir (oconfig_item_t *ci)
   }
 
   /* Initialize `dir' */
-  dir = (fc_directory_conf_t *) malloc (sizeof (*dir));
+  dir = calloc (1, sizeof (*dir));
   if (dir == NULL)
   {
-    ERROR ("filecount plugin: malloc failed.");
+    ERROR ("filecount plugin: calloc failed.");
     return (-1);
   }
-  memset (dir, 0, sizeof (*dir));
 
   dir->path = strdup (ci->values[0].value.string);
   if (dir->path == NULL)
   {
     ERROR ("filecount plugin: strdup failed.");
+    sfree (dir);
     return (-1);
   }
 
@@ -399,7 +399,7 @@ static int fc_config_add_dir (oconfig_item_t *ci)
   {
     fc_directory_conf_t **temp;
 
-    temp = (fc_directory_conf_t **) realloc (directories,
+    temp = realloc (directories,
         sizeof (*directories) * (directories_num + 1));
     if (temp == NULL)
     {
@@ -541,7 +541,7 @@ static int fc_read_dir (fc_directory_conf_t *dir)
 
   if (dir->mtime != 0)
     dir->now = time (NULL);
-    
+
   status = walk_directory (dir->path, fc_read_dir_callback, dir,
       /* include hidden */ (dir->options & FC_HIDDEN) ? 1 : 0);
   if (status != 0)
index c778d48..67e0406 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/gmond.c
- * Copyright (C) 2009,2010  Florian octo Forster
+ * Copyright (C) 2009-2015  Florian octo Forster
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -288,8 +288,14 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
     {
       int yes = 1;
 
-      setsockopt (sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
+      status = setsockopt (sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
           (void *) &yes, sizeof (yes));
+      if (status != 0)
+      {
+        char errbuf[1024];
+        WARNING ("gmond plugin: setsockopt(2) failed: %s",
+                 sstrerror (errno, errbuf, sizeof (errbuf)));
+      }
     }
 
     status = bind (sockets[sockets_num].fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
@@ -317,14 +323,27 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
       }
 
       loop = 1;
-      setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_MULTICAST_LOOP,
+      status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_MULTICAST_LOOP,
           (void *) &loop, sizeof (loop));
+      if (status != 0)
+      {
+        char errbuf[1024];
+        WARNING ("gmond plugin: setsockopt(2) failed: %s",
+                 sstrerror (errno, errbuf, sizeof (errbuf)));
+      }
 
       memset (&mreq, 0, sizeof (mreq));
       mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
       mreq.imr_interface.s_addr = htonl (INADDR_ANY);
-      setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+
+      status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
           (void *) &mreq, sizeof (mreq));
+      if (status != 0)
+      {
+        char errbuf[1024];
+        WARNING ("gmond plugin: setsockopt(2) failed: %s",
+                 sstrerror (errno, errbuf, sizeof (errbuf)));
+      }
     } /* if (ai_ptr->ai_family == AF_INET) */
     else if (ai_ptr->ai_family == AF_INET6)
     {
@@ -341,15 +360,27 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
       }
 
       loop = 1;
-      setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+      status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
           (void *) &loop, sizeof (loop));
+      if (status != 0)
+      {
+        char errbuf[1024];
+        WARNING ("gmond plugin: setsockopt(2) failed: %s",
+                 sstrerror (errno, errbuf, sizeof (errbuf)));
+      }
 
       memset (&mreq, 0, sizeof (mreq));
       memcpy (&mreq.ipv6mr_multiaddr,
           &addr->sin6_addr, sizeof (addr->sin6_addr));
       mreq.ipv6mr_interface = 0; /* any */
-      setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
+      status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
           (void *) &mreq, sizeof (mreq));
+      if (status != 0)
+      {
+        char errbuf[1024];
+        WARNING ("gmond plugin: setsockopt(2) failed: %s",
+                 sstrerror (errno, errbuf, sizeof (errbuf)));
+      }
     } /* if (ai_ptr->ai_family == AF_INET6) */
 
     sockets_num++;
@@ -407,10 +438,19 @@ static int request_meta_data (const char *host, const char *name) /* {{{ */
 
   pthread_mutex_lock (&mc_send_sockets_lock);
   for (i = 0; i < mc_send_sockets_num; i++)
-    sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
+  {
+    ssize_t status = sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
         /* flags = */ 0,
         (struct sockaddr *) &mc_send_sockets[i].addr,
         mc_send_sockets[i].addrlen);
+    if (status == -1)
+    {
+      char errbuf[1024];
+      ERROR ("gmond plugin: sendto(2) failed: %s",
+             sstrerror (errno, errbuf, sizeof (errbuf)));
+      continue;
+    }
+  }
   pthread_mutex_unlock (&mc_send_sockets_lock);
 
   sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
@@ -439,10 +479,9 @@ static staging_entry_t *staging_entry_get (const char *host, /* {{{ */
     return (se);
 
   /* insert new entry */
-  se = (staging_entry_t *) malloc (sizeof (*se));
+  se = calloc (1, sizeof (*se));
   if (se == NULL)
     return (NULL);
-  memset (se, 0, sizeof (*se));
 
   sstrncpy (se->key, key, sizeof (se->key));
   se->flags = 0;
@@ -476,36 +515,6 @@ static staging_entry_t *staging_entry_get (const char *host, /* {{{ */
   return (se);
 } /* }}} staging_entry_t *staging_entry_get */
 
-static int staging_entry_submit (const char *host, const char *name, /* {{{ */
-    staging_entry_t *se)
-{
-  value_list_t vl;
-  value_t values[se->vl.values_len];
-
-  if (se->vl.interval == 0)
-  {
-    /* No meta data has been received for this metric yet. */
-    se->flags = 0;
-    pthread_mutex_unlock (&staging_lock);
-    request_meta_data (host, name);
-    return (0);
-  }
-
-  se->flags = 0;
-
-  memcpy (values, se->vl.values, sizeof (values));
-  memcpy (&vl, &se->vl, sizeof (vl));
-
-  /* Unlock before calling `plugin_dispatch_values'.. */
-  pthread_mutex_unlock (&staging_lock);
-
-  vl.values = values;
-
-  plugin_dispatch_values (&vl);
-
-  return (0);
-} /* }}} int staging_entry_submit */
-
 static int staging_entry_update (const char *host, const char *name, /* {{{ */
     const char *type, const char *type_instance,
     size_t ds_index, int ds_type, value_t value)
@@ -555,17 +564,30 @@ static int staging_entry_update (const char *host, const char *name, /* {{{ */
 
   se->flags |= (0x01 << ds_index);
 
-  /* Check if all values have been set and submit if so. */
-  if (se->flags == ((0x01 << se->vl.values_len) - 1))
+  /* Check if all data sources have been set. If not, return here. */
+  if (se->flags != ((0x01 << se->vl.values_len) - 1))
   {
-    /* `staging_lock' is unlocked in `staging_entry_submit'. */
-    staging_entry_submit (host, name, se);
+    pthread_mutex_unlock (&staging_lock);
+    return (0);
   }
-  else
+
+  /* Check if the interval of this metric is known. If not, request meta data
+   * and return. */
+  if (se->vl.interval == 0)
   {
+    /* No meta data has been received for this metric yet. */
+    se->flags = 0;
     pthread_mutex_unlock (&staging_lock);
+
+    request_meta_data (host, name);
+    return (0);
   }
 
+  plugin_dispatch_values (&se->vl);
+
+  se->flags = 0;
+  pthread_mutex_unlock (&staging_lock);
+
   return (0);
 } /* }}} int staging_entry_update */
 
@@ -915,7 +937,7 @@ static int mc_receive_thread_stop (void) /* {{{ */
   return (0);
 } /* }}} int mc_receive_thread_stop */
 
-/* 
+/*
  * Config:
  *
  * <Plugin gmond>
index e17711e..d05dd72 100644 (file)
@@ -95,6 +95,7 @@ static ignorelist_t *ignorelist = NULL;
 extern kstat_ctl_t *kc;
 static kstat_t *ksp[MAX_NUMIF];
 static int numif = 0;
+static _Bool unique_name = 0;
 #endif /* HAVE_LIBKSTAT */
 
 static int interface_config (const char *key, const char *value)
@@ -113,6 +114,15 @@ static int interface_config (const char *key, const char *value)
                        invert = 0;
                ignorelist_set_invert (ignorelist, invert);
        }
+       else if (strcasecmp (key, "UniqueName") == 0)
+       {
+               #ifdef HAVE_LIBKSTAT
+               if (IS_TRUE (value))
+                       unique_name = 1;
+               #else
+                       WARNING ("interface plugin: the \"UniqueName\" option is only valid on Solaris.");
+               #endif /* HAVE_LIBKSTAT */
+       }
        else
        {
                return (-1);
@@ -180,7 +190,7 @@ static int interface_read (void)
        struct ifaddrs *if_list;
        struct ifaddrs *if_ptr;
 
-/* Darin/Mac OS X and possible other *BSDs */
+/* Darwin/Mac OS X and possible other *BSDs */
 #if HAVE_STRUCT_IF_DATA
 #  define IFA_DATA if_data
 #  define IFA_RX_BYTES ifi_ibytes
@@ -276,6 +286,10 @@ static int interface_read (void)
                incoming = atoll (fields[2]);
                outgoing = atoll (fields[10]);
                if_submit (device, "if_errors", incoming, outgoing);
+
+               incoming = atoll (fields[3]);
+               outgoing = atoll (fields[11]);
+               if_submit (device, "if_dropped", incoming, outgoing);
        }
 
        fclose (fh);
@@ -285,6 +299,7 @@ static int interface_read (void)
        int i;
        derive_t rx;
        derive_t tx;
+       char iname[DATA_MAX_NAME_LEN];
 
        if (kc == NULL)
                return (-1);
@@ -294,6 +309,11 @@ static int interface_read (void)
                if (kstat_read (kc, ksp[i], NULL) == -1)
                        continue;
 
+               if (unique_name)
+                       ssnprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module, ksp[i]->ks_instance, ksp[i]->ks_name);
+               else
+                       sstrncpy(iname, ksp[i]->ks_name, sizeof(iname));
+
                /* try to get 64bit counters */
                rx = get_kstat_value (ksp[i], "rbytes64");
                tx = get_kstat_value (ksp[i], "obytes64");
@@ -303,7 +323,7 @@ static int interface_read (void)
                if (tx == -1LL)
                        tx = get_kstat_value (ksp[i], "obytes");
                if ((rx != -1LL) || (tx != -1LL))
-                       if_submit (ksp[i]->ks_name, "if_octets", rx, tx);
+                       if_submit (iname, "if_octets", rx, tx);
 
                /* try to get 64bit counters */
                rx = get_kstat_value (ksp[i], "ipackets64");
@@ -314,13 +334,13 @@ static int interface_read (void)
                if (tx == -1LL)
                        tx = get_kstat_value (ksp[i], "opackets");
                if ((rx != -1LL) || (tx != -1LL))
-                       if_submit (ksp[i]->ks_name, "if_packets", rx, tx);
+                       if_submit (iname, "if_packets", rx, tx);
 
                /* no 64bit error counters yet */
                rx = get_kstat_value (ksp[i], "ierrors");
                tx = get_kstat_value (ksp[i], "oerrors");
                if ((rx != -1LL) || (tx != -1LL))
-                       if_submit (ksp[i]->ks_name, "if_errors", rx, tx);
+                       if_submit (iname, "if_errors", rx, tx);
        }
 /* #endif HAVE_LIBKSTAT */
 
@@ -348,9 +368,8 @@ static int interface_read (void)
 
        if (pnif != nif || ifstat == NULL)
        {
-               if (ifstat != NULL)
-                       free(ifstat);
-               ifstat = malloc(nif * sizeof(perfstat_netinterface_t));
+               free(ifstat);
+               ifstat = malloc(nif * sizeof (*ifstat));
        }
        pnif = nif;
 
index b403847..00b3a5f 100644 (file)
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -213,7 +213,7 @@ static caddr_t ipc_get_info (cid_t cid, int cmd, int version, int stsize, int *n
 
   *nmemb = size / stsize;
 
-  buff = (caddr_t)malloc (size);
+  buff = malloc (size);
   if (buff == NULL)  {
     ERROR ("ipc plugin: ipc_get_info malloc failed.");
     return (NULL);
@@ -298,7 +298,7 @@ static int ipc_read_msg (void) /* {{{ */
     msg_alloc_queues++;
     msg_used_space += ipcinfo_msg[i].msg_cbytes;
     msg_qnum += ipcinfo_msg[i].msg_qnum;
-
+  }
   free(ipcinfo_msg);
 
   ipc_submit_g("msg", "count", "queues", msg_alloc_queues);
index 51d33dc..76dd9cb 100644 (file)
@@ -279,7 +279,7 @@ static int sensor_list_add (ipmi_sensor_t *sensor)
     {
       /* `sensor_id_ptr' now points to "(123)". */
       ssnprintf (sensor_name, sizeof (sensor_name),
-          "%s %s", sensor_name_ptr, sensor_id_ptr); 
+          "%s %s", sensor_name_ptr, sensor_id_ptr);
     }
     /* else: don't touch sensor_name. */
   }
index 806b7a4..0103725 100644 (file)
@@ -61,14 +61,10 @@ typedef struct ip6tc_handle ip6tc_handle_t;
  */
 static const char *config_keys[] =
 {
-       "Chain",
-       "Chain6"
+    "Chain",
+    "Chain6"
 };
 static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
-/*
-    Each table/chain combo that will be queried goes into this list
-*/
-
 enum protocol_version_e
 {
     IPV4,
@@ -76,6 +72,9 @@ enum protocol_version_e
 };
 typedef enum protocol_version_e protocol_version_t;
 
+/*
+ * Each table/chain combo that will be queried goes into this list
+ */
 #ifndef XT_TABLE_MAXNAMELEN
 # define XT_TABLE_MAXNAMELEN 32
 #endif
@@ -85,14 +84,14 @@ typedef struct {
     char chain[XT_TABLE_MAXNAMELEN];
     union
     {
-       int   num;
-       char *comment;
+        int   num;
+        char *comment;
     } rule;
     enum
     {
-       RTYPE_NUM,
-       RTYPE_COMMENT,
-       RTYPE_COMMENT_ALL
+        RTYPE_NUM,
+        RTYPE_COMMENT,
+        RTYPE_COMMENT_ALL
     } rule_type;
     char name[64];
 } ip_chain_t;
@@ -102,147 +101,142 @@ static int chain_num = 0;
 
 static int iptables_config (const char *key, const char *value)
 {
-       /* int ip_value; */
-       protocol_version_t ip_version = 0;
-
-       if (strcasecmp (key, "Chain") == 0)
-               ip_version = IPV4;
-       else if (strcasecmp (key, "Chain6") == 0)
-               ip_version = IPV6;
-
-       if (( ip_version == IPV4 ) || ( ip_version == IPV6 ))
-       {
-               ip_chain_t temp, *final, **list;
-               char *table;
-               int   table_len;
-               char *chain;
-               int   chain_len;
-
-               char *value_copy;
-               char *fields[4];
-               int   fields_num;
-               
-               memset (&temp, 0, sizeof (temp));
-
-               value_copy = strdup (value);
-               if (value_copy == NULL)
-               {
-                   char errbuf[1024];
-                   ERROR ("strdup failed: %s",
-                           sstrerror (errno, errbuf, sizeof (errbuf)));
-                   return (1);
-               }
-
-               /*
-                *  Time to fill the temp element
-                *  Examine value string, it should look like:
-                *  Chain[6] <table> <chain> [<comment|num> [name]]
-                        */
-
-               /* set IPv4 or IPv6 */
-                temp.ip_version = ip_version;
-
-               /* Chain <table> <chain> [<comment|num> [name]] */
-               fields_num = strsplit (value_copy, fields, 4);
-               if (fields_num < 2)
-               {
-                   free (value_copy);
-                   return (1);
-               }
-
-               table = fields[0];
-               chain = fields[1];
-
-               table_len = strlen (table) + 1;
-               if ((unsigned int)table_len > sizeof(temp.table))
-               {
-                       ERROR ("Table `%s' too long.", table);
-                       free (value_copy);
-                       return (1);
-               }
-               sstrncpy (temp.table, table, table_len);
-
-               chain_len = strlen (chain) + 1;
-               if ((unsigned int)chain_len > sizeof(temp.chain))
-               {
-                       ERROR ("Chain `%s' too long.", chain);
-                       free (value_copy);
-                       return (1);
-               }
-               sstrncpy (temp.chain, chain, chain_len);
-
-               if (fields_num >= 3)
-               {
-                   char *comment = fields[2];
-                   int   rule = atoi (comment);
-
-                   if (rule)
-                   {
-                       temp.rule.num = rule;
-                       temp.rule_type = RTYPE_NUM;
-                   }
-                   else
-                   {
-                       temp.rule.comment = strdup (comment);
-                       if (temp.rule.comment == NULL)
-                       {
-                           free (value_copy);
-                           return (1);
-                       }
-                       temp.rule_type = RTYPE_COMMENT;
-                   }
-               }
-               else
-               {
-                   temp.rule_type = RTYPE_COMMENT_ALL;
-               }
-
-               if (fields_num >= 4)
-                   sstrncpy (temp.name, fields[3], sizeof (temp.name));
-
-               free (value_copy);
-               value_copy = NULL;
-               table = NULL;
-               chain = NULL;
-
-               list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
-               if (list == NULL)
-               {
-                   char errbuf[1024];
-                   ERROR ("realloc failed: %s",
-                           sstrerror (errno, errbuf, sizeof (errbuf)));
-                   sfree (temp.rule.comment);
-                   return (1);
-               }
-
-               chain_list = list;
-               final = (ip_chain_t *) malloc( sizeof(temp) );
-               if (final == NULL) 
-               {
-                   char errbuf[1024];
-                   ERROR ("malloc failed: %s",
-                           sstrerror (errno, errbuf, sizeof (errbuf)));
-                   sfree (temp.rule.comment);
-                   return (1);
-               }
-               memcpy (final, &temp, sizeof (temp));
-               chain_list[chain_num] = final;
-               chain_num++;
-
-               DEBUG ("Chain #%i: table = %s; chain = %s;", chain_num, final->table, final->chain);
-       }
-       else 
-       {
-               return (-1);
-       }
-
-       return (0);
+    /* int ip_value; */
+    protocol_version_t ip_version = 0;
+
+    if (strcasecmp (key, "Chain") == 0)
+        ip_version = IPV4;
+    else if (strcasecmp (key, "Chain6") == 0)
+        ip_version = IPV6;
+    else
+        return (1);
+
+    ip_chain_t temp, *final, **list;
+    char *table;
+    int   table_len;
+    char *chain;
+    int   chain_len;
+
+    char *value_copy;
+    char *fields[4];
+    int   fields_num;
+
+    memset (&temp, 0, sizeof (temp));
+
+    value_copy = strdup (value);
+    if (value_copy == NULL)
+    {
+        char errbuf[1024];
+        ERROR ("strdup failed: %s",
+                sstrerror (errno, errbuf, sizeof (errbuf)));
+        return (1);
+    }
+
+    /*
+     *  Time to fill the temp element
+     *  Examine value string, it should look like:
+     *  Chain[6] <table> <chain> [<comment|num> [name]]
+     */
+
+    /* set IPv4 or IPv6 */
+    temp.ip_version = ip_version;
+
+    /* Chain <table> <chain> [<comment|num> [name]] */
+    fields_num = strsplit (value_copy, fields, 4);
+    if (fields_num < 2)
+    {
+        free (value_copy);
+        return (1);
+    }
+
+    table = fields[0];
+    chain = fields[1];
+
+    table_len = strlen (table) + 1;
+    if ((unsigned int)table_len > sizeof(temp.table))
+    {
+        ERROR ("Table `%s' too long.", table);
+        free (value_copy);
+        return (1);
+    }
+    sstrncpy (temp.table, table, table_len);
+
+    chain_len = strlen (chain) + 1;
+    if ((unsigned int)chain_len > sizeof(temp.chain))
+    {
+        ERROR ("Chain `%s' too long.", chain);
+        free (value_copy);
+        return (1);
+    }
+    sstrncpy (temp.chain, chain, chain_len);
+
+    if (fields_num >= 3)
+    {
+        char *comment = fields[2];
+        int   rule = atoi (comment);
+
+        if (rule)
+        {
+            temp.rule.num = rule;
+            temp.rule_type = RTYPE_NUM;
+        }
+        else
+        {
+            temp.rule.comment = strdup (comment);
+            if (temp.rule.comment == NULL)
+            {
+                free (value_copy);
+                return (1);
+            }
+            temp.rule_type = RTYPE_COMMENT;
+        }
+    }
+    else
+    {
+        temp.rule_type = RTYPE_COMMENT_ALL;
+    }
+
+    if (fields_num >= 4)
+        sstrncpy (temp.name, fields[3], sizeof (temp.name));
+
+    free (value_copy);
+    value_copy = NULL;
+    table = NULL;
+    chain = NULL;
+
+    list = realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
+    if (list == NULL)
+    {
+        char errbuf[1024];
+        ERROR ("realloc failed: %s",
+                sstrerror (errno, errbuf, sizeof (errbuf)));
+        sfree (temp.rule.comment);
+        return (1);
+    }
+
+    chain_list = list;
+    final = malloc(sizeof (*final));
+    if (final == NULL)
+    {
+        char errbuf[1024];
+        ERROR ("malloc failed: %s",
+                sstrerror (errno, errbuf, sizeof (errbuf)));
+        sfree (temp.rule.comment);
+        return (1);
+    }
+    memcpy (final, &temp, sizeof (temp));
+    chain_list[chain_num] = final;
+    chain_num++;
+
+    DEBUG ("Chain #%i: table = %s; chain = %s;", chain_num, final->table, final->chain);
+
+    return (0);
 } /* int iptables_config */
 
 static int submit6_match (const struct ip6t_entry_match *match,
-                const struct ip6t_entry *entry,
-                const ip_chain_t *chain,
-                int rule_num)
+                          const struct ip6t_entry *entry,
+                          const ip_chain_t *chain,
+                          int rule_num)
 {
     int status;
     value_t values[1];
@@ -259,7 +253,7 @@ static int submit6_match (const struct ip6t_entry_match *match,
         if (strcmp (match->u.user.name, "comment") != 0)
             return (0);
         if ((chain->rule_type == RTYPE_COMMENT)
-                && (strcmp (chain->rule.comment, (char *) match->data) != 0))
+             && (strcmp (chain->rule.comment, (char *) match->data) != 0))
             return (0);
     }
 
@@ -269,7 +263,7 @@ static int submit6_match (const struct ip6t_entry_match *match,
     sstrncpy (vl.plugin, "ip6tables", sizeof (vl.plugin));
 
     status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
-            "%s-%s", chain->table, chain->chain);
+                        "%s-%s", chain->table, chain->chain);
     if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance)))
         return (0);
 
@@ -281,10 +275,10 @@ static int submit6_match (const struct ip6t_entry_match *match,
     {
         if (chain->rule_type == RTYPE_NUM)
             ssnprintf (vl.type_instance, sizeof (vl.type_instance),
-                    "%i", chain->rule.num);
+                       "%i", chain->rule.num);
         else
             sstrncpy (vl.type_instance, (char *) match->data,
-                    sizeof (vl.type_instance));
+                      sizeof (vl.type_instance));
     }
 
     sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
@@ -301,9 +295,9 @@ static int submit6_match (const struct ip6t_entry_match *match,
 
 /* This needs to return `int' for IPT_MATCH_ITERATE to work. */
 static int submit_match (const struct ipt_entry_match *match,
-               const struct ipt_entry *entry,
-               const ip_chain_t *chain,
-               int rule_num) 
+                         const struct ipt_entry *entry,
+                         const ip_chain_t *chain,
+                         int rule_num)
 {
     int status;
     value_t values[1];
@@ -312,16 +306,16 @@ static int submit_match (const struct ipt_entry_match *match,
     /* Select the rules to collect */
     if (chain->rule_type == RTYPE_NUM)
     {
-       if (chain->rule.num != rule_num)
-           return (0);
+        if (chain->rule.num != rule_num)
+            return (0);
     }
     else
     {
-       if (strcmp (match->u.user.name, "comment") != 0)
-           return (0);
-       if ((chain->rule_type == RTYPE_COMMENT)
-               && (strcmp (chain->rule.comment, (char *) match->data) != 0))
-           return (0);
+        if (strcmp (match->u.user.name, "comment") != 0)
+            return (0);
+        if ((chain->rule_type == RTYPE_COMMENT)
+             && (strcmp (chain->rule.comment, (char *) match->data) != 0))
+            return (0);
     }
 
     vl.values = values;
@@ -330,22 +324,22 @@ static int submit_match (const struct ipt_entry_match *match,
     sstrncpy (vl.plugin, "iptables", sizeof (vl.plugin));
 
     status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
-           "%s-%s", chain->table, chain->chain);
+                        "%s-%s", chain->table, chain->chain);
     if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance)))
-       return (0);
+        return (0);
 
     if (chain->name[0] != '\0')
     {
-       sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance));
+        sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance));
     }
     else
     {
-       if (chain->rule_type == RTYPE_NUM)
-           ssnprintf (vl.type_instance, sizeof (vl.type_instance),
-                   "%i", chain->rule.num);
-       else
-           sstrncpy (vl.type_instance, (char *) match->data,
-                   sizeof (vl.type_instance));
+        if (chain->rule_type == RTYPE_NUM)
+            ssnprintf (vl.type_instance, sizeof (vl.type_instance),
+                       "%i", chain->rule.num);
+        else
+            sstrncpy (vl.type_instance, (char *) match->data,
+                      sizeof (vl.type_instance));
     }
 
     sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
@@ -361,7 +355,7 @@ static int submit_match (const struct ipt_entry_match *match,
 
 
 /* ipv6 submit_chain */
-static void submit6_chain( ip6tc_handle_t *handle, ip_chain_t *chain )
+static void submit6_chain (ip6tc_handle_t *handle, ip_chain_t *chain)
 {
     const struct ip6t_entry *entry;
     int rule_num;
@@ -393,33 +387,33 @@ static void submit6_chain( ip6tc_handle_t *handle, ip_chain_t *chain )
 
 
 /* ipv4 submit_chain */
-static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain )
+static void submit_chain (iptc_handle_t *handle, ip_chain_t *chain)
 {
     const struct ipt_entry *entry;
     int rule_num;
 
-    /* Find first rule for chain and use the iterate macro */    
+    /* Find first rule for chain and use the iterate macro */
     entry = iptc_first_rule( chain->chain, handle );
     if (entry == NULL)
     {
-       DEBUG ("iptc_first_rule failed: %s", iptc_strerror (errno));
-       return;
+        DEBUG ("iptc_first_rule failed: %s", iptc_strerror (errno));
+        return;
     }
 
     rule_num = 1;
     while (entry)
     {
-       if (chain->rule_type == RTYPE_NUM)
-       {
-           submit_match (NULL, entry, chain, rule_num);
-       }
-       else
-       {
-           IPT_MATCH_ITERATE( entry, submit_match, entry, chain, rule_num );
-       }
-
-       entry = iptc_next_rule( entry, handle );
-       rule_num++;
+        if (chain->rule_type == RTYPE_NUM)
+        {
+            submit_match (NULL, entry, chain, rule_num);
+        }
+        else
+        {
+            IPT_MATCH_ITERATE( entry, submit_match, entry, chain, rule_num );
+        }
+
+        entry = iptc_next_rule( entry, handle );
+        rule_num++;
     } /* while (entry) */
 }
 
@@ -430,65 +424,64 @@ static int iptables_read (void)
     int num_failures = 0;
     ip_chain_t *chain;
 
-    /* Init the iptc handle structure and query the correct table */    
+    /* Init the iptc handle structure and query the correct table */
     for (i = 0; i < chain_num; i++)
     {
-       chain = chain_list[i];
-       
-       if (!chain)
-       {
-           DEBUG ("iptables plugin: chain == NULL");
-           continue;
-       }
-
-       if ( chain->ip_version == IPV4 )
+        chain = chain_list[i];
+
+        if (!chain)
+        {
+            DEBUG ("iptables plugin: chain == NULL");
+            continue;
+        }
+
+        if ( chain->ip_version == IPV4 )
         {
 #ifdef HAVE_IPTC_HANDLE_T
-               iptc_handle_t _handle;
-               iptc_handle_t *handle = &_handle;
+            iptc_handle_t _handle;
+            iptc_handle_t *handle = &_handle;
 
-               *handle = iptc_init (chain->table);
+            *handle = iptc_init (chain->table);
 #else
-               iptc_handle_t *handle;
-                handle = iptc_init (chain->table);
+            iptc_handle_t *handle;
+            handle = iptc_init (chain->table);
 #endif
 
-                if (!handle)
-                {
-                        ERROR ("iptables plugin: iptc_init (%s) failed: %s",
-                                chain->table, iptc_strerror (errno));
-                        num_failures++;
-                        continue;
-                }
+            if (!handle)
+            {
+                ERROR ("iptables plugin: iptc_init (%s) failed: %s",
+                        chain->table, iptc_strerror (errno));
+                num_failures++;
+                continue;
+            }
 
-                submit_chain (handle, chain);
-                iptc_free (handle);
+            submit_chain (handle, chain);
+            iptc_free (handle);
         }
         else if ( chain->ip_version == IPV6 )
         {
 #ifdef HAVE_IP6TC_HANDLE_T
-               ip6tc_handle_t _handle;
-               ip6tc_handle_t *handle = &_handle;
+            ip6tc_handle_t _handle;
+            ip6tc_handle_t *handle = &_handle;
 
-               *handle = ip6tc_init (chain->table);
+            *handle = ip6tc_init (chain->table);
 #else
-                ip6tc_handle_t *handle;
-                handle = ip6tc_init (chain->table);
+            ip6tc_handle_t *handle;
+            handle = ip6tc_init (chain->table);
 #endif
-
-                if (!handle)
-                {
-                        ERROR ("iptables plugin: ip6tc_init (%s) failed: %s",
-                                chain->table, ip6tc_strerror (errno));
-                        num_failures++;
-                        continue;
-                }
-
-                submit6_chain (handle, chain);
-                ip6tc_free (handle);
+            if (!handle)
+            {
+                ERROR ("iptables plugin: ip6tc_init (%s) failed: %s",
+                        chain->table, ip6tc_strerror (errno));
+                num_failures++;
+                continue;
+            }
+
+            submit6_chain (handle, chain);
+            ip6tc_free (handle);
         }
-        else num_failures++;
-
+        else
+            num_failures++;
     } /* for (i = 0 .. chain_num) */
 
     return ((num_failures < chain_num) ? 0 : -1);
@@ -500,11 +493,9 @@ static int iptables_shutdown (void)
 
     for (i = 0; i < chain_num; i++)
     {
-       if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT))
-       {
-           sfree (chain_list[i]->rule.comment);
-       }
-       sfree (chain_list[i]);
+        if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT))
+            sfree (chain_list[i]->rule.comment);
+        sfree (chain_list[i]);
     }
     sfree (chain_list);
 
@@ -514,11 +505,8 @@ static int iptables_shutdown (void)
 void module_register (void)
 {
     plugin_register_config ("iptables", iptables_config,
-           config_keys, config_keys_num);
+                             config_keys, config_keys_num);
     plugin_register_read ("iptables", iptables_read);
     plugin_register_shutdown ("iptables", iptables_shutdown);
 } /* void module_register */
 
-/*
- * vim:shiftwidth=4:softtabstop=4:tabstop=8
- */
index 4345a46..760aa3c 100644 (file)
@@ -224,7 +224,8 @@ static int get_ti (struct ip_vs_dest_entry *de, char *ti, size_t size)
        return 0;
 } /* get_ti */
 
-static void cipvs_submit_connections (char *pi, char *ti, derive_t value)
+static void cipvs_submit_connections (const char *pi, const char *ti,
+               derive_t value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
@@ -245,7 +246,7 @@ static void cipvs_submit_connections (char *pi, char *ti, derive_t value)
        return;
 } /* cipvs_submit_connections */
 
-static void cipvs_submit_if (char *pi, char *t, char *ti,
+static void cipvs_submit_if (const char *pi, const char *t, const char *ti,
                derive_t rx, derive_t tx)
 {
        value_t values[2];
@@ -268,7 +269,8 @@ static void cipvs_submit_if (char *pi, char *t, char *ti,
        return;
 } /* cipvs_submit_if */
 
-static void cipvs_submit_dest (char *pi, struct ip_vs_dest_entry *de) {
+static void cipvs_submit_dest (const char *pi, struct ip_vs_dest_entry *de)
+{
        struct ip_vs_stats_user stats = de->stats;
 
        char ti[DATA_MAX_NAME_LEN];
index 6afacf0..93f3f53 100644 (file)
--- a/src/irq.c
+++ b/src/irq.c
@@ -120,6 +120,7 @@ static int irq_read (void)
        } else {
                ERROR ("irq plugin: unable to get CPU count from first line "
                                "of /proc/interrupts");
+               fclose (fh);
                return (-1);
        }
 
index 6b92f54..4187e7c 100644 (file)
@@ -1801,14 +1801,13 @@ static cjni_callback_info_t *cjni_callback_info_create (JNIEnv *jvm_env, /* {{{
     return (NULL);
   }
 
-  cbi = (cjni_callback_info_t *) malloc (sizeof (*cbi));
+  cbi = calloc (1, sizeof (*cbi));
   if (cbi == NULL)
   {
-    ERROR ("java plugin: cjni_callback_info_create: malloc failed.");
+    ERROR ("java plugin: cjni_callback_info_create: calloc failed.");
     (*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name);
     return (NULL);
   }
-  memset (cbi, 0, sizeof (*cbi));
   cbi->type = type;
 
   cbi->name = strdup (c_name);
@@ -1906,7 +1905,7 @@ static int cjni_callback_register (JNIEnv *jvm_env, /* {{{ */
 
   pthread_mutex_lock (&java_callbacks_lock);
 
-  tmp = (cjni_callback_info_t *) realloc (java_callbacks,
+  tmp = realloc (java_callbacks,
       (java_callbacks_num + 1) * sizeof (*java_callbacks));
   if (tmp == NULL)
   {
@@ -2067,13 +2066,12 @@ static JNIEnv *cjni_thread_attach (void) /* {{{ */
   if (cjni_env == NULL)
   {
     /* This pointer is free'd in `cjni_jvm_env_destroy'. */
-    cjni_env = (cjni_jvm_env_t *) malloc (sizeof (*cjni_env));
+    cjni_env = calloc (1, sizeof (*cjni_env));
     if (cjni_env == NULL)
     {
-      ERROR ("java plugin: cjni_thread_attach: malloc failed.");
+      ERROR ("java plugin: cjni_thread_attach: calloc failed.");
       return (NULL);
     }
-    memset (cjni_env, 0, sizeof (*cjni_env));
     cjni_env->reference_counter = 0;
     cjni_env->jvm_env = NULL;
 
@@ -2169,7 +2167,7 @@ static int cjni_config_add_jvm_arg (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  tmp = (char **) realloc (jvm_argv, sizeof (char *) * (jvm_argc + 1));
+  tmp = realloc (jvm_argv, sizeof (char *) * (jvm_argc + 1));
   if (tmp == NULL)
   {
     ERROR ("java plugin: realloc failed.");
@@ -2205,7 +2203,7 @@ static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */
   if (jvm_env == NULL)
     return (-1);
 
-  class = (java_plugin_class_t *) realloc (java_classes_list,
+  class = realloc (java_classes_list,
       (java_classes_list_len + 1) * sizeof (*java_classes_list));
   if (class == NULL)
   {
@@ -2801,13 +2799,13 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */
 
   /* Allocate a new callback info structure. This is going to be our user_data
    * pointer. */
-  cbi_ret = (cjni_callback_info_t *) malloc (sizeof (*cbi_ret));
+  cbi_ret = calloc (1, sizeof (*cbi_ret));
   if (cbi_ret == NULL)
   {
-    ERROR ("java plugin: cjni_match_target_create: malloc failed.");
+    ERROR ("java plugin: cjni_match_target_create: calloc failed.");
     BAIL_OUT (-1);
   }
-  memset (cbi_ret, 0, sizeof (*cbi_ret));
+
   cbi_ret->object = NULL;
   cbi_ret->type = type;
 
index eaee9c0..8b5ac0b 100644 (file)
@@ -312,7 +312,7 @@ static int lcc_receive (lcc_connection_t *c, /* {{{ */
   /* Allocate space for the char-pointers */
   res.lines_num = (size_t) res.status;
   res.status = 0;
-  res.lines = (char **) malloc (res.lines_num * sizeof (char *));
+  res.lines = malloc (res.lines_num * sizeof (*res.lines));
   if (res.lines == NULL)
   {
     lcc_set_errno (c, ENOMEM);
@@ -526,9 +526,11 @@ static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */
   if (status != 0)
   {
     lcc_set_errno (c, status);
+    freeaddrinfo (ai_res);
     return (-1);
   }
 
+  freeaddrinfo (ai_res);
   return (0);
 } /* }}} int lcc_open_netsocket */
 
@@ -582,10 +584,9 @@ int lcc_connect (const char *address, lcc_connection_t **ret_con) /* {{{ */
   if (ret_con == NULL)
     return (-1);
 
-  c = (lcc_connection_t *) malloc (sizeof (*c));
+  c = calloc (1, sizeof (*c));
   if (c == NULL)
     return (-1);
-  memset (c, 0, sizeof (*c));
 
   status = lcc_open_socket (c, address);
   if (status != 0)
@@ -685,7 +686,7 @@ int lcc_getval (lcc_connection_t *c, lcc_identifier_t *ident, /* {{{ */
   /* Allocate space for the values */
   if (ret_values != NULL)
   {
-    values = (gauge_t *) malloc (values_num * sizeof (*values));
+    values = malloc (values_num * sizeof (*values));
     if (values == NULL)
       BAIL_OUT (ENOMEM);
   }
@@ -892,7 +893,7 @@ int lcc_listval (lcc_connection_t *c, /* {{{ */
   }
 
   ident_num = res.lines_num;
-  ident = (lcc_identifier_t *) malloc (ident_num * sizeof (*ident));
+  ident = malloc (ident_num * sizeof (*ident));
   if (ident == NULL)
   {
     lcc_response_free (&res);
index 049f7f0..64cf9c9 100644 (file)
@@ -56,7 +56,7 @@ typedef enum lcc_security_level_e lcc_security_level_t;
 lcc_network_t *lcc_network_create (void);
 void lcc_network_destroy (lcc_network_t *net);
 
-/* 
+/*
  * Add servers
  */
 lcc_server_t *lcc_server_create (lcc_network_t *net,
index 0539cd0..4564fbb 100644 (file)
@@ -89,6 +89,7 @@ static int server_close_socket (lcc_server_t *srv) /* {{{ */
     return (0);
 
   close (srv->fd);
+  srv->fd = -1;
   free (srv->sa);
   srv->sa = NULL;
   srv->sa_len = 0;
@@ -107,12 +108,6 @@ static void int_server_destroy (lcc_server_t *srv) /* {{{ */
 
   next = srv->next;
 
-  if (srv->fd >= 0)
-  {
-    close (srv->fd);
-    srv->fd = -1;
-  }
-
   free (srv->node);
   free (srv->service);
   free (srv->username);
@@ -154,7 +149,6 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */
 
     if (ai_ptr->ai_family == AF_INET)
     {
-
       struct sockaddr_in *addr = (struct sockaddr_in *) ai_ptr->ai_addr;
       int optname;
 
@@ -163,9 +157,8 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */
       else
         optname = IP_TTL;
 
-      setsockopt (srv->fd, IPPROTO_IP, optname,
-          &srv->ttl,
-          sizeof (srv->ttl));
+      status = setsockopt (srv->fd, IPPROTO_IP, optname,
+          &srv->ttl, sizeof (srv->ttl));
     }
     else if (ai_ptr->ai_family == AF_INET6)
     {
@@ -178,9 +171,15 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */
       else
         optname = IPV6_UNICAST_HOPS;
 
-      setsockopt (srv->fd, IPPROTO_IPV6, optname,
-          &srv->ttl,
-          sizeof (srv->ttl));
+      status = setsockopt (srv->fd, IPPROTO_IPV6, optname,
+          &srv->ttl, sizeof (srv->ttl));
+    }
+    if (status != 0)
+    {
+      /* setsockopt failed. */
+      close (srv->fd);
+      srv->fd = -1;
+      continue;
     }
 
     srv->sa = malloc (ai_ptr->ai_addrlen);
@@ -272,10 +271,9 @@ lcc_network_t *lcc_network_create (void) /* {{{ */
 {
   lcc_network_t *net;
 
-  net = malloc (sizeof (*net));
+  net = calloc (1, sizeof (*net));
   if (net == NULL)
     return (NULL);
-  memset (net, 0, sizeof (*net));
 
   net->servers = NULL;
 
@@ -300,10 +298,9 @@ lcc_server_t *lcc_server_create (lcc_network_t *net, /* {{{ */
   if (service == NULL)
     service = NET_DEFAULT_PORT;
 
-  srv = malloc (sizeof (*srv));
+  srv = calloc (1, sizeof (*srv));
   if (srv == NULL)
     return (NULL);
-  memset (srv, 0, sizeof (*srv));
 
   srv->fd = -1;
   srv->security_level = NONE;
index 343c285..130da23 100644 (file)
@@ -651,19 +651,17 @@ lcc_network_buffer_t *lcc_network_buffer_create (size_t size) /* {{{ */
     return (NULL);
   }
 
-  nb = malloc (sizeof (*nb));
+  nb = calloc (1, sizeof (*nb));
   if (nb == NULL)
     return (NULL);
-  memset (nb, 0, sizeof (*nb));
 
   nb->size = size;
-  nb->buffer = malloc (nb->size);
+  nb->buffer = calloc (1, nb->size);
   if (nb->buffer == NULL)
   {
     free (nb);
     return (NULL);
   }
-  memset (nb->buffer, 0, nb->size);
 
   nb->ptr = nb->buffer;
   nb->free = nb->size;
index b5162cc..5ac0ef3 100644 (file)
@@ -1,5 +1,3 @@
-AUTOMAKE_OPTIONS = foreign no-dependencies
-
 BUILT_SOURCES = parser.h
 #CLEANFILES = parser.[ch] scanner.c
 AM_YFLAGS = -d
index d01c79d..cfe9c5a 100644 (file)
@@ -106,13 +106,12 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
 {
   oconfig_item_t *ci_copy;
 
-  ci_copy = (oconfig_item_t *) malloc (sizeof (*ci_copy));
+  ci_copy = calloc (1, sizeof (*ci_copy));
   if (ci_copy == NULL)
   {
-    fprintf (stderr, "malloc failed.\n");
+    fprintf (stderr, "calloc failed.\n");
     return (NULL);
   }
-  memset (ci_copy, 0, sizeof (*ci_copy));
   ci_copy->values = NULL;
   ci_copy->parent = NULL;
   ci_copy->children = NULL;
@@ -177,7 +176,7 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
     for (i = 0; i < ci_copy->children_num; i++)
     {
       oconfig_item_t *child;
-      
+
       child = oconfig_clone (ci_orig->children + i);
       if (child == NULL)
       {
@@ -193,7 +192,7 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
   return (ci_copy);
 } /* oconfig_item_t *oconfig_clone */
 
-void oconfig_free_all (oconfig_item_t *ci)
+static void oconfig_free_all (oconfig_item_t *ci)
 {
   int i;
 
@@ -222,7 +221,6 @@ void oconfig_free (oconfig_item_t *ci)
 {
   oconfig_free_all (ci);
   free (ci);
-  ci = NULL;
 }
 
 /*
index f0e886c..1eb7aec 100644 (file)
@@ -208,15 +208,13 @@ statement_list:
 entire_file:
        statement_list
        {
-        ci_root = malloc (sizeof (oconfig_item_t));
-        memset (ci_root, '\0', sizeof (oconfig_item_t));
+        ci_root = calloc (1, sizeof (*ci_root));
         ci_root->children = $1.statement;
         ci_root->children_num = $1.statement_num;
        }
        | /* epsilon */
        {
-        ci_root = malloc (sizeof (oconfig_item_t));
-        memset (ci_root, '\0', sizeof (oconfig_item_t));
+        ci_root = calloc (1, sizeof (*ci_root));
         ci_root->children = NULL;
         ci_root->children_num = 0;
        }
@@ -225,7 +223,7 @@ entire_file:
 %%
 static int yyerror (const char *s)
 {
-       char *text;
+       const char *text;
 
        if (*yytext == '\n')
                text = "<newline>";
index 41d6643..7a831c2 100644 (file)
@@ -146,7 +146,7 @@ static void ml_append (char *string)
 
        if (ml_free <= len) {
                ml_len += len - ml_free + 1;
-               ml_buffer = (char *)realloc (ml_buffer, ml_len);
+               ml_buffer = realloc (ml_buffer, ml_len);
                if (NULL == ml_buffer)
                        YY_FATAL_ERROR ("out of dynamic memory in ml_append");
        }
index b75ecb8..1179718 100644 (file)
@@ -201,7 +201,7 @@ static int logfile_notification (const notification_t *n,
 
 #define APPEND(bufptr, buflen, key, value) \
        if ((buflen > 0) && (strlen (value) > 0)) { \
-               int status = ssnprintf (bufptr, buflen, ", %s = %s", key, value); \
+               status = ssnprintf (bufptr, buflen, ", %s = %s", key, value); \
                if (status > 0) { \
                        bufptr += status; \
                        buflen -= status; \
index bb33b15..949724e 100644 (file)
@@ -23,7 +23,7 @@
 
 
 /**
- * There are several data streams provided by Madwifi plugin, some are 
+ * There are several data streams provided by Madwifi plugin, some are
  * connected to network interface, some are connected to each node
  * associated to that interface. Nodes represents other sides in
  * wireless communication, for example on network interface in AP mode,
  *     node_stat       Node statistic counters
  *
  * Both statistic counters have type instances for each counter returned
- * by Madwifi. See madwifi.h for content of ieee80211_nodestats, 
+ * by Madwifi. See madwifi.h for content of ieee80211_nodestats,
  * ieee80211_stats and ath_stats structures. Type instances use the same
  * name as fields in these structures (like ns_rx_dup). Some fields are
  * not reported, because they are not counters (like ns_tx_deauth_code
  * or ast_tx_rssi). Fields ns_rx_bytes and ns_tx_bytes are reported as
  * node_octets data stream instead of type instance of node_stat.
  * Statistics are not logged when they are zero.
- * 
+ *
  * There are two sets of these counters - the first 'WatchList' is a
  * set of counters that are individually logged. The second 'MiscList'
  * is a set of counters that are summed together and the sum is logged.
- * By default, the most important statistics are in the WatchList and 
+ * By default, the most important statistics are in the WatchList and
  * many error statistics are in MiscList. There are also many statistics
  * that are not in any of these sets, so they are not monitored by default.
  * It is possible to alter these lists using configuration options:
@@ -629,7 +629,7 @@ process_stat_struct (int which, const void *ptr, const char *dev, const char *ma
                if (item_summed (i))
                        misc += val;
        }
-       
+
        if (misc != 0)
                submit_derive (dev, type_name, misc_name, mac, misc);
 
@@ -821,15 +821,16 @@ check_devname (const char *dev)
 
        if (dev[0] == '.')
                return 0;
-       
+
        ssnprintf (buf, sizeof (buf), "/sys/class/net/%s/device/driver", dev);
-       buf[sizeof (buf) - 1] = 0;
+       buf[sizeof (buf) - 1] = '\0';
 
-       memset (buf2, 0, sizeof (buf2));
        i = readlink (buf, buf2, sizeof (buf2) - 1);
        if (i < 0)
                return 0;
 
+       buf2[i] = '\0';
+
        if (strstr (buf2, "/drivers/ath_") == NULL)
                return 0;
        return 1;
@@ -890,7 +891,7 @@ procfs_iterate(int sk)
        int status;
        int num_success;
        int num_fail;
-       
+
        if ((fh = fopen ("/proc/net/dev", "r")) == NULL)
        {
                WARNING ("madwifi plugin: opening /proc/net/dev failed");
@@ -952,7 +953,7 @@ static int madwifi_read (void)
 
 /* procfs iteration is not safe because it does not check whether given
    interface is madwifi interface and there are private ioctls used, which
-   may do something completely different on non-madwifi devices.   
+   may do something completely different on non-madwifi devices.
    Therefore, it is not used unless explicitly enabled (and should be used
    together with ignorelist). */
 
index e30ff91..8f99a6d 100644 (file)
@@ -46,13 +46,12 @@ static int mec_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   mec_match_t *m;
 
-  m = (mec_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
   {
-    ERROR ("mec_create: malloc failed.");
+    ERROR ("mec_create: calloc failed.");
     return (-ENOMEM);
   }
-  memset (m, 0, sizeof (*m));
 
   if (ci->children_num != 0)
   {
index ba0c47c..4178d75 100644 (file)
@@ -101,13 +101,12 @@ static int mh_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   mh_match_t *m;
   int i;
 
-  m = (mh_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
   {
-    ERROR ("mh_create: malloc failed.");
+    ERROR ("mh_create: calloc failed.");
     return (-ENOMEM);
   }
-  memset (m, 0, sizeof (*m));
 
   for (i = 0; i < ci->children_num; i++)
   {
index 4fa6ce7..bbc35cd 100644 (file)
@@ -140,13 +140,12 @@ static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
                return (-1);
        }
 
-       re = (mr_regex_t *) malloc (sizeof (*re));
+       re = calloc (1, sizeof (*re));
        if (re == NULL)
        {
-               log_err ("mr_config_add_regex: malloc failed.");
+               log_err ("mr_config_add_regex: calloc failed.");
                return (-1);
        }
-       memset (re, 0, sizeof (*re));
        re->next = NULL;
 
        re->re_str = strdup (ci->values[0].value.string);
@@ -163,7 +162,7 @@ static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
                char errmsg[1024];
                regerror (status, &re->re, errmsg, sizeof (errmsg));
                errmsg[sizeof (errmsg) - 1] = 0;
-               log_err ("Compiling regex `%s' for `%s' failed: %s.", 
+               log_err ("Compiling regex `%s' for `%s' failed: %s.",
                                re->re_str, ci->key, errmsg);
                free (re->re_str);
                free (re);
@@ -194,14 +193,13 @@ static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
        int status;
        int i;
 
-       m = (mr_match_t *) malloc (sizeof (*m));
+       m = calloc (1, sizeof (*m));
        if (m == NULL)
        {
-               log_err ("mr_create: malloc failed.");
+               log_err ("mr_create: calloc failed.");
                return (-ENOMEM);
        }
-       memset (m, 0, sizeof (*m));
-       
+
        m->invert = 0;
 
        status = 0;
index 996201a..77c8f51 100644 (file)
@@ -52,13 +52,12 @@ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   int status;
   int i;
 
-  m = (mt_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
   {
-    ERROR ("mt_create: malloc failed.");
+    ERROR ("mt_create: calloc failed.");
     return (-ENOMEM);
   }
-  memset (m, 0, sizeof (*m));
 
   m->future = 0;
   m->past = 0;
index 9ffceca..599f1cf 100644 (file)
@@ -59,7 +59,7 @@ struct mv_match_s
 static void mv_free_match (mv_match_t *m) /* {{{ */
 {
   size_t i;
-  
+
   if (m == NULL)
     return;
 
@@ -69,7 +69,7 @@ static void mv_free_match (mv_match_t *m) /* {{{ */
       free(m->data_sources[i]);
     free(m->data_sources);
   }
-  
+
   free (m);
 } /* }}} void mv_free_match */
 
@@ -129,7 +129,7 @@ static int mv_config_add_data_source (mv_match_t *m, /* {{{ */
 
   /* Allocate space for the char pointers */
   new_data_sources_num = m->data_sources_num + ((size_t) ci->values_num);
-  temp = (char **) realloc (m->data_sources,
+  temp = realloc (m->data_sources,
       new_data_sources_num * sizeof (char *));
   if (temp == NULL)
   {
@@ -200,13 +200,12 @@ static int mv_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   int status;
   int i;
 
-  m = (mv_match_t *) malloc (sizeof (*m));
+  m = calloc (1, sizeof (*m));
   if (m == NULL)
   {
-    ERROR ("mv_create: malloc failed.");
+    ERROR ("mv_create: calloc failed.");
     return (-ENOMEM);
   }
-  memset (m, 0, sizeof (*m));
 
   m->min = NAN;
   m->max = NAN;
@@ -336,7 +335,7 @@ static int mv_match (const data_set_t *ds, const value_list_t *vl, /* {{{ */
       if (m->satisfy == SATISFY_ANY)
         break;
     }
-    else if (value_matches == 0)
+    else
     {
       status = FC_MATCH_NO_MATCH;
       if (m->satisfy == SATISFY_ALL)
index 5e87f00..2d6d77e 100644 (file)
@@ -260,8 +260,8 @@ static int mbmon_read (void)
                double value;
                char *nextc;
 
-               char *type;
-               char *inst;
+               const char *type;
+               const char *inst;
 
                *t++ = '\0';
                trim_spaces (s);
index 013b6c4..629b99b 100644 (file)
@@ -206,13 +206,12 @@ static int cmc_config_add_match (web_page_t *page, /* {{{ */
     WARNING ("memcachec plugin: Ignoring arguments for the `Match' block.");
   }
 
-  match = (web_match_t *) malloc (sizeof (*match));
+  match = calloc (1, sizeof (*match));
   if (match == NULL)
   {
-    ERROR ("memcachec plugin: malloc failed.");
+    ERROR ("memcachec plugin: calloc failed.");
     return (-1);
   }
-  memset (match, 0, sizeof (*match));
 
   status = 0;
   for (i = 0; i < ci->children_num; i++)
@@ -305,13 +304,12 @@ static int cmc_config_add_page (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  page = (web_page_t *) malloc (sizeof (*page));
+  page = calloc (1, sizeof (*page));
   if (page == NULL)
   {
-    ERROR ("memcachec plugin: malloc failed.");
+    ERROR ("memcachec plugin: calloc failed.");
     return (-1);
   }
-  memset (page, 0, sizeof (*page));
   page->server = NULL;
   page->key = NULL;
 
@@ -389,7 +387,7 @@ static int cmc_config_add_page (oconfig_item_t *ci) /* {{{ */
     web_page_t *prev;
 
     prev = pages_g;
-    while ((prev != NULL) && (prev->next != NULL))
+    while (prev->next != NULL)
       prev = prev->next;
     prev->next = page;
   }
index f684abf..62ac72a 100644 (file)
@@ -98,8 +98,8 @@ static int memcached_connect_unix (memcached_t *st)
 
 static int memcached_connect_inet (memcached_t *st)
 {
-  char *host;
-  char *port;
+  const char *host;
+  const char *port;
 
   struct addrinfo  ai_hints;
   struct addrinfo *ai_list, *ai_ptr;
@@ -173,8 +173,7 @@ static int memcached_connect (memcached_t *st)
 
 static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t *st)
 {
-  int fd = -1;
-  int status;
+  int fd, status;
   size_t buffer_fill;
 
   fd = memcached_connect (st);
@@ -439,7 +438,7 @@ static int memcached_read (user_data_t *user_data)
     }
     else if (FIELD_IS ("listen_disabled_num"))
     {
-      submit_derive ("memcached_connections", "listen_disabled", atof (fields[2]), st);
+      submit_derive ("connections", "listen_disabled", atof (fields[2]), st);
     }
 
     /*
@@ -587,14 +586,13 @@ static int config_add_instance(oconfig_item_t *ci)
   /* Disable automatic generation of default instance in the init callback. */
   memcached_have_instances = 1;
 
-  st = malloc (sizeof (*st));
+  st = calloc (1, sizeof (*st));
   if (st == NULL)
   {
-    ERROR ("memcached plugin: malloc failed.");
+    ERROR ("memcached plugin: calloc failed.");
     return (-1);
   }
 
-  memset (st, 0, sizeof (*st));
   st->name = NULL;
   st->socket = NULL;
   st->host = NULL;
@@ -685,10 +683,9 @@ static int memcached_init (void)
     return (0);
 
   /* No instances were configured, lets start a default instance. */
-  st = malloc (sizeof (*st));
+  st = calloc (1, sizeof (*st));
   if (st == NULL)
     return (ENOMEM);
-  memset (st, 0, sizeof (*st));
   st->name = sstrdup ("__legacy__");
   st->socket = NULL;
   st->host = NULL;
index ea16ce3..3d8a867 100644 (file)
@@ -237,7 +237,7 @@ static int memory_read_internal (value_list_t *vl)
         * vm.stats.vm.v_inactive_count: 113730
         * vm.stats.vm.v_cache_count: 10809
         */
-       char *sysctl_keys[8] =
+       const char *sysctl_keys[8] =
        {
                "vm.stats.vm.v_page_size",
                "vm.stats.vm.v_page_count",
index cfc6331..51447b1 100644 (file)
@@ -80,7 +80,7 @@ enum mb_register_type_e /* {{{ */
   REG_TYPE_UINT32,
   REG_TYPE_FLOAT
 }; /* }}} */
-enum mb_mreg_type_e /* {{{ */ 
+enum mb_mreg_type_e /* {{{ */
 {
   MREG_HOLDING,
   MREG_INPUT
@@ -310,7 +310,9 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */
   if (host == NULL)
     return (EINVAL);
 
+#if COLLECT_DEBUG
   modbus_set_debug (&host->connection, 1);
+#endif
 
   /* We'll do the error handling ourselves. */
   modbus_set_error_handling (&host->connection, NOP_ON_ERROR);
@@ -390,7 +392,9 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */
     }
   }
 
+#if COLLECT_DEBUG
   modbus_set_debug (host->connection, 1);
+#endif
 
   /* We'll do the error handling ourselves. */
   modbus_set_error_recovery (host->connection, 0);
@@ -499,7 +503,7 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
     modbus_free (host->connection);
 #endif
   }
+
 #if LEGACY_LIBMODBUS
   /* Version 2.0.3: Pass the connection struct as a pointer and pass the slave
    * id to each call of "read_holding_registers". */
@@ -934,17 +938,22 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */
   int status;
   int i;
 
-  host = malloc (sizeof (*host));
+  host = calloc (1, sizeof (*host));
   if (host == NULL)
     return (ENOMEM);
-  memset (host, 0, sizeof (*host));
   host->slaves = NULL;
 
   status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host));
   if (status != 0)
+  {
+    sfree (host);
     return (status);
+  }
   if (host->host[0] == 0)
+  {
+    sfree (host);
     return (EINVAL);
+  }
 
   for (i = 0; i < ci->children_num; i++)
   {
index 1b71d42..0b00bab 100644 (file)
@@ -24,6 +24,7 @@
  * Authors:
  *   Marc Falzon <marc at baha dot mu>
  *   Florian octo Forster <octo at collectd.org>
+ *   Jan-Piet Mens <jpmens at gmail.com>
  **/
 
 // Reference: http://mosquitto.org/api/files/mosquitto-h.html
@@ -48,6 +49,9 @@
 #ifndef MQTT_KEEPALIVE
 # define MQTT_KEEPALIVE 60
 #endif
+#ifndef SSL_VERIFY_PEER
+# define SSL_VERIFY_PEER  1
+#endif
 
 
 /*
@@ -67,6 +71,11 @@ struct mqtt_client_conf
     char               *username;
     char               *password;
     int                 qos;
+    char                *cacertificatefile;
+    char                *certificatefile;
+    char                *certificatekeyfile;
+    char                *tlsprotocol;
+    char                *ciphersuite;
 
     /* For publishing */
     char               *topic_prefix;
@@ -176,9 +185,10 @@ static void on_message (
     char *payload;
     int status;
 
-    if ((msg->payloadlen <= 0)
-            || (((uint8_t *) msg->payload)[msg->payloadlen - 1] != 0))
+    if (msg->payloadlen <= 0) {
+        DEBUG ("mqtt plugin: message has empty payload");
         return;
+    }
 
     topic = strdup (msg->topic);
     name = strip_prefix (topic);
@@ -207,7 +217,16 @@ static void on_message (
     }
     vl.values_len = ds->ds_num;
 
-    payload = strdup ((void *) msg->payload);
+    payload = malloc (msg->payloadlen+1);
+    if (payload == NULL)
+    {
+        ERROR ("mqtt plugin: malloc for payload buffer failed.");
+        sfree (vl.values);
+        return;
+    }
+    memmove (payload, msg->payload, msg->payloadlen);
+    payload[msg->payloadlen] = 0;
+
     DEBUG ("mqtt plugin: payload = \"%s\"", payload);
     status = parse_values (payload, &vl, ds);
     if (status != 0)
@@ -277,6 +296,35 @@ static int mqtt_connect (mqtt_client_conf_t *conf)
         return (-1);
     }
 
+#if LIBMOSQUITTO_MAJOR != 0
+    if (conf->cacertificatefile) {
+        status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL,
+                                  conf->certificatefile, conf->certificatekeyfile, /* pw_callback */NULL);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+
+        status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, conf->tlsprotocol, conf->ciphersuite);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_opts_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+
+        status = mosquitto_tls_insecure_set(conf->mosq, false);
+        if (status != MOSQ_ERR_SUCCESS) {
+            ERROR ("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", mosquitto_strerror(status));
+            mosquitto_destroy (conf->mosq);
+            conf->mosq = NULL;
+            return (-1);
+        }
+    }
+#endif
+
     if (conf->username && conf->password)
     {
         status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password);
@@ -494,6 +542,10 @@ static int mqtt_write (const data_set_t *ds, const value_list_t *vl,
  *   StoreRates true
  *   Retain false
  *   QoS 0
+ *   CACert "ca.pem"                   Enables TLS if set
+ *   CertificateFile "client-cert.pem"         optional
+ *   CertificateKeyFile "client-key.pem"               optional
+ *   TLSProtocol "tlsv1.2"             optional
  * </Publish>
  */
 static int mqtt_config_publisher (oconfig_item_t *ci)
@@ -507,7 +559,7 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
     conf = calloc (1, sizeof (*conf));
     if (conf == NULL)
     {
-        ERROR ("mqtt plugin: malloc failed.");
+        ERROR ("mqtt plugin: calloc failed.");
         return (-1);
     }
     conf->publish = 1;
@@ -570,6 +622,16 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
             cf_util_get_boolean (child, &conf->store_rates);
         else if (strcasecmp ("Retain", child->key) == 0)
             cf_util_get_boolean (child, &conf->retain);
+        else if (strcasecmp ("CACert", child->key) == 0)
+            cf_util_get_string (child, &conf->cacertificatefile);
+        else if (strcasecmp ("CertificateFile", child->key) == 0)
+            cf_util_get_string (child, &conf->certificatefile);
+        else if (strcasecmp ("CertificateKeyFile", child->key) == 0)
+            cf_util_get_string (child, &conf->certificatekeyfile);
+        else if (strcasecmp ("TLSProtocol", child->key) == 0)
+            cf_util_get_string (child, &conf->tlsprotocol);
+        else if (strcasecmp ("CipherSuite", child->key) == 0)
+            cf_util_get_string (child, &conf->ciphersuite);
         else
             ERROR ("mqtt plugin: Unknown config option: %s", child->key);
     }
@@ -590,7 +652,7 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
  *   User "guest"
  *   Password "secret"
  *   Topic "collectd/#"
- * </Publish>
+ * </Subscribe>
  */
 static int mqtt_config_subscriber (oconfig_item_t *ci)
 {
@@ -602,7 +664,7 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
     conf = calloc (1, sizeof (*conf));
     if (conf == NULL)
     {
-        ERROR ("mqtt plugin: malloc failed.");
+        ERROR ("mqtt plugin: calloc failed.");
         return (-1);
     }
     conf->publish = 0;
@@ -638,11 +700,11 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
             cf_util_get_string (child, &conf->host);
         else if (strcasecmp ("Port", child->key) == 0)
         {
-            int tmp = cf_util_get_port_number (child);
-            if (tmp < 0)
+            status = cf_util_get_port_number (child);
+            if (status < 0)
                 ERROR ("mqtt plugin: Invalid port number.");
             else
-                conf->port = tmp;
+                conf->port = status;
         }
         else if (strcasecmp ("ClientId", child->key) == 0)
             cf_util_get_string (child, &conf->client_id);
@@ -652,12 +714,12 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
             cf_util_get_string (child, &conf->password);
         else if (strcasecmp ("QoS", child->key) == 0)
         {
-            int tmp = -1;
-            status = cf_util_get_int (child, &tmp);
-            if ((status != 0) || (tmp < 0) || (tmp > 2))
+            int qos = -1;
+            status = cf_util_get_int (child, &qos);
+            if ((status != 0) || (qos < 0) || (qos > 2))
                 ERROR ("mqtt plugin: Not a valid QoS setting.");
             else
-                conf->qos = tmp;
+                conf->qos = qos;
         }
         else if (strcasecmp ("Topic", child->key) == 0)
             cf_util_get_string (child, &conf->topic);
@@ -667,7 +729,7 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
             ERROR ("mqtt plugin: Unknown config option: %s", child->key);
     }
 
-    tmp = realloc (subscribers, sizeof (*subscribers) * subscribers_num);
+    tmp = realloc (subscribers, sizeof (*subscribers) * (subscribers_num + 1) );
     if (tmp == NULL)
     {
         ERROR ("mqtt plugin: realloc failed.");
index 775eb57..6953750 100644 (file)
@@ -153,17 +153,18 @@ static int multimeter_init (void)
 
        for (i = 0; i < 10; i++)
        {
-               device[strlen(device)-1] = i + '0'; 
+               device[strlen(device)-1] = i + '0';
 
-               if ((fd = open(device, O_RDWR | O_NOCTTY)) > 0)
+               if ((fd = open(device, O_RDWR | O_NOCTTY)) != -1)
                {
                        struct termios tios;
                        int rts = TIOCM_RTS;
                        double value;
 
+                       memset (&tios, 0, sizeof (tios));
                        tios.c_cflag = B1200 | CS7 | CSTOPB | CREAD | CLOCAL;
                        tios.c_iflag = IGNBRK | IGNPAR;
-                       tios.c_oflag = 0;
+                       tios.c_oflag = 0;
                        tios.c_lflag = 0;
                        tios.c_cc[VTIME] = 3;
                        tios.c_cc[VMIN]  = LINE_LENGTH;
@@ -171,7 +172,7 @@ static int multimeter_init (void)
                        tcflush(fd, TCIFLUSH);
                        tcsetattr(fd, TCSANOW, &tios);
                        ioctl(fd, TIOCMBIC, &rts);
-                       
+
                        if (multimeter_read_value (&value) < -1)
                        {
                                close (fd);
index a8a8e86..a239413 100644 (file)
@@ -65,9 +65,6 @@ typedef struct mysql_database_s mysql_database_t; /* }}} */
 
 static int mysql_read (user_data_t *ud);
 
-void mysql_read_default_options(struct st_mysql_options *options,
-               const char *filename,const char *group);
-
 static void mysql_database_free (void *arg) /* {{{ */
 {
        mysql_database_t *db;
@@ -116,13 +113,12 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
                return (-1);
        }
 
-       db = (mysql_database_t *) malloc (sizeof (*db));
+       db = calloc (1, sizeof (*db));
        if (db == NULL)
        {
-               ERROR ("mysql plugin: malloc failed.");
+               ERROR ("mysql plugin: calloc failed.");
                return (-1);
        }
-       memset (db, 0, sizeof (*db));
 
        /* initialize all the pointers */
        db->alias    = NULL;
@@ -403,8 +399,8 @@ static int mysql_read_master_stats (mysql_database_t *db, MYSQL *con)
        MYSQL_RES *res;
        MYSQL_ROW  row;
 
-       char *query;
-       int   field_num;
+       const char *query;
+       int         field_num;
        unsigned long long position;
 
        query = "SHOW MASTER STATUS";
@@ -449,8 +445,8 @@ static int mysql_read_slave_stats (mysql_database_t *db, MYSQL *con)
        MYSQL_RES *res;
        MYSQL_ROW  row;
 
-       char *query;
-       int   field_num;
+       const char *query;
+       int         field_num;
 
        /* WTF? libmysqlclient does not seem to provide any means to
         * translate a column name to a column index ... :-/ */
@@ -572,84 +568,84 @@ static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con)
        MYSQL_RES *res;
        MYSQL_ROW  row;
 
-       char *query;
-    struct {
-        char *key;
-        char *type;
-        int ds_type;
-    } metrics[] = {
-        { "metadata_mem_pool_size",         "bytes",        DS_TYPE_GAUGE },
-        { "lock_deadlocks",                 "mysql_locks",  DS_TYPE_DERIVE },
-        { "lock_timeouts",                  "mysql_locks",  DS_TYPE_DERIVE },
-        { "lock_row_lock_current_waits",    "mysql_locks",  DS_TYPE_DERIVE },
-        { "buffer_pool_size",               "bytes",        DS_TYPE_GAUGE },
-
-        { "buffer_pool_reads",              "operations",   DS_TYPE_DERIVE },
-        { "buffer_pool_read_requests",      "operations",   DS_TYPE_DERIVE },
-        { "buffer_pool_write_requests",     "operations",   DS_TYPE_DERIVE },
-        { "buffer_pool_wait_free",          "operations",   DS_TYPE_DERIVE },
-        { "buffer_pool_read_ahead",         "operations",   DS_TYPE_DERIVE },
-        { "buffer_pool_read_ahead_evicted", "operations",   DS_TYPE_DERIVE },
-
-        { "buffer_pool_pages_total",        "gauge",        DS_TYPE_GAUGE },
-        { "buffer_pool_pages_misc",         "gauge",        DS_TYPE_GAUGE },
-        { "buffer_pool_pages_data",         "gauge",        DS_TYPE_GAUGE },
-        { "buffer_pool_bytes_data",         "gauge",        DS_TYPE_GAUGE },
-        { "buffer_pool_pages_dirty",        "gauge",        DS_TYPE_GAUGE },
-        { "buffer_pool_bytes_dirty",        "gauge",        DS_TYPE_GAUGE },
-        { "buffer_pool_pages_free",         "gauge",        DS_TYPE_GAUGE },
-
-        { "buffer_pages_created",           "operations",   DS_TYPE_DERIVE },
-        { "buffer_pages_written",           "operations",   DS_TYPE_DERIVE },
-        { "buffer_pages_read",              "operations",   DS_TYPE_DERIVE },
-        { "buffer_data_reads",              "operations",   DS_TYPE_DERIVE },
-        { "buffer_data_written",            "operations",   DS_TYPE_DERIVE },
-
-        { "os_data_reads",                  "operations",   DS_TYPE_DERIVE },
-        { "os_data_writes",                 "operations",   DS_TYPE_DERIVE },
-        { "os_data_fsyncs",                 "operations",   DS_TYPE_DERIVE },
-        { "os_log_bytes_written",           "operations",   DS_TYPE_DERIVE },
-        { "os_log_fsyncs",                  "operations",   DS_TYPE_DERIVE },
-        { "os_log_pending_fsyncs",          "operations",   DS_TYPE_DERIVE },
-        { "os_log_pending_writes",          "operations",   DS_TYPE_DERIVE },
-
-        { "trx_rseg_history_len",           "gauge",        DS_TYPE_GAUGE },
-
-        { "log_waits",                      "operations",   DS_TYPE_DERIVE },
-        { "log_write_requests",             "operations",   DS_TYPE_DERIVE },
-        { "log_writes",                     "operations",   DS_TYPE_DERIVE },
-        { "adaptive_hash_searches",         "operations",   DS_TYPE_DERIVE },
-
-        { "file_num_open_files",            "gauge",        DS_TYPE_GAUGE },
-
-        { "ibuf_merges_insert",             "operations",   DS_TYPE_DERIVE },
-        { "ibuf_merges_delete_mark",        "operations",   DS_TYPE_DERIVE },
-        { "ibuf_merges_delete",             "operations",   DS_TYPE_DERIVE },
-        { "ibuf_merges_discard_insert",     "operations",   DS_TYPE_DERIVE },
-        { "ibuf_merges_discard_delete_mark","operations",   DS_TYPE_DERIVE },
-        { "ibuf_merges_discard_delete",     "operations",   DS_TYPE_DERIVE },
-        { "ibuf_merges_discard_merges",     "operations",   DS_TYPE_DERIVE },
-        { "ibuf_size",                      "bytes",        DS_TYPE_GAUGE },
-
-        { "innodb_activity_count",          "gauge",        DS_TYPE_GAUGE },
-        { "innodb_dblwr_writes",            "operations",   DS_TYPE_DERIVE },
-        { "innodb_dblwr_pages_written",     "operations",   DS_TYPE_DERIVE },
-        { "innodb_dblwr_page_size",         "gauge",        DS_TYPE_GAUGE },
-
-        { "innodb_rwlock_s_spin_waits",     "operations",   DS_TYPE_DERIVE },
-        { "innodb_rwlock_x_spin_waits",     "operations",   DS_TYPE_DERIVE },
-        { "innodb_rwlock_s_spin_rounds",    "operations",   DS_TYPE_DERIVE },
-        { "innodb_rwlock_x_spin_rounds",    "operations",   DS_TYPE_DERIVE },
-        { "innodb_rwlock_s_os_waits",       "operations",   DS_TYPE_DERIVE },
-        { "innodb_rwlock_x_os_waits",       "operations",   DS_TYPE_DERIVE },
-
-        { "dml_reads",                      "operations",   DS_TYPE_DERIVE },
-        { "dml_inserts",                    "operations",   DS_TYPE_DERIVE },
-        { "dml_deletes",                    "operations",   DS_TYPE_DERIVE },
-        { "dml_updates",                    "operations",   DS_TYPE_DERIVE },
-
-        { NULL,                     NULL,           0}
-    };
+       const char *query;
+       struct {
+               const char *key;
+               const char *type;
+               int ds_type;
+       } metrics[] = {
+               { "metadata_mem_pool_size",          "bytes",        DS_TYPE_GAUGE },
+               { "lock_deadlocks",                  "mysql_locks",  DS_TYPE_DERIVE },
+               { "lock_timeouts",                   "mysql_locks",  DS_TYPE_DERIVE },
+               { "lock_row_lock_current_waits",     "mysql_locks",  DS_TYPE_DERIVE },
+               { "buffer_pool_size",                "bytes",        DS_TYPE_GAUGE },
+
+               { "buffer_pool_reads",               "operations",   DS_TYPE_DERIVE },
+               { "buffer_pool_read_requests",       "operations",   DS_TYPE_DERIVE },
+               { "buffer_pool_write_requests",      "operations",   DS_TYPE_DERIVE },
+               { "buffer_pool_wait_free",           "operations",   DS_TYPE_DERIVE },
+               { "buffer_pool_read_ahead",          "operations",   DS_TYPE_DERIVE },
+               { "buffer_pool_read_ahead_evicted",  "operations",   DS_TYPE_DERIVE },
+
+               { "buffer_pool_pages_total",         "gauge",        DS_TYPE_GAUGE },
+               { "buffer_pool_pages_misc",          "gauge",        DS_TYPE_GAUGE },
+               { "buffer_pool_pages_data",          "gauge",        DS_TYPE_GAUGE },
+               { "buffer_pool_bytes_data",          "gauge",        DS_TYPE_GAUGE },
+               { "buffer_pool_pages_dirty",         "gauge",        DS_TYPE_GAUGE },
+               { "buffer_pool_bytes_dirty",         "gauge",        DS_TYPE_GAUGE },
+               { "buffer_pool_pages_free",          "gauge",        DS_TYPE_GAUGE },
+
+               { "buffer_pages_created",            "operations",   DS_TYPE_DERIVE },
+               { "buffer_pages_written",            "operations",   DS_TYPE_DERIVE },
+               { "buffer_pages_read",               "operations",   DS_TYPE_DERIVE },
+               { "buffer_data_reads",               "operations",   DS_TYPE_DERIVE },
+               { "buffer_data_written",             "operations",   DS_TYPE_DERIVE },
+
+               { "os_data_reads",                   "operations",   DS_TYPE_DERIVE },
+               { "os_data_writes",                  "operations",   DS_TYPE_DERIVE },
+               { "os_data_fsyncs",                  "operations",   DS_TYPE_DERIVE },
+               { "os_log_bytes_written",            "operations",   DS_TYPE_DERIVE },
+               { "os_log_fsyncs",                   "operations",   DS_TYPE_DERIVE },
+               { "os_log_pending_fsyncs",           "operations",   DS_TYPE_DERIVE },
+               { "os_log_pending_writes",           "operations",   DS_TYPE_DERIVE },
+
+               { "trx_rseg_history_len",            "gauge",        DS_TYPE_GAUGE },
+
+               { "log_waits",                       "operations",   DS_TYPE_DERIVE },
+               { "log_write_requests",              "operations",   DS_TYPE_DERIVE },
+               { "log_writes",                      "operations",   DS_TYPE_DERIVE },
+               { "adaptive_hash_searches",          "operations",   DS_TYPE_DERIVE },
+
+               { "file_num_open_files",             "gauge",        DS_TYPE_GAUGE },
+
+               { "ibuf_merges_insert",              "operations",   DS_TYPE_DERIVE },
+               { "ibuf_merges_delete_mark",         "operations",   DS_TYPE_DERIVE },
+               { "ibuf_merges_delete",              "operations",   DS_TYPE_DERIVE },
+               { "ibuf_merges_discard_insert",      "operations",   DS_TYPE_DERIVE },
+               { "ibuf_merges_discard_delete_mark", "operations",   DS_TYPE_DERIVE },
+               { "ibuf_merges_discard_delete",      "operations",   DS_TYPE_DERIVE },
+               { "ibuf_merges_discard_merges",      "operations",   DS_TYPE_DERIVE },
+               { "ibuf_size",                       "bytes",        DS_TYPE_GAUGE },
+
+               { "innodb_activity_count",           "gauge",        DS_TYPE_GAUGE },
+               { "innodb_dblwr_writes",             "operations",   DS_TYPE_DERIVE },
+               { "innodb_dblwr_pages_written",      "operations",   DS_TYPE_DERIVE },
+               { "innodb_dblwr_page_size",          "gauge",        DS_TYPE_GAUGE },
+
+               { "innodb_rwlock_s_spin_waits",      "operations",   DS_TYPE_DERIVE },
+               { "innodb_rwlock_x_spin_waits",      "operations",   DS_TYPE_DERIVE },
+               { "innodb_rwlock_s_spin_rounds",     "operations",   DS_TYPE_DERIVE },
+               { "innodb_rwlock_x_spin_rounds",     "operations",   DS_TYPE_DERIVE },
+               { "innodb_rwlock_s_os_waits",        "operations",   DS_TYPE_DERIVE },
+               { "innodb_rwlock_x_os_waits",        "operations",   DS_TYPE_DERIVE },
+
+               { "dml_reads",                       "operations",   DS_TYPE_DERIVE },
+               { "dml_inserts",                     "operations",   DS_TYPE_DERIVE },
+               { "dml_deletes",                     "operations",   DS_TYPE_DERIVE },
+               { "dml_updates",                     "operations",   DS_TYPE_DERIVE },
+
+               { NULL,                              NULL,           0}
+       };
 
        query = "SELECT name, count, type FROM information_schema.innodb_metrics WHERE status = 'enabled'";
 
@@ -659,45 +655,43 @@ static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con)
 
        while ((row = mysql_fetch_row (res)))
        {
-        int i;
+               int i;
                char *key;
                unsigned long long val;
 
                key = row[0];
                val = atoll (row[1]);
 
-        for (i = 0;
-             metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0;
-             i++)
-            ;
-
-        if (metrics[i].key == NULL)
-            continue;
-
-        switch (metrics[i].ds_type) {
-        case DS_TYPE_COUNTER:
-            counter_submit(metrics[i].type, key, (counter_t)val, db);
-            break;
-        case DS_TYPE_GAUGE:
-            gauge_submit(metrics[i].type, key, (gauge_t)val, db);
-            break;
-        case DS_TYPE_DERIVE:
-            derive_submit(metrics[i].type, key, (derive_t)val, db);
-            break;
-        }
-    }
-
-    mysql_free_result(res);
-    return (0);
+               for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++)
+                       ;
+
+               if (metrics[i].key == NULL)
+                       continue;
+
+               switch (metrics[i].ds_type) {
+                       case DS_TYPE_COUNTER:
+                               counter_submit(metrics[i].type, key, (counter_t)val, db);
+                               break;
+                       case DS_TYPE_GAUGE:
+                               gauge_submit(metrics[i].type, key, (gauge_t)val, db);
+                               break;
+                       case DS_TYPE_DERIVE:
+                               derive_submit(metrics[i].type, key, (derive_t)val, db);
+                               break;
+               }
+       }
+
+       mysql_free_result(res);
+       return (0);
 }
 
 static int mysql_read (user_data_t *ud)
 {
        mysql_database_t *db;
-       MYSQL     *con;
-       MYSQL_RES *res;
-       MYSQL_ROW  row;
-       char      *query;
+       MYSQL      *con;
+       MYSQL_RES  *res;
+       MYSQL_ROW   row;
+       const char *query;
 
        derive_t qcache_hits          = 0;
        derive_t qcache_inserts       = 0;
@@ -712,7 +706,7 @@ static int mysql_read (user_data_t *ud)
 
        unsigned long long traffic_incoming = 0ULL;
        unsigned long long traffic_outgoing = 0ULL;
-    unsigned long mysql_version = 0ULL;
+       unsigned long mysql_version = 0ULL;
 
        if ((ud == NULL) || (ud->data == NULL))
        {
@@ -726,7 +720,7 @@ static int mysql_read (user_data_t *ud)
        if ((con = getconnection (db)) == NULL)
                return (-1);
 
-  mysql_version = mysql_get_server_version(con);
+       mysql_version = mysql_get_server_version(con);
 
        query = "SHOW STATUS";
        if (mysql_version >= 50002)
@@ -744,7 +738,7 @@ static int mysql_read (user_data_t *ud)
                key = row[0];
                val = atoll (row[1]);
 
-               if (strncmp (key, "Com_", 
+               if (strncmp (key, "Com_",
                                  strlen ("Com_")) == 0)
                {
                        if (val == 0ULL)
@@ -752,18 +746,18 @@ static int mysql_read (user_data_t *ud)
 
                        /* Ignore `prepared statements' */
                        if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0)
-                               counter_submit ("mysql_commands", 
-                                               key + strlen ("Com_"), 
+                               counter_submit ("mysql_commands",
+                                               key + strlen ("Com_"),
                                                val, db);
                }
-               else if (strncmp (key, "Handler_", 
+               else if (strncmp (key, "Handler_",
                                        strlen ("Handler_")) == 0)
                {
                        if (val == 0ULL)
                                continue;
 
-                       counter_submit ("mysql_handler", 
-                                       key + strlen ("Handler_"), 
+                       counter_submit ("mysql_handler",
+                                       key + strlen ("Handler_"),
                                        val, db);
                }
                else if (strncmp (key, "Qcache_",
@@ -780,7 +774,7 @@ static int mysql_read (user_data_t *ud)
                        else if (strcmp (key, "Qcache_queries_in_cache") == 0)
                                qcache_queries_in_cache = (gauge_t) val;
                }
-               else if (strncmp (key, "Bytes_", 
+               else if (strncmp (key, "Bytes_",
                                        strlen ("Bytes_")) == 0)
                {
                        if (strcmp (key, "Bytes_received") == 0)
@@ -788,7 +782,7 @@ static int mysql_read (user_data_t *ud)
                        else if (strcmp (key, "Bytes_sent") == 0)
                                traffic_outgoing += val;
                }
-               else if (strncmp (key, "Threads_", 
+               else if (strncmp (key, "Threads_",
                                                strlen ("Threads_")) == 0)
                {
                        if (strcmp (key, "Threads_running") == 0)
@@ -900,8 +894,15 @@ static int mysql_read (user_data_t *ud)
                }
                else if (strncmp (key, "Sort_", strlen ("Sort_")) == 0)
                {
-                       counter_submit ("mysql_sort", key + strlen ("Sort_"),
-                                       val, db);
+                       if (strcmp (key, "Sort_merge_passes") == 0)
+                               counter_submit ("mysql_sort_merge_passes", NULL, val, db);
+                       else if (strcmp (key, "Sort_rows") == 0)
+                               counter_submit ("mysql_sort_rows", NULL, val, db);
+                       else if (strcmp (key, "Sort_range") == 0)
+                               counter_submit ("mysql_sort", "range", val, db);
+                       else if (strcmp (key, "Sort_scan") == 0)
+                               counter_submit ("mysql_sort", "scan", val, db);
+
                }
        }
        mysql_free_result (res); res = NULL;
@@ -940,7 +941,7 @@ static int mysql_read (user_data_t *ud)
        traffic_submit  (traffic_incoming, traffic_outgoing, db);
 
        if (mysql_version >= 50600 && db->innodb_stats)
-        mysql_read_innodb_stats (db, con);
+               mysql_read_innodb_stats (db, con);
 
        if (db->master_stats)
                mysql_read_master_stats (db, con);
index 020bfba..e00c252 100644 (file)
@@ -464,10 +464,9 @@ static disk_t *get_disk(cfg_disk_t *cd, const char *name) /* {{{ */
                        return d;
        }
 
-       d = malloc(sizeof(*d));
+       d = calloc (1, sizeof (*d));
        if (d == NULL)
                return (NULL);
-       memset (d, 0, sizeof (*d));
        d->next = NULL;
 
        d->name = strdup(name);
@@ -513,10 +512,9 @@ static data_volume_usage_t *get_volume_usage (cfg_volume_usage_t *cvu, /* {{{ */
                return (NULL);
 
        /* Not found: allocate. */
-       new = malloc (sizeof (*new));
+       new = calloc (1, sizeof (*new));
        if (new == NULL)
                return (NULL);
-       memset (new, 0, sizeof (*new));
        new->next = NULL;
 
        new->name = strdup (name);
@@ -581,10 +579,9 @@ static data_volume_perf_t *get_volume_perf (cfg_volume_perf_t *cvp, /* {{{ */
                return (NULL);
 
        /* Not found: allocate. */
-       new = malloc (sizeof (*new));
+       new = calloc (1, sizeof (*new));
        if (new == NULL)
                return (NULL);
-       memset (new, 0, sizeof (*new));
        new->next = NULL;
 
        new->name = strdup (name);
@@ -882,7 +879,7 @@ static cdtime_t cna_child_get_cdtime (na_elem_t *data) /* {{{ */
 } /* }}} cdtime_t cna_child_get_cdtime */
 
 
-/* 
+/*
  * Query functions
  *
  * These functions are called with appropriate data returned by the libnetapp
@@ -900,7 +897,7 @@ static int cna_handle_wafl_data (const char *hostname, cfg_wafl_t *cfg_wafl, /*
        na_elem_iter_t counter_iter;
 
        memset (&perf_data, 0, sizeof (perf_data));
-       
+
        perf_data.timestamp = cna_child_get_cdtime (data);
 
        instances = na_elem_child(na_elem_child (data, "instances"), "instance-data");
@@ -1065,7 +1062,7 @@ static int cna_handle_disk_data (const char *hostname, /* {{{ */
 
        if ((cfg_disk == NULL) || (data == NULL))
                return (EINVAL);
-       
+
        timestamp = cna_child_get_cdtime (data);
 
        instances = na_elem_child (data, "instances");
@@ -1257,7 +1254,7 @@ static int cna_handle_volume_perf_data (const char *hostname, /* {{{ */
        na_elem_t *elem_instances;
        na_elem_iter_t iter_instances;
        na_elem_t *elem_instance;
-       
+
        timestamp = cna_child_get_cdtime (data);
 
        elem_instances = na_elem_child(data, "instances");
@@ -1524,7 +1521,7 @@ static int cna_change_volume_status (const char *hostname, /* {{{ */
 {
        notification_t n;
 
-       memset (&n, 0, sizeof (&n));
+       memset (&n, 0, sizeof (n));
        n.time = cdtime ();
        sstrncpy (n.host, hostname, sizeof (n.host));
        sstrncpy (n.plugin, "netapp", sizeof (n.plugin));
@@ -1736,7 +1733,7 @@ static int cna_handle_volume_usage_data (const host_config_t *host, /* {{{ */
 
                if ((v->flags & CFG_VOLUME_USAGE_SNAP) != 0)
                        cna_handle_volume_snap_usage(host, v);
-               
+
                if ((v->flags & CFG_VOLUME_USAGE_DF) == 0)
                        continue;
 
@@ -2131,7 +2128,7 @@ static int cna_handle_system_data (const char *hostname, /* {{{ */
 
        const char *instance;
        cdtime_t timestamp;
-       
+
        timestamp = cna_child_get_cdtime (data);
 
        instances = na_elem_child(na_elem_child (data, "instances"), "instance-data");
@@ -2198,7 +2195,7 @@ static int cna_handle_system_data (const char *hostname, /* {{{ */
                        && (HAS_ALL_FLAGS (counter_flags, 0x01 | 0x02)))
                submit_two_derive (hostname, instance, "disk_octets", NULL,
                                disk_read, disk_written, timestamp, interval);
-                               
+
        if ((cfg_system->flags & CFG_SYSTEM_NET)
                        && (HAS_ALL_FLAGS (counter_flags, 0x04 | 0x08)))
                submit_two_derive (hostname, instance, "if_octets", NULL,
@@ -2405,10 +2402,9 @@ static int cna_config_volume_performance (host_config_t *host, /* {{{ */
 
        if (host->cfg_volume_perf == NULL)
        {
-               cfg_volume_perf = malloc (sizeof (*cfg_volume_perf));
+               cfg_volume_perf = calloc (1, sizeof (*cfg_volume_perf));
                if (cfg_volume_perf == NULL)
                        return (ENOMEM);
-               memset (cfg_volume_perf, 0, sizeof (*cfg_volume_perf));
 
                /* Set default flags */
                cfg_volume_perf->query = NULL;
@@ -2441,10 +2437,10 @@ static int cna_config_volume_performance (host_config_t *host, /* {{{ */
                host->cfg_volume_perf = cfg_volume_perf;
        }
        cfg_volume_perf = host->cfg_volume_perf;
-       
+
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
-               
+
                /* if (!item || !item->key || !*item->key) continue; */
                if (strcasecmp(item->key, "Interval") == 0)
                        cna_config_get_interval (item, &cfg_volume_perf->interval);
@@ -2533,10 +2529,9 @@ static int cna_config_quota (host_config_t *host, oconfig_item_t *ci) /* {{{ */
 
        if (host->cfg_quota == NULL)
        {
-               cfg_quota = malloc (sizeof (*cfg_quota));
+               cfg_quota = calloc (1, sizeof (*cfg_quota));
                if (cfg_quota == NULL)
                        return (ENOMEM);
-               memset (cfg_quota, 0, sizeof (*cfg_quota));
                cfg_quota->query = NULL;
 
                host->cfg_quota = cfg_quota;
@@ -2566,10 +2561,9 @@ static int cna_config_disk(host_config_t *host, oconfig_item_t *ci) { /* {{{ */
 
        if (host->cfg_disk == NULL)
        {
-               cfg_disk = malloc (sizeof (*cfg_disk));
+               cfg_disk = calloc (1, sizeof (*cfg_disk));
                if (cfg_disk == NULL)
                        return (ENOMEM);
-               memset (cfg_disk, 0, sizeof (*cfg_disk));
 
                /* Set default flags */
                cfg_disk->flags = CFG_DISK_ALL;
@@ -2579,10 +2573,10 @@ static int cna_config_disk(host_config_t *host, oconfig_item_t *ci) { /* {{{ */
                host->cfg_disk = cfg_disk;
        }
        cfg_disk = host->cfg_disk;
-       
+
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
-               
+
                /* if (!item || !item->key || !*item->key) continue; */
                if (strcasecmp(item->key, "Interval") == 0)
                        cna_config_get_interval (item, &cfg_disk->interval);
@@ -2612,10 +2606,9 @@ static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */
 
        if (host->cfg_wafl == NULL)
        {
-               cfg_wafl = malloc (sizeof (*cfg_wafl));
+               cfg_wafl = calloc (1, sizeof (*cfg_wafl));
                if (cfg_wafl == NULL)
                        return (ENOMEM);
-               memset (cfg_wafl, 0, sizeof (*cfg_wafl));
 
                /* Set default flags */
                cfg_wafl->flags = CFG_WAFL_ALL;
@@ -2626,7 +2619,7 @@ static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */
 
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
-               
+
                if (strcasecmp(item->key, "Interval") == 0)
                        cna_config_get_interval (item, &cfg_wafl->interval);
                else if (!strcasecmp(item->key, "GetNameCache"))
@@ -2681,10 +2674,9 @@ static int cna_config_volume_usage(host_config_t *host, /* {{{ */
 
        if (host->cfg_volume_usage == NULL)
        {
-               cfg_volume_usage = malloc (sizeof (*cfg_volume_usage));
+               cfg_volume_usage = calloc (1, sizeof (*cfg_volume_usage));
                if (cfg_volume_usage == NULL)
                        return (ENOMEM);
-               memset (cfg_volume_usage, 0, sizeof (*cfg_volume_usage));
 
                /* Set default flags */
                cfg_volume_usage->query = NULL;
@@ -2708,10 +2700,10 @@ static int cna_config_volume_usage(host_config_t *host, /* {{{ */
                host->cfg_volume_usage = cfg_volume_usage;
        }
        cfg_volume_usage = host->cfg_volume_usage;
-       
+
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
-               
+
                /* if (!item || !item->key || !*item->key) continue; */
                if (strcasecmp(item->key, "Interval") == 0)
                        cna_config_get_interval (item, &cfg_volume_usage->interval);
@@ -2743,10 +2735,9 @@ static int cna_config_snapvault (host_config_t *host, /* {{{ */
 
        if (host->cfg_snapvault == NULL)
        {
-               cfg_snapvault = malloc (sizeof (*cfg_snapvault));
+               cfg_snapvault = calloc (1, sizeof (*cfg_snapvault));
                if (cfg_snapvault == NULL)
                        return ENOMEM;
-               memset (cfg_snapvault, 0, sizeof (*cfg_snapvault));
                cfg_snapvault->query = NULL;
 
                host->cfg_snapvault = cfg_snapvault;
@@ -2773,16 +2764,15 @@ static int cna_config_system (host_config_t *host, /* {{{ */
 {
        cfg_system_t *cfg_system;
        int i;
-       
+
        if ((host == NULL) || (ci == NULL))
                return (EINVAL);
 
        if (host->cfg_system == NULL)
        {
-               cfg_system = malloc (sizeof (*cfg_system));
+               cfg_system = calloc (1, sizeof (*cfg_system));
                if (cfg_system == NULL)
                        return (ENOMEM);
-               memset (cfg_system, 0, sizeof (*cfg_system));
 
                /* Set default flags */
                cfg_system->flags = CFG_SYSTEM_ALL;
@@ -2827,10 +2817,9 @@ static host_config_t *cna_alloc_host (void) /* {{{ */
 {
        host_config_t *host;
 
-       host = malloc(sizeof(*host));
-       if (! host)
+       host = calloc (1, sizeof (*host));
+       if (host == NULL)
                return (NULL);
-       memset (host, 0, sizeof (*host));
 
        host->name = NULL;
        host->protocol = NA_SERVER_TRANSPORT_HTTPS;
index e1f378d..5c3a9f0 100644 (file)
@@ -109,12 +109,10 @@ static int add_ignorelist (const char *dev, const char *type,
 {
   ir_ignorelist_t *entry;
 
-  entry = (ir_ignorelist_t *) malloc (sizeof (ir_ignorelist_t));
+  entry = calloc (1, sizeof (*entry));
   if (entry == NULL)
     return (-1);
 
-  memset (entry, '\0', sizeof (ir_ignorelist_t));
-
   if (strcasecmp (dev, "All") != 0)
   {
     entry->device = strdup (dev);
@@ -246,7 +244,7 @@ static int update_iflist (struct ifinfomsg *msg, const char *dev)
   {
     char **temp;
 
-    temp = (char **) realloc (iflist, (msg->ifi_index + 1) * sizeof (char *));
+    temp = realloc (iflist, (msg->ifi_index + 1) * sizeof (char *));
     if (temp == NULL)
     {
       ERROR ("netlink plugin: update_iflist: realloc failed.");
@@ -470,7 +468,7 @@ static int qos_filter_cb (const struct nlmsghdr *nlh, void *args)
   const char *kind = NULL;
 
   /* char *type_instance; */
-  char *tc_type;
+  const char *tc_type;
   char tc_inst[DATA_MAX_NAME_LEN];
 
   _Bool stats_submitted = 0;
index 9169000..bf1f2ab 100644 (file)
@@ -618,14 +618,14 @@ static int write_part_values (char **ret_buffer, int *ret_buffer_len,
        if (*ret_buffer_len < packet_len)
                return (-1);
 
-       pkg_values_types = (uint8_t *) malloc (num_values * sizeof (uint8_t));
+       pkg_values_types = malloc (num_values * sizeof (*pkg_values_types));
        if (pkg_values_types == NULL)
        {
                ERROR ("network plugin: write_part_values: malloc failed.");
                return (-1);
        }
 
-       pkg_values = (value_t *) malloc (num_values * sizeof (value_t));
+       pkg_values = malloc (num_values * sizeof (*pkg_values));
        if (pkg_values == NULL)
        {
                free (pkg_values_types);
@@ -776,11 +776,11 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
 
        uint16_t tmp16;
        size_t exp_size;
-       int   i;
+       size_t i;
 
        uint16_t pkg_length;
        uint16_t pkg_type;
-       uint16_t pkg_numval;
+       size_t pkg_numval;
 
        uint8_t *pkg_types;
        value_t *pkg_values;
@@ -802,7 +802,7 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
 
        memcpy ((void *) &tmp16, buffer, sizeof (tmp16));
        buffer += sizeof (tmp16);
-       pkg_numval = ntohs (tmp16);
+       pkg_numval = (size_t) ntohs (tmp16);
 
        assert (pkg_type == TYPE_VALUES);
 
@@ -817,6 +817,7 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
                                exp_size, buffer_len);
                return (-1);
        }
+       assert (pkg_numval <= ((buffer_len - 6) / 9));
 
        if (pkg_length != exp_size)
        {
@@ -826,20 +827,20 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
                return (-1);
        }
 
-       pkg_types = (uint8_t *) malloc (pkg_numval * sizeof (uint8_t));
-       pkg_values = (value_t *) malloc (pkg_numval * sizeof (value_t));
+       pkg_types = calloc (pkg_numval, sizeof (*pkg_types));
+       pkg_values = calloc (pkg_numval, sizeof (*pkg_values));
        if ((pkg_types == NULL) || (pkg_values == NULL))
        {
                sfree (pkg_types);
                sfree (pkg_values);
-               ERROR ("network plugin: parse_part_values: malloc failed.");
+               ERROR ("network plugin: parse_part_values: calloc failed.");
                return (-1);
        }
 
-       memcpy ((void *) pkg_types, (void *) buffer, pkg_numval * sizeof (uint8_t));
-       buffer += pkg_numval * sizeof (uint8_t);
-       memcpy ((void *) pkg_values, (void *) buffer, pkg_numval * sizeof (value_t));
-       buffer += pkg_numval * sizeof (value_t);
+       memcpy (pkg_types, buffer, pkg_numval * sizeof (*pkg_types));
+       buffer += pkg_numval * sizeof (*pkg_types);
+       memcpy (pkg_values, buffer, pkg_numval * sizeof (*pkg_values));
+       buffer += pkg_numval * sizeof (*pkg_values);
 
        for (i = 0; i < pkg_numval; i++)
        {
@@ -873,7 +874,7 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
 
        *ret_buffer     = buffer;
        *ret_buffer_len = buffer_len - pkg_length;
-       *ret_num_values = (size_t) pkg_numval;
+       *ret_num_values = pkg_numval;
        *ret_values     = pkg_values;
 
        sfree (pkg_types);
@@ -933,7 +934,7 @@ static int parse_part_string (void **ret_buffer, size_t *ret_buffer_len,
        uint16_t pkg_length;
        size_t payload_size;
 
-       if (output_len <= 0)
+       if (output_len == 0)
                return (EINVAL);
 
        if (buffer_len < header_size)
@@ -1368,7 +1369,7 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
     warning_has_been_printed = 1;
   }
 
-  *ret_buffer += ph_length;
+  *ret_buffer = (void *) (((char *) *ret_buffer) + ph_length);
   *ret_buffer_size -= ph_length;
 
   return (0);
@@ -1407,7 +1408,7 @@ static int parse_packet (sockent_t *se, /* {{{ */
                                (void *) buffer,
                                sizeof (pkg_type));
                memcpy ((void *) &pkg_length,
-                               (void *) (buffer + sizeof (pkg_type)),
+                               (void *) (((char *) buffer) + sizeof (pkg_type)),
                                sizeof (pkg_length));
 
                pkg_length = ntohs (pkg_length);
@@ -2011,10 +2012,9 @@ static sockent_t *sockent_create (int type) /* {{{ */
        if ((type != SOCKENT_TYPE_CLIENT) && (type != SOCKENT_TYPE_SERVER))
                return (NULL);
 
-       se = malloc (sizeof (*se));
+       se = calloc (1, sizeof (*se));
        if (se == NULL)
                return (NULL);
-       memset (se, 0, sizeof (*se));
 
        se->type = type;
        se->node = NULL;
@@ -2195,16 +2195,15 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */
                        continue;
                }
 
-               client->addr = malloc (sizeof (*client->addr));
+               client->addr = calloc (1, sizeof (*client->addr));
                if (client->addr == NULL)
                {
-                       ERROR ("network plugin: malloc failed.");
+                       ERROR ("network plugin: calloc failed.");
                        close (client->fd);
                        client->fd = -1;
                        continue;
                }
 
-               memset (client->addr, 0, sizeof (*client->addr));
                assert (sizeof (*client->addr) >= ai_ptr->ai_addrlen);
                memcpy (client->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
                client->addrlen = ai_ptr->ai_addrlen;
@@ -2312,7 +2311,7 @@ static int sockent_server_listen (sockent_t *se) /* {{{ */
 
        freeaddrinfo (ai_list);
 
-       if (se->data.server.fd_num <= 0)
+       if (se->data.server.fd_num == 0)
                return (-1);
        return (0);
 } /* }}} int sockent_server_listen */
@@ -2494,14 +2493,14 @@ static int network_receive (void) /* {{{ */
                         * these entries in the dispatch thread but put them in
                         * another list, so we don't have to allocate more and
                         * more of these structures. */
-                       ent = malloc (sizeof (receive_list_entry_t));
+                       ent = calloc (1, sizeof (*ent));
                        if (ent == NULL)
                        {
-                               ERROR ("network plugin: malloc failed.");
+                               ERROR ("network plugin: calloc failed.");
                                status = ENOMEM;
                                break;
                        }
-                       memset (ent, 0, sizeof (receive_list_entry_t));
+
                        ent->data = malloc (network_config_packet_size);
                        if (ent->data == NULL)
                        {
@@ -2586,7 +2585,7 @@ static void network_init_buffer (void)
        memset (&send_buffer_vl, 0, sizeof (send_buffer_vl));
 } /* int network_init_buffer */
 
-static void networt_send_buffer_plain (sockent_t *se, /* {{{ */
+static void network_send_buffer_plain (sockent_t *se, /* {{{ */
                const char *buffer, size_t buffer_size)
 {
        int status;
@@ -2616,7 +2615,7 @@ static void networt_send_buffer_plain (sockent_t *se, /* {{{ */
 
                break;
        } /* while (42) */
-} /* }}} void networt_send_buffer_plain */
+} /* }}} void network_send_buffer_plain */
 
 #if HAVE_LIBGCRYPT
 #define BUFFER_ADD(p,s) do { \
@@ -2624,7 +2623,7 @@ static void networt_send_buffer_plain (sockent_t *se, /* {{{ */
   buffer_offset += (s); \
 } while (0)
 
-static void networt_send_buffer_signed (sockent_t *se, /* {{{ */
+static void network_send_buffer_signed (sockent_t *se, /* {{{ */
                const char *in_buffer, size_t in_buffer_size)
 {
   part_signature_sha256_t ps;
@@ -2698,10 +2697,10 @@ static void networt_send_buffer_signed (sockent_t *se, /* {{{ */
   hd = NULL;
 
   buffer_offset = PART_SIGNATURE_SHA256_SIZE + username_len + in_buffer_size;
-  networt_send_buffer_plain (se, buffer, buffer_offset);
-} /* }}} void networt_send_buffer_signed */
+  network_send_buffer_plain (se, buffer, buffer_offset);
+} /* }}} void network_send_buffer_signed */
 
-static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
+static void network_send_buffer_encrypted (sockent_t *se, /* {{{ */
                const char *in_buffer, size_t in_buffer_size)
 {
   part_encryption_aes256_t pea;
@@ -2731,7 +2730,7 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
     - sizeof (pea.hash);
 
   assert (buffer_size <= sizeof (buffer));
-  DEBUG ("network plugin: networt_send_buffer_encrypted: "
+  DEBUG ("network plugin: network_send_buffer_encrypted: "
       "buffer_size = %zu;", buffer_size);
 
   pea.head.length = htons ((uint16_t) (PART_ENCRYPTION_AES256_SIZE
@@ -2778,8 +2777,8 @@ static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
   }
 
   /* Send it out without further modifications */
-  networt_send_buffer_plain (se, buffer, buffer_size);
-} /* }}} void networt_send_buffer_encrypted */
+  network_send_buffer_plain (se, buffer, buffer_size);
+} /* }}} void network_send_buffer_encrypted */
 #undef BUFFER_ADD
 #endif /* HAVE_LIBGCRYPT */
 
@@ -2793,12 +2792,12 @@ static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */
   {
 #if HAVE_LIBGCRYPT
     if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
-      networt_send_buffer_encrypted (se, buffer, buffer_len);
+      network_send_buffer_encrypted (se, buffer, buffer_len);
     else if (se->data.client.security_level == SECURITY_LEVEL_SIGN)
-      networt_send_buffer_signed (se, buffer, buffer_len);
+      network_send_buffer_signed (se, buffer, buffer_len);
     else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */
 #endif /* HAVE_LIBGCRYPT */
-      networt_send_buffer_plain (se, buffer, buffer_len);
+      network_send_buffer_plain (se, buffer, buffer_len);
   } /* for (sending_sockets) */
 } /* }}} void network_send_buffer */
 
@@ -3191,7 +3190,7 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
   }
 
   /* No call to sockent_client_connect() here -- it is called from
-   * networt_send_buffer_plain(). */
+   * network_send_buffer_plain(). */
 
   status = sockent_add (se);
   if (status != 0)
index be82372..0948bc7 100644 (file)
--- a/src/nfs.c
+++ b/src/nfs.c
@@ -221,7 +221,7 @@ static size_t nfs4_server40_procedures_names_num = STATIC_ARRAY_SIZE (nfs4_serve
 static const char *nfs4_server41_procedures_names[] =
 {
        "backchannel_ctl",
-       "bind_conn_to_session", 
+       "bind_conn_to_session",
        "exchange_id",
        "create_session",
        "destroy_session",
@@ -404,7 +404,7 @@ static void nfs_procedures_submit (const char *plugin_instance,
 } /* void nfs_procedures_submit */
 
 #if KERNEL_LINUX
-static void nfs_submit_fields (int nfs_version, const char *instance, 
+static void nfs_submit_fields (int nfs_version, const char *instance,
                char **fields, size_t fields_num, const char **proc_names)
 {
        char plugin_instance[DATA_MAX_NAME_LEN];
@@ -434,19 +434,19 @@ static int nfs_submit_fields_safe (int nfs_version, const char *instance,
                return (EINVAL);
        }
 
-       nfs_submit_fields (nfs_version, instance, fields, fields_num, 
+       nfs_submit_fields (nfs_version, instance, fields, fields_num,
                        proc_names);
 
        return (0);
 }
 
-static int nfs_submit_nfs4_server (const char *instance, char **fields, 
+static int nfs_submit_nfs4_server (const char *instance, char **fields,
                size_t fields_num)
 {
        static int suppress_warning = 0;
 
        if (fields_num != NFS4_SERVER40_NUM_PROC &&
-               fields_num != NFS4_SERVER41_NUM_PROC) 
+               fields_num != NFS4_SERVER41_NUM_PROC)
        {
                if (!suppress_warning)
                {
@@ -466,7 +466,7 @@ static int nfs_submit_nfs4_server (const char *instance, char **fields,
                }
        }
 
-        nfs_submit_fields (4, instance, fields, 
+        nfs_submit_fields (4, instance, fields,
                        nfs4_server40_procedures_names_num,
                        nfs4_server40_procedures_names);
 
@@ -474,15 +474,15 @@ static int nfs_submit_nfs4_server (const char *instance, char **fields,
        {
                fields += nfs4_server40_procedures_names_num;
 
-               nfs_submit_fields (4, instance, fields, 
-                               nfs4_server41_procedures_names_num, 
+               nfs_submit_fields (4, instance, fields,
+                               nfs4_server41_procedures_names_num,
                                nfs4_server41_procedures_names);
        }
 
        return (0);
 }
 
-static int nfs_submit_nfs4_client (const char *instance, char **fields, 
+static int nfs_submit_nfs4_client (const char *instance, char **fields,
                size_t fields_num)
 {
        size_t proc40_names_num, proc41_names_num;
@@ -554,7 +554,7 @@ static int nfs_submit_nfs4_client (const char *instance, char **fields,
        return (0);
 }
 
-static void nfs_read_linux (FILE *fh, char *inst)
+static void nfs_read_linux (FILE *fh, const char *inst)
 {
        char buffer[1024];
 
@@ -589,21 +589,21 @@ static void nfs_read_linux (FILE *fh, char *inst)
                else if (strcmp (fields[0], "proc4ops") == 0)
                {
                        if (inst[0] == 's')
-                               nfs_submit_nfs4_server (inst, fields + 2, 
+                               nfs_submit_nfs4_server (inst, fields + 2,
                                                (size_t) (fields_num - 2));
                }
                else if (strcmp (fields[0], "proc4") == 0)
                {
                        if (inst[0] == 'c')
                                nfs_submit_nfs4_client (inst, fields + 2,
-                                               (size_t) (fields_num - 2));                     
+                                               (size_t) (fields_num - 2));
                }
        } /* while (fgets) */
 } /* void nfs_read_linux */
 #endif /* KERNEL_LINUX */
 
 #if HAVE_LIBKSTAT
-static int nfs_read_kstat (kstat_t *ksp, int nfs_version, char *inst,
+static int nfs_read_kstat (kstat_t *ksp, int nfs_version, const char *inst,
                char const **proc_names, size_t proc_names_num)
 {
        char plugin_instance[DATA_MAX_NAME_LEN];
index 69ec06d..7587c1f 100644 (file)
@@ -71,7 +71,7 @@ static size_t nginx_curl_callback (void *buf, size_t size, size_t nmemb,
     len = (sizeof (nginx_buffer) - 1) - nginx_buffer_len;
   }
 
-  if (len <= 0)
+  if (len == 0)
     return (len);
 
   memcpy (&nginx_buffer[nginx_buffer_len], buf, len);
@@ -195,7 +195,7 @@ static int init (void)
   return (0);
 } /* void init */
 
-static void submit (char *type, char *inst, long long value)
+static void submit (const char *type, const char *inst, long long value)
 {
   value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
index 24c66ec..c77b2d1 100644 (file)
@@ -66,7 +66,7 @@ static char *email_subject = NULL;
 /* Callback to get username and password */
 static int authinteract (auth_client_request_t request, char **result,
     int fields, void __attribute__((unused)) *arg)
-{               
+{
   int i;
   for (i = 0; i < fields; i++)
   {
@@ -145,7 +145,7 @@ static int notify_email_init (void)
   if ( !smtp_auth_set_context (session, authctx)) {
     pthread_mutex_unlock (&session_lock);
     ERROR ("notify_email plugin: cannot set SMTP auth context");
-    return (-1);   
+    return (-1);
   }
 
   pthread_mutex_unlock (&session_lock);
@@ -176,7 +176,7 @@ static int notify_email_config (const char *key, const char *value)
   {
     char **tmp;
 
-    tmp = (char **) realloc ((void *) recipients, (recipients_len + 1) * sizeof (char *));
+    tmp = realloc (recipients, (recipients_len + 1) * sizeof (char *));
     if (tmp == NULL) {
       ERROR ("notify_email: realloc failed.");
       return (-1);
@@ -282,7 +282,7 @@ static int notify_email_notification (const notification_t *n,
   if (!(message = smtp_add_message (session))) {
     pthread_mutex_unlock (&session_lock);
     ERROR ("notify_email plugin: cannot set SMTP message");
-    return (-1);   
+    return (-1);
   }
   smtp_set_reverse_path (message, email_from);
   smtp_set_header (message, "To", NULL, NULL);
@@ -293,7 +293,6 @@ static int notify_email_notification (const notification_t *n,
 
   /* Initiate a connection to the SMTP server and transfer the message. */
   if (!smtp_start_session (session)) {
-    char buf[MAXSTRING];
     ERROR ("notify_email plugin: SMTP server problem: %s",
         smtp_strerror (smtp_errno (), buf, sizeof buf));
     pthread_mutex_unlock (&session_lock);
diff --git a/src/notify_nagios.c b/src/notify_nagios.c
new file mode 100644 (file)
index 0000000..1f4182b
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * collectd - src/notify_nagios.c
+ * Copyright (C) 2015       Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Florian octo Forster <octo at collectd.org>
+ */
+
+#include "collectd.h"
+#include "plugin.h"
+#include "common.h"
+#include "configfile.h"
+
+#define NAGIOS_OK       0
+#define NAGIOS_WARNING  1
+#define NAGIOS_CRITICAL 2
+#define NAGIOS_UNKNOWN  3
+
+#ifndef NAGIOS_COMMAND_FILE
+# define NAGIOS_COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd"
+#endif
+
+static char *nagios_command_file;
+
+static int nagios_config (oconfig_item_t *ci) /* {{{ */
+{
+  int i;
+
+  for (i = 0; i < ci->children_num; i++)
+  {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp ("CommandFile", child->key) == 0)
+      cf_util_get_string (child, &nagios_command_file);
+    else
+      WARNING ("notify_nagios plugin: Ignoring unknown config option \"%s\".",
+          child->key);
+  }
+
+  return 0;
+} /* }}} nagios_config */
+
+static int nagios_print (char const *buffer) /* {{{ */
+{
+  char const *file = NAGIOS_COMMAND_FILE;
+  int fd;
+  int status;
+  struct flock lock;
+
+  if (nagios_command_file != NULL)
+    file = nagios_command_file;
+
+  fd = open (file, O_WRONLY | O_APPEND);
+  if (fd < 0)
+  {
+    char errbuf[1024];
+    status = errno;
+    ERROR ("notify_nagios plugin: Opening \"%s\" failed: %s",
+        file, sstrerror (status, errbuf, sizeof (errbuf)));
+    return status;
+  }
+
+  memset (&lock, 0, sizeof (lock));
+  lock.l_type = F_WRLCK;
+  lock.l_whence = SEEK_END;
+  lock.l_start = 0;
+  lock.l_len = 0; /* to end of file */
+
+  status = fcntl (fd, F_GETLK, &lock);
+  if (status != 0)
+  {
+    char errbuf[1024];
+    status = errno;
+    ERROR ("notify_nagios plugin: Failed to acquire write lock on \"%s\": %s",
+        file, sstrerror (status, errbuf, sizeof (errbuf)));
+    close (fd);
+    return status;
+  }
+
+  status = (int) lseek (fd, 0, SEEK_END);
+  if (status == -1)
+  {
+    char errbuf[1024];
+    status = errno;
+    ERROR ("notify_nagios plugin: Seeking to end of \"%s\" failed: %s",
+        file, sstrerror (status, errbuf, sizeof (errbuf)));
+    close (fd);
+    return status;
+  }
+
+  status = (int) swrite (fd, buffer, strlen (buffer));
+  if (status != 0)
+  {
+    char errbuf[1024];
+    status = errno;
+    ERROR ("notify_nagios plugin: Writing to \"%s\" failed: %s",
+        file, sstrerror (status, errbuf, sizeof (errbuf)));
+    close (fd);
+    return status;
+  }
+
+  close (fd);
+  return status;
+} /* }}} int nagios_print */
+
+static int nagios_notify (const notification_t *n, /* {{{ */
+    __attribute__((unused)) user_data_t *user_data)
+{
+  char svc_description[4 * DATA_MAX_NAME_LEN];
+  char buffer[4096];
+  int code;
+  int status;
+
+  status = format_name (svc_description, (int) sizeof (svc_description),
+      /* host */ "", n->plugin, n->plugin_instance, n->type, n->type_instance);
+  if (status != 0)
+  {
+    ERROR ("notify_nagios plugin: Formatting service name failed.");
+    return status;
+  }
+
+  switch (n->severity)
+  {
+    case NOTIF_OKAY:
+      code = NAGIOS_OK;
+      break;
+    case NOTIF_WARNING:
+      code = NAGIOS_WARNING;
+      break;
+    case NOTIF_FAILURE:
+      code = NAGIOS_CRITICAL;
+      break;
+    default:
+      code = NAGIOS_UNKNOWN;
+      break;
+  }
+
+  ssnprintf (buffer, sizeof (buffer),
+      "[%.0f] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
+      CDTIME_T_TO_DOUBLE (n->time), n->host, &svc_description[1], code,
+      n->message);
+
+  return nagios_print (buffer);
+} /* }}} int nagios_notify */
+
+void module_register (void)
+{
+  plugin_register_complex_config ("notify_nagios", nagios_config);
+  plugin_register_notification ("notify_nagios", nagios_notify, NULL);
+} /* void module_register (void) */
+
+/* vim: set sw=2 sts=2 ts=8 et : */
index dbde660..1071d0b 100644 (file)
@@ -163,16 +163,16 @@ struct resp_pkt
 /* l_fp to double */
 #define M_LFPTOD(r_i, r_uf, d) \
        do { \
-               register int32_t  i; \
-               register uint32_t f; \
+               register int32_t  ri; \
+               register uint32_t rf; \
                \
-               i = (r_i); \
-               f = (r_uf); \
-               if (i < 0) { \
-                       M_NEG(i, f); \
-                       (d) = -((double) i + ((double) f) / 4294967296.0); \
+               ri = (r_i); \
+               rf = (r_uf); \
+               if (ri < 0) { \
+                       M_NEG(ri, rf); \
+                       (d) = -((double) ri + ((double) rf) / 4294967296.0); \
                } else { \
-                       (d) = (double) i + ((double) f) / 4294967296.0; \
+                       (d) = (double) ri + ((double) rf) / 4294967296.0; \
                } \
        } while (0)
 
@@ -247,7 +247,7 @@ struct info_kernel
 };
 
 /* List of reference clock names */
-static char *refclock_names[] =
+static const char *refclock_names[] =
 {
        "UNKNOWN",    "LOCAL",        "GPS_TRAK",   "WWV_PST",     /*  0- 3 */
        "SPECTRACOM", "TRUETIME",     "IRIG_AUDIO", "CHU_AUDIO",   /*  4- 7 */
@@ -307,7 +307,7 @@ static int ntpd_config (const char *key, const char *value)
        return (0);
 }
 
-static void ntpd_submit (char *type, char *type_inst, double value)
+static void ntpd_submit (const char *type, const char *type_inst, gauge_t value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
@@ -328,8 +328,8 @@ static void ntpd_submit (char *type, char *type_inst, double value)
 /* Each time a peer is polled, ntpd shifts the reach register to the left and
  * sets the LSB based on whether the peer was reachable. If the LSB is zero,
  * the values are out of date. */
-static void ntpd_submit_reach (char *type, char *type_inst, uint8_t reach,
-               double value)
+static void ntpd_submit_reach (const char *type, const char *type_inst,
+               uint8_t reach, gauge_t value)
 {
        if (!(reach & 1))
                value = NAN;
@@ -339,8 +339,8 @@ static void ntpd_submit_reach (char *type, char *type_inst, uint8_t reach,
 
 static int ntpd_connect (void)
 {
-       char *host;
-       char *port;
+       const char *host;
+       const char *port;
 
        struct addrinfo  ai_hints;
        struct addrinfo *ai_list;
@@ -663,7 +663,7 @@ static int ntpd_receive_response (int *res_items, int *res_size,
                 */
                DEBUG ("realloc (%p, %zu)", (void *) *res_data,
                                (items_num + pkt_item_num) * res_item_size);
-               items = realloc ((void *) *res_data,
+               items = realloc (*res_data,
                                (items_num + pkt_item_num) * res_item_size);
                if (items == NULL)
                {
@@ -902,9 +902,19 @@ static int ntpd_read (void)
        int                       ps_num;
        int                       ps_size;
 
+       gauge_t offset_loop;
+       gauge_t freq_loop;
+       gauge_t offset_error;
+
        int status;
        int i;
 
+       /* On Linux, if the STA_NANO bit is set in ik->status, then ik->offset
+        * is is nanoseconds, otherwise it's microseconds.
+        * TODO(octo): STA_NANO is defined in the Linux specific <sys/timex.h> header. */
+       double scale_loop  = 1e-6;
+       double scale_error = 1e-6;
+
        ik      = NULL;
        ik_num  = 0;
        ik_size = 0;
@@ -927,18 +937,19 @@ static int ntpd_read (void)
        }
 
        /* kerninfo -> estimated error */
+       offset_loop  = scale_loop * ((gauge_t) ntohl (ik->offset));
+       freq_loop    = ntpd_read_fp (ik->freq);
+       offset_error = scale_error * ((gauge_t) ntohl (ik->esterror));
 
        DEBUG ("info_kernel:\n"
-                       "  pll offset    = %.8f\n"
-                       "  pll frequency = %.8f\n" /* drift compensation */
-                       "  est error     = %.8f\n",
-                       ntpd_read_fp (ik->offset),
-                       ntpd_read_fp (ik->freq),
-                       ntpd_read_fp (ik->esterror));
-
-       ntpd_submit ("frequency_offset", "loop",  ntpd_read_fp (ik->freq));
-       ntpd_submit ("time_offset",      "loop",  ntpd_read_fp (ik->offset));
-       ntpd_submit ("time_offset",      "error", ntpd_read_fp (ik->esterror));
+                       "  pll offset    = %.8g\n"
+                       "  pll frequency = %.8g\n" /* drift compensation */
+                       "  est error     = %.8g\n",
+                       offset_loop, freq_loop, offset_error);
+
+       ntpd_submit ("frequency_offset", "loop",  freq_loop);
+       ntpd_submit ("time_offset",      "loop",  offset_loop);
+       ntpd_submit ("time_offset",      "error", offset_error);
 
        free (ik);
        ik = NULL;
index d5ecc98..17eb1b9 100644 (file)
--- a/src/nut.c
+++ b/src/nut.c
@@ -80,13 +80,12 @@ static int nut_add_ups (const char *name)
 
   DEBUG ("nut plugin: nut_add_ups (name = %s);", name);
 
-  ups = (nut_ups_t *) malloc (sizeof (nut_ups_t));
+  ups = calloc (1, sizeof (*ups));
   if (ups == NULL)
   {
-    ERROR ("nut plugin: nut_add_ups: malloc failed.");
+    ERROR ("nut plugin: nut_add_ups: calloc failed.");
     return (1);
   }
-  memset (ups, '\0', sizeof (nut_ups_t));
 
   status = upscli_splitname (name, &ups->upsname, &ups->hostname,
       &ups->port);
@@ -152,7 +151,7 @@ static int nut_read_one (nut_ups_t *ups)
   /* (Re-)Connect if we have no connection */
   if (ups->conn == NULL)
   {
-    ups->conn = (collectd_upsconn_t *) malloc (sizeof (collectd_upsconn_t));
+    ups->conn = malloc (sizeof (*ups->conn));
     if (ups->conn == NULL)
     {
       ERROR ("nut plugin: malloc failed.");
index bbf387f..6d22d98 100644 (file)
@@ -611,7 +611,7 @@ static int olsrd_read_table (FILE *fh, /* {{{ */
   {
     /* An empty line ends the table. */
     buffer_len = strchomp (buffer);
-    if (buffer_len <= 0)
+    if (buffer_len == 0)
     {
       (*callback) (lineno, /* fields_num = */ 0, /* fields = */ NULL);
       break;
@@ -622,7 +622,7 @@ static int olsrd_read_table (FILE *fh, /* {{{ */
     (*callback) (lineno, fields_num, fields);
     lineno++;
   } /* while (fgets) */
-  
+
   return (0);
 } /* }}} int olsrd_read_table */
 
@@ -663,9 +663,9 @@ static int olsrd_read (void) /* {{{ */
   while (fgets (buffer, sizeof (buffer), fh) != NULL)
   {
     buffer_len = strchomp (buffer);
-    if (buffer_len <= 0)
+    if (buffer_len == 0)
       continue;
-    
+
     if (strcmp ("Table: Links", buffer) == 0)
       olsrd_read_table (fh, olsrd_cb_links);
     else if (strcmp ("Table: Neighbors", buffer) == 0)
@@ -690,7 +690,7 @@ static int olsrd_read (void) /* {{{ */
   } /* while (fgets) */
 
   fclose (fh);
-  
+
   return (0);
 } /* }}} int olsrd_read */
 
index 58c35e1..42bd1eb 100644 (file)
@@ -176,11 +176,11 @@ static int direct_list_insert(const char * config)
 {
     regmatch_t               pmatch[3];
     size_t                   nmatch = 3;
-    direct_access_element_t *element = NULL;
+    direct_access_element_t *element;
 
     DEBUG ("onewire plugin: direct_list_insert <%s>", config);
 
-    element = (direct_access_element_t *) malloc (sizeof(*element));
+    element = malloc (sizeof (*element));
     if (element == NULL)
     {
         ERROR ("onewire plugin: direct_list_insert - cannot allocate element");
@@ -415,11 +415,11 @@ static int cow_read_ds2409 (const char *path)
   int status;
 
   status = ssnprintf (subpath, sizeof (subpath), "%s/main", path);
-  if ((status > 0) && (status < sizeof (subpath)))
+  if ((status > 0) && (status < (int) sizeof (subpath)))
     cow_read_bus (subpath);
 
   status = ssnprintf (subpath, sizeof (subpath), "%s/aux", path);
-  if ((status > 0) && (status < sizeof (subpath)))
+  if ((status > 0) && (status < (int) sizeof (subpath)))
     cow_read_bus (subpath);
 
   return (0);
@@ -459,7 +459,7 @@ static int cow_read_bus (const char *path)
     else
       status = ssnprintf (subpath, sizeof (subpath), "%s/%s",
           path, buffer_ptr);
-    if ((status <= 0) || (status >= sizeof (subpath)))
+    if ((status <= 0) || (status >= (int) sizeof (subpath)))
       continue;
 
     for (i = 0; i < ow_family_features_num; i++)
index dc93334..615aee3 100644 (file)
 #include "plugin.h"
 #include "configfile.h"
 
+#if defined(__APPLE__)
+#pragma clang diagnostic push
+#pragma clang diagnostic warning "-Wdeprecated-declarations"
+#endif
+
 #include <lber.h>
 #include <ldap.h>
 
@@ -556,13 +561,12 @@ static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
        int i;
        int status;
 
-       st = malloc (sizeof (*st));
+       st = calloc (1, sizeof (*st));
        if (st == NULL)
        {
-               ERROR ("openldap plugin: malloc failed.");
+               ERROR ("openldap plugin: calloc failed.");
                return (-1);
        }
-       memset (st, 0, sizeof (*st));
 
        status = cf_util_get_string (ci, &st->name);
        if (status != 0)
@@ -735,3 +739,7 @@ void module_register (void) /* {{{ */
        plugin_register_init ("openldap", cldap_init);
        plugin_register_shutdown ("openldap", cldap_shutdown);
 } /* }}} void module_register */
+
+#if defined(__APPLE__)
+#pragma clang diagnostic pop
+#endif
index 663a82d..85760e9 100644 (file)
@@ -95,7 +95,8 @@ static int openvpn_strsplit (char *string, char **fields, size_t size)
 } /* int openvpn_strsplit */
 
 /* dispatches number of users */
-static void numusers_submit (char *pinst, char *tinst, gauge_t value)
+static void numusers_submit (const char *pinst, const char *tinst,
+               gauge_t value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
@@ -115,8 +116,10 @@ static void numusers_submit (char *pinst, char *tinst, gauge_t value)
        plugin_dispatch_values (&vl);
 } /* void numusers_submit */
 
-/* dispatches stats about traffic (TCP or UDP) generated by the tunnel per single endpoint */
-static void iostats_submit (char *pinst, char *tinst, derive_t rx, derive_t tx)
+/* dispatches stats about traffic (TCP or UDP) generated by the tunnel
+ * per single endpoint */
+static void iostats_submit (const char *pinst, const char *tinst,
+               derive_t rx, derive_t tx)
 {
        value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
@@ -145,7 +148,7 @@ static void iostats_submit (char *pinst, char *tinst, derive_t rx, derive_t tx)
 } /* void traffic_submit */
 
 /* dispatches stats about data compression shown when in single mode */
-static void compression_submit (char *pinst, char *tinst,
+static void compression_submit (const char *pinst, const char *tinst,
                derive_t uncompressed, derive_t compressed)
 {
        value_t values[2];
@@ -168,7 +171,7 @@ static void compression_submit (char *pinst, char *tinst,
        plugin_dispatch_values (&vl);
 } /* void compression_submit */
 
-static int single_read (char *name, FILE *fh)
+static int single_read (const char *name, FILE *fh)
 {
        char buffer[1024];
        char *fields[4];
@@ -261,7 +264,7 @@ static int single_read (char *name, FILE *fh)
 } /* int single_read */
 
 /* for reading status version 1 */
-static int multi1_read (char *name, FILE *fh)
+static int multi1_read (const char *name, FILE *fh)
 {
        char buffer[1024];
        char *fields[10];
@@ -324,7 +327,7 @@ static int multi1_read (char *name, FILE *fh)
 } /* int multi1_read */
 
 /* for reading status version 2 */
-static int multi2_read (char *name, FILE *fh)
+static int multi2_read (const char *name, FILE *fh)
 {
        char buffer[1024];
        char *fields[10];
@@ -386,7 +389,7 @@ static int multi2_read (char *name, FILE *fh)
 } /* int multi2_read */
 
 /* for reading status version 3 */
-static int multi3_read (char *name, FILE *fh)
+static int multi3_read (const char *name, FILE *fh)
 {
        char buffer[1024];
        char *fields[15];
@@ -451,7 +454,7 @@ static int multi3_read (char *name, FILE *fh)
 } /* int multi3_read */
 
 /* for reading status version 4 */
-static int multi4_read (char *name, FILE *fh)
+static int multi4_read (const char *name, FILE *fh)
 {
        char buffer[1024];
        char *fields[11];
@@ -696,22 +699,32 @@ static int openvpn_config (const char *key, const char *value)
                }
 
                /* create a new vpn element since file, version and name are ok */
-               temp = (vpn_status_t *) malloc (sizeof (vpn_status_t));
+               temp = malloc (sizeof (*temp));
+               if (temp == NULL)
+               {
+                       char errbuf[1024];
+                       ERROR ("openvpn plugin: malloc failed: %s",
+                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+                       sfree (status_file);
+                       return (1);
+               }
                temp->file = status_file;
                temp->version = status_version;
                temp->name = status_name;
 
-               vpn_list = (vpn_status_t **) realloc (vpn_list, (vpn_num + 1) * sizeof (vpn_status_t *));
-               if (vpn_list == NULL)
+               vpn_status_t **tmp_list = realloc (vpn_list, (vpn_num + 1) * sizeof (*vpn_list));
+               if (tmp_list == NULL)
                {
                        char errbuf[1024];
-                       ERROR ("openvpn plugin: malloc failed: %s",
+                       ERROR ("openvpn plugin: realloc failed: %s",
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
 
+                       sfree (vpn_list);
                        sfree (temp->file);
                        sfree (temp);
                        return (1);
                }
+               vpn_list = tmp_list;
 
                vpn_list[vpn_num] = temp;
                vpn_num++;
index ab0812b..cb9b3db 100644 (file)
@@ -174,7 +174,7 @@ static void o_database_free (o_database_t *db) /* {{{ */
  *       ValuesFrom "value"
  *     </Result>
  *   </Query>
- *     
+ *
  *   <Database "plugin_instance1">
  *     ConnectID "db01"
  *     Username "oracle"
@@ -198,13 +198,12 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  db = (o_database_t *) malloc (sizeof (*db));
+  db = calloc (1, sizeof (*db));
   if (db == NULL)
   {
-    ERROR ("oracle plugin: malloc failed.");
+    ERROR ("oracle plugin: calloc failed.");
     return (-1);
   }
-  memset (db, 0, sizeof (*db));
   db->name = NULL;
   db->host = NULL;
   db->connect_id = NULL;
@@ -273,7 +272,7 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
 
     if (db->q_prep_areas == NULL)
     {
-      WARNING ("oracle plugin: malloc failed");
+      WARNING ("oracle plugin: calloc failed");
       status = -1;
       break;
     }
@@ -300,7 +299,7 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
   {
     o_database_t **temp;
 
-    temp = (o_database_t **) realloc (databases,
+    temp = realloc (databases,
         sizeof (*databases) * (databases_num + 1));
     if (temp == NULL)
     {
@@ -463,7 +462,7 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
   {
     ub4 param_counter = 0;
     status = OCIAttrGet (oci_statement, OCI_HTYPE_STMT, /* {{{ */
-        &param_counter, /* size pointer = */ NULL, 
+        &param_counter, /* size pointer = */ NULL,
         OCI_ATTR_PARAM_COUNT, oci_error);
     if (status != OCI_SUCCESS)
     {
@@ -476,7 +475,7 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
   } while (0); /* }}} */
 
   /* Allocate the following buffers:
-   * 
+   *
    *  +---------------+-----------------------------------+
    *  ! Name          ! Size                              !
    *  +---------------+-----------------------------------+
@@ -502,13 +501,12 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
 #define ALLOC_OR_FAIL(ptr, ptr_size) \
   do { \
     size_t alloc_size = (size_t) ((ptr_size)); \
-    (ptr) = malloc (alloc_size); \
+    (ptr) = calloc (1, alloc_size); \
     if ((ptr) == NULL) { \
       FREE_ALL; \
-      ERROR ("oracle plugin: o_read_database_query: malloc failed."); \
+      ERROR ("oracle plugin: o_read_database_query: calloc failed."); \
       return (-1); \
     } \
-    memset ((ptr), 0, alloc_size); \
   } while (0)
 
   /* Initialize everything to NULL so the above works. */
@@ -653,7 +651,7 @@ static int o_read_database (o_database_t *db) /* {{{ */
     ub4 connection_status;
 
     server_handle = NULL;
-    status = OCIAttrGet ((void *) db->oci_service_context, OCI_HTYPE_SVCCTX, 
+    status = OCIAttrGet ((void *) db->oci_service_context, OCI_HTYPE_SVCCTX,
         (void *) &server_handle, /* size pointer = */ NULL,
         OCI_ATTR_SERVER, oci_error);
     if (status != OCI_SUCCESS)
@@ -745,7 +743,7 @@ static int o_shutdown (void) /* {{{ */
       OCIHandleFree (databases[i]->oci_service_context, OCI_HTYPE_SVCCTX);
       databases[i]->oci_service_context = NULL;
     }
-  
+
   for (i = 0; i < queries_num; i++)
   {
     OCIStmt *oci_statement;
@@ -757,7 +755,7 @@ static int o_shutdown (void) /* {{{ */
       udb_query_set_user_data (queries[i], NULL);
     }
   }
-  
+
   OCIHandleFree (oci_env, OCI_HTYPE_ENV);
   oci_env = NULL;
 
index 0a98684..92a162b 100644 (file)
@@ -437,7 +437,7 @@ static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds)
                return -1;
        }
 
-       ds->ds = (data_source_t *)smalloc ((len + 1) * sizeof (data_source_t));
+       ds->ds = smalloc ((len + 1) * sizeof (*ds->ds));
        ds->ds_num = len + 1;
 
        for (i = 0; i <= len; ++i) {
@@ -501,7 +501,7 @@ static int av2notification_meta (pTHX_ AV *array, notification_meta_t **meta)
 
                hash = (HV *)SvRV (*tmp);
 
-               *m = (notification_meta_t *)smalloc (sizeof (**m));
+               *m = smalloc (sizeof (**m));
 
                if (NULL == (tmp = hv_fetch (hash, "name", 4, 0))) {
                        log_warn ("av2notification_meta: Skipping invalid "
@@ -1199,7 +1199,10 @@ static void c_ithread_destructor (void *arg)
 
        /* the ithread no longer exists */
        if (NULL == t)
+       {
+               pthread_mutex_unlock (&perl_threads->mutex);
                return;
+       }
 
        c_ithread_destroy (ithread);
 
@@ -1215,7 +1218,7 @@ static c_ithread_t *c_ithread_create (PerlInterpreter *base)
 
        assert (NULL != perl_threads);
 
-       t = (c_ithread_t *)smalloc (sizeof (c_ithread_t));
+       t = smalloc (sizeof (*t));
        memset (t, 0, sizeof (c_ithread_t));
 
        t->interp = (NULL == base)
@@ -1425,7 +1428,7 @@ static int fc_create (int type, const oconfig_item_t *ci, void **user_data)
                return -1;
        }
 
-       data = (pfc_user_data_t *)smalloc (sizeof (*data));
+       data = smalloc (sizeof (*data));
        data->name      = sstrdup (ci->values[0].value.string);
        data->user_data = newSV (0);
 
@@ -1640,15 +1643,15 @@ static XS (Collectd_plugin_dispatch_values)
 
        values = ST (/* stack index = */ 0);
 
+       if (NULL == values)
+               XSRETURN_EMPTY;
+
        /* Make sure the argument is a hash reference. */
        if (! (SvROK (values) && (SVt_PVHV == SvTYPE (SvRV (values))))) {
                log_err ("Collectd::plugin_dispatch_values: Invalid values.");
                XSRETURN_EMPTY;
        }
 
-       if (NULL == values)
-               XSRETURN_EMPTY;
-
        ret = pplugin_dispatch_values (aTHX_ (HV *)SvRV (values));
 
        if (0 == ret)
@@ -2061,9 +2064,8 @@ static int perl_flush (cdtime_t timeout, const char *identifier,
 
 static int perl_shutdown (void)
 {
-       c_ithread_t *t = NULL;
-
-       int ret = 0;
+       c_ithread_t *t;
+       int ret;
 
        dTHX;
 
@@ -2073,8 +2075,6 @@ static int perl_shutdown (void)
                return 0;
 
        if (NULL == aTHX) {
-               c_ithread_t *t = NULL;
-
                pthread_mutex_lock (&perl_threads->mutex);
                t = c_ithread_create (perl_threads->head->interp);
                pthread_mutex_unlock (&perl_threads->mutex);
@@ -2249,7 +2249,7 @@ static int init_pi (int argc, char **argv)
 #endif
        PERL_SYS_INIT3 (&argc, &argv, &environ);
 
-       perl_threads = (c_ithread_list_t *)smalloc (sizeof (c_ithread_list_t));
+       perl_threads = smalloc (sizeof (*perl_threads));
        memset (perl_threads, 0, sizeof (c_ithread_list_t));
 
        pthread_mutex_init (&perl_threads->mutex, NULL);
@@ -2379,7 +2379,7 @@ static int perl_config_enabledebugger (pTHX_ oconfig_item_t *ci)
 
        value = ci->values[0].value.string;
 
-       perl_argv = (char **)realloc (perl_argv,
+       perl_argv = realloc (perl_argv,
                        (++perl_argc + 1) * sizeof (char *));
 
        if (NULL == perl_argv) {
@@ -2391,7 +2391,7 @@ static int perl_config_enabledebugger (pTHX_ oconfig_item_t *ci)
                perl_argv[perl_argc - 1] = "-d";
        }
        else {
-               perl_argv[perl_argc - 1] = (char *)smalloc (strlen (value) + 4);
+               perl_argv[perl_argc - 1] = smalloc (strlen (value) + 4);
                sstrncpy (perl_argv[perl_argc - 1], "-d:", 4);
                sstrncpy (perl_argv[perl_argc - 1] + 3, value, strlen (value) + 1);
        }
@@ -2416,7 +2416,7 @@ static int perl_config_includedir (pTHX_ oconfig_item_t *ci)
        value = ci->values[0].value.string;
 
        if (NULL == aTHX) {
-               perl_argv = (char **)realloc (perl_argv,
+               perl_argv = realloc (perl_argv,
                                (++perl_argc + 1) * sizeof (char *));
 
                if (NULL == perl_argv) {
@@ -2424,7 +2424,7 @@ static int perl_config_includedir (pTHX_ oconfig_item_t *ci)
                        exit (3);
                }
 
-               perl_argv[perl_argc - 1] = (char *)smalloc (strlen (value) + 3);
+               perl_argv[perl_argc - 1] = smalloc (strlen (value) + 3);
                sstrncpy(perl_argv[perl_argc - 1], "-I", 3);
                sstrncpy(perl_argv[perl_argc - 1] + 2, value, strlen (value) + 1);
 
@@ -2506,7 +2506,10 @@ static int perl_config (oconfig_item_t *ci)
                int current_status = 0;
 
                if (NULL != perl_threads)
-                       aTHX = PERL_GET_CONTEXT;
+               {
+                       if ((aTHX = PERL_GET_CONTEXT) == NULL)
+                               return -1;
+               }
 
                if (0 == strcasecmp (c->key, "LoadPlugin"))
                        current_status = perl_config_loadplugin (aTHX_ c);
@@ -2539,7 +2542,7 @@ static int perl_config (oconfig_item_t *ci)
 void module_register (void)
 {
        perl_argc = 4;
-       perl_argv = (char **)smalloc ((perl_argc + 1) * sizeof (char *));
+       perl_argv = smalloc ((perl_argc + 1) * sizeof (*perl_argv));
 
        /* default options for the Perl interpreter */
        perl_argv[0] = "";
index a2bd549..225d536 100644 (file)
--- a/src/pf.c
+++ b/src/pf.c
@@ -106,7 +106,6 @@ static int pf_read (void)
        }
 
        close (fd);
-       fd = -1;
 
        if (!state.running)
        {
index b6e7b15..980fbf2 100644 (file)
@@ -171,7 +171,7 @@ static void service_statnode_add(const char *name, /* {{{ */
     const char *script)
 {
   pinba_statnode_t *node;
-  
+
   node = realloc (stat_nodes,
       sizeof (*stat_nodes) * (stat_nodes_num + 1));
   if (node == NULL)
@@ -183,7 +183,7 @@ static void service_statnode_add(const char *name, /* {{{ */
 
   node = stat_nodes + stat_nodes_num;
   memset (node, 0, sizeof (*node));
-  
+
   /* reset strings */
   node->name   = NULL;
   node->host   = NULL;
@@ -191,13 +191,13 @@ static void service_statnode_add(const char *name, /* {{{ */
   node->script = NULL;
 
   node->mem_peak = NAN;
-  
+
   /* fill query data */
   strset (&node->name, name);
   strset (&node->host, host);
   strset (&node->server, server);
   strset (&node->script, script);
-  
+
   /* increment counter */
   stat_nodes_num++;
 } /* }}} void service_statnode_add */
@@ -209,14 +209,14 @@ static unsigned int service_statnode_collect (pinba_statnode_t *res, /* {{{ */
     unsigned int index)
 {
   pinba_statnode_t *node;
-  
+
   if (stat_nodes_num == 0)
     return 0;
-  
+
   /* begin collecting */
   if (index == 0)
     pthread_mutex_lock (&stat_nodes_lock);
-  
+
   /* end collecting */
   if (index >= stat_nodes_num)
   {
@@ -229,7 +229,7 @@ static unsigned int service_statnode_collect (pinba_statnode_t *res, /* {{{ */
 
   /* reset node */
   node->mem_peak = NAN;
-  
+
   return (index + 1);
 } /* }}} unsigned int service_statnode_collect */
 
@@ -255,7 +255,7 @@ static void service_process_request (Pinba__Request *request) /* {{{ */
   unsigned int i;
 
   pthread_mutex_lock (&stat_nodes_lock);
-  
+
   for (i = 0; i < stat_nodes_num; i++)
   {
     if ((stat_nodes[i].host != NULL)
@@ -272,7 +272,7 @@ static void service_process_request (Pinba__Request *request) /* {{{ */
 
     service_statnode_process(&stat_nodes[i], request);
   }
-  
+
   pthread_mutex_unlock(&stat_nodes_lock);
 } /* }}} void service_process_request */
 
@@ -335,6 +335,7 @@ static int pb_add_socket (pinba_socket_t *s, /* {{{ */
     char errbuf[1024];
     ERROR ("pinba plugin: bind(2) failed: %s",
         sstrerror (errno, errbuf, sizeof (errbuf)));
+    close (fd);
     return (0);
   }
 
@@ -380,14 +381,13 @@ static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */
   }
   assert (ai_list != NULL);
 
-  s = malloc (sizeof (*s));
+  s = calloc (1, sizeof (*s));
   if (s == NULL)
   {
     freeaddrinfo (ai_list);
-    ERROR ("pinba plugin: malloc failed.");
+    ERROR ("pinba plugin: calloc failed.");
     return (NULL);
   }
-  memset (s, 0, sizeof (*s));
 
   for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
@@ -395,7 +395,7 @@ static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */
     if (status != 0)
       break;
   } /* for (ai_list) */
-  
+
   freeaddrinfo (ai_list);
 
   if (s->fd_num < 1)
@@ -414,7 +414,7 @@ static void pinba_socket_free (pinba_socket_t *socket) /* {{{ */
 
   if (!socket)
     return;
-  
+
   for (i = 0; i < socket->fd_num; i++)
   {
     if (socket->fd[i].fd < 0)
@@ -422,23 +422,23 @@ static void pinba_socket_free (pinba_socket_t *socket) /* {{{ */
     close (socket->fd[i].fd);
     socket->fd[i].fd = -1;
   }
-  
+
   sfree(socket);
 } /* }}} void pinba_socket_free */
 
 static int pinba_process_stats_packet (const uint8_t *buffer, /* {{{ */
     size_t buffer_size)
 {
-  Pinba__Request *request;  
-  
+  Pinba__Request *request;
+
   request = pinba__request__unpack (NULL, buffer_size, buffer);
-  
+
   if (!request)
     return (-1);
 
   service_process_request(request);
   pinba__request__free_unpacked (request, NULL);
-    
+
   return (0);
 } /* }}} int pinba_process_stats_packet */
 
@@ -609,7 +609,7 @@ static int pinba_config_view (const oconfig_item_t *ci) /* {{{ */
 static int plugin_config (oconfig_item_t *ci) /* {{{ */
 {
   int i;
-  
+
   /* The lock should not be necessary in the config callback, but let's be
    * sure.. */
   pthread_mutex_lock (&stat_nodes_lock);
@@ -629,7 +629,7 @@ static int plugin_config (oconfig_item_t *ci) /* {{{ */
   }
 
   pthread_mutex_unlock(&stat_nodes_lock);
-  
+
   return (0);
 } /* }}} int pinba_config */
 
@@ -693,7 +693,7 @@ static int plugin_submit (const pinba_statnode_t *res) /* {{{ */
 {
   value_t value;
   value_list_t vl = VALUE_LIST_INIT;
-  
+
   vl.values = &value;
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -701,15 +701,15 @@ static int plugin_submit (const pinba_statnode_t *res) /* {{{ */
   sstrncpy (vl.plugin_instance, res->name, sizeof (vl.plugin_instance));
 
   value.derive = res->req_count;
-  sstrncpy (vl.type, "total_requests", sizeof (vl.type)); 
+  sstrncpy (vl.type, "total_requests", sizeof (vl.type));
   plugin_dispatch_values (&vl);
 
   value.derive = float_counter_get (&res->req_time, /* factor = */ 1000);
-  sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type)); 
+  sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type));
   plugin_dispatch_values (&vl);
 
   value.derive = res->doc_size;
-  sstrncpy (vl.type, "total_bytes", sizeof (vl.type)); 
+  sstrncpy (vl.type, "total_bytes", sizeof (vl.type));
   plugin_dispatch_values (&vl);
 
   value.derive = float_counter_get (&res->ru_utime, /* factor = */ 100);
@@ -734,12 +734,12 @@ static int plugin_read (void) /* {{{ */
 {
   unsigned int i=0;
   pinba_statnode_t data;
-  
+
   while ((i = service_statnode_collect (&data, i)) != 0)
   {
     plugin_submit (&data);
   }
-  
+
   return 0;
 } /* }}} int plugin_read */
 
index df2f6da..88661e9 100644 (file)
@@ -73,6 +73,7 @@ static char  *ping_source = NULL;
 #ifdef HAVE_OPING_1_3
 static char  *ping_device = NULL;
 #endif
+static char  *ping_data = NULL;
 static int    ping_ttl = PING_DEF_TTL;
 static double ping_interval = 1.0;
 static double ping_timeout = 0.9;
@@ -91,6 +92,7 @@ static const char *config_keys[] =
 #ifdef HAVE_OPING_1_3
   "Device",
 #endif
+  "Size",
   "TTL",
   "Interval",
   "Timeout",
@@ -242,7 +244,7 @@ static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */
 
 static void *ping_thread (void *arg) /* {{{ */
 {
-  static pingobj_t *pingobj = NULL;
+  pingobj_t *pingobj = NULL;
 
   struct timeval  tv_begin;
   struct timeval  tv_end;
@@ -280,6 +282,9 @@ static void *ping_thread (void *arg) /* {{{ */
   ping_setopt (pingobj, PING_OPT_TIMEOUT, (void *) &ping_timeout);
   ping_setopt (pingobj, PING_OPT_TTL, (void *) &ping_ttl);
 
+  if (ping_data != NULL)
+    ping_setopt (pingobj, PING_OPT_DATA, (void *) ping_data);
+
   /* Add all the hosts to the ping object. */
   count = 0;
   for (hl = hostlist_head; hl != NULL; hl = hl->next)
@@ -394,7 +399,7 @@ static int start_thread (void) /* {{{ */
     pthread_mutex_unlock (&ping_lock);
     return (-1);
   }
-    
+
   pthread_mutex_unlock (&ping_lock);
   return (0);
 } /* }}} int start_thread */
@@ -422,8 +427,10 @@ static int stop_thread (void) /* {{{ */
     status = -1;
   }
 
+  pthread_mutex_lock (&ping_lock);
   memset (&ping_thread_id, 0, sizeof (ping_thread_id));
   ping_thread_error = 0;
+  pthread_mutex_unlock (&ping_lock);
 
   return (status);
 } /* }}} int stop_thread */
@@ -476,7 +483,7 @@ static int ping_config (const char *key, const char *value) /* {{{ */
     hostlist_t *hl;
     char *host;
 
-    hl = (hostlist_t *) malloc (sizeof (hostlist_t));
+    hl = malloc (sizeof (*hl));
     if (hl == NULL)
     {
       char errbuf[1024];
@@ -537,6 +544,39 @@ static int ping_config (const char *key, const char *value) /* {{{ */
       WARNING ("ping plugin: Ignoring invalid interval %g (%s)",
           tmp, value);
   }
+  else if (strcasecmp (key, "Size") == 0) {
+    size_t size = (size_t) atoi (value);
+
+    /* Max IP packet size - (IPv6 + ICMP) = 65535 - (40 + 8) = 65487 */
+    if (size <= 65487)
+    {
+      size_t i;
+
+      sfree (ping_data);
+      ping_data = malloc (size + 1);
+      if (ping_data == NULL)
+      {
+        ERROR ("ping plugin: malloc failed.");
+        return (1);
+      }
+
+      /* Note: By default oping is using constant string
+       * "liboping -- ICMP ping library <http://octo.it/liboping/>"
+       * which is exactly 56 bytes.
+       *
+       * Optimally we would follow the ping(1) behaviour, but we
+       * cannot use byte 00 or start data payload at exactly same
+       * location, due to oping library limitations. */
+      for (i = 0; i < size; i++) /* {{{ */
+      {
+        /* This restricts data pattern to be only composed of easily
+         * printable characters, and not NUL character. */
+        ping_data[i] = ('0' + i % 64);
+      }  /* }}} for (i = 0; i < size; i++) */
+      ping_data[size] = 0;
+    } else
+      WARNING ("ping plugin: Ignoring invalid Size %zu.", size);
+  }
   else if (strcasecmp (key, "Timeout") == 0)
   {
     double tmp;
@@ -688,6 +728,11 @@ static int ping_shutdown (void) /* {{{ */
     hl = hl_next;
   }
 
+  if (ping_data != NULL) {
+    free (ping_data);
+    ping_data = NULL;
+  }
+
   return (0);
 } /* }}} int ping_shutdown */
 
index bef3490..759560e 100644 (file)
@@ -154,7 +154,7 @@ typedef struct {
        int ref_cnt;
 } c_psql_database_t;
 
-static char *def_queries[] = {
+static const char *const def_queries[] = {
        "backends",
        "transactions",
        "queries",
@@ -218,13 +218,13 @@ static c_psql_database_t *c_psql_database_new (const char *name)
        c_psql_database_t **tmp;
        c_psql_database_t  *db;
 
-       db = (c_psql_database_t *)malloc (sizeof(*db));
+       db = malloc (sizeof(*db));
        if (NULL == db) {
                log_err ("Out of memory.");
                return NULL;
        }
 
-       tmp = (c_psql_database_t **)realloc (databases,
+       tmp = realloc (databases,
                        (databases_num + 1) * sizeof (*databases));
        if (NULL == tmp) {
                log_err ("Out of memory.");
@@ -429,9 +429,9 @@ static PGresult *c_psql_exec_query_noparams (c_psql_database_t *db,
 static PGresult *c_psql_exec_query_params (c_psql_database_t *db,
                udb_query_t *q, c_psql_user_data_t *data)
 {
-       char *params[db->max_params_num];
-       char  interval[64];
-       int   i;
+       const char *params[db->max_params_num];
+       char        interval[64];
+       int         i;
 
        if ((data == NULL) || (data->params_num == 0))
                return (c_psql_exec_query_noparams (db, q));
@@ -555,7 +555,7 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q,
                log_err ("calloc failed.");
                BAIL_OUT (-1);
        }
-       
+
        for (col = 0; col < column_num; ++col) {
                /* Pointers returned by `PQfname' are freed by `PQclear' via
                 * `BAIL_OUT'. */
@@ -826,7 +826,7 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl,
 {
        c_psql_database_t *db;
 
-       char time_str[32];
+       char time_str[RFC3339NANO_SIZE];
        char values_name_str[1024];
        char values_type_str[1024];
        char values_str[1024];
@@ -845,8 +845,8 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl,
        assert (db->database != NULL);
        assert (db->writers != NULL);
 
-       if (cdtime_to_iso8601 (time_str, sizeof (time_str), vl->time) == 0) {
-               log_err ("c_psql_write: Failed to convert time to ISO 8601 format");
+       if (rfc3339nano (time_str, sizeof (time_str), vl->time) != 0) {
+               log_err ("c_psql_write: Failed to convert time to RFC 3339 format");
                return -1;
        }
 
@@ -867,7 +867,7 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl,
 #undef VALUE_OR_NULL
 
        if( db->expire_delay > 0 && vl->time < (cdtime() - vl->interval - db->expire_delay) ) {
-               log_info ("c_psql_write: Skipped expired value @ %s - %s/%s-%s/%s-%s/%s", 
+               log_info ("c_psql_write: Skipped expired value @ %s - %s/%s-%s/%s-%s/%s",
                        params[0], params[1], params[2], params[3], params[4], params[5], params[6] );
                return 0;
         }
@@ -1042,17 +1042,18 @@ static int config_query_param_add (udb_query_t *q, oconfig_item_t *ci)
 
        data = udb_query_get_user_data (q);
        if (NULL == data) {
-               data = (c_psql_user_data_t *) smalloc (sizeof (*data));
+               data = calloc (1, sizeof (*data));
                if (NULL == data) {
                        log_err ("Out of memory.");
                        return -1;
                }
-               memset (data, 0, sizeof (*data));
                data->params = NULL;
+               data->params_num = 0;
+
+               udb_query_set_user_data (q, data);
        }
 
-       tmp = (c_psql_param_t *) realloc (data->params,
-                       (data->params_num + 1) * sizeof (c_psql_param_t));
+       tmp = realloc (data->params, (data->params_num + 1) * sizeof (*data->params));
        if (NULL == tmp) {
                log_err ("Out of memory.");
                return -1;
@@ -1076,8 +1077,6 @@ static int config_query_param_add (udb_query_t *q, oconfig_item_t *ci)
        }
 
        data->params_num++;
-       udb_query_set_user_data (q, data);
-
        return (0);
 } /* config_query_param_add */
 
@@ -1116,7 +1115,7 @@ static int config_add_writer (oconfig_item_t *ci,
                if (strcasecmp (name, src_writers[i].name) != 0)
                        continue;
 
-               tmp = (c_psql_writer_t **)realloc (*dst_writers,
+               tmp = realloc (*dst_writers,
                                sizeof (**dst_writers) * (*dst_writers_num + 1));
                if (tmp == NULL) {
                        log_err ("Out of memory.");
@@ -1152,7 +1151,7 @@ static int c_psql_config_writer (oconfig_item_t *ci)
                return 1;
        }
 
-       tmp = (c_psql_writer_t *)realloc (writers,
+       tmp = realloc (writers,
                        sizeof (*writers) * (writers_num + 1));
        if (tmp == NULL) {
                log_err ("Out of memory.");
@@ -1161,7 +1160,7 @@ static int c_psql_config_writer (oconfig_item_t *ci)
 
        writers = tmp;
        writer  = writers + writers_num;
-       ++writers_num;
+       memset (writer, 0, sizeof (*writer));
 
        writer->name = sstrdup (ci->values[0].value.string);
        writer->statement = NULL;
@@ -1181,10 +1180,10 @@ static int c_psql_config_writer (oconfig_item_t *ci)
        if (status != 0) {
                sfree (writer->statement);
                sfree (writer->name);
-               sfree (writer);
                return status;
        }
 
+       ++writers_num;
        return 0;
 } /* c_psql_config_writer */
 
index 1050e7f..f72bd40 100644 (file)
@@ -75,9 +75,9 @@ struct list_item_s
 
 struct statname_lookup_s
 {
-  char *name;
-  char *type;
-  char *type_instance;
+  const char *name;
+  const char *type;
+  const char *type_instance;
 };
 typedef struct statname_lookup_s statname_lookup_t;
 
@@ -143,9 +143,9 @@ uptime                number of seconds process has been running (since 3.1.5)
 user-msec             number of CPU milliseconds spent in 'user' mode
 }}} */
 
-const char* const default_server_fields[] = /* {{{ */
+static const char* const default_server_fields[] = /* {{{ */
 {
-  "latency"
+  "latency",
   "packetcache-hit",
   "packetcache-miss",
   "packetcache-size",
@@ -158,9 +158,9 @@ const char* const default_server_fields[] = /* {{{ */
   "udp-answers",
   "udp-queries",
 }; /* }}} */
-int default_server_fields_num = STATIC_ARRAY_SIZE (default_server_fields);
+static int default_server_fields_num = STATIC_ARRAY_SIZE (default_server_fields);
 
-statname_lookup_t lookup_table[] = /* {{{ */
+static statname_lookup_t lookup_table[] = /* {{{ */
 {
   /*********************
    * Server statistics *
@@ -285,7 +285,7 @@ statname_lookup_t lookup_table[] = /* {{{ */
   {"unexpected-packets",   "dns_answer",   "unexpected"},
   {"uptime",               "uptime",       NULL}
 }; /* }}} */
-int lookup_table_length = STATIC_ARRAY_SIZE (lookup_table);
+static int lookup_table_length = STATIC_ARRAY_SIZE (lookup_table);
 
 static llist_t *list = NULL;
 
@@ -465,7 +465,7 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */
     return (-1);
 
   assert (buffer_size > 0);
-  buffer = (char *) malloc (buffer_size);
+  buffer = malloc (buffer_size);
   if (buffer == NULL)
   {
     FUNC_ERROR ("malloc");
@@ -542,7 +542,7 @@ static int powerdns_get_data_stream (list_item_t *item, /* {{{ */
     else if (status == 0)
       break;
 
-    buffer_new = (char *) realloc (buffer, buffer_size + status + 1);
+    buffer_new = realloc (buffer, buffer_size + status + 1);
     if (buffer_new == NULL)
     {
       FUNC_ERROR ("realloc");
@@ -799,7 +799,7 @@ static int powerdns_config_add_collect (list_item_t *li, /* {{{ */
       return (-1);
     }
 
-  temp = (char **) realloc (li->fields,
+  temp = realloc (li->fields,
       sizeof (char *) * (li->fields_num + ci->values_num));
   if (temp == NULL)
   {
@@ -840,13 +840,12 @@ static int powerdns_config_add_server (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  item = (list_item_t *) malloc (sizeof (list_item_t));
+  item = calloc (1, sizeof (*item));
   if (item == NULL)
   {
-    ERROR ("powerdns plugin: malloc failed.");
+    ERROR ("powerdns plugin: calloc failed.");
     return (-1);
   }
-  memset (item, '\0', sizeof (list_item_t));
 
   item->instance = strdup (ci->values[0].value.string);
   if (item->instance == NULL)
index d094e73..03b44b5 100644 (file)
@@ -262,20 +262,19 @@ static void ps_list_register (const char *name, const char *regexp)
        procstat_t *ptr;
        int status;
 
-       new = (procstat_t *) malloc (sizeof (procstat_t));
+       new = calloc (1, sizeof (*new));
        if (new == NULL)
        {
-               ERROR ("processes plugin: ps_list_register: malloc failed.");
+               ERROR ("processes plugin: ps_list_register: calloc failed.");
                return;
        }
-       memset (new, 0, sizeof (procstat_t));
        sstrncpy (new->name, name, sizeof (new->name));
 
 #if HAVE_REGEX_H
        if (regexp != NULL)
        {
                DEBUG ("ProcessMatch: adding \"%s\" as criteria to process %s.", regexp, name);
-               new->re = (regex_t *) malloc (sizeof (regex_t));
+               new->re = malloc (sizeof (*new->re));
                if (new->re == NULL)
                {
                        ERROR ("processes plugin: ps_list_register: malloc failed.");
@@ -287,7 +286,8 @@ static void ps_list_register (const char *name, const char *regexp)
                if (status != 0)
                {
                        DEBUG ("ProcessMatch: compiling the regular expression \"%s\" failed.", regexp);
-                       sfree(new->re);
+                       sfree (new->re);
+                       sfree (new);
                        return;
                }
        }
@@ -313,7 +313,9 @@ static void ps_list_register (const char *name, const char *regexp)
                                        "`ProcessMatch' with the same name. "
                                        "All but the first setting will be "
                                        "ignored.");
+#if HAVE_REGEX_H
                        sfree (new->re);
+#endif
                        sfree (new);
                        return;
                }
@@ -358,6 +360,31 @@ static int ps_list_match (const char *name, const char *cmdline, procstat_t *ps)
        return (0);
 } /* int ps_list_match */
 
+static void ps_update_counter (
+        _Bool init,
+        derive_t *group_counter,
+        derive_t *curr_counter, unsigned long *curr_value,
+        derive_t new_counter, unsigned long new_value) {
+    if (init)
+    {
+        *curr_value = new_value;
+        *curr_counter += new_value;
+        *group_counter += new_value;
+        return;
+    }
+
+    if (new_counter < *curr_counter)
+    {
+        *curr_value = new_counter + (ULONG_MAX - *curr_counter);
+    }
+    else
+    {
+        *curr_value = new_counter - *curr_counter;
+    }
+    *curr_counter = new_counter;
+    *group_counter += *curr_value;
+}
+
 /* add process entry to 'instances' of process 'name' (or refresh it) */
 static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t *entry)
 {
@@ -369,6 +396,8 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
 
        for (ps = list_head_g; ps != NULL; ps = ps->next)
        {
+        _Bool want_init;
+
                if ((ps_list_match (name, cmdline, ps)) == 0)
                        continue;
 
@@ -380,10 +409,9 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
                {
                        procstat_entry_t *new;
 
-                       new = (procstat_entry_t *) malloc (sizeof (procstat_entry_t));
+                       new = calloc (1, sizeof (*new));
                        if (new == NULL)
                                return;
-                       memset (new, 0, sizeof (procstat_entry_t));
                        new->id = entry->id;
 
                        if (pse == NULL)
@@ -425,79 +453,27 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
                ps->cswitch_vol   += ((pse->cswitch_vol == -1)?0:pse->cswitch_vol);
                ps->cswitch_invol += ((pse->cswitch_invol == -1)?0:pse->cswitch_invol);
 
-               if ((entry->vmem_minflt_counter == 0)
-                               && (entry->vmem_majflt_counter == 0))
-               {
-                       pse->vmem_minflt_counter += entry->vmem_minflt;
-                       pse->vmem_minflt = entry->vmem_minflt;
-
-                       pse->vmem_majflt_counter += entry->vmem_majflt;
-                       pse->vmem_majflt = entry->vmem_majflt;
-               }
-               else
-               {
-                       if (entry->vmem_minflt_counter < pse->vmem_minflt_counter)
-                       {
-                               pse->vmem_minflt = entry->vmem_minflt_counter
-                                       + (ULONG_MAX - pse->vmem_minflt_counter);
-                       }
-                       else
-                       {
-                               pse->vmem_minflt = entry->vmem_minflt_counter - pse->vmem_minflt_counter;
-                       }
-                       pse->vmem_minflt_counter = entry->vmem_minflt_counter;
-
-                       if (entry->vmem_majflt_counter < pse->vmem_majflt_counter)
-                       {
-                               pse->vmem_majflt = entry->vmem_majflt_counter
-                                       + (ULONG_MAX - pse->vmem_majflt_counter);
-                       }
-                       else
-                       {
-                               pse->vmem_majflt = entry->vmem_majflt_counter - pse->vmem_majflt_counter;
-                       }
-                       pse->vmem_majflt_counter = entry->vmem_majflt_counter;
-               }
-
-               ps->vmem_minflt_counter += pse->vmem_minflt;
-               ps->vmem_majflt_counter += pse->vmem_majflt;
-
-               if ((entry->cpu_user_counter == 0)
-                               && (entry->cpu_system_counter == 0))
-               {
-                       pse->cpu_user_counter += entry->cpu_user;
-                       pse->cpu_user = entry->cpu_user;
-
-                       pse->cpu_system_counter += entry->cpu_system;
-                       pse->cpu_system = entry->cpu_system;
-               }
-               else
-               {
-                       if (entry->cpu_user_counter < pse->cpu_user_counter)
-                       {
-                               pse->cpu_user = entry->cpu_user_counter
-                                       + (ULONG_MAX - pse->cpu_user_counter);
-                       }
-                       else
-                       {
-                               pse->cpu_user = entry->cpu_user_counter - pse->cpu_user_counter;
-                       }
-                       pse->cpu_user_counter = entry->cpu_user_counter;
-
-                       if (entry->cpu_system_counter < pse->cpu_system_counter)
-                       {
-                               pse->cpu_system = entry->cpu_system_counter
-                                       + (ULONG_MAX - pse->cpu_system_counter);
-                       }
-                       else
-                       {
-                               pse->cpu_system = entry->cpu_system_counter - pse->cpu_system_counter;
-                       }
-                       pse->cpu_system_counter = entry->cpu_system_counter;
-               }
-
-               ps->cpu_user_counter   += pse->cpu_user;
-               ps->cpu_system_counter += pse->cpu_system;
+               want_init = (entry->vmem_minflt_counter == 0)
+                               && (entry->vmem_majflt_counter == 0);
+               ps_update_counter (want_init,
+                               &ps->vmem_minflt_counter,
+                               &pse->vmem_minflt_counter, &pse->vmem_minflt,
+                               entry->vmem_minflt_counter, entry->vmem_minflt);
+               ps_update_counter (want_init,
+                               &ps->vmem_majflt_counter,
+                               &pse->vmem_majflt_counter, &pse->vmem_majflt,
+                               entry->vmem_majflt_counter, entry->vmem_majflt);
+
+               want_init = (entry->cpu_user_counter == 0)
+                               && (entry->cpu_system_counter == 0);
+               ps_update_counter (want_init,
+                               &ps->cpu_user_counter,
+                               &pse->cpu_user_counter, &pse->cpu_user,
+                               entry->cpu_user_counter, entry->cpu_user);
+               ps_update_counter (want_init,
+                               &ps->cpu_system_counter,
+                               &pse->cpu_system_counter, &pse->cpu_system,
+                               entry->cpu_system_counter, entry->cpu_system);
        }
 }
 
@@ -814,7 +790,7 @@ static void ps_submit_fork_rate (derive_t value)
 
 /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */
 #if KERNEL_LINUX
-static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
+static procstat_t *ps_read_tasks_status (long pid, procstat_t *ps)
 {
        char           dirname[64];
        DIR           *dh;
@@ -827,7 +803,7 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
        char *fields[8];
        int numfields;
 
-       ssnprintf (dirname, sizeof (dirname), "/proc/%i/task", pid);
+       ssnprintf (dirname, sizeof (dirname), "/proc/%li/task", pid);
 
        if ((dh = opendir (dirname)) == NULL)
        {
@@ -844,7 +820,7 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
 
                tpid = ent->d_name;
 
-               ssnprintf (filename, sizeof (filename), "/proc/%i/task/%s/status", pid, tpid);
+               ssnprintf (filename, sizeof (filename), "/proc/%li/task/%s/status", pid, tpid);
                if ((fh = fopen (filename, "r")) == NULL)
                {
                        DEBUG ("Failed to open file `%s'", filename);
@@ -898,7 +874,7 @@ static procstat_t *ps_read_tasks_status (int pid, procstat_t *ps)
 } /* int *ps_read_tasks_status */
 
 /* Read data from /proc/pid/status */
-static procstat_t *ps_read_status (int pid, procstat_t *ps)
+static procstat_t *ps_read_status (long pid, procstat_t *ps)
 {
        FILE *fh;
        char buffer[1024];
@@ -910,7 +886,7 @@ static procstat_t *ps_read_status (int pid, procstat_t *ps)
        char *fields[8];
        int numfields;
 
-       ssnprintf (filename, sizeof (filename), "/proc/%i/status", pid);
+       ssnprintf (filename, sizeof (filename), "/proc/%li/status", pid);
        if ((fh = fopen (filename, "r")) == NULL)
                return (NULL);
 
@@ -968,7 +944,7 @@ static procstat_t *ps_read_status (int pid, procstat_t *ps)
        return (ps);
 } /* procstat_t *ps_read_vmem */
 
-static procstat_t *ps_read_io (int pid, procstat_t *ps)
+static procstat_t *ps_read_io (long pid, procstat_t *ps)
 {
        FILE *fh;
        char buffer[1024];
@@ -977,7 +953,7 @@ static procstat_t *ps_read_io (int pid, procstat_t *ps)
        char *fields[8];
        int numfields;
 
-       ssnprintf (filename, sizeof (filename), "/proc/%i/io", pid);
+       ssnprintf (filename, sizeof (filename), "/proc/%li/io", pid);
        if ((fh = fopen (filename, "r")) == NULL)
                return (NULL);
 
@@ -1023,7 +999,7 @@ static procstat_t *ps_read_io (int pid, procstat_t *ps)
        return (ps);
 } /* procstat_t *ps_read_io */
 
-int ps_read_process (int pid, procstat_t *ps, char *state)
+static int ps_read_process (long pid, procstat_t *ps, char *state)
 {
        char  filename[64];
        char  buffer[1024];
@@ -1048,7 +1024,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
 
        memset (ps, 0, sizeof (procstat_t));
 
-       ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid);
+       ssnprintf (filename, sizeof (filename), "/proc/%li/stat", pid);
 
        status = read_file_contents (filename, buffer, sizeof(buffer) - 1);
        if (status <= 0)
@@ -1062,13 +1038,11 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
         * 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))
+       while (name_start_pos < buffer_len && buffer[name_start_pos] != '(')
                name_start_pos++;
 
        name_end_pos = buffer_len;
-       while ((buffer[name_end_pos] != ')')
-                       && (name_end_pos > 0))
+       while (name_end_pos > 0 && buffer[name_end_pos] != ')')
                name_end_pos--;
 
        /* Either '(' or ')' is not found or they are in the wrong order.
@@ -1093,9 +1067,9 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
        fields_len = strsplit (buffer_ptr, fields, STATIC_ARRAY_SIZE (fields));
        if (fields_len < 22)
        {
-               DEBUG ("processes plugin: ps_read_process (pid = %i):"
+               DEBUG ("processes plugin: ps_read_process (pid = %li):"
                                " `%s' has only %i fields..",
-                               (int) pid, filename, fields_len);
+                               pid, filename, fields_len);
                return (-1);
        }
 
@@ -1114,9 +1088,9 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
                        /* No VMem data */
                        ps->vmem_data = -1;
                        ps->vmem_code = -1;
-                       DEBUG("ps_read_process: did not get vmem data for pid %i",pid);
+                       DEBUG("ps_read_process: did not get vmem data for pid %li", pid);
                }
-               if (ps->num_lwp <= 0)
+               if (ps->num_lwp == 0)
                        ps->num_lwp = 1;
                ps->num_proc = 1;
        }
@@ -1124,7 +1098,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
        /* Leave the rest at zero if this is only a zombi */
        if (ps->num_proc == 0)
        {
-               DEBUG ("processes plugin: This is only a zombi: pid = %i; "
+               DEBUG ("processes plugin: This is only a zombie: pid = %li; "
                                "name = %s;", pid, ps->name);
                return (0);
        }
@@ -1164,7 +1138,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
                ps->io_syscr = -1;
                ps->io_syscw = -1;
 
-               DEBUG("ps_read_process: not get io data for pid %i",pid);
+               DEBUG("ps_read_process: not get io data for pid %li", pid);
        }
 
        if ( report_ctx_switch )
@@ -1175,7 +1149,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
                        ps->cswitch_invol = -1;
 
                        DEBUG("ps_read_tasks_status: not get context "
-                                       "switch data for pid %i",pid);
+                                       "switch data for pid %li", pid);
                }
        }
 
@@ -1183,7 +1157,7 @@ int ps_read_process (int pid, procstat_t *ps, char *state)
        return (0);
 } /* int ps_read_process (...) */
 
-static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len)
+static char *ps_get_cmdline (long pid, char *name, char *buf, size_t buf_len)
 {
        char  *buf_ptr;
        size_t len;
@@ -1196,8 +1170,7 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len)
        if ((pid < 1) || (NULL == buf) || (buf_len < 2))
                return NULL;
 
-       ssnprintf (file, sizeof (file), "/proc/%u/cmdline",
-                       (unsigned int) pid);
+       ssnprintf (file, sizeof (file), "/proc/%li/cmdline", pid);
 
        errno = 0;
        fd = open (file, O_RDONLY);
@@ -1241,7 +1214,7 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len)
                buf_ptr += status;
                len     -= status;
 
-               if (len <= 0)
+               if (len == 0)
                        break;
        }
 
@@ -1278,7 +1251,7 @@ static char *ps_get_cmdline (pid_t pid, char *name, char *buf, size_t buf_len)
        return buf;
 } /* char *ps_get_cmdline (...) */
 
-static int read_fork_rate ()
+static int read_fork_rate (void)
 {
        FILE *proc_stat;
        char buffer[1024];
@@ -1325,8 +1298,8 @@ static int read_fork_rate ()
 #endif /*KERNEL_LINUX */
 
 #if KERNEL_SOLARIS
-static const char *ps_get_cmdline (long pid, /* {{{ */
-               char *buffer, size_t buffer_size)
+static char *ps_get_cmdline (long pid, char *name __attribute__((unused)), /* {{{ */
+    char *buffer, size_t buffer_size)
 {
        char path[PATH_MAX];
        psinfo_t info;
@@ -1371,18 +1344,15 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
        snprintf(f_usage, sizeof (f_usage), "/proc/%li/usage", pid);
 
 
-       buffer = malloc(sizeof (pstatus_t));
-       memset(buffer, 0, sizeof (pstatus_t));
+       buffer = calloc(1, sizeof (pstatus_t));
        read_file_contents(filename, buffer, sizeof (pstatus_t));
        myStatus = (pstatus_t *) buffer;
 
-       buffer = malloc(sizeof (psinfo_t));
-       memset(buffer, 0, sizeof(psinfo_t));
+       buffer = calloc(1, sizeof (psinfo_t));
        read_file_contents(f_psinfo, buffer, sizeof (psinfo_t));
        myInfo = (psinfo_t *) buffer;
 
-       buffer = malloc(sizeof (prusage_t));
-       memset(buffer, 0, sizeof(prusage_t));
+       buffer = calloc(1, sizeof (prusage_t));
        read_file_contents(f_usage, buffer, sizeof (prusage_t));
        myUsage = (prusage_t *) buffer;
 
@@ -1392,6 +1362,10 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
                ps->num_proc = 0;
                ps->num_lwp = 0;
                *state = (char) 'Z';
+
+               sfree(myStatus);
+               sfree(myInfo);
+               sfree(myUsage);
                return (0);
        } else {
                ps->num_proc = 1;
@@ -1436,6 +1410,12 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
        ps->io_syscr = myUsage->pr_sysc;
        ps->io_syscw = myUsage->pr_sysc;
 
+       /*
+        * TODO: context switch counters for Solaris
+   */
+       ps->cswitch_vol   = -1;
+       ps->cswitch_invol = -1;
+
 
        /*
         * TODO: Find way of setting BLOCKED and PAGING status
@@ -1467,7 +1447,7 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
  * are retrieved from kstat (module cpu, name sys, class misc, stat nthreads).
  * The result is the sum for all the threads created on each cpu
  */
-static int read_fork_rate()
+static int read_fork_rate (void)
 {
        extern kstat_ctl_t *kc;
        kstat_t *ksp_chain = NULL;
@@ -1673,6 +1653,10 @@ static int ps_read (void)
 
                                pse.cpu_user_counter = task_absolutetime_info.total_user;
                                pse.cpu_system_counter = task_absolutetime_info.total_system;
+
+                               /* context switch counters not implemented */
+                               pse.cswitch_vol   = -1;
+                               pse.cswitch_invol = -1;
                        }
 
                        status = task_threads (task_list[task], &thread_list,
@@ -1814,7 +1798,7 @@ static int ps_read (void)
 
        struct dirent *ent;
        DIR           *proc;
-       int            pid;
+       long           pid;
 
        char cmdline[CMDLINE_BUFFER_SIZE];
 
@@ -1841,7 +1825,7 @@ static int ps_read (void)
                if (!isdigit (ent->d_name[0]))
                        continue;
 
-               if ((pid = atoi (ent->d_name)) < 1)
+               if ((pid = atol (ent->d_name)) < 1)
                        continue;
 
                status = ps_read_process (pid, &ps, &state);
@@ -2026,6 +2010,10 @@ static int ps_read (void)
                        pse.io_syscr = -1;
                        pse.io_syscw = -1;
 
+                       /* context switch counters not implemented */
+                       pse.cswitch_vol   = -1;
+                       pse.cswitch_invol = -1;
+
                        ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse);
 
                        switch (procs[i].ki_stat)
@@ -2159,7 +2147,8 @@ static int ps_read (void)
                        pse.io_syscr = -1;
                        pse.io_syscw = -1;
 
-                       pse.cswitch_vol = -1;
+                       /* context switch counters not implemented */
+                       pse.cswitch_vol   = -1;
                        pse.cswitch_invol = -1;
 
                        ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse);
@@ -2308,6 +2297,9 @@ static int ps_read (void)
                        pse.io_syscr = -1;
                        pse.io_syscw = -1;
 
+                       pse.cswitch_vol   = -1;
+                       pse.cswitch_invol = -1;
+
                        ps_list_add (cmdline, cargs, &pse);
                } /* for (i = 0 .. nprocs) */
 
@@ -2421,7 +2413,7 @@ static int ps_read (void)
 
 
                ps_list_add (ps.name,
-                               ps_get_cmdline (pid, cmdline, sizeof (cmdline)),
+                               ps_get_cmdline (pid, ps.name, cmdline, sizeof (cmdline)),
                                &pse);
        } /* while(readdir) */
        closedir (proc);
index 1a39aad..4d2b2ea 100644 (file)
@@ -48,7 +48,7 @@ static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
 static ignorelist_t *values_list = NULL;
 
-/* 
+/*
  * Functions
  */
 static void submit (const char *protocol_name,
index b5c01aa..32b31cc 100644 (file)
@@ -21,7 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Sven Trenkel <collectd at semidefinite.de>  
+ *   Sven Trenkel <collectd at semidefinite.de>
  **/
 
 #include <Python.h>
@@ -57,11 +57,11 @@ static char children_doc[] = "This is a tuple of child nodes. For most nodes thi
 
 static PyObject *Config_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
        Config *self;
-       
+
        self = (Config *) type->tp_alloc(type, 0);
        if (self == NULL)
                return NULL;
-       
+
        self->parent = NULL;
        self->key = NULL;
        self->values = NULL;
@@ -73,11 +73,11 @@ static int Config_init(PyObject *s, PyObject *args, PyObject *kwds) {
        PyObject *key = NULL, *parent = NULL, *values = NULL, *children = NULL, *tmp;
        Config *self = (Config *) s;
        static char *kwlist[] = {"key", "parent", "values", "children", NULL};
-       
+
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist,
                        &key, &parent, &values, &children))
                return -1;
-       
+
        if (!IS_BYTES_OR_UNICODE(key)) {
                PyErr_SetString(PyExc_TypeError, "argument 1 must be str");
                Py_XDECREF(parent);
@@ -122,7 +122,7 @@ static PyObject *Config_repr(PyObject *s) {
        Config *self = (Config *) s;
        PyObject *ret = NULL;
        static PyObject *node_prefix = NULL, *root_prefix = NULL, *ending = NULL;
-       
+
        /* This is ok because we have the GIL, so this is thread-save by default. */
        if (node_prefix == NULL)
                node_prefix = cpy_string_to_unicode_or_bytes("<collectd.Config node ");
@@ -132,7 +132,7 @@ static PyObject *Config_repr(PyObject *s) {
                ending = cpy_string_to_unicode_or_bytes(">");
        if (node_prefix == NULL || root_prefix == NULL || ending == NULL)
                return NULL;
-       
+
        ret = PyObject_Str(self->key);
        CPY_SUBSTITUTE(PyObject_Repr, ret, ret);
        if (self->parent == NULL || self->parent == Py_None)
@@ -140,7 +140,7 @@ static PyObject *Config_repr(PyObject *s) {
        else
                CPY_STRCAT(&ret, node_prefix);
        CPY_STRCAT(&ret, ending);
-       
+
        return ret;
 }
 
index 210d785..1ed6dc0 100644 (file)
@@ -21,7 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Sven Trenkel <collectd at semidefinite.de>  
+ *   Sven Trenkel <collectd at semidefinite.de>
  **/
 
 #include <Python.h>
@@ -250,16 +250,16 @@ static void cpy_destroy_user_data(void *data) {
 static void cpy_build_name(char *buf, size_t size, PyObject *callback, const char *name) {
        const char *module = NULL;
        PyObject *mod = NULL;
-       
+
        if (name != NULL) {
                snprintf(buf, size, "python.%s", name);
                return;
        }
-       
+
        mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */
        if (mod != NULL)
                module = cpy_unicode_or_bytes_to_string(&mod);
-       
+
        if (module != NULL) {
                snprintf(buf, size, "python.%s", module);
                Py_XDECREF(mod);
@@ -267,7 +267,7 @@ static void cpy_build_name(char *buf, size_t size, PyObject *callback, const cha
                return;
        }
        Py_XDECREF(mod);
-       
+
        snprintf(buf, size, "python.%p", callback);
        PyErr_Clear();
 }
@@ -276,7 +276,7 @@ void cpy_log_exception(const char *context) {
        int l = 0, i;
        const char *typename = NULL, *message = NULL;
        PyObject *type, *value, *traceback, *tn, *m, *list;
-       
+
        PyErr_Fetch(&type, &value, &traceback);
        PyErr_NormalizeException(&type, &value, &traceback);
        if (type == NULL) return;
@@ -305,21 +305,34 @@ void cpy_log_exception(const char *context) {
        list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. Steals references from "type", "value" and "traceback". */
        if (list)
                l = PyObject_Length(list);
+
        for (i = 0; i < l; ++i) {
-               char *s;
                PyObject *line;
-               
+               char const *msg;
+               char *cpy;
+
                line = PyList_GET_ITEM(list, i); /* Borrowed reference. */
                Py_INCREF(line);
-               s = strdup(cpy_unicode_or_bytes_to_string(&line));
+
+               msg = cpy_unicode_or_bytes_to_string(&line);
                Py_DECREF(line);
-               if (s[strlen(s) - 1] == '\n')
-                       s[strlen(s) - 1] = 0;
+               if (msg == NULL)
+                       continue;
+
+               cpy = strdup(msg);
+               if (cpy == NULL)
+                       continue;
+
+               if (cpy[strlen(cpy) - 1] == '\n')
+                       cpy[strlen(cpy) - 1] = 0;
+
                Py_BEGIN_ALLOW_THREADS
-               ERROR("%s", s);
+               ERROR("%s", cpy);
                Py_END_ALLOW_THREADS
-               free(s);
+
+               free(cpy);
        }
+
        Py_XDECREF(list);
        PyErr_Clear();
 }
@@ -377,7 +390,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                }
                dict = PyDict_New();  /* New reference. */
                if (value_list->meta) {
-                       int i, num;
+                       int num;
                        char **table;
                        meta_data_t *meta = value_list->meta;
 
@@ -389,7 +402,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                                uint64_t ui;
                                double d;
                                _Bool b;
-                               
+
                                type = meta_data_type(meta, table[i]);
                                if (type == MD_TYPE_STRING) {
                                        if (meta_data_get_string(meta, table[i], &string))
@@ -527,7 +540,7 @@ static PyObject *cpy_register_generic(cpy_callback_t **list_head, PyObject *args
        char *name = NULL;
        PyObject *callback = NULL, *data = NULL, *mod = NULL;
        static char *kwlist[] = {"callback", "data", "name", NULL};
-       
+
        if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
        if (PyCallable_Check(callback) == 0) {
                PyMem_Free(name);
@@ -538,7 +551,11 @@ static PyObject *cpy_register_generic(cpy_callback_t **list_head, PyObject *args
 
        Py_INCREF(callback);
        Py_XINCREF(data);
-       c = malloc(sizeof(*c));
+
+       c = calloc(1, sizeof(*c));
+       if (c == NULL)
+               return NULL;
+
        c->name = strdup(buf);
        c->callback = callback;
        c->data = data;
@@ -585,7 +602,7 @@ static PyObject *cpy_flush(PyObject *self, PyObject *args, PyObject *kwds) {
        int timeout = -1;
        char *plugin = NULL, *identifier = NULL;
        static char *kwlist[] = {"plugin", "timeout", "identifier", NULL};
-       
+
        if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin, &timeout, NULL, &identifier) == 0) return NULL;
        Py_BEGIN_ALLOW_THREADS
        plugin_flush(plugin, timeout, identifier);
@@ -609,11 +626,11 @@ static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObjec
        char buf[512];
        reg_function_t *register_function = (reg_function_t *) reg;
        cpy_callback_t *c = NULL;
-       user_data_t *user_data = NULL;
+       user_data_t user_data;
        char *name = NULL;
        PyObject *callback = NULL, *data = NULL;
        static char *kwlist[] = {"callback", "data", "name", NULL};
-       
+
        if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
        if (PyCallable_Check(callback) == 0) {
                PyMem_Free(name);
@@ -622,30 +639,36 @@ static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObjec
        }
        cpy_build_name(buf, sizeof(buf), callback, name);
        PyMem_Free(name);
-       
+
        Py_INCREF(callback);
        Py_XINCREF(data);
-       c = malloc(sizeof(*c));
+
+       c = calloc(1, sizeof(*c));
+       if (c == NULL)
+               return NULL;
+
        c->name = strdup(buf);
        c->callback = callback;
        c->data = data;
        c->next = NULL;
-       user_data = malloc(sizeof(*user_data));
-       user_data->free_func = cpy_destroy_user_data;
-       user_data->data = c;
-       register_function(buf, handler, user_data);
+
+       memset (&user_data, 0, sizeof (user_data));
+       user_data.free_func = cpy_destroy_user_data;
+       user_data.data = c;
+
+       register_function(buf, handler, &user_data);
        return cpy_string_to_unicode_or_bytes(buf);
 }
 
 static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) {
        char buf[512];
        cpy_callback_t *c = NULL;
-       user_data_t *user_data = NULL;
+       user_data_t user_data;
        double interval = 0;
        char *name = NULL;
        PyObject *callback = NULL, *data = NULL;
        static char *kwlist[] = {"callback", "interval", "data", "name", NULL};
-       
+
        if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, &interval, &data, NULL, &name) == 0) return NULL;
        if (PyCallable_Check(callback) == 0) {
                PyMem_Free(name);
@@ -654,19 +677,25 @@ static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwd
        }
        cpy_build_name(buf, sizeof(buf), callback, name);
        PyMem_Free(name);
-       
+
        Py_INCREF(callback);
        Py_XINCREF(data);
-       c = malloc(sizeof(*c));
+
+       c = calloc(1, sizeof(*c));
+       if (c == NULL)
+               return NULL;
+
        c->name = strdup(buf);
        c->callback = callback;
        c->data = data;
        c->next = NULL;
-       user_data = malloc(sizeof(*user_data));
-       user_data->free_func = cpy_destroy_user_data;
-       user_data->data = c;
-       plugin_register_complex_read(/* group = */ NULL, buf,
-                       cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), user_data);
+
+       memset (&user_data, 0, sizeof (user_data));
+       user_data.free_func = cpy_destroy_user_data;
+       user_data.data = c;
+
+       plugin_register_complex_read(/* group = */ "python", buf,
+                       cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), &user_data);
        return cpy_string_to_unicode_or_bytes(buf);
 }
 
@@ -766,7 +795,7 @@ static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, PyObject *ar
        for (tmp = *list_head; tmp; prev = tmp, tmp = tmp->next)
                if (strcmp(name, tmp->name) == 0)
                        break;
-       
+
        Py_DECREF(arg);
        if (tmp == NULL) {
                PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
@@ -871,7 +900,7 @@ static PyMethodDef cpy_methods[] = {
 static int cpy_shutdown(void) {
        cpy_callback_t *c;
        PyObject *ret;
-       
+
        /* This can happen if the module was loaded but not configured. */
        if (state != NULL)
                PyEval_RestoreThread(state);
@@ -895,14 +924,14 @@ static void cpy_int_handler(int sig) {
 static void *cpy_interactive(void *data) {
        sigset_t sigset;
        struct sigaction sig_int_action, old;
-       
+
        /* Signal handler in a plugin? Bad stuff, but the best way to
         * handle it I guess. In an interactive session people will
         * press Ctrl+C at some time, which will generate a SIGINT.
         * This will cause collectd to shutdown, thus killing the
         * interactive interpreter, and leaving the terminal in a
         * mess. Chances are, this isn't what the user wanted to do.
-        * 
+        *
         * So this is the plan:
         * 1. Block SIGINT in the main thread.
         * 2. Install our own signal handler that does nothing.
@@ -915,7 +944,7 @@ static void *cpy_interactive(void *data) {
        memset (&sig_int_action, '\0', sizeof (sig_int_action));
        sig_int_action.sa_handler = cpy_int_handler;
        sigaction (SIGINT, &sig_int_action, &old);
-       
+
        sigemptyset(&sigset);
        sigaddset(&sigset, SIGINT);
        pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
@@ -944,7 +973,7 @@ static int cpy_init(void) {
        PyObject *ret;
        static pthread_t thread;
        sigset_t sigset;
-       
+
        if (!Py_IsInitialized()) {
                WARNING("python: Plugin loaded but not configured.");
                plugin_unregister_shutdown("python");
@@ -975,10 +1004,10 @@ static int cpy_init(void) {
 static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
        int i;
        PyObject *item, *values, *children, *tmp;
-       
+
        if (parent == NULL)
                parent = Py_None;
-       
+
        values = PyTuple_New(ci->values_num); /* New reference. */
        for (i = 0; i < ci->values_num; ++i) {
                if (ci->values[i].type == OCONFIG_TYPE_STRING) {
@@ -989,7 +1018,7 @@ static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
                        PyTuple_SET_ITEM(values, i, PyBool_FromLong(ci->values[i].value.boolean));
                }
        }
-       
+
        tmp = cpy_string_to_unicode_or_bytes(ci->key);
        item = PyObject_CallFunction((void *) &ConfigType, "NONO", tmp, parent, values, Py_None);
        if (item == NULL)
@@ -1018,7 +1047,7 @@ PyMODINIT_FUNC PyInit_collectd(void) {
 }
 #endif
 
-static int cpy_init_python() {
+static int cpy_init_python(void) {
        PyObject *sys;
        PyObject *module;
 
@@ -1029,9 +1058,9 @@ static int cpy_init_python() {
 #else
        char *argv = "";
 #endif
-       
+
        Py_Initialize();
-       
+
        PyType_Ready(&ConfigType);
        PyType_Ready(&PluginDataType);
        ValuesType.tp_base = &PluginDataType;
@@ -1096,7 +1125,7 @@ static int cpy_config(oconfig_item_t *ci) {
 
        for (i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
-               
+
                if (strcasecmp(item->key, "Interactive") == 0) {
                        if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
                                continue;
@@ -1133,8 +1162,8 @@ static int cpy_config(oconfig_item_t *ci) {
                } else if (strcasecmp(item->key, "ModulePath") == 0) {
                        char *dir = NULL;
                        PyObject *dir_object;
-                       
-                       if (cf_util_get_string(item, &dir) != 0) 
+
+                       if (cf_util_get_string(item, &dir) != 0)
                                continue;
                        dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */
                        if (dir_object == NULL) {
@@ -1154,8 +1183,8 @@ static int cpy_config(oconfig_item_t *ci) {
                } else if (strcasecmp(item->key, "Import") == 0) {
                        char *module_name = NULL;
                        PyObject *module;
-                       
-                       if (cf_util_get_string(item, &module_name) != 0) 
+
+                       if (cf_util_get_string(item, &module_name) != 0)
                                continue;
                        module = PyImport_ImportModule(module_name); /* New reference. */
                        if (module == NULL) {
@@ -1168,7 +1197,7 @@ static int cpy_config(oconfig_item_t *ci) {
                        char *name = NULL;
                        cpy_callback_t *c;
                        PyObject *ret;
-                       
+
                        if (cf_util_get_string(item, &name) != 0)
                                continue;
                        for (c = cpy_config_callbacks; c; c = c->next) {
index 4417601..0ba0436 100644 (file)
@@ -21,7 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  *
  * Authors:
- *   Sven Trenkel <collectd at semidefinite.de>  
+ *   Sven Trenkel <collectd at semidefinite.de>
  **/
 
 #include <Python.h>
@@ -45,7 +45,7 @@ static PyObject *cpy_common_repr(PyObject *s) {
        static PyObject *l_type = NULL, *l_type_instance = NULL, *l_plugin = NULL, *l_plugin_instance = NULL;
        static PyObject *l_host = NULL, *l_time = NULL;
        PluginData *self = (PluginData *) s;
-       
+
        if (l_type == NULL)
                l_type = cpy_string_to_unicode_or_bytes("(type=");
        if (l_type_instance == NULL)
@@ -58,10 +58,10 @@ static PyObject *cpy_common_repr(PyObject *s) {
                l_host = cpy_string_to_unicode_or_bytes(",host=");
        if (l_time == NULL)
                l_time = cpy_string_to_unicode_or_bytes(",time=");
-       
+
        if (!l_type || !l_type_instance || !l_plugin || !l_plugin_instance || !l_host || !l_time)
                return NULL;
-       
+
        ret = cpy_string_to_unicode_or_bytes(s->ob_type->tp_name);
 
        CPY_STRCAT(&ret, l_type);
@@ -106,19 +106,19 @@ static PyObject *cpy_common_repr(PyObject *s) {
        return ret;
 }
 
-static char time_doc[] = "This is the Unix timestap of the time this value was read.\n"
+static char time_doc[] = "This is the Unix timestamp of the time this value was read.\n"
                "For dispatching values this can be set to 0 which means \"now\".\n"
                "This means the time the value is actually dispatched, not the time\n"
                "it was set to 0.";
 
 static char host_doc[] = "The hostname of the host this value was read from.\n"
                "For dispatching this can be set to an empty string which means\n"
-               "the local hostname as defined in the collectd.conf.";
+               "the local hostname as defined in collectd.conf.";
 
 static char type_doc[] = "The type of this value. This type has to be defined\n"
-               "in your types.db. Attempting to set it to any other value will\n"
-               "raise a TypeError exception.\n"
-               "Assigning a type is mandetory, calling dispatch without doing\n"
+               "in the types.db file. Attempting to set it to any other value\n"
+               "will raise a TypeError exception.\n"
+               "Assigning a type is mandatory, calling dispatch without doing\n"
                "so will raise a RuntimeError exception.";
 
 static char type_instance_doc[] = "";
@@ -129,16 +129,16 @@ static char plugin_doc[] = "The name of the plugin that read the data. Setting t
 static char plugin_instance_doc[] = "";
 
 static char PluginData_doc[] = "This is an internal class that is the base for Values\n"
-               "and Notification. It is pretty useless by itself and was therefore not\n"
+               "and Notification. It is pretty useless by itself and is therefore not\n"
                "exported to the collectd module.";
 
 static PyObject *PluginData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
        PluginData *self;
-       
+
        self = (PluginData *) type->tp_alloc(type, 0);
        if (self == NULL)
                return NULL;
-       
+
        self->time = 0;
        self->host[0] = 0;
        self->plugin[0] = 0;
@@ -154,11 +154,11 @@ static int PluginData_init(PyObject *s, PyObject *args, PyObject *kwds) {
        char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL;
        static char *kwlist[] = {"type", "plugin_instance", "type_instance",
                        "plugin", "host", "time", NULL};
-       
+
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetd", kwlist, NULL, &type,
                        NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time))
                return -1;
-       
+
        if (type && plugin_get_ds(type) == NULL) {
                PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
                FreeAll();
@@ -180,13 +180,13 @@ static int PluginData_init(PyObject *s, PyObject *args, PyObject *kwds) {
 static PyObject *PluginData_repr(PyObject *s) {
        PyObject *ret;
        static PyObject *l_closing = NULL;
-       
+
        if (l_closing == NULL)
                l_closing = cpy_string_to_unicode_or_bytes(")");
-       
+
        if (l_closing == NULL)
                return NULL;
-       
+
        ret = cpy_common_repr(s);
        CPY_STRCAT(&ret, l_closing);
        return ret;
@@ -199,14 +199,14 @@ static PyMemberDef PluginData_members[] = {
 
 static PyObject *PluginData_getstring(PyObject *self, void *data) {
        const char *value = ((char *) self) + (intptr_t) data;
-       
+
        return cpy_string_to_unicode_or_bytes(value);
 }
 
 static int PluginData_setstring(PyObject *self, PyObject *value, void *data) {
        char *old;
        const char *new;
-       
+
        if (value == NULL) {
                PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
                return -1;
@@ -226,7 +226,7 @@ static int PluginData_setstring(PyObject *self, PyObject *value, void *data) {
 static int PluginData_settype(PyObject *self, PyObject *value, void *data) {
        char *old;
        const char *new;
-       
+
        if (value == NULL) {
                PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
                return -1;
@@ -312,8 +312,8 @@ static char interval_doc[] = "The interval is the timespan in seconds between tw
 static char values_doc[] = "These are the actual values that get dispatched to collectd.\n"
                "It has to be a sequence (a tuple or list) of numbers.\n"
                "The size of the sequence and the type of its content depend on the type\n"
-               "member your types.db file. For more information on this read the types.db\n"
-               "man page.\n"
+               "member in the types.db file. For more information on this read the\n"
+               "types.db man page.\n"
                "\n"
                "If the sequence does not have the correct size upon dispatch a RuntimeError\n"
                "exception will be raised. If the content of the sequence is not a number,\n"
@@ -322,7 +322,7 @@ static char values_doc[] = "These are the actual values that get dispatched to c
 static char meta_doc[] = "These are the meta data for this Value object.\n"
                "It has to be a dictionary of numbers, strings or bools. All keys must be\n"
                "strings. int and long objects will be dispatched as signed integers unless\n"
-               "they are between 2**63 and 2**64-1, which will result in a unsigned integer.\n"
+               "they are between 2**63 and 2**64-1, which will result in an unsigned integer.\n"
                "You can force one of these storage classes by using the classes\n"
                "collectd.Signed and collectd.Unsigned. A meta object received by a write\n"
                "callback will always contain Signed or Unsigned objects.";
@@ -340,7 +340,7 @@ static char dispatch_doc[] = "dispatch([type][, values][, plugin_instance][, typ
 static char write_doc[] = "write([destination][, type][, values][, plugin_instance][, type_instance]"
                "[, plugin][, host][, time][, interval]) -> None.  Dispatch a value list.\n"
                "\n"
-               "Write this instance to a single plugin or all plugins if 'destination' is obmitted.\n"
+               "Write this instance to a single plugin or all plugins if 'destination' is omitted.\n"
                "This will bypass the main collectd process and all filtering and caching.\n"
                "Other than that it works similar to 'dispatch'. In most cases 'dispatch' should be\n"
                "used instead of 'write'.\n";
@@ -349,11 +349,11 @@ static char Values_doc[] = "A Values object used for dispatching values to colle
 
 static PyObject *Values_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
        Values *self;
-       
+
        self = (Values *) PluginData_new(type, args, kwds);
        if (self == NULL)
                return NULL;
-       
+
        self->values = PyList_New(0);
        self->meta = PyDict_New();
        self->interval = 0;
@@ -367,12 +367,12 @@ static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) {
        char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL;
        static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", "meta", NULL};
-       
+
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist,
                        NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
                        NULL, &plugin, NULL, &host, &time, &interval, &meta))
                return -1;
-       
+
        if (type && plugin_get_ds(type) == NULL) {
                PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
                FreeAll();
@@ -394,18 +394,18 @@ static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) {
        } else {
                Py_INCREF(values);
        }
-       
+
        if (meta == NULL) {
                meta = PyDict_New();
                PyErr_Clear();
        } else {
                Py_INCREF(meta);
        }
-       
+
        tmp = self->values;
        self->values = values;
        Py_XDECREF(tmp);
-       
+
        tmp = self->meta;
        self->meta = meta;
        Py_XDECREF(tmp);
@@ -418,7 +418,7 @@ static meta_data_t *cpy_build_meta(PyObject *meta) {
        int i, s;
        meta_data_t *m = NULL;
        PyObject *l;
-       
+
        if ((meta == NULL) || (meta == Py_None))
                return NULL;
 
@@ -437,7 +437,7 @@ static meta_data_t *cpy_build_meta(PyObject *meta) {
        for (i = 0; i < s; ++i) {
                const char *string, *keystring;
                PyObject *key, *value, *item, *tmp;
-               
+
                item = PyList_GET_ITEM(l, i);
                key = PyTuple_GET_ITEM(item, 0);
                Py_INCREF(key);
@@ -510,7 +510,7 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
        PyObject *values = self->values, *meta = self->meta;
        double time = self->data.time, interval = self->interval;
        char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL;
-       
+
        static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", "meta", NULL};
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist,
@@ -619,7 +619,7 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        PyObject *values = self->values, *meta = self->meta;
        double time = self->data.time, interval = self->interval;
        char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL, *dest = NULL;
-       
+
        static char *kwlist[] = {"destination", "type", "values", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "interval", "meta", NULL};
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|etOetetetetdiO", kwlist, NULL, &dest,
@@ -697,7 +697,7 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        value_list.values_len = size;
        value_list.time = DOUBLE_TO_CDTIME_T(time);
        value_list.interval = DOUBLE_TO_CDTIME_T(interval);
-       value_list.meta = cpy_build_meta(meta);;
+       value_list.meta = cpy_build_meta(meta);
        if (value_list.host[0] == 0)
                sstrncpy(value_list.host, hostname_g, sizeof(value_list.host));
        if (value_list.plugin[0] == 0)
@@ -718,7 +718,7 @@ static PyObject *Values_repr(PyObject *s) {
        PyObject *ret, *tmp;
        static PyObject *l_interval = NULL, *l_values = NULL, *l_meta = NULL, *l_closing = NULL;
        Values *self = (Values *) s;
-       
+
        if (l_interval == NULL)
                l_interval = cpy_string_to_unicode_or_bytes(",interval=");
        if (l_values == NULL)
@@ -727,10 +727,10 @@ static PyObject *Values_repr(PyObject *s) {
                l_meta = cpy_string_to_unicode_or_bytes(",meta=");
        if (l_closing == NULL)
                l_closing = cpy_string_to_unicode_or_bytes(")");
-       
+
        if (l_interval == NULL || l_values == NULL || l_meta == NULL || l_closing == NULL)
                return NULL;
-       
+
        ret = cpy_common_repr(s);
        if (self->interval != 0) {
                CPY_STRCAT(&ret, l_interval);
@@ -844,12 +844,12 @@ static int Notification_init(PyObject *s, PyObject *args, PyObject *kwds) {
        char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL;
        static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "severity", NULL};
-       
+
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist,
                        NULL, &type, NULL, &message, NULL, &plugin_instance, NULL, &type_instance,
                        NULL, &plugin, NULL, &host, &time, &severity))
                return -1;
-       
+
        if (type && plugin_get_ds(type) == NULL) {
                PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
                FreeAll();
@@ -879,7 +879,7 @@ static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObj
        int severity = self->severity;
        char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL;
        char *message = NULL;
-       
+
        static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance",
                        "plugin", "host", "time", "severity", NULL};
        if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist,
@@ -927,11 +927,11 @@ static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObj
 
 static PyObject *Notification_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
        Notification *self;
-       
+
        self = (Notification *) PluginData_new(type, args, kwds);
        if (self == NULL)
                return NULL;
-       
+
        self->message[0] = 0;
        self->severity = 0;
        return (PyObject *) self;
@@ -940,7 +940,7 @@ static PyObject *Notification_new(PyTypeObject *type, PyObject *args, PyObject *
 static int Notification_setstring(PyObject *self, PyObject *value, void *data) {
        char *old;
        const char *new;
-       
+
        if (value == NULL) {
                PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
                return -1;
@@ -961,17 +961,17 @@ static PyObject *Notification_repr(PyObject *s) {
        PyObject *ret, *tmp;
        static PyObject *l_severity = NULL, *l_message = NULL, *l_closing = NULL;
        Notification *self = (Notification *) s;
-       
+
        if (l_severity == NULL)
                l_severity = cpy_string_to_unicode_or_bytes(",severity=");
        if (l_message == NULL)
                l_message = cpy_string_to_unicode_or_bytes(",message=");
        if (l_closing == NULL)
                l_closing = cpy_string_to_unicode_or_bytes(")");
-       
+
        if (l_severity == NULL || l_message == NULL || l_closing == NULL)
                return NULL;
-       
+
        ret = cpy_common_repr(s);
        if (self->severity != 0) {
                CPY_STRCAT(&ret, l_severity);
index 7864ead..919a831 100644 (file)
@@ -130,7 +130,7 @@ static redis_query_t *redis_config_query (oconfig_item_t *ci) /* {{{ */
 
     rq = calloc(1, sizeof(*rq));
     if (rq == NULL) {
-        ERROR("redis plugin: calloca failed adding redis_query.");
+        ERROR("redis plugin: calloc failed adding redis_query.");
         return NULL;
     }
     status = cf_util_get_string_buffer(ci, rq->query, sizeof(rq->query));
@@ -141,7 +141,7 @@ static redis_query_t *redis_config_query (oconfig_item_t *ci) /* {{{ */
      * Default to a gauge type.
      */
     (void)strncpy(rq->type, "gauge", sizeof(rq->type));
-    (void)strncpy(rq->instance, rq->query, sizeof(rq->instance));
+    (void)sstrncpy(rq->instance, rq->query, sizeof(rq->instance));
     replace_special(rq->instance, sizeof(rq->instance));
 
     for (i = 0; i < ci->children_num; i++) {
@@ -294,7 +294,7 @@ static int redis_init (void) /* {{{ */
   return (0);
 } /* }}} int redis_init */
 
-int redis_handle_info (char *node, char const *info_line, char const *type, char const *type_instance, char const *field_name, int ds_type) /* {{{ */
+static int redis_handle_info (char *node, char const *info_line, char const *type, char const *type_instance, char const *field_name, int ds_type) /* {{{ */
 {
   char *str = strstr (info_line, field_name);
   static char buf[MAX_REDIS_VAL_SIZE];
@@ -304,7 +304,7 @@ int redis_handle_info (char *node, char const *info_line, char const *type, char
     int i;
 
     str += strlen (field_name) + 1; /* also skip the ':' */
-    for(i=0;(*str && (isdigit(*str) || *str == '.'));i++,str++)
+    for(i=0;(*str && (isdigit((unsigned char)*str) || *str == '.'));i++,str++)
       buf[i] = *str;
     buf[i] ='\0';
 
@@ -321,7 +321,7 @@ int redis_handle_info (char *node, char const *info_line, char const *type, char
 
 } /* }}} int redis_handle_info */
 
-int redis_handle_query (redisContext *rh, redis_node_t *rn, redis_query_t *rq) /* {{{ */
+static int redis_handle_query (redisContext *rh, redis_node_t *rn, redis_query_t *rq) /* {{{ */
 {
     redisReply *rr;
     const data_set_t *ds;
@@ -376,7 +376,7 @@ int redis_handle_query (redisContext *rh, redis_node_t *rn, redis_query_t *rq) /
     redis_submit(rn->name, rq->type, (strlen(rq->instance) >0)?rq->instance:NULL, val);
     freeReplyObject (rr);
     return 0;
-} /* }}} int redis_handle_info */
+} /* }}} int redis_handle_query */
 
 static int redis_read (void) /* {{{ */
 {
@@ -399,25 +399,27 @@ static int redis_read (void) /* {{{ */
 
     if (strlen (rn->passwd) > 0)
     {
-      DEBUG ("redis plugin: authenticanting node `%s' passwd(%s).", rn->name, rn->passwd);
-      rr = redisCommand (rh, "AUTH %s", rn->passwd);
+      DEBUG ("redis plugin: authenticating node `%s' passwd(%s).", rn->name, rn->passwd);
 
-      if (rr == NULL || rr->type != REDIS_REPLY_STATUS)
+      if ((rr = redisCommand (rh, "AUTH %s", rn->passwd)) == NULL)
       {
         WARNING ("redis plugin: unable to authenticate on node `%s'.", rn->name);
-        if (rr != NULL)
-          freeReplyObject (rr);
+        goto redis_fail;
+      }
 
-        redisFree (rh);
-        continue;
+      if (rr->type != REDIS_REPLY_STATUS)
+      {
+        WARNING ("redis plugin: invalid authentication on node `%s'.", rn->name);
+        goto redis_fail;
       }
+
+      freeReplyObject (rr);
     }
 
     if ((rr = redisCommand(rh, "INFO")) == NULL)
     {
-      WARNING ("redis plugin: unable to connect to node `%s'.", rn->name);
-      redisFree (rh);
-      continue;
+      WARNING ("redis plugin: unable to get info from node `%s'.", rn->name);
+      goto redis_fail;
     }
 
     redis_handle_info (rn->name, rr->str, "uptime", NULL, "uptime_in_seconds", DS_TYPE_GAUGE);
@@ -429,16 +431,22 @@ static int redis_read (void) /* {{{ */
     redis_handle_info (rn->name, rr->str, "volatile_changes", NULL, "changes_since_last_save", DS_TYPE_GAUGE);
     redis_handle_info (rn->name, rr->str, "total_connections", NULL, "total_connections_received", DS_TYPE_DERIVE);
     redis_handle_info (rn->name, rr->str, "total_operations", NULL, "total_commands_processed", DS_TYPE_DERIVE);
-    redis_handle_info (rn->name, rr->str, "expired_keys", NULL, "expired_keys", DS_TYPE_GAUGE);
+    redis_handle_info (rn->name, rr->str, "expired_keys", NULL, "expired_keys", DS_TYPE_DERIVE);
+    redis_handle_info (rn->name, rr->str, "evicted_keys", NULL, "evicted_keys", DS_TYPE_DERIVE);
     redis_handle_info (rn->name, rr->str, "pubsub", "channels", "pubsub_channels", DS_TYPE_GAUGE);
     redis_handle_info (rn->name, rr->str, "pubsub", "patterns", "pubsub_patterns", DS_TYPE_GAUGE);
     redis_handle_info (rn->name, rr->str, "current_connections", "slaves", "connected_slaves", DS_TYPE_GAUGE);
-
-    freeReplyObject (rr);
+    redis_handle_info (rn->name, rr->str, "cache_result", "hits", "keyspace_hits", DS_TYPE_DERIVE);
+    redis_handle_info (rn->name, rr->str, "cache_result", "misses", "keyspace_misses", DS_TYPE_DERIVE);
+    redis_handle_info (rn->name, rr->str, "total_bytes", "input", "total_net_input_bytes", DS_TYPE_DERIVE);
+    redis_handle_info (rn->name, rr->str, "total_bytes", "output", "total_net_output_bytes", DS_TYPE_DERIVE);
 
     for (rq = rn->queries; rq != NULL; rq = rq->next)
         redis_handle_query(rh, rn, rq);
 
+redis_fail:
+    if (rr != NULL)
+      freeReplyObject (rr);
     redisFree (rh);
   }
 
diff --git a/src/riemann.proto b/src/riemann.proto
deleted file mode 100644 (file)
index 3e946a3..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-option java_package = "com.aphyr.riemann";
-option java_outer_classname = "Proto";
-
-message State {
-  optional int64 time = 1;
-  optional string state = 2;
-  optional string service = 3;
-  optional string host = 4;
-  optional string description = 5;
-  optional bool once = 6;
-  repeated string tags = 7;
-  optional float ttl = 8;
-}
-
-message Event {
-  optional int64 time = 1;
-  optional string state = 2;
-  optional string service = 3;
-  optional string host = 4;
-  optional string description = 5;
-  repeated string tags = 7;
-  optional float ttl = 8;
-  repeated Attribute attributes = 9;
-
-  optional sint64 metric_sint64 = 13;
-  optional double metric_d = 14;
-  optional float metric_f = 15;
-}
-
-message Query {
-  optional string string = 1;
-}
-
-message Msg {
-  optional bool ok = 2;
-  optional string error = 3;
-  repeated State states = 4;
-  optional Query query = 5;
-  repeated Event events = 6;
-}
-
-message Attribute {
-  required string key = 1;
-  optional string value = 2;
-}
index 667c2fa..7ee3024 100644 (file)
@@ -328,10 +328,9 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */
   int status;
   int i;
 
-  router_data = malloc (sizeof (*router_data));
+  router_data = calloc (1, sizeof (*router_data));
   if (router_data == NULL)
     return (-1);
-  memset (router_data, 0, sizeof (*router_data));
   router_data->connection = NULL;
   router_data->node = NULL;
   router_data->service = NULL;
index 5d98de8..3a6c985 100644 (file)
@@ -95,7 +95,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
       status = ssnprintf (buffer + offset, buffer_len - offset,
           ":%llu", vl->values[i].counter);
     }
-    else if (ds->ds[i].type == DS_TYPE_GAUGE) 
+    else if (ds->ds[i].type == DS_TYPE_GAUGE)
     {
       status = ssnprintf (buffer + offset, buffer_len - offset,
           ":%f", vl->values[i].gauge);
@@ -107,7 +107,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
     else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ {
       status = ssnprintf (buffer + offset, buffer_len - offset,
          ":%"PRIu64, vl->values[i].absolute);
+
     }
 
     if ((status < 1) || (status >= (buffer_len - offset)))
index 764d6d6..3cd6d6b 100644 (file)
@@ -166,7 +166,7 @@ static int srrd_update (char *filename, char *template,
        assert (template == NULL);
 
        new_argc = 2 + argc;
-       new_argv = (char **) malloc ((new_argc + 1) * sizeof (char *));
+       new_argv = malloc ((new_argc + 1) * sizeof (*new_argv));
        if (new_argv == NULL)
        {
                ERROR ("rrdtool plugin: malloc failed.");
@@ -442,7 +442,7 @@ static void *rrd_queue_thread (void __attribute__((unused)) *data)
                }
 
                /* Update `tv_next_update' */
-               if (write_rate > 0.0) 
+               if (write_rate > 0.0)
                 {
                   gettimeofday (&tv_now, /* timezone = */ NULL);
                   tv_next_update.tv_sec = tv_now.tv_sec;
@@ -480,7 +480,7 @@ static int rrd_queue_enqueue (const char *filename,
 {
   rrd_queue_t *queue_entry;
 
-  queue_entry = (rrd_queue_t *) malloc (sizeof (rrd_queue_t));
+  queue_entry = malloc (sizeof (*queue_entry));
   if (queue_entry == NULL)
     return (-1);
 
@@ -522,7 +522,7 @@ static int rrd_queue_dequeue (const char *filename,
   {
     if (strcmp (this->filename, filename) == 0)
       break;
-    
+
     prev = this;
     this = this->next;
   }
@@ -588,7 +588,7 @@ static void rrd_cache_flush (cdtime_t timeout)
                }
                else /* ancient and no values -> waste of memory */
                {
-                       char **tmp = (char **) realloc ((void *) keys,
+                       char **tmp = realloc (keys,
                                        (keys_num + 1) * sizeof (char *));
                        if (tmp == NULL)
                        {
@@ -607,7 +607,7 @@ static void rrd_cache_flush (cdtime_t timeout)
                }
        } /* while (c_avl_iterator_next) */
        c_avl_iterator_destroy (iter);
-       
+
        for (i = 0; i < keys_num; i++)
        {
                if (c_avl_remove (cache, keys[i], (void *) &key, (void *) &rc) != 0)
@@ -733,7 +733,10 @@ static int rrd_cache_insert (const char *filename,
        {
                rc = malloc (sizeof (*rc));
                if (rc == NULL)
+               {
+                       pthread_mutex_unlock (&cache_lock);
                        return (-1);
+               }
                rc->values_num = 0;
                rc->values = NULL;
                rc->first_value = 0;
@@ -753,7 +756,7 @@ static int rrd_cache_insert (const char *filename,
                return (-1);
        }
 
-       values_new = (char **) realloc ((void *) rc->values,
+       values_new = realloc ((void *) rc->values,
                        (rc->values_num + 1) * sizeof (char *));
        if (values_new == NULL)
        {
@@ -1005,23 +1008,36 @@ static int rrd_config (const char *key, const char *value)
        }
        else if (strcasecmp ("DataDir", key) == 0)
        {
-               if (datadir != NULL)
-                       free (datadir);
-               datadir = strdup (value);
+               char *tmp;
+               size_t len;
+
+               tmp = strdup (value);
+               if (tmp == NULL)
+               {
+                       ERROR ("rrdtool plugin: strdup failed.");
+                       return (1);
+               }
+
+               len = strlen (tmp);
+               while ((len > 0) && (tmp[len - 1] == '/'))
+               {
+                       len--;
+                       tmp[len] = 0;
+               }
+
+               if (len == 0)
+               {
+                       ERROR ("rrdtool plugin: Invalid \"DataDir\" option.");
+                       sfree (tmp);
+                       return (1);
+               }
+
                if (datadir != NULL)
                {
-                       int len = strlen (datadir);
-                       while ((len > 0) && (datadir[len - 1] == '/'))
-                       {
-                               len--;
-                               datadir[len] = '\0';
-                       }
-                       if (len <= 0)
-                       {
-                               free (datadir);
-                               datadir = NULL;
-                       }
+                       sfree (datadir);
                }
+
+               datadir = tmp;
        }
        else if (strcasecmp ("StepSize", key) == 0)
        {
@@ -1071,7 +1087,7 @@ static int rrd_config (const char *key, const char *value)
                while ((ptr = strtok_r (dummy, ", \t", &saveptr)) != NULL)
                {
                        dummy = NULL;
-                       
+
                        tmp_alloc = realloc (rrdcreate_config.timespans,
                                        sizeof (int) * (rrdcreate_config.timespans_num + 1));
                        if (tmp_alloc == NULL)
@@ -1204,6 +1220,7 @@ static int rrd_init (void)
        cache = c_avl_create ((int (*) (const void *, const void *)) strcmp);
        if (cache == NULL)
        {
+               pthread_mutex_unlock (&cache_lock);
                ERROR ("rrdtool plugin: c_avl_create failed.");
                return (-1);
        }
index f5b09bd..63a1c8e 100644 (file)
@@ -18,7 +18,7 @@
  *
  * Authors:
  *   Florian octo Forster <octo at collectd.org>
- *   
+ *
  *   Lubos Stanek <lubek at users.sourceforge.net> Wed Oct 27, 2006
  *   - config ExtendedSensorNaming option
  *   - precise sensor feature selection (chip-bus-address/type-feature)
@@ -76,7 +76,7 @@ struct sensors_labeltypes_s
 typedef struct sensors_labeltypes_s sensors_labeltypes_t;
 
 /* finite list of known labels extracted from lm_sensors */
-static sensors_labeltypes_t known_features[] = 
+static sensors_labeltypes_t known_features[] =
 {
        { "fan1", SENSOR_TYPE_FANSPEED },
        { "fan2", SENSOR_TYPE_FANSPEED },
@@ -140,7 +140,8 @@ static const char *config_keys[] =
 {
        "Sensor",
        "IgnoreSelected",
-       "SensorConfigFile"
+       "SensorConfigFile",
+       "UseLabels"
 };
 static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
@@ -169,6 +170,7 @@ typedef struct featurelist
 } featurelist_t;
 
 static char *conffile = NULL;
+static _Bool use_labels = 0;
 /* #endif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */
 
 #else /* if SENSORS_API_VERSION >= 0x500 */
@@ -176,7 +178,7 @@ static char *conffile = NULL;
        "as bug."
 #endif
 
-featurelist_t *first_feature = NULL;
+static featurelist_t *first_feature = NULL;
 static ignorelist_t *sensor_list;
 
 #if SENSORS_API_VERSION < 0x400
@@ -257,6 +259,12 @@ static int sensors_config (const char *key, const char *value)
                if (IS_TRUE (value))
                        ignorelist_set_invert (sensor_list, 0);
        }
+#if (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500)
+       else if (strcasecmp (key, "UseLabels") == 0)
+       {
+               use_labels = IS_TRUE (value) ? 1 : 0;
+       }
+#endif
        else
        {
                return (-1);
@@ -265,7 +273,7 @@ static int sensors_config (const char *key, const char *value)
        return (0);
 }
 
-void sensors_free_features (void)
+static void sensors_free_features (void)
 {
        featurelist_t *thisft;
        featurelist_t *nextft;
@@ -289,7 +297,7 @@ static int sensors_load_conf (void)
 
        FILE *fh = NULL;
        featurelist_t *last_feature = NULL;
-       
+
        const sensors_chip_name *chip;
        int chip_num;
 
@@ -378,13 +386,12 @@ static int sensors_load_conf (void)
                                continue;
                        }
 
-                       fl = (featurelist_t *) malloc (sizeof (featurelist_t));
+                       fl = calloc (1, sizeof (*fl));
                        if (fl == NULL)
                        {
-                               ERROR ("sensors plugin: malloc failed.");
+                               ERROR ("sensors plugin: calloc failed.");
                                continue;
                        }
-                       memset (fl, '\0', sizeof (featurelist_t));
 
                        fl->chip = chip;
                        fl->data = feature;
@@ -435,13 +442,12 @@ static int sensors_load_conf (void)
                                                && (subfeature->type != SENSORS_SUBFEATURE_POWER_INPUT))
                                        continue;
 
-                               fl = (featurelist_t *) malloc (sizeof (featurelist_t));
+                               fl = calloc (1, sizeof (*fl));
                                if (fl == NULL)
                                {
-                                       ERROR ("sensors plugin: malloc failed.");
+                                       ERROR ("sensors plugin: calloc failed.");
                                        continue;
                                }
-                               memset (fl, '\0', sizeof (featurelist_t));
 
                                fl->chip = chip;
                                fl->feature = feature;
@@ -555,6 +561,7 @@ static int sensors_read (void)
                int status;
                char plugin_instance[DATA_MAX_NAME_LEN];
                char type_instance[DATA_MAX_NAME_LEN];
+               char *sensor_label;
                const char *type;
 
                status = sensors_get_value (fl->chip,
@@ -567,8 +574,17 @@ static int sensors_read (void)
                if (status < 0)
                        continue;
 
-               sstrncpy (type_instance, fl->feature->name,
-                               sizeof (type_instance));
+               if (use_labels)
+               {
+                       sensor_label = sensors_get_label (fl->chip, fl->feature);
+                       sstrncpy (type_instance, sensor_label, sizeof (type_instance));
+                       free (sensor_label);
+               }
+               else
+               {
+                       sstrncpy (type_instance, fl->feature->name,
+                                       sizeof (type_instance));
+               }
 
                if (fl->feature->type == SENSORS_FEATURE_IN)
                        type = "voltage";
index eecb54c..6c781f8 100644 (file)
@@ -72,11 +72,10 @@ static int sigrok_config_device(oconfig_item_t *ci)
        struct config_device *cfdev;
        int i;
 
-       if (!(cfdev = malloc(sizeof(struct config_device)))) {
-               ERROR("sigrok plugin: malloc() failed.");
+       if (!(cfdev = calloc(1, sizeof(*cfdev)))) {
+               ERROR("sigrok plugin: calloc failed.");
                return -1;
        }
-       memset(cfdev, 0, sizeof(*cfdev));
        if (cf_util_get_string(ci, &cfdev->name)) {
                free(cfdev);
                WARNING("sigrok plugin: Invalid device name.");
@@ -136,9 +135,9 @@ static int sigrok_config(oconfig_item_t *ci)
        return 0;
 }
 
-static char *sigrok_value_type(const struct sr_datafeed_analog *analog)
+static const char *sigrok_value_type(const struct sr_datafeed_analog *analog)
 {
-       char *s;
+       const char *s;
 
        if (analog->mq == SR_MQ_VOLTAGE)
                s = "voltage";
@@ -236,14 +235,14 @@ static int sigrok_init_driver(struct config_device *cfdev,
 
        drvopts = NULL;
        if (cfdev->conn) {
-               if (!(src = malloc(sizeof(struct sr_config))))
+               if (!(src = malloc(sizeof(*src))))
                        return -1;
                src->key = SR_CONF_CONN;
                src->data = g_variant_new_string(cfdev->conn);
                drvopts = g_slist_append(drvopts, src);
        }
        if (cfdev->serialcomm) {
-               if (!(src = malloc(sizeof(struct sr_config))))
+               if (!(src = malloc(sizeof(*src))))
                        return -1;
                src->key = SR_CONF_SERIALCOMM;
                src->data = g_variant_new_string(cfdev->serialcomm);
@@ -360,10 +359,13 @@ static int sigrok_init(void)
                return -1;
        }
 
-       if ((status = plugin_thread_create(&sr_thread, NULL, sigrok_read_thread,
-                       NULL)) != 0) {
+       status = plugin_thread_create(&sr_thread, NULL, sigrok_read_thread,
+                       NULL);
+       if (status != 0)
+       {
+               char errbuf[1024];
                ERROR("sigrok plugin: Failed to create thread: %s.",
-                               strerror(status));
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
                return -1;
        }
        sr_thread_running = TRUE;
index 2207bd6..7b39aae 100644 (file)
@@ -68,7 +68,8 @@ static int smart_config (const char *key, const char *value)
   return (0);
 } /* int smart_config */
 
-static void smart_submit (const char *dev, char *type, char *type_inst, double value)
+static void smart_submit (const char *dev, const char *type,
+               const char *type_inst, double value)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
index 18c5207..89cbc46 100644 (file)
@@ -310,7 +310,7 @@ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *
 
   sfree (dd->values);
   dd->values_len = 0;
-  dd->values = (oid_t *) malloc (sizeof (oid_t) * ci->values_num);
+  dd->values = malloc (sizeof (*dd->values) * ci->values_num);
   if (dd->values == NULL)
     return (-1);
   dd->values_len = (size_t) ci->values_num;
@@ -384,10 +384,9 @@ static int csnmp_config_add_data (oconfig_item_t *ci)
   int status = 0;
   int i;
 
-  dd = (data_definition_t *) malloc (sizeof (data_definition_t));
+  dd = calloc (1, sizeof (*dd));
   if (dd == NULL)
     return (-1);
-  memset (dd, '\0', sizeof (data_definition_t));
 
   status = cf_util_get_string(ci, &dd->name);
   if (status != 0)
@@ -521,7 +520,7 @@ static int csnmp_config_add_host_collect (host_definition_t *host,
     }
 
   data_list_len = host->data_list_len + ci->values_num;
-  data_list = (data_definition_t **) realloc (host->data_list,
+  data_list = realloc (host->data_list,
       sizeof (data_definition_t *) * data_list_len);
   if (data_list == NULL)
     return (-1);
@@ -646,16 +645,18 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
   char cb_name[DATA_MAX_NAME_LEN];
   user_data_t cb_data;
 
-  hd = (host_definition_t *) malloc (sizeof (host_definition_t));
+  hd = calloc (1, sizeof (*hd));
   if (hd == NULL)
     return (-1);
-  memset (hd, '\0', sizeof (host_definition_t));
   hd->version = 2;
   C_COMPLAIN_INIT (&hd->complaint);
 
   status = cf_util_get_string(ci, &hd->name);
   if (status != 0)
+  {
+    sfree (hd);
     return status;
+  }
 
   hd->sess_handle = NULL;
   hd->interval = 0;
@@ -924,8 +925,7 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
     tmp_unsigned = (uint32_t) *vl->val.integer;
     tmp_signed = (int32_t) *vl->val.integer;
 
-    if ((vl->type == ASN_INTEGER)
-        || (vl->type == ASN_GAUGE))
+    if (vl->type == ASN_INTEGER)
       prefer_signed = 1;
 
     DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
@@ -1104,6 +1104,14 @@ static int csnmp_strvbcopy (char *dst, /* {{{ */
     src = (char *) vb->val.string;
   else if (vb->type == ASN_BIT_STR)
     src = (char *) vb->val.bitstring;
+  else if (vb->type == ASN_IPADDRESS)
+  {
+    return ssnprintf (dst, dst_size, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"",
+          (uint8_t) vb->val.string[0],
+          (uint8_t) vb->val.string[1],
+          (uint8_t) vb->val.string[2],
+          (uint8_t) vb->val.string[3]);
+  }
   else
   {
     dst[0] = 0;
@@ -1152,13 +1160,12 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head,
 
   csnmp_oid_init (&vb_name, vb->name, vb->name_length);
 
-  il = malloc (sizeof (*il));
+  il = calloc (1, sizeof (*il));
   if (il == NULL)
   {
-    ERROR ("snmp plugin: malloc failed.");
+    ERROR ("snmp plugin: calloc failed.");
     return (-1);
   }
-  memset (il, 0, sizeof (*il));
   il->next = NULL;
 
   status = csnmp_oid_suffix (&il->suffix, &vb_name, &dd->instance.oid);
@@ -1169,7 +1176,7 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head,
   }
 
   /* Get instance name */
-  if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR))
+  if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR) || (vb->type == ASN_IPADDRESS))
   {
     char *ptr;
 
@@ -1388,7 +1395,7 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
 static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
 {
   struct snmp_pdu *req;
-  struct snmp_pdu *res;
+  struct snmp_pdu *res = NULL;
   struct variable_list *vb;
 
   const data_set_t *ds;
@@ -1597,14 +1604,13 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
           continue;
         }
 
-        vt = malloc (sizeof (*vt));
+        vt = calloc (1, sizeof (*vt));
         if (vt == NULL)
         {
-          ERROR ("snmp plugin: malloc failed.");
+          ERROR ("snmp plugin: calloc failed.");
           status = -1;
           break;
         }
-        memset (vt, 0, sizeof (*vt));
 
         vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type,
             data->scale, data->shift, host->name, data->name);
@@ -1667,7 +1673,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data)
 static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
 {
   struct snmp_pdu *req;
-  struct snmp_pdu *res;
+  struct snmp_pdu *res = NULL;
   struct variable_list *vb;
 
   const data_set_t *ds;
@@ -1700,7 +1706,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
   }
 
   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)
     return (-1);
   for (i = 0; i < vl.values_len; i++)
@@ -1729,7 +1735,6 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
   for (i = 0; i < data->values_len; i++)
     snmp_add_null_var (req, data->values[i].oid, data->values[i].oid_len);
 
-  res = NULL;
   status = snmp_sess_synch_response (host->sess_handle, req, &res);
 
   if ((status != STAT_SUCCESS) || (res == NULL))
@@ -1742,9 +1747,9 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
 
     if (res != NULL)
       snmp_free_pdu (res);
-    res = NULL;
 
     sfree (errstr);
+    sfree (vl.values);
     csnmp_host_close_session (host);
 
     return (-1);
@@ -1767,9 +1772,7 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
             data->scale, data->shift, host->name, data->name);
   } /* for (res->variables) */
 
-  if (res != NULL)
-    snmp_free_pdu (res);
-  res = NULL;
+  snmp_free_pdu (res);
 
   DEBUG ("snmp plugin: -> plugin_dispatch_values (&vl);");
   plugin_dispatch_values (&vl);
@@ -1781,8 +1784,6 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
 static int csnmp_read_host (user_data_t *ud)
 {
   host_definition_t *host;
-  cdtime_t time_start;
-  cdtime_t time_end;
   int status;
   int success;
   int i;
@@ -1792,8 +1793,6 @@ static int csnmp_read_host (user_data_t *ud)
   if (host->interval == 0)
     host->interval = plugin_get_interval ();
 
-  time_start = cdtime ();
-
   if (host->sess_handle == NULL)
     csnmp_host_open_session (host);
 
@@ -1814,16 +1813,6 @@ static int csnmp_read_host (user_data_t *ud)
       success++;
   }
 
-  time_end = cdtime ();
-  if ((time_end - time_start) > host->interval)
-  {
-    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)
     return (-1);
 
index 9a6da1d..5b7a6f1 100644 (file)
@@ -64,6 +64,7 @@ struct statsd_metric_s
 {
   metric_type_t type;
   double value;
+  derive_t counter;
   latency_counter_t *latency;
   c_avl_tree_t *set;
   unsigned long updates_num;
@@ -88,6 +89,7 @@ static _Bool conf_delete_sets     = 0;
 static double *conf_timer_percentile = NULL;
 static size_t  conf_timer_percentile_num = 0;
 
+static _Bool conf_counter_sum     = 0;
 static _Bool conf_timer_lower     = 0;
 static _Bool conf_timer_upper     = 0;
 static _Bool conf_timer_sum       = 0;
@@ -125,14 +127,13 @@ static statsd_metric_t *statsd_metric_lookup_unsafe (char const *name, /* {{{ */
     return (NULL);
   }
 
-  metric = malloc (sizeof (*metric));
+  metric = calloc (1, sizeof (*metric));
   if (metric == NULL)
   {
-    ERROR ("statsd plugin: malloc failed.");
+    ERROR ("statsd plugin: calloc failed.");
     sfree (key_copy);
     return (NULL);
   }
-  memset (metric, 0, sizeof (*metric));
 
   metric->type = type;
   metric->latency = NULL;
@@ -261,6 +262,8 @@ static int statsd_handle_counter (char const *name, /* {{{ */
   if (status != 0)
     return (status);
 
+  /* Changes to the counter are added to (statsd_metric_t*)->value. ->counter is
+   * only updated in statsd_metric_submit_unsafe(). */
   return (statsd_metric_add (name, (double) (value.gauge / scale.gauge),
         STATSD_COUNTER));
 } /* }}} int statsd_handle_counter */
@@ -561,6 +564,7 @@ static int statsd_network_init (struct pollfd **ret_fds, /* {{{ */
     if (tmp == NULL)
     {
       ERROR ("statsd plugin: realloc failed.");
+      close (fd);
       continue;
     }
     fds = tmp;
@@ -684,6 +688,8 @@ static int statsd_config (oconfig_item_t *ci) /* {{{ */
       cf_util_get_boolean (child, &conf_delete_gauges);
     else if (strcasecmp ("DeleteSets", child->key) == 0)
       cf_util_get_boolean (child, &conf_delete_sets);
+    else if (strcasecmp ("CounterSum", child->key) == 0)
+      cf_util_get_boolean (child, &conf_counter_sum);
     else if (strcasecmp ("TimerLower", child->key) == 0)
       cf_util_get_boolean (child, &conf_timer_lower);
     else if (strcasecmp ("TimerUpper", child->key) == 0)
@@ -754,8 +760,7 @@ static int statsd_metric_clear_set_unsafe (statsd_metric_t *metric) /* {{{ */
 } /* }}} int statsd_metric_clear_set_unsafe */
 
 /* Must hold metrics_lock when calling this function. */
-static int statsd_metric_submit_unsafe (char const *name, /* {{{ */
-    statsd_metric_t const *metric)
+static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metric) /* {{{ */
 {
   value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
@@ -850,8 +855,30 @@ static int statsd_metric_submit_unsafe (char const *name, /* {{{ */
     else
       values[0].gauge = (gauge_t) c_avl_size (metric->set);
   }
-  else
-    values[0].derive = (derive_t) metric->value;
+  else { /* STATSD_COUNTER */
+    gauge_t delta = nearbyint (metric->value);
+
+    /* Etsy's statsd writes counters as two metrics: a rate and the change since
+     * the last write. Since collectd does not reset its DERIVE metrics to zero,
+     * this makes little sense, but we're dispatching a "count" metric here
+     * anyway - if requested by the user - for compatibility reasons. */
+    if (conf_counter_sum)
+    {
+      sstrncpy (vl.type, "count", sizeof (vl.type));
+      values[0].gauge = delta;
+      plugin_dispatch_values (&vl);
+
+      /* restore vl.type */
+      sstrncpy (vl.type, "derive", sizeof (vl.type));
+    }
+
+    /* Rather than resetting value to zero, subtract delta so we correctly keep
+     * track of residuals. */
+    metric->value   -= delta;
+    metric->counter += (derive_t) delta;
+
+    values[0].derive = metric->counter;
+  }
 
   return (plugin_dispatch_values (&vl));
 } /* }}} int statsd_metric_submit_unsafe */
@@ -941,7 +968,7 @@ static int statsd_shutdown (void) /* {{{ */
   while (c_avl_pick (metrics_tree, &key, &value) == 0)
   {
     sfree (key);
-    sfree (value);
+    statsd_metric_free (value);
   }
   c_avl_destroy (metrics_tree);
   metrics_tree = NULL;
index cfde4ea..d714b5f 100644 (file)
@@ -82,6 +82,10 @@ static derive_t pagesize;
 static _Bool report_by_device = 0;
 /* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS */
 
+#elif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS
+/* No global variables */
+/* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS */
+
 #elif defined(VM_SWAPUSAGE)
 /* No global variables */
 /* #endif defined(VM_SWAPUSAGE) */
@@ -521,10 +525,10 @@ static int swap_read (void) /* {{{ */
                 return (0);
 
        /* Allocate and initialize the swaptbl_t structure */
-        s = (swaptbl_t *) smalloc (swap_num * sizeof (swapent_t) + sizeof (struct swaptable));
+        s = malloc (swap_num * sizeof (swapent_t) + sizeof (struct swaptable));
         if (s == NULL)
         {
-                ERROR ("swap plugin: smalloc failed.");
+                ERROR ("swap plugin: malloc failed.");
                 return (-1);
         }
 
@@ -534,7 +538,7 @@ static int swap_read (void) /* {{{ */
        s_paths = calloc (swap_num, PATH_MAX);
        if (s_paths == NULL)
        {
-               ERROR ("swap plugin: malloc failed.");
+               ERROR ("swap plugin: calloc failed.");
                sfree (s);
                return (-1);
        }
index 3f73178..849f7d1 100644 (file)
@@ -90,7 +90,7 @@ static int sl_notification (const notification_t *n,
        char  buf[1024] = "";
        size_t offset = 0;
        int log_severity;
-       char *severity_string;
+       const char *severity_string;
        int status;
 
        if (n->severity > notif_severity)
index b0bc95f..38d5f03 100644 (file)
@@ -188,9 +188,9 @@ static int tbl_config_result (tbl_t *tbl, oconfig_item_t *ci)
                return 1;
        }
 
-       res = (tbl_result_t *)realloc (tbl->results,
+       res = realloc (tbl->results,
                        (tbl->results_num + 1) * sizeof (*tbl->results));
-       if (NULL == tbl) {
+       if (res == NULL) {
                char errbuf[1024];
                log_err ("realloc failed: %s.",
                                sstrerror (errno, errbuf, sizeof (errbuf)));
@@ -254,7 +254,7 @@ static int tbl_config_table (oconfig_item_t *ci)
                return 1;
        }
 
-       tbl = (tbl_t *)realloc (tables, (tables_num + 1) * sizeof (*tables));
+       tbl = realloc (tables, (tables_num + 1) * sizeof (*tables));
        if (NULL == tbl) {
                char errbuf[1024];
                log_err ("realloc failed: %s.",
@@ -458,7 +458,7 @@ static int tbl_parse_line (tbl_t *tbl, char *line, size_t len)
        }
 
        if (i <= tbl->max_colnum) {
-               log_err ("Not enough columns in line "
+               log_warn ("Not enough columns in line "
                                "(expected at least %zu, got %zu).",
                                tbl->max_colnum + 1, i);
                return -1;
@@ -490,11 +490,11 @@ static int tbl_read_table (tbl_t *tbl)
        while (NULL != fgets (buf, sizeof (buf), fh)) {
                if ('\0' != buf[sizeof (buf) - 1]) {
                        buf[sizeof (buf) - 1] = '\0';
-                       log_err ("Table %s: Truncated line: %s", tbl->file, buf);
+                       log_warn ("Table %s: Truncated line: %s", tbl->file, buf);
                }
 
                if (0 != tbl_parse_line (tbl, buf, sizeof (buf))) {
-                       log_err ("Table %s: Failed to parse line: %s", tbl->file, buf);
+                       log_warn ("Table %s: Failed to parse line: %s", tbl->file, buf);
                        continue;
                }
        }
index 751243b..5402f66 100644 (file)
@@ -56,9 +56,9 @@ struct ctail_config_match_s
 };
 typedef struct ctail_config_match_s ctail_config_match_t;
 
-cu_tail_match_t **tail_match_list = NULL;
-size_t tail_match_list_num = 0;
-cdtime_t tail_match_list_intervals[255];
+static cu_tail_match_t **tail_match_list = NULL;
+static size_t tail_match_list_num = 0;
+static cdtime_t tail_match_list_intervals[255];
 
 static int ctail_config_add_match_dstype (ctail_config_match_t *cm,
     oconfig_item_t *ci)
@@ -236,7 +236,7 @@ static int ctail_config_add_file (oconfig_item_t *ci)
   if (tm == NULL)
   {
     ERROR ("tail plugin: tail_match_create (%s) failed.",
-       ci->values[0].value.string);
+        ci->values[0].value.string);
     return (-1);
   }
 
@@ -253,7 +253,7 @@ static int ctail_config_add_file (oconfig_item_t *ci)
     {
       status = ctail_config_add_match (tm, plugin_instance, option, interval);
       if (status == 0)
-       num_matches++;
+        num_matches++;
       /* Be mild with failed matches.. */
       status = 0;
     }
@@ -266,10 +266,12 @@ static int ctail_config_add_file (oconfig_item_t *ci)
       break;
   } /* for (i = 0; i < ci->children_num; i++) */
 
+  sfree (plugin_instance);
+
   if (num_matches == 0)
   {
     ERROR ("tail plugin: No (valid) matches found for file `%s'.",
-       ci->values[0].value.string);
+        ci->values[0].value.string);
     tail_match_destroy (tm);
     return (-1);
   }
@@ -277,8 +279,8 @@ static int ctail_config_add_file (oconfig_item_t *ci)
   {
     cu_tail_match_t **temp;
 
-    temp = (cu_tail_match_t **) realloc (tail_match_list,
-       sizeof (cu_tail_match_t *) * (tail_match_list_num + 1));
+    temp = realloc (tail_match_list,
+        sizeof (cu_tail_match_t *) * (tail_match_list_num + 1));
     if (temp == NULL)
     {
       ERROR ("tail plugin: realloc failed.");
index bb9b58a..a768ef8 100644 (file)
@@ -85,7 +85,7 @@ static int tcsv_submit (instance_definition_t *id,
 static cdtime_t parse_time (char const *tbuf)
 {
     double t;
-    char *endptr = 0;
+    char *endptr = NULL;
 
     errno = 0;
     t = strtod (tbuf, &endptr);
@@ -290,10 +290,9 @@ static int tcsv_config_add_metric(oconfig_item_t *ci){
     int status;
     int i;
 
-    md = (metric_definition_t *)malloc(sizeof(*md));
+    md = calloc(1, sizeof(*md));
     if (md == NULL)
         return (-1);
-    memset(md, 0, sizeof(*md));
     md->name = NULL;
     md->type = NULL;
     md->instance = NULL;
@@ -426,10 +425,9 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
     char cb_name[DATA_MAX_NAME_LEN];
     user_data_t cb_data;
 
-    id = malloc(sizeof(*id));
+    id = calloc(1, sizeof(*id));
     if (id == NULL)
         return (-1);
-    memset(id, 0, sizeof(*id));
     id->instance = NULL;
     id->path = NULL;
     id->metric_list = NULL;
index 14fb541..55b72ac 100644 (file)
@@ -126,13 +126,12 @@ static int tn_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   int status;
   int i;
 
-  data = (tn_data_t *) malloc (sizeof (*data));
+  data = calloc (1, sizeof (*data));
   if (data == NULL)
   {
-    ERROR ("tn_create: malloc failed.");
+    ERROR ("tn_create: calloc failed.");
     return (-ENOMEM);
   }
-  memset (data, 0, sizeof (*data));
 
   data->message = NULL;
   data->severity = 0;
index bd8f9e5..545fa35 100644 (file)
@@ -61,7 +61,7 @@ static char *tr_strdup (const char *orig) /* {{{ */
     return (NULL);
 
   sz = strlen (orig) + 1;
-  dest = (char *) malloc (sz);
+  dest = malloc (sz);
   if (dest == NULL)
     return (NULL);
 
@@ -102,13 +102,12 @@ static int tr_config_add_action (tr_action_t **dest, /* {{{ */
     return (-1);
   }
 
-  act = (tr_action_t *) malloc (sizeof (*act));
+  act = calloc (1, sizeof (*act));
   if (act == NULL)
   {
-    ERROR ("tr_config_add_action: malloc failed.");
+    ERROR ("tr_config_add_action: calloc failed.");
     return (-ENOMEM);
   }
-  memset (act, 0, sizeof (*act));
 
   act->replacement = NULL;
   act->may_be_empty = may_be_empty;
@@ -244,13 +243,12 @@ static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   int status;
   int i;
 
-  data = (tr_data_t *) malloc (sizeof (*data));
+  data = calloc (1, sizeof (*data));
   if (data == NULL)
   {
-    ERROR ("tr_create: malloc failed.");
+    ERROR ("tr_create: calloc failed.");
     return (-ENOMEM);
   }
-  memset (data, 0, sizeof (*data));
 
   data->host = NULL;
   data->plugin = NULL;
index 6169fa0..74652ff 100644 (file)
@@ -328,7 +328,7 @@ static int ts_config_add_data_source(ts_data_t *data, /* {{{ */
 
        /* Allocate space for the char pointers */
        new_data_sources_num = data->data_sources_num + ((size_t) ci->values_num);
-       temp = (char **) realloc (data->data_sources,
+       temp = realloc (data->data_sources,
                        new_data_sources_num * sizeof (char *));
        if (temp == NULL)
        {
@@ -387,13 +387,12 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
        int status;
        int i;
 
-       data = (ts_data_t *) malloc (sizeof (*data));
+       data = calloc (1, sizeof (*data));
        if (data == NULL)
        {
-               ERROR ("ts_create: malloc failed.");
+               ERROR ("ts_create: calloc failed.");
                return (-ENOMEM);
        }
-       memset (data, 0, sizeof (*data));
 
        data->factor = NAN;
        data->offset = NAN;
index daeaf8b..6115639 100644 (file)
@@ -35,9 +35,27 @@ struct ts_data_s
   char *plugin_instance;
   /* char *type; */
   char *type_instance;
+  meta_data_t *meta;
 };
 typedef struct ts_data_s ts_data_t;
 
+static int ts_util_get_key_and_string_wo_strdup (const oconfig_item_t *ci, char **ret_key, char **ret_string) /* {{{ */
+{
+  if ((ci->values_num != 2)
+      || (ci->values[0].type != OCONFIG_TYPE_STRING)
+      || (ci->values[1].type != OCONFIG_TYPE_STRING))
+  {
+    ERROR ("ts_util_get_key_and_string_wo_strdup: The %s option requires "
+        "exactly two string argument.", ci->key);
+    return (-1);
+  }
+
+  *ret_key = ci->values[0].value.string;
+  *ret_string = ci->values[1].value.string;
+
+  return (0);
+} /* }}} int ts_util_get_key_and_string_wo_strdup */
+
 static int ts_config_add_string (char **dest, /* {{{ */
     const oconfig_item_t *ci, int may_be_empty)
 {
@@ -60,6 +78,44 @@ static int ts_config_add_string (char **dest, /* {{{ */
   return (0);
 } /* }}} int ts_config_add_string */
 
+static int ts_config_add_meta (meta_data_t **dest, /* {{{ */
+    const oconfig_item_t *ci, int may_be_empty)
+{
+  char *key = NULL;
+  char *string = NULL;
+  int status;
+
+  status = ts_util_get_key_and_string_wo_strdup (ci, &key, &string);
+  if (status != 0)
+    return (status);
+
+  if (strlen (key) == 0)
+  {
+    ERROR ("Target `set': The `%s' option does not accept empty string as first argument.",
+        ci->key);
+    return (-1);
+  }
+
+  if (!may_be_empty && (strlen (string) == 0))
+  {
+    ERROR ("Target `set': The `%s' option does not accept empty string as second argument.",
+        ci->key);
+    return (-1);
+  }
+
+  if ((*dest) == NULL)
+  {
+    // Create a new meta_data_t
+    if ((*dest = meta_data_create()) == NULL)
+    {
+      ERROR ("Target `set': failed to create a meta data for `%s'.", ci->key);
+      return (-1);
+    }
+  }
+
+  return (meta_data_add_string (*dest, key, string));
+} /* }}} int ts_config_add_meta */
+
 static int ts_destroy (void **user_data) /* {{{ */
 {
   ts_data_t *data;
@@ -76,6 +132,7 @@ static int ts_destroy (void **user_data) /* {{{ */
   free (data->plugin_instance);
   /* free (data->type); */
   free (data->type_instance);
+  meta_data_destroy(data->meta);
   free (data);
 
   return (0);
@@ -87,19 +144,19 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   int status;
   int i;
 
-  data = (ts_data_t *) malloc (sizeof (*data));
+  data = calloc (1, sizeof (*data));
   if (data == NULL)
   {
-    ERROR ("ts_create: malloc failed.");
+    ERROR ("ts_create: calloc failed.");
     return (-ENOMEM);
   }
-  memset (data, 0, sizeof (*data));
 
   data->host = NULL;
   data->plugin = NULL;
   data->plugin_instance = NULL;
   /* data->type = NULL; */
   data->type_instance = NULL;
+  data->meta = NULL;
 
   status = 0;
   for (i = 0; i < ci->children_num; i++)
@@ -124,6 +181,9 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
     else if (strcasecmp ("TypeInstance", child->key) == 0)
       status = ts_config_add_string (&data->type_instance, child,
           /* may be empty = */ 1);
+    else if (strcasecmp ("MetaDataSet", child->key) == 0)
+      status = ts_config_add_meta (&data->meta, child,
+          /* may be empty = */ 1);
     else
     {
       ERROR ("Target `set': The `%s' configuration option is not understood "
@@ -142,10 +202,12 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
         && (data->plugin == NULL)
         && (data->plugin_instance == NULL)
         /* && (data->type == NULL) */
-        && (data->type_instance == NULL))
+        && (data->type_instance == NULL)
+        && (data->meta == NULL))
     {
       ERROR ("Target `set': You need to set at least one of `Host', "
-          "`Plugin', `PluginInstance' or `TypeInstance'.");
+          "`Plugin', `PluginInstance', `TypeInstance', "
+          "`MetaDataSet' or `MetaDataEval'.");
       status = -1;
     }
 
@@ -177,6 +239,11 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
     return (-EINVAL);
   }
 
+  if (data->meta != NULL)
+  {
+    meta_data_clone_merge(&(vl->meta), data->meta);
+  }
+
 #define SET_FIELD(f) if (data->f != NULL) { sstrncpy (vl->f, data->f, sizeof (vl->f)); }
   SET_FIELD (host);
   SET_FIELD (plugin);
index 8f40be6..6bc3384 100644 (file)
@@ -283,7 +283,7 @@ static uint32_t count_total[TCP_STATE_MAX + 1];
 static uint32_t sequence_number = 0;
 #endif
 
-enum
+static enum
 {
   SRC_DUNNO,
   SRC_NETLINK,
@@ -385,10 +385,9 @@ static port_entry_t *conn_get_port_entry (uint16_t port, int create)
 
   if ((ret == NULL) && (create != 0))
   {
-    ret = (port_entry_t *) malloc (sizeof (port_entry_t));
+    ret = calloc (1, sizeof (*ret));
     if (ret == NULL)
       return (NULL);
-    memset (ret, '\0', sizeof (port_entry_t));
 
     ret->port = port;
     ret->next = port_list_head;
@@ -832,7 +831,7 @@ static int conn_read (void)
     return (-1);
   }
 
-  buffer = (char *) malloc (buffer_len);
+  buffer = malloc (buffer_len);
   if (buffer == NULL)
   {
     ERROR ("tcpconns plugin: malloc failed.");
index 56e8d14..41f58e5 100644 (file)
@@ -83,13 +83,12 @@ static int tss2_add_vserver (int vserver_port)
        }
 
        /* Allocate memory */
-       entry = (vserver_list_t *) malloc (sizeof (vserver_list_t));
+       entry = calloc (1, sizeof (*entry));
        if (entry == NULL)
        {
-               ERROR ("teamspeak2 plugin: malloc failed.");
+               ERROR ("teamspeak2 plugin: calloc failed.");
                return (-1);
        }
-       memset (entry, 0, sizeof (vserver_list_t));
 
        /* Save data */
        entry->port = vserver_port;
@@ -140,7 +139,7 @@ static void tss2_submit_gauge (const char *plugin_instance,
        if (type_instance != NULL)
                sstrncpy (vl.type_instance, type_instance,
                                sizeof (vl.type_instance));
-       
+
        plugin_dispatch_values (&vl);
 } /* void tss2_submit_gauge */
 
@@ -257,6 +256,7 @@ static int tss2_get_socket (FILE **ret_read_fh, FILE **ret_write_fh)
                        WARNING ("teamspeak2 plugin: connect failed: %s",
                                        sstrerror (errno, errbuf, sizeof (errbuf)));
                        close (sd);
+                       sd = -1;
                        continue;
                }
 
@@ -351,7 +351,7 @@ static int tss2_receive_line (FILE *fh, char *buffer, int buffer_size)
         * Receive a single line from the given file object
         */
        char *temp;
-        
+
        /*
         * fgets is blocking but much easier then doing anything else
         * TODO: Non-blocking Version would be safer
@@ -434,7 +434,7 @@ static int tss2_vserver_gapl (FILE *read_fh, FILE *write_fh,
                char buffer[4096];
                char *value;
                char *endptr = NULL;
-               
+
                status = tss2_receive_line (read_fh, buffer, sizeof (buffer));
                if (status != 0)
                {
@@ -445,7 +445,7 @@ static int tss2_vserver_gapl (FILE *read_fh, FILE *write_fh,
                        return (-1);
                }
                buffer[sizeof (buffer) - 1] = 0;
-               
+
                if (strncmp ("average_packet_loss=", buffer,
                                        strlen ("average_packet_loss=")) == 0)
                {
@@ -461,9 +461,9 @@ static int tss2_vserver_gapl (FILE *read_fh, FILE *write_fh,
                                }
                                value++;
                        }
-                       
+
                        value = &buffer[20];
-                       
+
                        packet_loss = strtod (value, &endptr);
                        if (value == endptr)
                        {
@@ -488,7 +488,7 @@ static int tss2_vserver_gapl (FILE *read_fh, FILE *write_fh,
                                        buffer);
                }
        }
-       
+
        *ret_value = packet_loss;
        return (0);
 } /* int tss2_vserver_gapl */
@@ -558,7 +558,7 @@ static int tss2_read_vserver (vserver_list_t *vserver)
                char *key;
                char *value;
                char *endptr = NULL;
-               
+
                /* Read one line of the server's answer */
                status = tss2_receive_line (read_fh, buffer, sizeof (buffer));
                if (status != 0)
@@ -753,7 +753,7 @@ static int tss2_config (const char *key, const char *value)
        {
                /* Server variable found */
                int status;
-               
+
                status = tss2_add_vserver (atoi (value));
                if (status != 0)
                        return (1);
@@ -803,7 +803,7 @@ static int tss2_read (void)
                        continue;
                }
        }
-       
+
        if (success == 0)
                return (-1);
     return (0);
@@ -832,7 +832,7 @@ static int tss2_shutdown(void)
        /* Get rid of the configuration */
        sfree (config_host);
        sfree (config_port);
-       
+
     return (0);
 } /* int tss2_shutdown */
 
index e76b3c9..37ab85d 100644 (file)
--- a/src/ted.c
+++ b/src/ted.c
@@ -263,7 +263,7 @@ static int ted_open_device (void)
     return (0);
 } /* int ted_open_device */
 
-static void ted_submit (char *type, double value)
+static void ted_submit (const char *type, double value)
 {
     value_t values[1];
     value_list_t vl = VALUE_LIST_INIT;
index 0c415e4..2e4bf05 100644 (file)
@@ -24,6 +24,9 @@
  *   Florian octo Forster <octo at collectd.org>
  */
 
+#ifndef TESTING_H
+#define TESTING_H 1
+
 #include <inttypes.h>
 
 static int fail_count__ = 0;
@@ -33,7 +36,7 @@ static int check_count__ = 0;
 # define DBL_PRECISION 1e-12
 #endif
 
-#define DEF_TEST(func) static int test_##func ()
+#define DEF_TEST(func) static int test_##func (void)
 
 #define RUN_TEST(func) do { \
   int status; \
@@ -109,3 +112,5 @@ static int check_count__ = 0;
   status_ = (long) (expr); \
   OK1(status_ == 0L, #expr); \
 } while (0)
+
+#endif /* TESTING_H */
index 27c92bc..54311a6 100644 (file)
@@ -35,8 +35,8 @@ static const char *config_keys[] = {
        "ForceUseProcfs"
 };
 
-const char *const dirname_sysfs = "/sys/class/thermal";
-const char *const dirname_procfs = "/proc/acpi/thermal_zone";
+static const char *const dirname_sysfs = "/sys/class/thermal";
+static const char *const dirname_procfs = "/proc/acpi/thermal_zone";
 
 static _Bool force_procfs = 0;
 static ignorelist_t *device_list;
index 38c7efb..e849b1d 100644 (file)
@@ -70,7 +70,7 @@ static int ut_threshold_add (const threshold_t *th)
     return (-1);
   }
 
-  th_copy = (threshold_t *) malloc (sizeof (threshold_t));
+  th_copy = malloc (sizeof (*th_copy));
   if (th_copy == NULL)
   {
     sfree (name_copy);
@@ -78,7 +78,6 @@ static int ut_threshold_add (const threshold_t *th)
     return (-1);
   }
   memcpy (th_copy, th, sizeof (threshold_t));
-  th_ptr = NULL;
 
   DEBUG ("ut_threshold_add: Adding entry `%s'", name);
 
@@ -868,10 +867,11 @@ static int ut_missing (const value_list_t *vl,
   return (0);
 } /* }}} int ut_missing */
 
-int ut_config (oconfig_item_t *ci)
+static int ut_config (oconfig_item_t *ci)
 { /* {{{ */
   int i;
   int status = 0;
+  int old_size = c_avl_size (threshold_tree);
 
   threshold_t th;
 
@@ -915,7 +915,9 @@ int ut_config (oconfig_item_t *ci)
       break;
   }
 
-  if (c_avl_size (threshold_tree) > 0) {
+  /* register callbacks if this is the first time we see a valid config */
+  if ((old_size == 0) && (c_avl_size (threshold_tree) > 0))
+  {
     plugin_register_missing ("threshold", ut_missing,
         /* user data = */ NULL);
     plugin_register_write ("threshold", ut_check_threshold,
index 7fa621b..befbd50 100644 (file)
@@ -78,7 +78,7 @@ static int tt_config (const char *key, const char *value)
        return (0);
 }
 
-static void printerr()
+static void printerr (void)
 {
        int ecode = tcrdbecode(rdb);
        ERROR ("tokyotyrant plugin: error: %d, %s",
@@ -106,8 +106,8 @@ static void tt_submit (gauge_t val, const char* type)
 
 static void tt_open_db (void)
 {
-       char* host = NULL;
-       int   port = DEFAULT_PORT;
+       const char *host;
+       int         port = DEFAULT_PORT;
 
        if (rdb != NULL)
                return;
index 42fed52..bd5d86c 100644 (file)
@@ -457,7 +457,7 @@ delta_core(struct core_data *delta, const struct core_data *new, const struct co
  */
 static inline int __attribute__((warn_unused_result))
 delta_thread(struct thread_data *delta, const struct thread_data *new, const struct thread_data *old,
-       const struct core_data *core_delta)
+       const struct core_data *cdelta)
 {
        delta->tsc = new->tsc - old->tsc;
 
@@ -491,12 +491,12 @@ delta_thread(struct thread_data *delta, const struct thread_data *new, const str
         * it is possible for mperf's non-halted cycles + idle states
         * to exceed TSC's all cycles: show c1 = 0% in that case.
         */
-       if ((delta->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > delta->tsc)
+       if ((delta->mperf + cdelta->c3 + cdelta->c6 + cdelta->c7) > delta->tsc)
                delta->c1 = 0;
        else {
                /* normal case, derive c1 */
-               delta->c1 = delta->tsc - delta->mperf - core_delta->c3
-                       - core_delta->c6 - core_delta->c7;
+               delta->c1 = delta->tsc - delta->mperf - cdelta->c3
+                       - cdelta->c6 - cdelta->c7;
        }
 
        if (delta->mperf == 0) {
@@ -805,7 +805,7 @@ guess:
  * Identify the functionality of the CPU
  */
 static int __attribute__((warn_unused_result))
-probe_cpu()
+probe_cpu(void)
 {
        unsigned int eax, ebx, ecx, edx, max_level;
        unsigned int fms, family, model;
@@ -1037,6 +1037,7 @@ parse_int_file(const char *fmt, ...)
        }
        if (fscanf(filep, "%d", &value) != 1) {
                ERROR("turbostat plugin: Failed to parse number from '%s'", path);
+               fclose(filep);
                return -1;
        }
        fclose(filep);
@@ -1146,7 +1147,7 @@ allocate_cpu_set(cpu_set_t ** set, size_t * size) {
  * Build a local representation of the cpu distribution
  */
 static int __attribute__((warn_unused_result))
-topology_probe()
+topology_probe(void)
 {
        unsigned int i;
        int ret;
@@ -1341,7 +1342,7 @@ free_all_buffers(void)
 
        CPU_FREE(cpu_present_set);
        cpu_present_set = NULL;
-       cpu_present_set = 0;
+       cpu_present_setsize = 0;
 
        CPU_FREE(cpu_affinity_set);
        cpu_affinity_set = NULL;
@@ -1515,7 +1516,7 @@ check_permissions(void)
        }
 
        if (euidaccess("/dev/cpu/0/msr", R_OK)) {
-               WARNING("turbostat plugin: Collectd cannot open"
+               WARNING("turbostat plugin: Collectd cannot open "
                        "/dev/cpu/0/msr. If you don't want to run collectd as "
                        "root, you need to change the ownership (chown) and "
                        "permissions on /dev/cpu/*/msr to allow such access");
@@ -1538,8 +1539,8 @@ turbostat_init(void)
        int ret;
 
        if (stat("/dev/cpu/0/msr", &sb)) {
-               ERROR("turbostat plugin: Initialization failed: /dev/cpu/0/msr"
-                     " does not exist while the CPU supports MSR. You may be "
+               ERROR("turbostat plugin: Initialization failed: /dev/cpu/0/msr "
+                     "does not exist while the CPU supports MSR. You may be "
                      "missing the corresponding kernel module, please try '# "
                      "modprobe msr'");
                return -1;
index 2fd59e5..0c5a433 100644 (file)
-absolute               value:ABSOLUTE:0:U
-apache_bytes           value:DERIVE:0:U
-apache_connections     value:GAUGE:0:65535
-apache_idle_workers    value:GAUGE:0:65535
-apache_requests                value:DERIVE:0:U
-apache_scoreboard      value:GAUGE:0:65535
-ath_nodes              value:GAUGE:0:65535
-ath_stat               value:DERIVE:0:U
-backends               value:GAUGE:0:65535
-bitrate                        value:GAUGE:0:4294967295
-blocked_clients value:GAUGE:0:U
-bytes                  value:GAUGE:0:U
-cache_eviction         value:DERIVE:0:U
-cache_operation                value:DERIVE:0:U
-cache_ratio            value:GAUGE:0:100
-cache_result           value:DERIVE:0:U
-cache_size             value:GAUGE:0:1125899906842623
-ceph_bytes             value:GAUGE:U:U
-ceph_latency   value:GAUGE:U:U
-ceph_rate                      value:DERIVE:0:U
-changes_since_last_save   value:GAUGE:0:U
-charge                 value:GAUGE:0:U
-compression_ratio      value:GAUGE:0:2
-compression            uncompressed:DERIVE:0:U, compressed:DERIVE:0:U
-connections            value:DERIVE:0:U
-conntrack              value:GAUGE:0:4294967295
-contextswitch          value:DERIVE:0:U
-count                  value:GAUGE:0:U
-counter                        value:COUNTER:U:U
-cpufreq                        value:GAUGE:0:U
-cpu                    value:DERIVE:0:U
-current_connections    value:GAUGE:0:U
-current_sessions       value:GAUGE:0:U
-current                        value:GAUGE:U:U
-delay                  value:GAUGE:-1000000:1000000
-derive                 value:DERIVE:0:U
-df_complex             value:GAUGE:0:U
-df_inodes              value:GAUGE:0:U
-df                     used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
-disk_latency           read:GAUGE:0:U, write:GAUGE:0:U
-disk_merged            read:DERIVE:0:U, write:DERIVE:0:U
-disk_octets            read:DERIVE:0:U, write:DERIVE:0:U
-disk_ops_complex       value:DERIVE:0:U
-disk_ops               read:DERIVE:0:U, write:DERIVE:0:U
-disk_time              read:DERIVE:0:U, write:DERIVE:0:U
-disk_io_time           io_time:DERIVE:0:U, weighted_io_time:DERIVE:0:U
-dns_answer             value:DERIVE:0:U
-dns_notify             value:DERIVE:0:U
-dns_octets             queries:DERIVE:0:U, responses:DERIVE:0:U
-dns_opcode             value:DERIVE:0:U
-dns_qtype_cached       value:GAUGE:0:4294967295
-dns_qtype              value:DERIVE:0:U
-dns_query              value:DERIVE:0:U
-dns_question           value:DERIVE:0:U
-dns_rcode              value:DERIVE:0:U
-dns_reject             value:DERIVE:0:U
-dns_request            value:DERIVE:0:U
-dns_resolver           value:DERIVE:0:U
-dns_response           value:DERIVE:0:U
-dns_transfer           value:DERIVE:0:U
-dns_update             value:DERIVE:0:U
-dns_zops               value:DERIVE:0:U
-drbd_resource  value:DERIVE:0:U
-duration               seconds:GAUGE:0:U
-email_check            value:GAUGE:0:U
-email_count            value:GAUGE:0:U
-email_size             value:GAUGE:0:U
-entropy                        value:GAUGE:0:4294967295
-expired_keys    value:GAUGE:0:U
-fanspeed               value:GAUGE:0:U
-file_handles           value:GAUGE:0:U
-file_size              value:GAUGE:0:U
-files                  value:GAUGE:0:U
-flow                   value:GAUGE:0:U
-fork_rate              value:DERIVE:0:U
-frequency_offset       value:GAUGE:-1000000:1000000
-frequency              value:GAUGE:0:U
-fscache_stat           value:DERIVE:0:U
-gauge                  value:GAUGE:U:U
-hash_collisions                value:DERIVE:0:U
-http_request_methods   value:DERIVE:0:U
-http_requests          value:DERIVE:0:U
-http_response_codes    value:DERIVE:0:U
-humidity               value:GAUGE:0:100
-if_collisions          value:DERIVE:0:U
-if_dropped             rx:DERIVE:0:U, tx:DERIVE:0:U
-if_errors              rx:DERIVE:0:U, tx:DERIVE:0:U
-if_multicast           value:DERIVE:0:U
-if_octets              rx:DERIVE:0:U, tx:DERIVE:0:U
-if_packets             rx:DERIVE:0:U, tx:DERIVE:0:U
-if_rx_errors           value:DERIVE:0:U
-if_rx_octets           value:DERIVE:0:U
-if_tx_errors           value:DERIVE:0:U
-if_tx_octets           value:DERIVE:0:U
-invocations            value:DERIVE:0:U
-io_octets              rx:DERIVE:0:U, tx:DERIVE:0:U
-io_packets             rx:DERIVE:0:U, tx:DERIVE:0:U
-ipt_bytes              value:DERIVE:0:U
-ipt_packets            value:DERIVE:0:U
-irq                    value:DERIVE:0:U
-latency                        value:GAUGE:0:U
-links                  value:GAUGE:0:U
-load                   shortterm:GAUGE:0:5000, midterm:GAUGE:0:5000, longterm:GAUGE:0:5000
-md_disks               value:GAUGE:0:U
-memcached_command      value:DERIVE:0:U
-memcached_connections  value:GAUGE:0:U
-memcached_items                value:GAUGE:0:U
-memcached_octets       rx:DERIVE:0:U, tx:DERIVE:0:U
-memcached_ops          value:DERIVE:0:U
-memory                 value:GAUGE:0:281474976710656
-memory_lua             value:GAUGE:0:281474976710656
-multimeter             value:GAUGE:U:U
-mutex_operations       value:DERIVE:0:U
-mysql_commands         value:DERIVE:0:U
-mysql_handler          value:DERIVE:0:U
-mysql_locks            value:DERIVE:0:U
-mysql_log_position     value:DERIVE:0:U
-mysql_octets           rx:DERIVE:0:U, tx:DERIVE:0:U
-mysql_bpool_pages      value:GAUGE:0:U
-mysql_bpool_bytes      value:GAUGE:0:U
-mysql_bpool_counters   value:DERIVE:0:U
-mysql_innodb_data      value:DERIVE:0:U
-mysql_innodb_dblwr     value:DERIVE:0:U
-mysql_innodb_log       value:DERIVE:0:U
-mysql_innodb_pages     value:DERIVE:0:U
-mysql_innodb_row_lock  value:DERIVE:0:U
-mysql_innodb_rows      value:DERIVE:0:U
-mysql_select           value:DERIVE:0:U
-mysql_sort             value:DERIVE:0:U
-nfs_procedure          value:DERIVE:0:U
-nginx_connections      value:GAUGE:0:U
-nginx_requests         value:DERIVE:0:U
-node_octets            rx:DERIVE:0:U, tx:DERIVE:0:U
-node_rssi              value:GAUGE:0:255
-node_stat              value:DERIVE:0:U
-node_tx_rate           value:GAUGE:0:127
-objects                        value:GAUGE:0:U
-operations             value:DERIVE:0:U
-packets                        value:DERIVE:0:U
-pending_operations     value:GAUGE:0:U
-percent                        value:GAUGE:0:100.1
-percent_bytes          value:GAUGE:0:100.1
-percent_inodes         value:GAUGE:0:100.1
-pf_counters            value:DERIVE:0:U
-pf_limits              value:DERIVE:0:U
-pf_source              value:DERIVE:0:U
-pf_states              value:GAUGE:0:U
-pf_state               value:DERIVE:0:U
-pg_blks                        value:DERIVE:0:U
-pg_db_size             value:GAUGE:0:U
-pg_n_tup_c             value:DERIVE:0:U
-pg_n_tup_g             value:GAUGE:0:U
-pg_numbackends         value:GAUGE:0:U
-pg_scan                        value:DERIVE:0:U
-pg_xact                        value:DERIVE:0:U
-ping_droprate          value:GAUGE:0:100
-ping_stddev            value:GAUGE:0:65535
-ping                   value:GAUGE:0:65535
-players                        value:GAUGE:0:1000000
-power                  value:GAUGE:0:U
-pressure                       value:GAUGE:0:U
-protocol_counter       value:DERIVE:0:U
-ps_code                        value:GAUGE:0:9223372036854775807
-ps_count               processes:GAUGE:0:1000000, threads:GAUGE:0:1000000
-ps_cputime             user:DERIVE:0:U, syst:DERIVE:0:U
-ps_data                        value:GAUGE:0:9223372036854775807
-ps_disk_octets         read:DERIVE:0:U, write:DERIVE:0:U
-ps_disk_ops            read:DERIVE:0:U, write:DERIVE:0:U
-ps_pagefaults          minflt:DERIVE:0:U, majflt:DERIVE:0:U
-ps_rss                 value:GAUGE:0:9223372036854775807
-ps_stacksize           value:GAUGE:0:9223372036854775807
-ps_state               value:GAUGE:0:65535
-ps_vm                  value:GAUGE:0:9223372036854775807
-pubsub        value:GAUGE:0:U
-queue_length           value:GAUGE:0:U
-records                        value:GAUGE:0:U
-requests               value:GAUGE:0:U
-response_time          value:GAUGE:0:U
-response_code          value:GAUGE:0:U
-route_etx              value:GAUGE:0:U
-route_metric           value:GAUGE:0:U
-routes                 value:GAUGE:0:U
-segments               value:GAUGE:0:65535
-serial_octets          rx:DERIVE:0:U, tx:DERIVE:0:U
-signal_noise           value:GAUGE:U:0
-signal_power           value:GAUGE:U:0
-signal_quality         value:GAUGE:0:U
-smart_poweron          value:GAUGE:0:U
-smart_powercycles      value:GAUGE:0:U
-smart_badsectors       value:GAUGE:0:U
-smart_temperature      value:GAUGE:-300:300
+absolute                value:ABSOLUTE:0:U
+apache_bytes            value:DERIVE:0:U
+apache_connections      value:GAUGE:0:65535
+apache_idle_workers     value:GAUGE:0:65535
+apache_requests         value:DERIVE:0:U
+apache_scoreboard       value:GAUGE:0:65535
+ath_nodes               value:GAUGE:0:65535
+ath_stat                value:DERIVE:0:U
+backends                value:GAUGE:0:65535
+bitrate                 value:GAUGE:0:4294967295
+blocked_clients         value:GAUGE:0:U
+bytes                   value:GAUGE:0:U
+cache_eviction          value:DERIVE:0:U
+cache_operation         value:DERIVE:0:U
+cache_ratio             value:GAUGE:0:100
+cache_result            value:DERIVE:0:U
+cache_size              value:GAUGE:0:1125899906842623
+capacity                value:GAUGE:0:U
+ceph_bytes              value:GAUGE:U:U
+ceph_latency            value:GAUGE:U:U
+ceph_rate               value:DERIVE:0:U
+changes_since_last_save value:GAUGE:0:U
+charge                  value:GAUGE:0:U
+compression             uncompressed:DERIVE:0:U, compressed:DERIVE:0:U
+compression_ratio       value:GAUGE:0:2
+connections             value:DERIVE:0:U
+conntrack               value:GAUGE:0:4294967295
+contextswitch           value:DERIVE:0:U
+count                   value:GAUGE:0:U
+counter                 value:COUNTER:U:U
+cpu                     value:DERIVE:0:U
+cpufreq                 value:GAUGE:0:U
+current                 value:GAUGE:U:U
+current_connections     value:GAUGE:0:U
+current_sessions        value:GAUGE:0:U
+delay                   value:GAUGE:-1000000:1000000
+derive                  value:DERIVE:0:U
+df                      used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
+df_complex              value:GAUGE:0:U
+df_inodes               value:GAUGE:0:U
+disk_io_time            io_time:DERIVE:0:U, weighted_io_time:DERIVE:0:U
+disk_latency            read:GAUGE:0:U, write:GAUGE:0:U
+disk_merged             read:DERIVE:0:U, write:DERIVE:0:U
+disk_octets             read:DERIVE:0:U, write:DERIVE:0:U
+disk_ops                read:DERIVE:0:U, write:DERIVE:0:U
+disk_ops_complex        value:DERIVE:0:U
+disk_time               read:DERIVE:0:U, write:DERIVE:0:U
+dns_answer              value:DERIVE:0:U
+dns_notify              value:DERIVE:0:U
+dns_octets              queries:DERIVE:0:U, responses:DERIVE:0:U
+dns_opcode              value:DERIVE:0:U
+dns_qtype               value:DERIVE:0:U
+dns_qtype_cached        value:GAUGE:0:4294967295
+dns_query               value:DERIVE:0:U
+dns_question            value:DERIVE:0:U
+dns_rcode               value:DERIVE:0:U
+dns_reject              value:DERIVE:0:U
+dns_request             value:DERIVE:0:U
+dns_resolver            value:DERIVE:0:U
+dns_response            value:DERIVE:0:U
+dns_transfer            value:DERIVE:0:U
+dns_update              value:DERIVE:0:U
+dns_zops                value:DERIVE:0:U
+drbd_resource           value:DERIVE:0:U
+duration                seconds:GAUGE:0:U
+email_check             value:GAUGE:0:U
+email_count             value:GAUGE:0:U
+email_size              value:GAUGE:0:U
+entropy                 value:GAUGE:0:4294967295
+evicted_keys            value:DERIVE:0:U
+expired_keys            value:DERIVE:0:U
+fanspeed                value:GAUGE:0:U
+file_handles            value:GAUGE:0:U
+file_size               value:GAUGE:0:U
+files                   value:GAUGE:0:U
+flow                    value:GAUGE:0:U
+fork_rate               value:DERIVE:0:U
+frequency               value:GAUGE:0:U
+frequency_offset        value:GAUGE:-1000000:1000000
+fscache_stat            value:DERIVE:0:U
+gauge                   value:GAUGE:U:U
+hash_collisions         value:DERIVE:0:U
+http_request_methods    value:DERIVE:0:U
+http_requests           value:DERIVE:0:U
+http_response_codes     value:DERIVE:0:U
+humidity                value:GAUGE:0:100
+if_collisions           value:DERIVE:0:U
+if_dropped              rx:DERIVE:0:U, tx:DERIVE:0:U
+if_errors               rx:DERIVE:0:U, tx:DERIVE:0:U
+if_multicast            value:DERIVE:0:U
+if_octets               rx:DERIVE:0:U, tx:DERIVE:0:U
+if_packets              rx:DERIVE:0:U, tx:DERIVE:0:U
+if_rx_errors            value:DERIVE:0:U
+if_rx_octets            value:DERIVE:0:U
+if_tx_errors            value:DERIVE:0:U
+if_tx_octets            value:DERIVE:0:U
+invocations             value:DERIVE:0:U
+io_octets               rx:DERIVE:0:U, tx:DERIVE:0:U
+io_packets              rx:DERIVE:0:U, tx:DERIVE:0:U
+ipt_bytes               value:DERIVE:0:U
+ipt_packets             value:DERIVE:0:U
+irq                     value:DERIVE:0:U
+latency                 value:GAUGE:0:U
+links                   value:GAUGE:0:U
+load                    shortterm:GAUGE:0:5000, midterm:GAUGE:0:5000, longterm:GAUGE:0:5000
+md_disks                value:GAUGE:0:U
+memcached_command       value:DERIVE:0:U
+memcached_connections   value:GAUGE:0:U
+memcached_items         value:GAUGE:0:U
+memcached_octets        rx:DERIVE:0:U, tx:DERIVE:0:U
+memcached_ops           value:DERIVE:0:U
+memory                  value:GAUGE:0:281474976710656
+memory_lua              value:GAUGE:0:281474976710656
+memory_throttle_count   value:DERIVE:0:U
+multimeter              value:GAUGE:U:U
+mutex_operations        value:DERIVE:0:U
+mysql_bpool_bytes       value:GAUGE:0:U
+mysql_bpool_counters    value:DERIVE:0:U
+mysql_bpool_pages       value:GAUGE:0:U
+mysql_commands          value:DERIVE:0:U
+mysql_handler           value:DERIVE:0:U
+mysql_innodb_data       value:DERIVE:0:U
+mysql_innodb_dblwr      value:DERIVE:0:U
+mysql_innodb_log        value:DERIVE:0:U
+mysql_innodb_pages      value:DERIVE:0:U
+mysql_innodb_row_lock   value:DERIVE:0:U
+mysql_innodb_rows       value:DERIVE:0:U
+mysql_locks             value:DERIVE:0:U
+mysql_log_position      value:DERIVE:0:U
+mysql_octets            rx:DERIVE:0:U, tx:DERIVE:0:U
+mysql_select            value:DERIVE:0:U
+mysql_sort              value:DERIVE:0:U
+mysql_sort_merge_passes value:DERIVE:0:U
+mysql_sort_rows         value:DERIVE:0:U
+nfs_procedure           value:DERIVE:0:U
+nginx_connections       value:GAUGE:0:U
+nginx_requests          value:DERIVE:0:U
+node_octets             rx:DERIVE:0:U, tx:DERIVE:0:U
+node_rssi               value:GAUGE:0:255
+node_stat               value:DERIVE:0:U
+node_tx_rate            value:GAUGE:0:127
+objects                 value:GAUGE:0:U
+operations              value:DERIVE:0:U
+packets                 value:DERIVE:0:U
+pending_operations      value:GAUGE:0:U
+percent                 value:GAUGE:0:100.1
+percent_bytes           value:GAUGE:0:100.1
+percent_inodes          value:GAUGE:0:100.1
+pf_counters             value:DERIVE:0:U
+pf_limits               value:DERIVE:0:U
+pf_source               value:DERIVE:0:U
+pf_state                value:DERIVE:0:U
+pf_states               value:GAUGE:0:U
+pg_blks                 value:DERIVE:0:U
+pg_db_size              value:GAUGE:0:U
+pg_n_tup_c              value:DERIVE:0:U
+pg_n_tup_g              value:GAUGE:0:U
+pg_numbackends          value:GAUGE:0:U
+pg_scan                 value:DERIVE:0:U
+pg_xact                 value:DERIVE:0:U
+ping                    value:GAUGE:0:65535
+ping_droprate           value:GAUGE:0:100
+ping_stddev             value:GAUGE:0:65535
+players                 value:GAUGE:0:1000000
+power                   value:GAUGE:0:U
+pressure                value:GAUGE:0:U
+protocol_counter        value:DERIVE:0:U
+ps_code                 value:GAUGE:0:9223372036854775807
+ps_count                processes:GAUGE:0:1000000, threads:GAUGE:0:1000000
+ps_cputime              user:DERIVE:0:U, syst:DERIVE:0:U
+ps_data                 value:GAUGE:0:9223372036854775807
+ps_disk_octets          read:DERIVE:0:U, write:DERIVE:0:U
+ps_disk_ops             read:DERIVE:0:U, write:DERIVE:0:U
+ps_pagefaults           minflt:DERIVE:0:U, majflt:DERIVE:0:U
+ps_rss                  value:GAUGE:0:9223372036854775807
+ps_stacksize            value:GAUGE:0:9223372036854775807
+ps_state                value:GAUGE:0:65535
+ps_vm                   value:GAUGE:0:9223372036854775807
+pubsub                  value:GAUGE:0:U
+queue_length            value:GAUGE:0:U
+records                 value:GAUGE:0:U
+requests                value:GAUGE:0:U
+response_code           value:GAUGE:0:U
+response_time           value:GAUGE:0:U
+route_etx               value:GAUGE:0:U
+route_metric            value:GAUGE:0:U
+routes                  value:GAUGE:0:U
+segments                value:GAUGE:0:65535
+serial_octets           rx:DERIVE:0:U, tx:DERIVE:0:U
+signal_noise            value:GAUGE:U:0
+signal_power            value:GAUGE:U:0
+signal_quality          value:GAUGE:0:U
 smart_attribute         current:GAUGE:0:255, worst:GAUGE:0:255, threshold:GAUGE:0:255, pretty:GAUGE:0:U
-snr                    value:GAUGE:0:U
-spam_check             value:GAUGE:0:U
-spam_score             value:GAUGE:U:U
-spl                    value:GAUGE:U:U
-swap_io                        value:DERIVE:0:U
-swap                   value:GAUGE:0:1099511627776
-tcp_connections                value:GAUGE:0:4294967295
-temperature            value:GAUGE:U:U
-threads                        value:GAUGE:0:U
-time_dispersion                value:GAUGE:-1000000:1000000
-timeleft               value:GAUGE:0:U
-time_offset            value:GAUGE:-1000000:1000000
-total_bytes            value:DERIVE:0:U
-total_connections      value:DERIVE:0:U
-total_objects          value:DERIVE:0:U
-total_operations       value:DERIVE:0:U
-total_requests         value:DERIVE:0:U
-total_sessions         value:DERIVE:0:U
-total_threads          value:DERIVE:0:U
-total_time_in_ms       value:DERIVE:0:U
-total_values           value:DERIVE:0:U
-uptime                 value:GAUGE:0:4294967295
-users                  value:GAUGE:0:65535
-vcl                    value:GAUGE:0:65535
-vcpu                   value:GAUGE:0:U
-virt_cpu_total         value:DERIVE:0:U
-virt_vcpu              value:DERIVE:0:U
-vmpage_action          value:DERIVE:0:U
-vmpage_faults          minflt:DERIVE:0:U, majflt:DERIVE:0:U
-vmpage_io              in:DERIVE:0:U, out:DERIVE:0:U
-vmpage_number          value:GAUGE:0:4294967295
-volatile_changes       value:GAUGE:0:U
-voltage_threshold      value:GAUGE:U:U, threshold:GAUGE:U:U
-voltage                        value:GAUGE:U:U
-vs_memory              value:GAUGE:0:9223372036854775807
-vs_processes           value:GAUGE:0:65535
-vs_threads             value:GAUGE:0:65535
+smart_badsectors        value:GAUGE:0:U
+smart_powercycles       value:GAUGE:0:U
+smart_poweron           value:GAUGE:0:U
+smart_temperature       value:GAUGE:-300:300
+snr                     value:GAUGE:0:U
+spam_check              value:GAUGE:0:U
+spam_score              value:GAUGE:U:U
+spl                     value:GAUGE:U:U
+swap                    value:GAUGE:0:1099511627776
+swap_io                 value:DERIVE:0:U
+tcp_connections         value:GAUGE:0:4294967295
+temperature             value:GAUGE:U:U
+threads                 value:GAUGE:0:U
+time_dispersion         value:GAUGE:-1000000:1000000
+time_offset             value:GAUGE:-1000000:1000000
+timeleft                value:GAUGE:0:U
+total_bytes             value:DERIVE:0:U
+total_connections       value:DERIVE:0:U
+total_objects           value:DERIVE:0:U
+total_operations        value:DERIVE:0:U
+total_requests          value:DERIVE:0:U
+total_sessions          value:DERIVE:0:U
+total_threads           value:DERIVE:0:U
+total_time_in_ms        value:DERIVE:0:U
+total_values            value:DERIVE:0:U
+uptime                  value:GAUGE:0:4294967295
+users                   value:GAUGE:0:65535
+vcl                     value:GAUGE:0:65535
+vcpu                    value:GAUGE:0:U
+virt_cpu_total          value:DERIVE:0:U
+virt_vcpu               value:DERIVE:0:U
+vmpage_action           value:DERIVE:0:U
+vmpage_faults           minflt:DERIVE:0:U, majflt:DERIVE:0:U
+vmpage_io               in:DERIVE:0:U, out:DERIVE:0:U
+vmpage_number           value:GAUGE:0:4294967295
+volatile_changes        value:GAUGE:0:U
+voltage                 value:GAUGE:U:U
+voltage_threshold       value:GAUGE:U:U, threshold:GAUGE:U:U
+vs_memory               value:GAUGE:0:9223372036854775807
+vs_processes            value:GAUGE:0:65535
+vs_threads              value:GAUGE:0:65535
 
 #
 # Legacy types
 # (required for the v5 upgrade target)
 #
-arc_counts             demand_data:COUNTER:0:U, demand_metadata:COUNTER:0:U, prefetch_data:COUNTER:0:U, prefetch_metadata:COUNTER:0:U
-arc_l2_bytes           read:COUNTER:0:U, write:COUNTER:0:U
-arc_l2_size            value:GAUGE:0:U
-arc_ratio              value:GAUGE:0:U
-arc_size               current:GAUGE:0:U, target:GAUGE:0:U, minlimit:GAUGE:0:U, maxlimit:GAUGE:0:U
-mysql_qcache           hits:COUNTER:0:U, inserts:COUNTER:0:U, not_cached:COUNTER:0:U, lowmem_prunes:COUNTER:0:U, queries_in_cache:GAUGE:0:U
-mysql_threads          running:GAUGE:0:U, connected:GAUGE:0:U, cached:GAUGE:0:U, created:COUNTER:0:U
+arc_counts              demand_data:COUNTER:0:U, demand_metadata:COUNTER:0:U, prefetch_data:COUNTER:0:U, prefetch_metadata:COUNTER:0:U
+arc_l2_bytes            read:COUNTER:0:U, write:COUNTER:0:U
+arc_l2_size             value:GAUGE:0:U
+arc_ratio               value:GAUGE:0:U
+arc_size                current:GAUGE:0:U, target:GAUGE:0:U, minlimit:GAUGE:0:U, maxlimit:GAUGE:0:U
+mysql_qcache            hits:COUNTER:0:U, inserts:COUNTER:0:U, not_cached:COUNTER:0:U, lowmem_prunes:COUNTER:0:U, queries_in_cache:GAUGE:0:U
+mysql_threads           running:GAUGE:0:U, connected:GAUGE:0:U, cached:GAUGE:0:U, created:COUNTER:0:U
index e6c75a6..1840e34 100644 (file)
@@ -127,7 +127,16 @@ static int us_open_socket (void)
                return (-1);
        }
 
-       chmod (sa.sun_path, sock_perms);
+       status = chmod (sa.sun_path, sock_perms);
+       if (status == -1)
+       {
+               char errbuf[1024];
+               ERROR ("unixsock plugin: chmod failed: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               close (sock_fd);
+               sock_fd = -1;
+               return (-1);
+       }
 
        status = listen (sock_fd, 8);
        if (status != 0)
@@ -142,7 +151,7 @@ static int us_open_socket (void)
 
        do
        {
-               char *grpname;
+               const char *grpname;
                struct group *g;
                struct group sg;
                char grbuf[2048];
@@ -359,7 +368,7 @@ static void *us_server_thread (void __attribute__((unused)) *arg)
                        pthread_exit ((void *) 1);
                }
 
-               remote_fd = (int *) malloc (sizeof (int));
+               remote_fd = malloc (sizeof (*remote_fd));
                if (remote_fd == NULL)
                {
                        char errbuf[1024];
index 139c976..a4ee4ef 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (C) 2005-2007  Sebastian Harl
  * Copyright (C) 2005       Niki W. Waibel
  * Copyright (C) 2005-2007  Florian octo Forster
- * Copyright (C) 2008       Oleg King 
+ * Copyright (C) 2008       Oleg King
  *
  * 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
@@ -77,7 +77,7 @@ static int users_read (void)
 
        users_submit (users);
 /* #endif HAVE_GETUTXENT */
-       
+
 #elif HAVE_GETUTENT
        unsigned int users = 0;
        struct utmp *entry = NULL;
@@ -106,7 +106,7 @@ static int users_read (void)
        us = sg_get_user_stats ();
 # endif
        if (us == NULL)
-               return (-1);   
+               return (-1);
 
        users_submit ((gauge_t)
 # if HAVE_LIBSTATGRAB_0_90
index 8b34a75..4106166 100644 (file)
@@ -30,6 +30,7 @@
 #include "common.h"
 #include "plugin.h"
 #include "utils_parse_option.h"
+#include "utils_cmd_flush.h"
 
 int handle_flush (FILE *fh, char *buffer)
 {
index 8cbb9b2..4d679f0 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "utils_cache.h"
 #include "utils_parse_option.h"
+#include "utils_cmd_getval.h"
 
 #define print_to_socket(fh, ...) \
   do { \
index 530d153..145cd10 100644 (file)
@@ -29,6 +29,7 @@
 #include "plugin.h"
 
 #include "utils_parse_option.h"
+#include "utils_cmd_putnotif.h"
 
 #define print_to_socket(fh, ...) \
   do { \
index 7b0258c..009ab3d 100644 (file)
@@ -29,6 +29,7 @@
 #include "plugin.h"
 
 #include "utils_parse_option.h"
+#include "utils_cmd_putval.h"
 
 #define print_to_socket(fh, ...) \
     do { \
@@ -162,7 +163,7 @@ int handle_putval (FILE *fh, char *buffer)
        sfree (identifier_copy);
 
        vl.values_len = ds->ds_num;
-       vl.values = (value_t *) malloc (vl.values_len * sizeof (value_t));
+       vl.values = malloc (vl.values_len * sizeof (*vl.values));
        if (vl.values == NULL)
        {
                print_to_socket (fh, "-1 malloc failed.\n");
@@ -217,7 +218,8 @@ int handle_putval (FILE *fh, char *buffer)
        } /* while (*buffer != 0) */
        /* Done parsing the options. */
 
-       print_to_socket (fh, "0 Success: %i %s been dispatched.\n",
+    if (fh!=stdout)
+           print_to_socket (fh, "0 Success: %i %s been dispatched.\n",
                        values_submitted,
                        (values_submitted == 1) ? "value has" : "values have");
 
index d2b8117..91fc142 100644 (file)
@@ -142,7 +142,7 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */
   }
 
   array_len = *ret_array_len;
-  array = (char **) realloc (*ret_array,
+  array = realloc (*ret_array,
       sizeof (char *) * (array_len + ci->values_num));
   if (array == NULL)
   {
@@ -204,10 +204,10 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */
   assert (((size_t) r_area->ds->ds_num) == r->values_num);
   assert (r->values_num > 0);
 
-  vl.values = (value_t *) calloc (r->values_num, sizeof (value_t));
+  vl.values = calloc (r->values_num, sizeof (*vl.values));
   if (vl.values == NULL)
   {
-    ERROR ("db query utils: malloc failed.");
+    ERROR ("db query utils: calloc failed.");
     return (-1);
   }
   vl.values_len = r_area->ds->ds_num;
@@ -221,6 +221,7 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */
       ERROR ("db query utils: udb_result_submit: Parsing `%s' as %s failed.",
           value_str, DS_TYPE_TO_STRING (r_area->ds->ds[i].type));
       errno = EINVAL;
+      free (vl.values);
       return (-1);
     }
   }
@@ -234,7 +235,7 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */
   sstrncpy (vl.type, r->type, sizeof (vl.type));
 
   /* Set vl.type_instance {{{ */
-  if (r->instances_num <= 0)
+  if (r->instances_num == 0)
   {
     if (r->instance_prefix == NULL)
       vl.type_instance[0] = 0;
@@ -390,7 +391,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
       = (size_t *) calloc (r->instances_num, sizeof (size_t));
     if (prep_area->instances_pos == NULL)
     {
-      ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+      ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
       BAIL_OUT (-ENOMEM);
     }
 
@@ -398,7 +399,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
       = (char **) calloc (r->instances_num, sizeof (char *));
     if (prep_area->instances_buffer == NULL)
     {
-      ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+      ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
       BAIL_OUT (-ENOMEM);
     }
   } /* if (r->instances_num > 0) */
@@ -407,7 +408,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
     = (size_t *) calloc (r->values_num, sizeof (size_t));
   if (prep_area->values_pos == NULL)
   {
-    ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+    ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
     BAIL_OUT (-ENOMEM);
   }
 
@@ -415,7 +416,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
     = (char **) calloc (r->values_num, sizeof (char *));
   if (prep_area->values_buffer == NULL)
   {
-    ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+    ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
     BAIL_OUT (-ENOMEM);
   }
 
@@ -423,7 +424,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
     = (size_t *) calloc (r->metadata_num, sizeof (size_t));
   if (prep_area->metadata_pos == NULL)
   {
-    ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+    ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
     BAIL_OUT (-ENOMEM);
   }
 
@@ -431,7 +432,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
     = (char **) calloc (r->metadata_num, sizeof (char *));
   if (prep_area->metadata_buffer == NULL)
   {
-    ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+    ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
     BAIL_OUT (-ENOMEM);
   }
 
@@ -550,13 +551,12 @@ static int udb_result_create (const char *query_name, /* {{{ */
         ci->values_num, (ci->values_num == 1) ? "" : "s");
   }
 
-  r = (udb_result_t *) malloc (sizeof (*r));
+  r = calloc (1, sizeof (*r));
   if (r == NULL)
   {
-    ERROR ("db query utils: malloc failed.");
+    ERROR ("db query utils: calloc failed.");
     return (-1);
   }
-  memset (r, 0, sizeof (*r));
   r->type = NULL;
   r->instance_prefix = NULL;
   r->instances = NULL;
@@ -638,7 +638,7 @@ static int udb_result_create (const char *query_name, /* {{{ */
 /*
  * Query private functions
  */
-void udb_query_free_one (udb_query_t *q) /* {{{ */
+static void udb_query_free_one (udb_query_t *q) /* {{{ */
 {
   if (q == NULL)
     return;
@@ -678,13 +678,12 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
     return (-1);
   }
 
-  q = (udb_query_t *) malloc (sizeof (*q));
+  q = calloc (1, sizeof (*q));
   if (q == NULL)
   {
-    ERROR ("db query utils: malloc failed.");
+    ERROR ("db query utils: calloc failed.");
     return (-1);
   }
-  memset (q, 0, sizeof (*q));
   q->min_version = 0;
   q->max_version = UINT_MAX;
 
@@ -752,7 +751,7 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
   {
     udb_query_t **temp;
 
-    temp = (udb_query_t **) realloc (query_list,
+    temp = realloc (query_list,
         sizeof (*query_list) * (query_list_len + 1));
     if (temp == NULL)
     {
@@ -817,7 +816,7 @@ int udb_query_pick_from_list_by_name (const char *name, /* {{{ */
       continue;
 
     tmp_list_len = *dst_list_len;
-    tmp_list = (udb_query_t **) realloc (*dst_list, (tmp_list_len + 1)
+    tmp_list = realloc (*dst_list, (tmp_list_len + 1)
         * sizeof (udb_query_t *));
     if (tmp_list == NULL)
     {
@@ -1072,17 +1071,16 @@ udb_query_allocate_preparation_area (udb_query_t *q) /* {{{ */
   udb_result_preparation_area_t **next_r_area;
   udb_result_t *r;
 
-  q_area = malloc (sizeof (*q_area));
+  q_area = calloc (1, sizeof (*q_area));
   if (q_area == NULL)
     return NULL;
-  memset (q_area, 0, sizeof (*q_area));
 
   next_r_area = &q_area->result_prep_areas;
   for (r = q->results; r != NULL; r = r->next)
   {
     udb_result_preparation_area_t *r_area;
 
-    r_area = malloc (sizeof (*r_area));
+    r_area = calloc (1, sizeof (*r_area));
     if (r_area == NULL)
     {
       udb_result_preparation_area_t *a = q_area->result_prep_areas;
@@ -1098,8 +1096,6 @@ udb_query_allocate_preparation_area (udb_query_t *q) /* {{{ */
       return NULL;
     }
 
-    memset (r_area, 0, sizeof (*r_area));
-
     *next_r_area = r_area;
     next_r_area  = &r_area->next;
   }
index 08b10bd..8586adb 100644 (file)
@@ -41,7 +41,7 @@ typedef struct udb_query_preparation_area_s udb_query_preparation_area_t;
 typedef int (*udb_query_create_callback_t) (udb_query_t *q,
     oconfig_item_t *ci);
 
-/* 
+/*
  * Public functions
  */
 int udb_query_create (udb_query_t ***ret_query_list,
@@ -62,7 +62,7 @@ const char *udb_query_get_statement (udb_query_t *q);
 void  udb_query_set_user_data (udb_query_t *q, void *user_data);
 void *udb_query_get_user_data (udb_query_t *q);
 
-/* 
+/*
  * udb_query_check_version
  *
  * Returns 0 if the query is NOT suitable for `version' and >0 if the
index 4c763a1..991d346 100644 (file)
@@ -62,9 +62,6 @@
 #if HAVE_NETINET_IP6_H
 # include <netinet/ip6.h>
 #endif
-#if HAVE_NETINET_IP_COMPAT_H
-# include <netinet/ip_compat.h>
-#endif
 #if HAVE_NETINET_IF_ETHER_H
 # include <netinet/if_ether.h>
 #endif
@@ -159,9 +156,6 @@ typedef int (printer)(const char *, ...);
 /*
  * Global variables
  */
-int qtype_counts[T_MAX];
-int opcode_counts[OP_MAX];
-int qclass_counts[C_MAX];
 
 #if HAVE_PCAP_H
 static pcap_t *pcap_obj = NULL;
@@ -215,7 +209,7 @@ static void ignore_list_add (const struct in6_addr *addr)
     if (ignore_list_match (addr) != 0)
        return;
 
-    new = malloc (sizeof (ip_list_t));
+    new = malloc (sizeof (*new));
     if (new == NULL)
     {
        perror ("malloc");
@@ -421,11 +415,6 @@ handle_dns(const char *buf, int len)
 
     qh.length = (uint16_t) len;
 
-    /* gather stats */
-    qtype_counts[qh.qtype]++;
-    qclass_counts[qh.qclass]++;
-    opcode_counts[qh.opcode]++;
-
     if (Callback != NULL)
            Callback (&qh);
 
index 83f0ea4..5c547c6 100644 (file)
@@ -3,10 +3,10 @@
  * Copyright (C) 2006       Florian octo Forster
  * Copyright (C) 2002       The Measurement Factory, Inc.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
- * 
+ *
  * 1. Redistributions of source code must retain the above copyright notice,
  *    this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
@@ -48,8 +48,6 @@
 #define DNS_MSG_HDR_SZ 12
 
 #define T_MAX 65536
-#define OP_MAX 16
-#define C_MAX 65536
 #define MAX_QNAME_SZ 512
 
 struct rfc1035_header_s {
@@ -75,10 +73,6 @@ struct rfc1035_header_s {
 };
 typedef struct rfc1035_header_s rfc1035_header_t;
 
-extern int qtype_counts[T_MAX];
-extern int opcode_counts[OP_MAX];
-extern int qclass_counts[C_MAX];
-
 #if HAVE_PCAP_H
 void dnstop_set_pcap_obj (pcap_t *po);
 #endif
index 70b8908..f27c082 100644 (file)
@@ -41,7 +41,7 @@ struct fbhash_s
   c_avl_tree_t *tree;
 };
 
-/* 
+/*
  * Private functions
  */
 static void fbh_free_tree (c_avl_tree_t *tree) /* {{{ */
@@ -198,7 +198,7 @@ static int fbh_check_file (fbhash_t *h) /* {{{ */
   return (status);
 } /* }}} int fbh_check_file */
 
-/* 
+/*
  * Public functions
  */
 fbhash_t *fbh_create (const char *file) /* {{{ */
@@ -209,10 +209,9 @@ fbhash_t *fbh_create (const char *file) /* {{{ */
   if (file == NULL)
     return (NULL);
 
-  h = malloc (sizeof (*h));
+  h = calloc (1, sizeof (*h));
   if (h == NULL)
     return (NULL);
-  memset (h, 0, sizeof (*h));
 
   h->filename = strdup (file);
   if (h->filename == NULL)
@@ -228,6 +227,7 @@ fbhash_t *fbh_create (const char *file) /* {{{ */
   if (status != 0)
   {
     fbh_destroy (h);
+    free (h);
     return (NULL);
   }
 
index 122c7f8..800b421 100644 (file)
@@ -230,20 +230,15 @@ static int dsnames_to_json (char *buffer, size_t buffer_size, /* {{{ */
   return (0);
 } /* }}} int dsnames_to_json */
 
-static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
-    meta_data_t *meta)
+static int meta_data_keys_to_json (char *buffer, size_t buffer_size, /* {{{ */
+    meta_data_t *meta, char **keys, size_t keys_num)
 {
   size_t offset = 0;
-  char **keys = NULL;
-  int keys_num;
   int status;
-  int i;
+  size_t i;
 
   buffer[0] = 0;
 
-  if (meta == NULL)
-    return (EINVAL);
-
 #define BUFFER_ADD(...) do { \
   status = ssnprintf (buffer + offset, buffer_size - offset, \
       __VA_ARGS__); \
@@ -255,13 +250,6 @@ static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
     offset += ((size_t) status); \
 } while (0)
 
-  keys_num = meta_data_toc (meta, &keys);
-  if (keys_num == 0)
-  {
-    sfree (keys);
-    return (0);
-  }
-
   for (i = 0; i < keys_num; ++i)
   {
     int type;
@@ -274,8 +262,12 @@ static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
       if (meta_data_get_string (meta, key, &value) == 0)
       {
         char temp[512] = "";
-        json_escape_string (temp, sizeof (temp), value);
+
+        status = json_escape_string (temp, sizeof (temp), value);
         sfree (value);
+        if (status != 0)
+          return status;
+
         BUFFER_ADD (",\"%s\":%s", key, temp);
       }
     }
@@ -303,12 +295,9 @@ static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
       if (meta_data_get_boolean (meta, key, &value) == 0)
         BUFFER_ADD (",\"%s\":%s", key, value ? "true" : "false");
     }
-
-    free (key);
   } /* for (keys) */
-  free (keys);
 
-  if (offset <= 0)
+  if (offset == 0)
     return (ENOENT);
 
   buffer[0] = '{'; /* replace leading ',' */
@@ -317,6 +306,31 @@ static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
 #undef BUFFER_ADD
 
   return (0);
+} /* }}} int meta_data_keys_to_json */
+
+static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
+    meta_data_t *meta)
+{
+  char **keys = NULL;
+  size_t keys_num;
+  int status;
+  size_t i;
+
+  if ((buffer == NULL) || (buffer_size == 0) || (meta == NULL))
+    return (EINVAL);
+
+  status = meta_data_toc (meta, &keys);
+  if (status <= 0)
+    return (status);
+  keys_num = (size_t) status;
+
+  status = meta_data_keys_to_json (buffer, buffer_size, meta, keys, keys_num);
+
+  for (i = 0; i < keys_num; ++i)
+    sfree (keys[i]);
+  sfree (keys);
+
+  return status;
 } /* }}} int meta_data_to_json */
 
 static int value_list_to_json (char *buffer, size_t buffer_size, /* {{{ */
diff --git a/src/utils_ignorelist.c b/src/utils_ignorelist.c
deleted file mode 100644 (file)
index a8ca7db..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/**
- * collectd - src/utils_ignorelist.c
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- * Copyright (C) 2008 Florian Forster <octo at collectd.org>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- *   Lubos Stanek <lubek at users.sourceforge.net>
- *   Florian Forster <octo at collectd.org>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-/**
- * Usage:
- * 
- * Define plugin's global pointer variable of type ignorelist_t:
- *   ignorelist_t *myconfig_ignore;
- * If you know the state of the global ignore (IgnoreSelected),
- * allocate the variable with:
- *   myconfig_ignore = ignorelist_create (YourKnownIgnore);
- * If you do not know the state of the global ignore,
- * initialize the global variable and set the ignore flag later:
- *   myconfig_ignore = ignorelist_init ();
- * Append single entries in your cf_register'ed callback function:
- *   ignorelist_add (myconfig_ignore, newentry);
- * When you hit the IgnoreSelected config option,
- * offer it to the list:
- *   ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
- * That is all for the ignorelist initialization.
- * Later during read and write (plugin's registered functions) get
- * the information whether this entry would be collected or not:
- *   if (ignorelist_match (myconfig_ignore, thisentry))
- *     return;
- **/
-
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "common.h"
-#include "plugin.h"
-#include "utils_ignorelist.h"
-
-/*
- * private prototypes
- */
-struct ignorelist_item_s
-{
-#if HAVE_REGEX_H
-       regex_t *rmatch;        /* regular expression entry identification */
-#endif
-       char *smatch;           /* string entry identification */
-       struct ignorelist_item_s *next;
-};
-typedef struct ignorelist_item_s ignorelist_item_t;
-
-struct ignorelist_s
-{
-       int ignore;             /* ignore entries */
-       ignorelist_item_t *head;        /* pointer to the first entry */
-};
-
-/* *** *** *** ********************************************* *** *** *** */
-/* *** *** *** *** *** ***   private functions   *** *** *** *** *** *** */
-/* *** *** *** ********************************************* *** *** *** */
-
-static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
-{
-       assert ((il != NULL) && (item != NULL));
-
-       item->next = il->head;
-       il->head = item;
-}
-
-#if HAVE_REGEX_H
-static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
-{
-       regex_t *re;
-       ignorelist_item_t *entry;
-       int status;
-
-       re = malloc (sizeof (*re));
-       if (re == NULL)
-       {
-               ERROR ("utils_ignorelist: malloc failed");
-               return (ENOMEM);
-       }
-       memset (re, 0, sizeof (*re));
-
-       status = regcomp (re, re_str, REG_EXTENDED);
-       if (status != 0)
-       {
-               char errbuf[1024] = "";
-               regerror (status, re, errbuf, sizeof (errbuf));
-               ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
-               regfree (re);
-               sfree (re);
-               return (status);
-       }
-
-       entry = malloc (sizeof (*entry));
-       if (entry == NULL)
-       {
-               ERROR ("utils_ignorelist: malloc failed");
-               regfree (re);
-               sfree (re);
-               return (ENOMEM);
-       }
-       memset (entry, 0, sizeof (*entry));
-       entry->rmatch = re;
-
-       ignorelist_append (il, entry);
-       return (0);
-} /* int ignorelist_append_regex */
-#endif
-
-static int ignorelist_append_string(ignorelist_t *il, const char *entry)
-{
-       ignorelist_item_t *new;
-
-       /* create new entry */
-       if ((new = malloc(sizeof(ignorelist_item_t))) == NULL )
-       {
-               ERROR ("cannot allocate new entry");
-               return (1);
-       }
-       memset (new, '\0', sizeof(ignorelist_item_t));
-       new->smatch = sstrdup(entry);
-
-       /* append new entry */
-       ignorelist_append (il, new);
-
-       return (0);
-} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
-
-#if HAVE_REGEX_H
-/*
- * check list for entry regex match
- * return 1 if found
- */
-static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
-{
-       assert ((item != NULL) && (item->rmatch != NULL)
-                       && (entry != NULL) && (strlen (entry) > 0));
-
-       /* match regex */
-       if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
-               return (1);
-
-       return (0);
-} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
-#endif
-
-/*
- * check list for entry string match
- * return 1 if found
- */
-static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
-{
-       assert ((item != NULL) && (item->smatch != NULL)
-                       && (entry != NULL) && (strlen (entry) > 0));
-
-       if (strcmp (entry, item->smatch) == 0)
-               return (1);
-
-       return (0);
-} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
-
-
-/* *** *** *** ******************************************** *** *** *** */
-/* *** *** *** *** *** ***   public functions   *** *** *** *** *** *** */
-/* *** *** *** ******************************************** *** *** *** */
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert)
-{
-       ignorelist_t *il;
-
-       /* smalloc exits if it failes */
-       il = (ignorelist_t *) smalloc (sizeof (ignorelist_t));
-       memset (il, '\0', sizeof (ignorelist_t));
-
-       /*
-        * ->ignore == 0  =>  collect
-        * ->ignore == 1  =>  ignore
-        */
-       il->ignore = invert ? 0 : 1;
-
-       return (il);
-} /* ignorelist_t *ignorelist_create (int ignore) */
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il)
-{
-       ignorelist_item_t *this;
-       ignorelist_item_t *next;
-
-       if (il == NULL)
-               return;
-
-       for (this = il->head; this != NULL; this = next)
-       {
-               next = this->next;
-#if HAVE_REGEX_H
-               if (this->rmatch != NULL)
-               {
-                       regfree (this->rmatch);
-                       sfree (this->rmatch);
-                       this->rmatch = NULL;
-               }
-#endif
-               if (this->smatch != NULL)
-               {
-                       sfree (this->smatch);
-                       this->smatch = NULL;
-               }
-               sfree (this);
-       }
-
-       sfree (il);
-       il = NULL;
-} /* void ignorelist_destroy (ignorelist_t *il) */
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert)
-{
-       if (il == NULL)
-       {
-               DEBUG("ignore call with ignorelist_t == NULL");
-               return;
-       }
-
-       il->ignore = invert ? 0 : 1;
-} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
-
-/*
- * append entry into ignorelist_t
- * return 0 for success
- */
-int ignorelist_add (ignorelist_t *il, const char *entry)
-{
-       size_t entry_len;
-
-       if (il == NULL)
-       {
-               DEBUG ("add called with ignorelist_t == NULL");
-               return (1);
-       }
-
-       entry_len = strlen (entry);
-
-       /* append nothing */
-       if (entry_len == 0)
-       {
-               DEBUG("not appending: empty entry");
-               return (1);
-       }
-
-#if HAVE_REGEX_H
-       /* regex string is enclosed in "/.../" */
-       if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/')
-       {
-               char *entry_copy;
-               size_t entry_copy_size;
-               int status;
-
-               /* We need to copy `entry' since it's const */
-               entry_copy_size = entry_len - 1;
-               entry_copy = smalloc (entry_copy_size);
-               sstrncpy (entry_copy, entry + 1, entry_copy_size);
-
-               status = ignorelist_append_regex(il, entry_copy);
-               sfree (entry_copy);
-               return status;
-       }
-#endif
-
-       return ignorelist_append_string(il, entry);
-} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry)
-{
-       ignorelist_item_t *traverse;
-
-       /* if no entries, collect all */
-       if ((il == NULL) || (il->head == NULL))
-               return (0);
-
-       if ((entry == NULL) || (strlen (entry) == 0))
-               return (0);
-
-       /* traverse list and check entries */
-       for (traverse = il->head; traverse != NULL; traverse = traverse->next)
-       {
-#if HAVE_REGEX_H
-               if (traverse->rmatch != NULL)
-               {
-                       if (ignorelist_match_regex (traverse, entry))
-                               return (il->ignore);
-               }
-               else
-#endif
-               {
-                       if (ignorelist_match_string (traverse, entry))
-                               return (il->ignore);
-               }
-       } /* for traverse */
-
-       return (1 - il->ignore);
-} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
-
diff --git a/src/utils_ignorelist.h b/src/utils_ignorelist.h
deleted file mode 100644 (file)
index b47b55a..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * collectd - src/utils_ignorelist.h
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- *   Lubos Stanek <lubek at users.sourceforge.net>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-
-#ifndef UTILS_IGNORELIST_H
-#define UTILS_IGNORELIST_H 1
-
-#include "collectd.h"
-
-#if HAVE_REGEX_H
-# include <regex.h>
-#endif
-
-/* public prototypes */
-
-struct ignorelist_s;
-typedef struct ignorelist_s ignorelist_t;
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert);
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il);
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert);
-
-/*
- * append entry to ignorelist_t
- * returns zero on success, non-zero upon failure.
- */
-int ignorelist_add (ignorelist_t *il, const char *entry);
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry);
-
-#endif /* UTILS_IGNORELIST_H */
index 12fc9b8..41af00c 100644 (file)
@@ -76,7 +76,7 @@ struct latency_counter_s
 * So, if the required bin width is 300, then new bin width will be 512 as it is
 * the next nearest power of 2.
 */
-void change_bin_width (latency_counter_t *lc, cdtime_t latency) /* {{{ */
+static void change_bin_width (latency_counter_t *lc, cdtime_t latency) /* {{{ */
 {
   /* This function is called because the new value is above histogram's range.
    * First find the required bin width:
@@ -117,14 +117,13 @@ void change_bin_width (latency_counter_t *lc, cdtime_t latency) /* {{{ */
       CDTIME_T_TO_DOUBLE (new_bin_width));
 } /* }}} void change_bin_width */
 
-latency_counter_t *latency_counter_create () /* {{{ */
+latency_counter_t *latency_counter_create (void) /* {{{ */
 {
   latency_counter_t *lc;
 
-  lc = malloc (sizeof (*lc));
+  lc = calloc (1, sizeof (*lc));
   if (lc == NULL)
     return (NULL);
-  memset (lc, 0, sizeof (*lc));
 
   latency_counter_reset (lc);
   lc->bin_width = HISTOGRAM_DEFAULT_BIN_WIDTH;
index 9930b72..2cfa71b 100644 (file)
@@ -30,7 +30,7 @@
 struct latency_counter_s;
 typedef struct latency_counter_s latency_counter_t;
 
-latency_counter_t *latency_counter_create ();
+latency_counter_t *latency_counter_create (void);
 void latency_counter_destroy (latency_counter_t *lc);
 
 void latency_counter_add (latency_counter_t *lc, cdtime_t latency);
index 5769ec9..f275813 100644 (file)
@@ -26,9 +26,9 @@
 
 #define DBL_PRECISION 1e-9
 
-#include "testing.h"
-#include "collectd.h"
 #include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
 #include "utils_time.h"
 #include "utils_latency.h"
 
index b63a81a..a36882c 100644 (file)
  * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public Licence for more details.
  *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Author:
  *   Niki W. Waibel <niki.waibel@gmx.net>
 **/
 
-#include "collectd.h"
-#include "utils_mount.h"
-
-#include "common.h" /* sstrncpy() et alii */
-#include "plugin.h" /* ERROR() macro */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
 
 #if HAVE_XFS_XQM_H
+# define _GNU_SOURCE
 # include <xfs/xqm.h>
 #define XFS_SUPER_MAGIC_STR "XFSB"
 #define XFS_SUPER_MAGIC2_STR "BSFX"
 #endif
 
+#include "collectd.h"
+#include "utils_mount.h"
+
+#include "common.h" /* sstrncpy() et alii */
+#include "plugin.h" /* ERROR() macro */
+
+
 #if HAVE_GETVFSSTAT
 #  if HAVE_SYS_TYPES_H
 #    include <sys/types.h>
@@ -430,16 +435,16 @@ static cu_mount_t *cu_mount_listmntent (void)
 #elif HAVE_GETVFSSTAT || HAVE_GETFSSTAT
 static cu_mount_t *cu_mount_getfsstat (void)
 {
-#if HAVE_GETVFSSTAT
-#  define STRUCT_STATFS struct statvfs
-#  define CMD_STATFS    getvfsstat
-#  define FLAGS_STATFS  ST_NOWAIT
-/* #endif HAVE_GETVFSSTAT */
-#elif HAVE_GETFSSTAT
+#if HAVE_GETFSSTAT
 #  define STRUCT_STATFS struct statfs
 #  define CMD_STATFS    getfsstat
 #  define FLAGS_STATFS  MNT_NOWAIT
-#endif /* HAVE_GETFSSTAT */
+/* #endif HAVE_GETFSSTAT */
+#elif HAVE_GETVFSSTAT
+#  define STRUCT_STATFS struct statvfs
+#  define CMD_STATFS    getvfsstat
+#  define FLAGS_STATFS  ST_NOWAIT
+#endif /* HAVE_GETVFSSTAT */
 
        int bufsize;
        STRUCT_STATFS *buf;
@@ -462,10 +467,8 @@ static cu_mount_t *cu_mount_getfsstat (void)
                return (NULL);
        }
 
-       if ((buf = (STRUCT_STATFS *) malloc (bufsize * sizeof (STRUCT_STATFS)))
-                       == NULL)
+       if ((buf = calloc (bufsize, sizeof (*buf))) == NULL)
                return (NULL);
-       memset (buf, '\0', bufsize * sizeof (STRUCT_STATFS));
 
        /* The bufsize needs to be passed in bytes. Really. This is not in the
         * manpage.. -octo */
@@ -482,10 +485,9 @@ static cu_mount_t *cu_mount_getfsstat (void)
 
        for (i = 0; i < num; i++)
        {
-               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+               if ((new = calloc (1, sizeof (*new))) == NULL)
                        break;
-               memset (new, '\0', sizeof (cu_mount_t));
-               
+
                /* Copy values from `struct mnttab' */
                new->dir         = sstrdup (buf[i].f_mntonname);
                new->spec_device = sstrdup (buf[i].f_mntfromname);
@@ -536,10 +538,9 @@ static cu_mount_t *cu_mount_gen_getmntent (void)
 
        while (getmntent (fp, &mt) == 0)
        {
-               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+               if ((new = calloc (1, sizeof (*new))) == NULL)
                        break;
-               memset (new, '\0', sizeof (cu_mount_t));
-               
+
                /* Copy values from `struct mnttab' */
                new->dir         = sstrdup (mt.mnt_mountp);
                new->spec_device = sstrdup (mt.mnt_special);
@@ -571,6 +572,63 @@ static cu_mount_t *cu_mount_gen_getmntent (void)
 #warn "This version of `getmntent' hat not yet been implemented!"
 /* #endif HAVE_SEQ_GETMNTENT */
 
+#elif HAVE_GETMNTENT_R
+static cu_mount_t *cu_mount_getmntent (void)
+{
+       FILE *fp;
+       struct mntent me;
+       char mntbuf[1024];
+
+       cu_mount_t *first = NULL;
+       cu_mount_t *last  = NULL;
+       cu_mount_t *new   = NULL;
+
+       DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
+
+       if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL)
+       {
+               char errbuf[1024];
+               ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB,
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (NULL);
+       }
+
+       while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) ))
+       {
+               if ((new = calloc (1, sizeof (*new))) == NULL)
+                       break;
+
+               /* Copy values from `struct mntent *' */
+               new->dir         = sstrdup (me.mnt_dir);
+               new->spec_device = sstrdup (me.mnt_fsname);
+               new->type        = sstrdup (me.mnt_type);
+               new->options     = sstrdup (me.mnt_opts);
+               new->device      = get_device_name (new->options);
+               new->next        = NULL;
+
+               DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}",
+                               new->dir, new->spec_device, new->type, new->options, new->device);
+
+               /* Append to list */
+               if (first == NULL)
+               {
+                       first = new;
+                       last  = new;
+               }
+               else
+               {
+                       last->next = new;
+                       last       = new;
+               }
+       }
+
+       endmntent (fp);
+
+       DEBUG ("utils_mount: return (0x%p)", (void *) first);
+
+       return (first);
+} /* HAVE_GETMNTENT_R */
+
 #elif HAVE_ONE_GETMNTENT
 static cu_mount_t *cu_mount_getmntent (void)
 {
@@ -593,10 +651,9 @@ static cu_mount_t *cu_mount_getmntent (void)
 
        while ((me = getmntent (fp)) != NULL)
        {
-               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+               if ((new = calloc (1, sizeof (*new))) == NULL)
                        break;
-               memset (new, '\0', sizeof (cu_mount_t));
-               
+
                /* Copy values from `struct mntent *' */
                new->dir         = sstrdup (me->mnt_dir);
                new->spec_device = sstrdup (me->mnt_fsname);
@@ -700,15 +757,15 @@ void cu_mount_freelist (cu_mount_t *list)
 } /* void cu_mount_freelist(cu_mount_t *list) */
 
 char *
-cu_mount_checkoption(char *line, char *keyword, int full)
+cu_mount_checkoption(char *line, const char *keyword, int full)
 {
-       char *line2, *l2;
-       int l = strlen(keyword);
-       char *p1, *p2;
+       char *line2, *l2, *p1, *p2;
+       int l;
 
        if(line == NULL || keyword == NULL) {
                return NULL;
        }
+
        if(full != 0) {
                full = 1;
        }
@@ -722,6 +779,7 @@ cu_mount_checkoption(char *line, char *keyword, int full)
                l2++;
        }
 
+       l = strlen(keyword);
        p1 = line - 1;
        p2 = strchr(line, ',');
        do {
@@ -740,7 +798,7 @@ cu_mount_checkoption(char *line, char *keyword, int full)
 } /* char *cu_mount_checkoption(char *line, char *keyword, int full) */
 
 char *
-cu_mount_getoptionvalue(char *line, char *keyword)
+cu_mount_getoptionvalue(char *line, const char *keyword)
 {
        char *r;
 
@@ -756,13 +814,13 @@ cu_mount_getoptionvalue(char *line, char *keyword)
                        if((p-r) == 1) {
                                return NULL;
                        }
-                       m = (char *)smalloc(p-r+1);
+                       m = smalloc(p-r+1);
                        sstrncpy(m, r, p-r+1);
                        return m;
                }
        }
        return r;
-} /* char *cu_mount_getoptionvalue(char *line, char *keyword) */
+} /* char *cu_mount_getoptionvalue(char *line, const char *keyword) */
 
 int
 cu_mount_type(const char *type)
index bc0077f..0a5c980 100644 (file)
  * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  * See the GNU General Public Licence for more details.
  *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Author:
  *   Niki W. Waibel <niki.waibel@gmx.net>
@@ -114,7 +113,7 @@ void cu_mount_freelist(cu_mount_t *list);
        allocated by *list and *list itself as well.
 */
 
-char *cu_mount_checkoption(char *line, char *keyword, int full);
+char *cu_mount_checkoption(char *line, const char *keyword, int full);
 /*
   DESCRIPTION
        The cu_mount_checkoption() function is a replacement of
@@ -154,7 +153,7 @@ char *cu_mount_checkoption(char *line, char *keyword, int full);
        maybe you might want to try cu_mount_getoptionvalue()...
 */
 
-char *cu_mount_getoptionvalue(char *line, char *keyword);
+char *cu_mount_getoptionvalue(char *line, const char *keyword);
 /*
   DESCRIPTION
        The cu_mount_getoptionvalue() function can be used to grab
index b4cb432..d9d685a 100644 (file)
@@ -24,8 +24,8 @@
  *   Florian octo Forster <octo at collectd.org>
  */
 
-#include "testing.h"
 #include "collectd.h"
+#include "testing.h"
 #include "utils_mount.h"
 
 #if HAVE_LIBKSTAT
index 7f06f29..69da040 100644 (file)
@@ -92,7 +92,7 @@ int parse_string (char **ret_buffer, char **ret_string)
       buffer++;
     }
   }
-  
+
   /* Eat up trailing spaces */
   while (isspace ((int) *buffer))
     buffer++;
index 39f42b2..6da5167 100644 (file)
@@ -62,7 +62,7 @@ static int rra_timespans[] =
 };
 static int rra_timespans_num = STATIC_ARRAY_SIZE (rra_timespans);
 
-static char *rra_types[] =
+static const char *const rra_types[] =
 {
   "AVERAGE",
   "MIN",
@@ -70,7 +70,7 @@ static char *rra_types[] =
 };
 static int rra_types_num = STATIC_ARRAY_SIZE (rra_types);
 
-#if !defined(HAVE_THREADSAFE_LIBRRD) || !HAVE_THREADSAFE_LIBRRD
+#if !defined(HAVE_THREADSAFE_LIBRRD)
 static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
@@ -113,13 +113,12 @@ static srrd_create_args_t *srrd_create_args_create (const char *filename,
 {
   srrd_create_args_t *args;
 
-  args = malloc (sizeof (*args));
+  args = calloc (1, sizeof (*args));
   if (args == NULL)
   {
-    ERROR ("srrd_create_args_create: malloc failed.");
+    ERROR ("srrd_create_args_create: calloc failed.");
     return (NULL);
   }
-  memset (args, 0, sizeof (*args));
   args->filename = NULL;
   args->pdp_step = pdp_step;
   args->last_up = last_up;
@@ -216,9 +215,8 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
   rra_max = rts_num * rra_types_num;
   assert (rra_max > 0);
 
-  if ((rra_def = malloc ((rra_max + 1) * sizeof (*rra_def))) == NULL)
+  if ((rra_def = calloc (rra_max + 1, sizeof (*rra_def))) == NULL)
     return (-1);
-  memset (rra_def, 0, (rra_max + 1) * sizeof (*rra_def));
   rra_num = 0;
 
   cdp_len = 0;
@@ -292,20 +290,19 @@ static int ds_get (char ***ret, /* {{{ */
 
   assert (ds->ds_num > 0);
 
-  ds_def = malloc (ds->ds_num * sizeof (*ds_def));
+  ds_def = calloc (ds->ds_num, sizeof (*ds_def));
   if (ds_def == NULL)
   {
     char errbuf[1024];
-    ERROR ("rrdtool plugin: malloc failed: %s",
+    ERROR ("rrdtool plugin: calloc failed: %s",
         sstrerror (errno, errbuf, sizeof (errbuf)));
     return (-1);
   }
-  memset (ds_def, 0, ds->ds_num * sizeof (*ds_def));
 
   for (ds_num = 0; ds_num < ds->ds_num; ds_num++)
   {
     data_source_t *d = ds->ds + ds_num;
-    char *type;
+    const char *type;
     int status;
 
     ds_def[ds_num] = NULL;
@@ -358,7 +355,7 @@ static int ds_get (char ***ret, /* {{{ */
     return (-1);
   }
 
-  if (ds_num <= 0)
+  if (ds_num == 0)
   {
     sfree (ds_def);
     return (0);
@@ -421,7 +418,7 @@ static int srrd_create (const char *filename, /* {{{ */
   char last_up_str[16];
 
   new_argc = 6 + argc;
-  new_argv = (char **) malloc ((new_argc + 1) * sizeof (char *));
+  new_argv = malloc ((new_argc + 1) * sizeof (*new_argv));
   if (new_argv == NULL)
   {
     ERROR ("rrdtool plugin: malloc failed.");
@@ -689,7 +686,7 @@ int cu_rrd_create_file (const char *filename, /* {{{ */
 
   argc = ds_num + rra_num;
 
-  if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL)
+  if ((argv = malloc (sizeof (*argv) * (argc + 1))) == NULL)
   {
     char errbuf[1024];
     ERROR ("cu_rrd_create_file failed: %s",
index f85910e..a023784 100644 (file)
@@ -157,7 +157,7 @@ static int lu_copy_ident_to_match_part (part_match_t *match_part, /* {{{ */
   assert (sizeof (match_part->str) > len);
   /* strip trailing slash */
   match_part->str[len - 2] = 0;
-  
+
   status = regcomp (&match_part->regex, match_part->str,
       /* flags = */ REG_EXTENDED);
   if (status != 0)
@@ -169,7 +169,7 @@ static int lu_copy_ident_to_match_part (part_match_t *match_part, /* {{{ */
     return (EINVAL);
   }
   match_part->is_regex = 1;
-  
+
   return (0);
 } /* }}} int lu_copy_ident_to_match_part */
 
@@ -204,13 +204,12 @@ static void *lu_create_user_obj (lookup_t *obj, /* {{{ */
 {
   user_obj_t *user_obj;
 
-  user_obj = malloc (sizeof (*user_obj));
+  user_obj = calloc (1, sizeof (*user_obj));
   if (user_obj == NULL)
   {
-    ERROR ("utils_vl_lookup: malloc failed.");
+    ERROR ("utils_vl_lookup: calloc failed.");
     return (NULL);
   }
-  memset (user_obj, 0, sizeof (*user_obj));
   user_obj->next = NULL;
 
   user_obj->user_obj = obj->cb_user_class (ds, vl, user_class->user_class);
@@ -337,7 +336,7 @@ static int lu_handle_user_class_list (lookup_t *obj, /* {{{ */
 {
   user_class_list_t *ptr;
   int retval = 0;
-  
+
   for (ptr = user_class_list; ptr != NULL; ptr = ptr->next)
   {
     int status;
@@ -373,16 +372,15 @@ static by_type_entry_t *lu_search_by_type (lookup_t *obj, /* {{{ */
     return (NULL);
   }
 
-  by_type = malloc (sizeof (*by_type));
+  by_type = calloc (1, sizeof (*by_type));
   if (by_type == NULL)
   {
-    ERROR ("utils_vl_lookup: malloc failed.");
+    ERROR ("utils_vl_lookup: calloc failed.");
     sfree (type_copy);
     return (NULL);
   }
-  memset (by_type, 0, sizeof (*by_type));
   by_type->wildcard_plugin_list = NULL;
-  
+
   by_type->by_plugin_tree = c_avl_create ((void *) strcmp);
   if (by_type->by_plugin_tree == NULL)
   {
@@ -403,7 +401,7 @@ static by_type_entry_t *lu_search_by_type (lookup_t *obj, /* {{{ */
     sfree (type_copy);
     return (NULL);
   }
-  
+
   return (by_type);
 } /* }}} by_type_entry_t *lu_search_by_type */
 
@@ -509,7 +507,7 @@ static void lu_destroy_user_class_list (lookup_t *obj, /* {{{ */
 static void lu_destroy_by_type (lookup_t *obj, /* {{{ */
     by_type_entry_t *by_type)
 {
-  
+
   while (42)
   {
     char *plugin = NULL;
@@ -544,13 +542,12 @@ lookup_t *lookup_create (lookup_class_callback_t cb_user_class, /* {{{ */
     lookup_free_class_callback_t cb_free_class,
     lookup_free_obj_callback_t cb_free_obj)
 {
-  lookup_t *obj = malloc (sizeof (*obj));
+  lookup_t *obj = calloc (1, sizeof (*obj));
   if (obj == NULL)
   {
-    ERROR ("utils_vl_lookup: malloc failed.");
+    ERROR ("utils_vl_lookup: calloc failed.");
     return (NULL);
   }
-  memset (obj, 0, sizeof (*obj));
 
   obj->by_type_tree = c_avl_create ((void *) strcmp);
   if (obj->by_type_tree == NULL)
@@ -605,13 +602,12 @@ int lookup_add (lookup_t *obj, /* {{{ */
   if (by_type == NULL)
     return (-1);
 
-  user_class_obj = malloc (sizeof (*user_class_obj));
+  user_class_obj = calloc (1, sizeof (*user_class_obj));
   if (user_class_obj == NULL)
   {
-    ERROR ("utils_vl_lookup: malloc failed.");
+    ERROR ("utils_vl_lookup: calloc failed.");
     return (ENOMEM);
   }
-  memset (user_class_obj, 0, sizeof (*user_class_obj));
   pthread_mutex_init (&user_class_obj->entry.lock, /* attr = */ NULL);
   user_class_obj->entry.user_class = user_class;
   lu_copy_ident_to_match (&user_class_obj->entry.match, ident, group_by);
@@ -655,6 +651,6 @@ int lookup_search (lookup_t *obj, /* {{{ */
       return (status);
     retval += status;
   }
-    
+
   return (retval);
 } /* }}} lookup_search */
index 41cc0a4..2d541ee 100644 (file)
@@ -24,8 +24,8 @@
  *   Florian Forster <octo at collectd.org>
  **/
 
-#include "testing.h"
 #include "collectd.h"
+#include "testing.h"
 #include "utils_vl_lookup.h"
 
 static _Bool expect_new_obj = 0;
@@ -68,7 +68,7 @@ static void *lookup_class_callback (data_set_t const *ds,
   assert (expect_new_obj);
 
   memcpy (&last_class_ident, class, sizeof (last_class_ident));
-  
+
   obj = malloc (sizeof (*obj));
   strncpy (obj->host, vl->host, sizeof (obj->host));
   strncpy (obj->plugin, vl->plugin, sizeof (obj->plugin));
index 2df6063..5088217 100644 (file)
@@ -100,7 +100,7 @@ uuid_get_from_dmidecode(void)
     if (!dmidecode) {
         return NULL;
     }
-    
+
     uuid = uuid_parse_dmidecode(dmidecode);
 
     pclose(dmidecode);
index c6c4df0..d7da95a 100644 (file)
@@ -135,6 +135,397 @@ static int varnish_submit_derive (const char *plugin_instance, /* {{{ */
        return (varnish_submit (plugin_instance, category, type, type_instance, value));
 } /* }}} int varnish_submit_derive */
 
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+static int varnish_monitor (void *priv, const struct VSC_point * const pt) /* {{{ */
+{
+       uint64_t val;
+       const user_config_t *conf;
+       const char *class;
+       const char *name;
+
+       if (pt == NULL)
+               return (0);
+
+       conf = priv;
+
+#if HAVE_VARNISH_V4
+       class = pt->section->fantom->type;
+       name  = pt->desc->name;
+
+       if (strcmp(class, "MAIN") != 0)
+               return (0);
+
+#elif HAVE_VARNISH_V3
+       class = pt->class;
+       name  = pt->name;
+
+       if (strcmp(class, "") != 0)
+               return (0);
+#endif
+
+       val = *(const volatile uint64_t*) pt->ptr;
+
+       if (conf->collect_cache)
+       {
+               if (strcmp(name, "cache_hit") == 0)
+                       return varnish_submit_derive (conf->instance, "cache", "cache_result", "hit",     val);
+               else if (strcmp(name, "cache_miss") == 0)
+                       return varnish_submit_derive (conf->instance, "cache", "cache_result", "miss",    val);
+               else if (strcmp(name, "cache_hitpass") == 0)
+                       return varnish_submit_derive (conf->instance, "cache", "cache_result", "hitpass", val);
+       }
+
+       if (conf->collect_connections)
+       {
+               if (strcmp(name, "client_conn") == 0)
+                       return varnish_submit_derive (conf->instance, "connections", "connections", "accepted", val);
+               else if (strcmp(name, "client_drop") == 0)
+                       return varnish_submit_derive (conf->instance, "connections", "connections", "dropped" , val);
+               else if (strcmp(name, "client_req") == 0)
+                       return varnish_submit_derive (conf->instance, "connections", "connections", "received", val);
+       }
+
+#ifdef HAVE_VARNISH_V3
+       if (conf->collect_dirdns)
+       {
+               if (strcmp(name, "dir_dns_lookups") == 0)
+                       return varnish_submit_derive (conf->instance, "dirdns", "cache_operation", "lookups",    val);
+               else if (strcmp(name, "dir_dns_failed") == 0)
+                       return varnish_submit_derive (conf->instance, "dirdns", "cache_result",    "failed",     val);
+               else if (strcmp(name, "dir_dns_hit") == 0)
+                       return varnish_submit_derive (conf->instance, "dirdns", "cache_result",    "hits",       val);
+               else if (strcmp(name, "dir_dns_cache_full") == 0)
+                       return varnish_submit_derive (conf->instance, "dirdns", "cache_result",    "cache_full", val);
+       }
+#endif
+
+       if (conf->collect_esi)
+       {
+               if (strcmp(name, "esi_errors") == 0)
+                       return varnish_submit_derive (conf->instance, "esi", "total_operations", "error",   val);
+               else if (strcmp(name, "esi_parse") == 0)
+                       return varnish_submit_derive (conf->instance, "esi", "total_operations", "parsed",  val);
+               else if (strcmp(name, "esi_warnings") == 0)
+                       return varnish_submit_derive (conf->instance, "esi", "total_operations", "warning", val);
+       }
+
+       if (conf->collect_backend)
+       {
+               if (strcmp(name, "backend_conn") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "success",       val);
+               else if (strcmp(name, "backend_unhealthy") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "not-attempted", val);
+               else if (strcmp(name, "backend_busy") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "too-many",      val);
+               else if (strcmp(name, "backend_fail") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "failures",      val);
+               else if (strcmp(name, "backend_reuse") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "reuses",        val);
+               else if (strcmp(name, "backend_toolate") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "was-closed",    val);
+               else if (strcmp(name, "backend_recycle") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "recycled",      val);
+               else if (strcmp(name, "backend_unused") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "unused",        val);
+               else if (strcmp(name, "backend_retry") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "connections", "retries",       val);
+               else if (strcmp(name, "backend_req") == 0)
+                       return varnish_submit_derive (conf->instance, "backend", "http_requests", "requests",    val);
+               else if (strcmp(name, "n_backend") == 0)
+                       return varnish_submit_gauge  (conf->instance, "backend", "backends", "n_backends",       val);
+       }
+
+       if (conf->collect_fetch)
+       {
+               if (strcmp(name, "fetch_head") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "head",        val);
+               else if (strcmp(name, "fetch_length") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "length",      val);
+               else if (strcmp(name, "fetch_chunked") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "chunked",     val);
+               else if (strcmp(name, "fetch_eof") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "eof",         val);
+               else if (strcmp(name, "fetch_bad") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "bad_headers", val);
+               else if (strcmp(name, "fetch_close") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "close",       val);
+               else if (strcmp(name, "fetch_oldhttp") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "oldhttp",     val);
+               else if (strcmp(name, "fetch_zero") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "zero",        val);
+               else if (strcmp(name, "fetch_failed") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "failed",      val);
+               else if (strcmp(name, "fetch_1xx") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_1xx", val);
+               else if (strcmp(name, "fetch_204") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_204", val);
+               else if (strcmp(name, "fetch_304") == 0)
+                       return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_304", val);
+       }
+
+       if (conf->collect_hcb)
+       {
+               if (strcmp(name, "hcb_nolock") == 0)
+                       return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_nolock", val);
+               else if (strcmp(name, "hcb_lock") == 0)
+                       return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_lock",   val);
+               else if (strcmp(name, "hcb_insert") == 0)
+                       return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "insert",        val);
+       }
+
+       if (conf->collect_objects)
+       {
+               if (strcmp(name, "n_expired") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "expired",            val);
+               else if (strcmp(name, "n_lru_nuked") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_nuked",          val);
+               else if (strcmp(name, "n_lru_saved") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_saved",          val);
+               else if (strcmp(name, "n_lru_moved") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_moved",          val);
+               else if (strcmp(name, "n_deathrow") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "deathrow",           val);
+               else if (strcmp(name, "losthdr") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "header_overflow",    val);
+               else if (strcmp(name, "n_obj_purged") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "purged",             val);
+               else if (strcmp(name, "n_objsendfile") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_sendfile",      val);
+               else if (strcmp(name, "n_objwrite") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_write",         val);
+               else if (strcmp(name, "n_objoverflow") == 0)
+                       return varnish_submit_derive (conf->instance, "objects", "total_objects", "workspace_overflow", val);
+       }
+
+#if HAVE_VARNISH_V3
+       if (conf->collect_ban)
+       {
+               if (strcmp(name, "n_ban") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "total",          val);
+               else if (strcmp(name, "n_ban_add") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "added",          val);
+               else if (strcmp(name, "n_ban_retire") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted",        val);
+               else if (strcmp(name, "n_ban_obj_test") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "objects_tested", val);
+               else if (strcmp(name, "n_ban_re_test") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "regexps_tested", val);
+               else if (strcmp(name, "n_ban_dups") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate",      val);
+       }
+#endif
+#if HAVE_VARNISH_V4
+       if (conf->collect_ban)
+       {
+               if (strcmp(name, "bans") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "total",     val);
+               else if (strcmp(name, "bans_added") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "added",     val);
+               else if (strcmp(name, "bans_obj") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "obj",       val);
+               else if (strcmp(name, "bans_req") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "req",       val);
+               else if (strcmp(name, "bans_completed") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "completed", val);
+               else if (strcmp(name, "bans_deleted") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted",   val);
+               else if (strcmp(name, "bans_tested") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "tested",    val);
+               else if (strcmp(name, "bans_dups") == 0)
+                       return varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", val);
+       }
+#endif
+
+       if (conf->collect_session)
+       {
+               if (strcmp(name, "sess_closed") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "closed",    val);
+               else if (strcmp(name, "sess_pipeline") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "pipeline",  val);
+               else if (strcmp(name, "sess_readahead") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "readahead", val);
+               else if (strcmp(name, "sess_conn") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "accepted",  val);
+               else if (strcmp(name, "sess_drop") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "dropped",   val);
+               else if (strcmp(name, "sess_fail") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "failed",    val);
+               else if (strcmp(name, "sess_pipe_overflow") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "overflow",  val);
+               else if (strcmp(name, "sess_queued") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "queued",    val);
+               else if (strcmp(name, "sess_linger") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "linger",    val);
+               else if (strcmp(name, "sess_herd") == 0)
+                       return varnish_submit_derive (conf->instance, "session", "total_operations", "herd",      val);
+       }
+
+       if (conf->collect_shm)
+       {
+               if (strcmp(name, "shm_records") == 0)
+                       return varnish_submit_derive (conf->instance, "shm", "total_operations", "records",    val);
+               else if (strcmp(name, "shm_writes") == 0)
+                       return varnish_submit_derive (conf->instance, "shm", "total_operations", "writes",     val);
+               else if (strcmp(name, "shm_flushes") == 0)
+                       return varnish_submit_derive (conf->instance, "shm", "total_operations", "flushes",    val);
+               else if (strcmp(name, "shm_cont") == 0)
+                       return varnish_submit_derive (conf->instance, "shm", "total_operations", "contention", val);
+               else if (strcmp(name, "shm_cycles") == 0)
+                       return varnish_submit_derive (conf->instance, "shm", "total_operations", "cycles",     val);
+       }
+
+       if (conf->collect_sms)
+       {
+               if (strcmp(name, "sms_nreq") == 0)
+                       return varnish_submit_derive (conf->instance, "sms", "total_requests", "allocator", val);
+               else if (strcmp(name, "sms_nobj") == 0)
+                       return varnish_submit_gauge (conf->instance,  "sms", "requests", "outstanding",     val);
+               else if (strcmp(name, "sms_nbytes") == 0)
+                       return varnish_submit_gauge (conf->instance,  "sms", "bytes", "outstanding",        val);
+               else if (strcmp(name, "sms_balloc") == 0)
+                       return varnish_submit_derive (conf->instance,  "sms", "total_bytes", "allocated",   val);
+               else if (strcmp(name, "sms_bfree") == 0)
+                       return varnish_submit_derive (conf->instance,  "sms", "total_bytes", "free",        val);
+       }
+
+       if (conf->collect_struct)
+       {
+               if (strcmp(name, "n_sess_mem") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess_mem",  val);
+               else if (strcmp(name, "n_sess") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess",      val);
+               else if (strcmp(name, "n_object") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "object",             val);
+               else if (strcmp(name, "n_vampireobject") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "vampireobject",      val);
+               else if (strcmp(name, "n_objectcore") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "objectcore",         val);
+               else if (strcmp(name, "n_waitinglist") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "waitinglist",        val);
+               else if (strcmp(name, "n_objecthead") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "objecthead",         val);
+               else if (strcmp(name, "n_smf") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "smf",                val);
+               else if (strcmp(name, "n_smf_frag") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "smf_frag",           val);
+               else if (strcmp(name, "n_smf_large") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "smf_large",          val);
+               else if (strcmp(name, "n_vbe_conn") == 0)
+                       return varnish_submit_gauge (conf->instance, "struct", "objects", "vbe_conn",           val);
+       }
+
+       if (conf->collect_totals)
+       {
+               if (strcmp(name, "s_sess") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_sessions", "sessions",  val);
+               else if (strcmp(name, "s_req") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_requests", "requests",  val);
+               else if (strcmp(name, "s_pipe") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_operations", "pipe",    val);
+               else if (strcmp(name, "s_pass") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_operations", "pass",    val);
+               else if (strcmp(name, "s_fetch") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_operations", "fetches", val);
+               else if (strcmp(name, "s_synth") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "synth",        val);
+               else if (strcmp(name, "s_req_hdrbytes") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_header",   val);
+               else if (strcmp(name, "s_req_bodybytes") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_body",     val);
+               else if (strcmp(name, "s_resp_hdrbytes") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_header",  val);
+               else if (strcmp(name, "s_resp_bodybytes") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_body",    val);
+               else if (strcmp(name, "s_pipe_hdrbytes") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_header",  val);
+               else if (strcmp(name, "s_pipe_in") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_in",      val);
+               else if (strcmp(name, "s_pipe_out") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_out",     val);
+               else if (strcmp(name, "n_purges") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_operations", "purges",  val);
+               else if (strcmp(name, "s_hdrbytes") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "header-bytes", val);
+               else if (strcmp(name, "s_bodybytes") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_bytes", "body-bytes",   val);
+               else if (strcmp(name, "n_gzip") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_operations", "gzip",    val);
+               else if (strcmp(name, "n_gunzip") == 0)
+                       return varnish_submit_derive (conf->instance, "totals", "total_operations", "gunzip",  val);
+       }
+
+       if (conf->collect_uptime)
+       {
+               if (strcmp(name, "uptime") == 0)
+                       return varnish_submit_gauge (conf->instance, "uptime", "uptime", "client_uptime", val);
+       }
+
+       if (conf->collect_vcl)
+       {
+               if (strcmp(name, "n_vcl") == 0)
+                       return varnish_submit_gauge (conf->instance, "vcl", "vcl", "total_vcl",     val);
+               else if (strcmp(name, "n_vcl_avail") == 0)
+                       return varnish_submit_gauge (conf->instance, "vcl", "vcl", "avail_vcl",     val);
+               else if (strcmp(name, "n_vcl_discard") == 0)
+                       return varnish_submit_gauge (conf->instance, "vcl", "vcl", "discarded_vcl", val);
+               else if (strcmp(name, "vmods") == 0)
+                       return varnish_submit_gauge (conf->instance, "vcl", "objects", "vmod",      val);
+       }
+
+       if (conf->collect_workers)
+       {
+               if (strcmp(name, "threads") == 0)
+                       return varnish_submit_gauge (conf->instance, "workers", "threads", "worker",               val);
+               else if (strcmp(name, "threads_created") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "created",       val);
+               else if (strcmp(name, "threads_failed") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "failed",        val);
+               else if (strcmp(name, "threads_limited") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "limited",       val);
+               else if (strcmp(name, "threads_destroyed") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped",       val);
+               else if (strcmp(name, "thread_queue_len") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "queue_length",  "threads",       val);
+               else if (strcmp(name, "n_wrk") == 0)
+                       return varnish_submit_gauge (conf->instance, "workers", "threads", "worker",               val);
+               else if (strcmp(name, "n_wrk_create") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "created",       val);
+               else if (strcmp(name, "n_wrk_failed") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "failed",        val);
+               else if (strcmp(name, "n_wrk_max") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "limited",       val);
+               else if (strcmp(name, "n_wrk_drop") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped",       val);
+               else if (strcmp(name, "n_wrk_queue") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_requests", "queued",       val);
+               else if (strcmp(name, "n_wrk_overflow") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_requests", "overflowed",   val);
+               else if (strcmp(name, "n_wrk_queued") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_requests", "queued",       val);
+               else if (strcmp(name, "n_wrk_lqueue") == 0)
+                       return varnish_submit_derive (conf->instance, "workers", "total_requests", "queue_length", val);
+       }
+
+#if HAVE_VARNISH_V4
+       if (conf->collect_vsm)
+       {
+               if (strcmp(name, "vsm_free") == 0)
+                       return varnish_submit_gauge (conf->instance, "vsm", "bytes", "free",              val);
+               else if (strcmp(name, "vsm_used") == 0)
+                       return varnish_submit_gauge (conf->instance, "vsm", "bytes", "used",              val);
+               else if (strcmp(name, "vsm_cooling") == 0)
+                       return varnish_submit_gauge (conf->instance, "vsm", "bytes", "cooling",           val);
+               else if (strcmp(name, "vsm_overflow") == 0)
+                       return varnish_submit_gauge (conf->instance, "vsm", "bytes", "overflow",          val);
+               else if (strcmp(name, "vsm_overflowed") == 0)
+                       return varnish_submit_derive (conf->instance, "vsm", "total_bytes", "overflowed", val);
+       }
+#endif
+
+       return (0);
+
+} /* }}} static int varnish_monitor */
+#else /* if HAVE_VARNISH_V2 */
 static void varnish_monitor (const user_config_t *conf, /* {{{ */
                const c_varnish_stats_t *stats)
 {
@@ -150,41 +541,20 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
 
        if (conf->collect_connections)
        {
-#ifndef HAVE_VARNISH_V4
                /* Client connections accepted */
                varnish_submit_derive (conf->instance, "connections", "connections", "accepted", stats->client_conn);
                /* Connection dropped, no sess */
                varnish_submit_derive (conf->instance, "connections", "connections", "dropped" , stats->client_drop);
-#endif
                /* Client requests received    */
                varnish_submit_derive (conf->instance, "connections", "connections", "received", stats->client_req);
        }
 
-#ifdef HAVE_VARNISH_V3
-       if (conf->collect_dirdns)
-       {
-               /* DNS director lookups */
-               varnish_submit_derive (conf->instance, "dirdns", "cache_operation", "lookups",    stats->dir_dns_lookups);
-               /* DNS director failed lookups */
-               varnish_submit_derive (conf->instance, "dirdns", "cache_result",    "failed",     stats->dir_dns_failed);
-               /* DNS director cached lookups hit */
-               varnish_submit_derive (conf->instance, "dirdns", "cache_result",    "hits",       stats->dir_dns_hit);
-               /* DNS director full dnscache */
-               varnish_submit_derive (conf->instance, "dirdns", "cache_result",    "cache_full", stats->dir_dns_cache_full);
-       }
-#endif
-
        if (conf->collect_esi)
        {
                /* ESI parse errors (unlock)   */
                varnish_submit_derive (conf->instance, "esi", "total_operations", "error",   stats->esi_errors);
-#if HAVE_VARNISH_V2
                /* Objects ESI parsed (unlock) */
                varnish_submit_derive (conf->instance, "esi", "total_operations", "parsed",  stats->esi_parse);
-#else
-               /* ESI parse warnings (unlock) */
-               varnish_submit_derive (conf->instance, "esi", "total_operations", "warning", stats->esi_warnings);
-#endif
        }
 
        if (conf->collect_backend)
@@ -203,13 +573,8 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_derive (conf->instance, "backend", "connections", "was-closed"   , stats->backend_toolate);
                /* Backend conn. recycles      */
                varnish_submit_derive (conf->instance, "backend", "connections", "recycled"     , stats->backend_recycle);
-#if HAVE_VARNISH_V2
                /* Backend conn. unused        */
                varnish_submit_derive (conf->instance, "backend", "connections", "unused"       , stats->backend_unused);
-#else
-               /* Backend conn. retry         */
-               varnish_submit_derive (conf->instance, "backend", "connections", "retries"      , stats->backend_retry);
-#endif
                /* Backend requests mades      */
                varnish_submit_derive (conf->instance, "backend", "http_requests", "requests"   , stats->backend_req);
                /* N backends                  */
@@ -236,14 +601,6 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_derive (conf->instance, "fetch", "http_requests", "zero"       , stats->fetch_zero);
                /* Fetch failed              */
                varnish_submit_derive (conf->instance, "fetch", "http_requests", "failed"     , stats->fetch_failed);
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
-               /* Fetch no body (1xx)       */
-               varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_1xx", stats->fetch_1xx);
-               /* Fetch no body (204)       */
-               varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_204", stats->fetch_204);
-               /* Fetch no body (304)       */
-               varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_304", stats->fetch_304);
-#endif
        }
 
        if (conf->collect_hcb)
@@ -262,32 +619,22 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "expired",            stats->n_expired);
                /* N LRU nuked objects           */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_nuked",          stats->n_lru_nuked);
-#if HAVE_VARNISH_V2
                /* N LRU saved objects           */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_saved",          stats->n_lru_saved);
-#endif
                /* N LRU moved objects           */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_moved",          stats->n_lru_moved);
-#if HAVE_VARNISH_V2
                /* N objects on deathrow         */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "deathrow",           stats->n_deathrow);
-#endif
                /* HTTP header overflows         */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "header_overflow",    stats->losthdr);
-#if HAVE_VARNISH_V4
-               /* N purged objects              */
-               varnish_submit_derive (conf->instance, "objects", "total_objects", "purged",             stats->n_obj_purged);
-#else
                /* Objects sent with sendfile    */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_sendfile",      stats->n_objsendfile);
                /* Objects sent with write       */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_write",         stats->n_objwrite);
                /* Objects overflowing workspace */
                varnish_submit_derive (conf->instance, "objects", "total_objects", "workspace_overflow", stats->n_objoverflow);
-#endif
        }
 
-#if HAVE_VARNISH_V2
        if (conf->collect_purge)
        {
                /* N total active purges      */
@@ -303,45 +650,6 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                /* N duplicate purges removed */
                varnish_submit_derive (conf->instance, "purge", "total_operations", "duplicate",        stats->n_purge_dups);
        }
-#endif
-#if HAVE_VARNISH_V3
-       if (conf->collect_ban)
-       {
-               /* N total active bans      */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "total",          stats->n_ban);
-               /* N new bans added         */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "added",          stats->n_ban_add);
-               /* N old bans deleted       */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted",        stats->n_ban_retire);
-               /* N objects tested         */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "objects_tested", stats->n_ban_obj_test);
-               /* N regexps tested against */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "regexps_tested", stats->n_ban_re_test);
-               /* N duplicate bans removed */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate",      stats->n_ban_dups);
-       }
-#endif
-#if HAVE_VARNISH_V4
-       if (conf->collect_ban)
-       {
-               /* N total active bans      */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "total",          stats->bans);
-               /* N new bans added         */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "added",          stats->bans_added);
-               /* N bans using obj */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "obj",            stats->bans_obj);
-               /* N bans using req */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "req",            stats->bans_req);
-               /* N new bans completed     */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "completed",      stats->bans_completed);
-               /* N old bans deleted       */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted",        stats->bans_deleted);
-               /* N objects tested         */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "tested",         stats->bans_tested);
-               /* N duplicate bans removed */
-               varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate",      stats->bans_dups);
-       }
-#endif
 
        if (conf->collect_session)
        {
@@ -351,21 +659,8 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_derive (conf->instance, "session", "total_operations", "pipeline",  stats->sess_pipeline);
                /* Session Read Ahead */
                varnish_submit_derive (conf->instance, "session", "total_operations", "readahead", stats->sess_readahead);
-#if HAVE_VARNISH_V4
-               /* Sessions accepted */
-               varnish_submit_derive (conf->instance, "session", "total_operations", "accepted",  stats->sess_conn);
-               /* Sessions dropped for thread */
-               varnish_submit_derive (conf->instance, "session", "total_operations", "dropped",   stats->sess_drop);
-               /* Sessions accept failure */
-               varnish_submit_derive (conf->instance, "session", "total_operations", "failed",    stats->sess_fail);
-               /* Sessions pipe overflow */
-               varnish_submit_derive (conf->instance, "session", "total_operations", "overflow",  stats->sess_pipe_overflow);
-               /* Sessions queued for thread */
-               varnish_submit_derive (conf->instance, "session", "total_operations", "queued",    stats->sess_queued);
-#else
                /* Session Linger     */
                varnish_submit_derive (conf->instance, "session", "total_operations", "linger",    stats->sess_linger);
-#endif
                /* Session herd       */
                varnish_submit_derive (conf->instance, "session", "total_operations", "herd",      stats->sess_herd);
        }
@@ -384,7 +679,6 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_derive (conf->instance, "shm", "total_operations", "cycles"    , stats->shm_cycles);
        }
 
-#if HAVE_VARNISH_V2
        if (conf->collect_sm)
        {
                /* allocator requests */
@@ -410,7 +704,6 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                /* SMA bytes free */
                varnish_submit_derive (conf->instance,  "sma", "total_bytes", "free" ,     stats->sma_bfree);
        }
-#endif
 
        if (conf->collect_sms)
        {
@@ -428,25 +721,14 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
 
        if (conf->collect_struct)
        {
-#if !HAVE_VARNISH_V4
                /* N struct sess_mem       */
                varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess_mem",  stats->n_sess_mem);
                /* N struct sess           */
                varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess",      stats->n_sess);
-#endif
                /* N struct object         */
                varnish_submit_gauge (conf->instance, "struct", "objects", "object",             stats->n_object);
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
-               /* N unresurrected objects */
-               varnish_submit_gauge (conf->instance, "struct", "objects", "vampireobject",      stats->n_vampireobject);
-               /* N struct objectcore     */
-               varnish_submit_gauge (conf->instance, "struct", "objects", "objectcore",         stats->n_objectcore);
-               /* N struct waitinglist    */
-               varnish_submit_gauge (conf->instance, "struct", "objects", "waitinglist",        stats->n_waitinglist);
-#endif
                /* N struct objecthead     */
                varnish_submit_gauge (conf->instance, "struct", "objects", "objecthead",         stats->n_objecthead);
-#ifdef HAVE_VARNISH_V2
                /* N struct smf            */
                varnish_submit_gauge (conf->instance, "struct", "objects", "smf",                stats->n_smf);
                /* N small free smf         */
@@ -455,7 +737,6 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_gauge (conf->instance, "struct", "objects", "smf_large",          stats->n_smf_large);
                /* N struct vbe_conn        */
                varnish_submit_gauge (conf->instance, "struct", "objects", "vbe_conn",           stats->n_vbe_conn);
-#endif
        }
 
        if (conf->collect_totals)
@@ -470,47 +751,12 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_derive (conf->instance, "totals", "total_operations", "pass",    stats->s_pass);
                /* Total fetch */
                varnish_submit_derive (conf->instance, "totals", "total_operations", "fetches", stats->s_fetch);
-#if HAVE_VARNISH_V4
-               /* Total synth */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "synth",       stats->s_synth);
-               /* Request header bytes */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_header",  stats->s_req_hdrbytes);
-               /* Request body byte */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_body",    stats->s_req_bodybytes);
-               /* Response header bytes */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_header", stats->s_resp_hdrbytes);
-               /* Response body byte */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_body",   stats->s_resp_bodybytes);
-               /* Pipe request header bytes */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_header", stats->s_pipe_hdrbytes);
-               /* Piped bytes from client */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_in",     stats->s_pipe_in);
-               /* Piped bytes to client */
-               varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_out",    stats->s_pipe_out);
-               /* Number of purge operations */
-               varnish_submit_derive (conf->instance, "totals", "total_operations", "purges", stats->n_purges);
-#else
                /* Total header bytes */
                varnish_submit_derive (conf->instance, "totals", "total_bytes", "header-bytes", stats->s_hdrbytes);
                /* Total body byte */
                varnish_submit_derive (conf->instance, "totals", "total_bytes", "body-bytes",   stats->s_bodybytes);
-#endif
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
-               /* Gzip operations */
-               varnish_submit_derive (conf->instance, "totals", "total_operations", "gzip",    stats->n_gzip);
-               /* Gunzip operations */
-               varnish_submit_derive (conf->instance, "totals", "total_operations", "gunzip",  stats->n_gunzip);
-#endif
        }
 
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
-       if (conf->collect_uptime)
-       {
-               /* Client uptime */
-               varnish_submit_gauge (conf->instance, "uptime", "uptime", "client_uptime", stats->uptime);
-       }
-#endif
-
        if (conf->collect_vcl)
        {
                /* N vcl total     */
@@ -519,28 +765,10 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_gauge (conf->instance, "vcl", "vcl", "avail_vcl",     stats->n_vcl_avail);
                /* N vcl discarded */
                varnish_submit_gauge (conf->instance, "vcl", "vcl", "discarded_vcl", stats->n_vcl_discard);
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
-               /* Loaded VMODs */
-               varnish_submit_gauge (conf->instance, "vcl", "objects", "vmod",      stats->vmods);
-#endif
        }
 
        if (conf->collect_workers)
        {
-#ifdef HAVE_VARNISH_V4
-               /* total number of threads */
-               varnish_submit_gauge (conf->instance, "workers", "threads", "worker",             stats->threads);
-               /* threads created */
-               varnish_submit_derive (conf->instance, "workers", "total_threads", "created",     stats->threads_created);
-               /* thread creation failed */
-               varnish_submit_derive (conf->instance, "workers", "total_threads", "failed",      stats->threads_failed);
-               /* threads hit max */
-               varnish_submit_derive (conf->instance, "workers", "total_threads", "limited",     stats->threads_limited);
-               /* threads destroyed */
-               varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped",     stats->threads_destroyed);
-               /* length of session queue */
-               varnish_submit_derive (conf->instance, "workers", "queue_length",  "threads",     stats->thread_queue_len);
-#else
                /* worker threads */
                varnish_submit_gauge (conf->instance, "workers", "threads", "worker",             stats->n_wrk);
                /* worker threads created */
@@ -551,43 +779,21 @@ static void varnish_monitor (const user_config_t *conf, /* {{{ */
                varnish_submit_derive (conf->instance, "workers", "total_threads", "limited",     stats->n_wrk_max);
                /* dropped work requests */
                varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped",     stats->n_wrk_drop);
-#ifdef HAVE_VARNISH_V2
                /* queued work requests */
                varnish_submit_derive (conf->instance, "workers", "total_requests", "queued",     stats->n_wrk_queue);
                /* overflowed work requests */
                varnish_submit_derive (conf->instance, "workers", "total_requests", "overflowed", stats->n_wrk_overflow);
-#else /* HAVE_VARNISH_V3 */
-               /* queued work requests */
-               varnish_submit_derive (conf->instance, "workers", "total_requests", "queued",       stats->n_wrk_queued);
-               /* work request queue length */
-               varnish_submit_derive (conf->instance, "workers", "total_requests", "queue_length", stats->n_wrk_lqueue);
-#endif
-#endif
        }
 
-#if HAVE_VARNISH_V4
-       if (conf->collect_vsm)
-       {
-               /* Free VSM space */
-               varnish_submit_gauge (conf->instance, "vsm", "bytes", "free",              stats->vsm_free);
-               /* Used VSM space */
-               varnish_submit_gauge (conf->instance, "vsm", "bytes", "used",              stats->vsm_used);
-               /* Cooling VSM space */
-               varnish_submit_gauge (conf->instance, "vsm", "bytes", "cooling",           stats->vsm_cooling);
-               /* Overflow VSM space */
-               varnish_submit_gauge (conf->instance, "vsm", "bytes", "overflow",          stats->vsm_overflow);
-               /* Total overflowed VSM space */
-               varnish_submit_derive (conf->instance, "vsm", "total_bytes", "overflowed", stats->vsm_overflowed);
-       }
-#endif
-
 } /* }}} void varnish_monitor */
+#endif
 
 #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
 static int varnish_read (user_data_t *ud) /* {{{ */
 {
        struct VSM_data *vd;
        const c_varnish_stats_t *stats;
+       _Bool ok;
 
        user_config_t *conf;
 
@@ -617,10 +823,11 @@ static int varnish_read (user_data_t *ud) /* {{{ */
        }
 
 #if HAVE_VARNISH_V3
-       if (VSC_Open (vd, /* diag = */ 1))
+       ok = (VSC_Open (vd, /* diag = */ 1) == 0);
 #else /* if HAVE_VARNISH_V4 */
-       if (VSM_Open (vd))
+       ok = (VSM_Open (vd) == 0);
 #endif
+       if (!ok)
        {
                VSM_Delete (vd);
                ERROR ("varnish plugin: Unable to open connection.");
@@ -641,8 +848,11 @@ static int varnish_read (user_data_t *ud) /* {{{ */
                return (-1);
        }
 
-
-       varnish_monitor (conf, stats);
+#if HAVE_VARNISH_V3
+       VSC_Iter (vd, varnish_monitor, conf);
+#else /* if HAVE_VARNISH_V4 */
+       VSC_Iter (vd, NULL, varnish_monitor, conf);
+#endif
        VSM_Delete (vd);
 
        return (0);
@@ -733,10 +943,9 @@ static int varnish_init (void) /* {{{ */
        if (have_instance)
                return (0);
 
-       conf = malloc (sizeof (*conf));
+       conf = calloc (1, sizeof (*conf));
        if (conf == NULL)
                return (ENOMEM);
-       memset (conf, 0, sizeof (*conf));
 
        /* Default settings: */
        conf->instance = NULL;
@@ -762,10 +971,9 @@ static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
        char callback_name[DATA_MAX_NAME_LEN];
        int i;
 
-       conf = malloc (sizeof (*conf));
+       conf = calloc (1, sizeof (*conf));
        if (conf == NULL)
                return (ENOMEM);
-       memset (conf, 0, sizeof (*conf));
        conf->instance = NULL;
 
        varnish_config_apply_default (conf);
@@ -792,6 +1000,7 @@ static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
        {
                WARNING ("Varnish plugin: \"Instance\" blocks accept only "
                                "one argument.");
+               sfree (conf);
                return (EINVAL);
        }
 
@@ -899,6 +1108,7 @@ static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
                WARNING ("Varnish plugin: No metric has been configured for "
                                "instance \"%s\". Disabling this instance.",
                                (conf->instance == NULL) ? "localhost" : conf->instance);
+               sfree (conf);
                return (EINVAL);
        }
 
index 6824b13..e5a8725 100644 (file)
@@ -327,8 +327,8 @@ lv_init (void)
 {
     if (virInitialize () != 0)
         return -1;
-
-       return 0;
+    else
+        return 0;
 }
 
 static int
@@ -686,8 +686,8 @@ refresh_lists (void)
         int *domids;
 
         /* Get list of domains. */
-        domids = malloc (sizeof (int) * n);
-        if (domids == 0) {
+        domids = malloc (sizeof (*domids) * n);
+        if (domids == NULL) {
             ERROR (PLUGIN_NAME " plugin: malloc failed.");
             return -1;
         }
@@ -833,7 +833,7 @@ refresh_lists (void)
 }
 
 static void
-free_domains ()
+free_domains (void)
 {
     int i;
 
@@ -866,7 +866,7 @@ add_domain (virDomainPtr dom)
 }
 
 static void
-free_block_devices ()
+free_block_devices (void)
 {
     int i;
 
@@ -906,7 +906,7 @@ add_block_device (virDomainPtr dom, const char *path)
 }
 
 static void
-free_interface_devices ()
+free_interface_devices (void)
 {
     int i;
 
index 5e609e6..f501706 100644 (file)
@@ -147,7 +147,7 @@ static int vmem_read (void)
     if (fields[1] == endptr)
       continue;
 
-    /* 
+    /*
      * Number of pages
      *
      * The total number of {inst} pages, e. g dirty pages.
@@ -167,7 +167,7 @@ static int vmem_read (void)
       }
     }
 
-    /* 
+    /*
      * Page in and page outs. For memory and swap.
      */
     else if (strcmp ("pgpgin", key) == 0)
@@ -227,6 +227,19 @@ static int vmem_read (void)
       value_t value  = { .derive = counter };
       submit_one (inst, "vmpage_action", "refill", value);
     }
+    else if (strncmp ("pgsteal_kswapd_", key, strlen ("pgsteal_kswapd_")) == 0)
+    {
+      char *inst = key + strlen ("pgsteal_kswapd_");
+      value_t value  = { .derive = counter };
+      submit_one (inst, "vmpage_action", "steal_kswapd", value);
+    }
+    else if (strncmp ("pgsteal_direct_", key, strlen ("pgsteal_direct_")) == 0)
+    {
+      char *inst = key + strlen ("pgsteal_direct_");
+      value_t value  = { .derive = counter };
+      submit_one (inst, "vmpage_action", "steal_direct", value);
+    }
+    /* For backwards compatibility (somewhen before 4.2.3) */
     else if (strncmp ("pgsteal_", key, strlen ("pgsteal_")) == 0)
     {
       char *inst = key + strlen ("pgsteal_");
index bd2e867..1d957eb 100644 (file)
@@ -146,7 +146,7 @@ static int vserver_read (void)
        if (proc == NULL)
        {
                char errbuf[1024];
-               ERROR ("vserver plugin: fopen (%s): %s", PROCDIR, 
+               ERROR ("vserver plugin: fopen (%s): %s", PROCDIR,
                                sstrerror (errno, errbuf, sizeof (errbuf)));
                return (-1);
        }
@@ -185,7 +185,7 @@ static int vserver_read (void)
                len = ssnprintf (file, sizeof (file), PROCDIR "/%s", dent->d_name);
                if ((len < 0) || (len >= BUFSIZE))
                        continue;
-               
+
                status = stat (file, &statbuf);
                if (status != 0)
                {
@@ -194,7 +194,7 @@ static int vserver_read (void)
                                        file, sstrerror (errno, errbuf, sizeof (errbuf)));
                        continue;
                }
-               
+
                if (!S_ISDIR (statbuf.st_mode))
                        continue;
 
@@ -215,7 +215,7 @@ static int vserver_read (void)
                {
                        derive_t rx;
                        derive_t tx;
-                       char *type_instance;
+                       const char *type_instance;
 
                        if (strsplit (buffer, cols, 4) < 4)
                                continue;
@@ -265,7 +265,7 @@ static int vserver_read (void)
 
                        if (2 == n)
                        {
-                               char   *type_instance;
+                               const char *type_instance;
                                gauge_t value;
 
                                if (0 == strcmp (cols[0], "nr_threads:"))
@@ -314,8 +314,8 @@ static int vserver_read (void)
 
                while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh)))
                {
-                       char *type = "vs_memory";
-                       char *type_instance;
+                       const char *type = "vs_memory";
+                       const char *type_instance;
                        gauge_t value;
 
                        if (strsplit (buffer, cols, 2) < 2)
index f2a3cf5..8445af2 100644 (file)
@@ -41,7 +41,7 @@ static double wireless_dbm_to_watt (double dbm)
 
        /*
         * dbm = 10 * log_{10} (1000 * power / W)
-        * power = 10^(dbm/10) * W/1000 
+        * power = 10^(dbm/10) * W/1000
         */
 
        watt = pow (10.0, (dbm / 10.0)) / 1000.0;
@@ -88,7 +88,7 @@ static int wireless_read (void)
        double  quality;
        double  power;
        double  noise;
-       
+
        char *fields[8];
        int   numfields;
 
index 7fc9eb9..0b8ab41 100644 (file)
@@ -94,8 +94,36 @@ struct wg_callback
     pthread_mutex_t send_lock;
     c_complain_t init_complaint;
     cdtime_t last_connect_time;
+
+    /* Force reconnect useful for load balanced environments */
+    cdtime_t last_reconnect_time;
+    cdtime_t reconnect_interval;
+    _Bool reconnect_interval_reached;
 };
 
+/* wg_force_reconnect_check closes cb->sock_fd when it was open for longer
+ * than cb->reconnect_interval. Must hold cb->send_lock when calling. */
+static void wg_force_reconnect_check (struct wg_callback *cb)
+{
+    cdtime_t now;
+
+    if (cb->reconnect_interval == 0)
+        return;
+
+    /* check if address changes if addr_timeout */
+    now = cdtime ();
+    if ((now - cb->last_reconnect_time) < cb->reconnect_interval)
+        return;
+
+    /* here we should close connection on next */
+    close (cb->sock_fd);
+    cb->sock_fd = -1;
+    cb->last_reconnect_time = now;
+    cb->reconnect_interval_reached = 1;
+
+    INFO ("write_graphite plugin: Connection closed after %.3f seconds.",
+          CDTIME_T_TO_DOUBLE (now - cb->last_reconnect_time));
+}
 
 /*
  * Functions
@@ -113,7 +141,7 @@ static int wg_send_buffer (struct wg_callback *cb)
     ssize_t status = 0;
 
     status = swrite (cb->sock_fd, cb->send_buf, strlen (cb->send_buf));
-    if (status < 0)
+    if (status != 0)
     {
         if (cb->log_send_errors)
         {
@@ -152,7 +180,7 @@ static int wg_flush_nolock (cdtime_t timeout, struct wg_callback *cb)
             return (0);
     }
 
-    if (cb->send_buf_fill <= 0)
+    if (cb->send_buf_fill == 0)
     {
         cb->send_buf_init_time = cdtime ();
         return (0);
@@ -250,7 +278,13 @@ static int wg_callback_init (struct wg_callback *cb)
                 cb->node, cb->service, cb->protocol);
     }
 
-    wg_reset_buffer (cb);
+    /* wg_force_reconnect_check does not flush the buffer before closing a
+     * sending socket, so only call wg_reset_buffer() if the socket was closed
+     * for a different reason (tracked in cb->reconnect_interval_reached). */
+    if (!cb->reconnect_interval_reached || (cb->send_buf_free == 0))
+        wg_reset_buffer (cb);
+    else
+        cb->reconnect_interval_reached = 0;
 
     return (0);
 }
@@ -326,6 +360,8 @@ static int wg_send_message (char const *message, struct wg_callback *cb)
 
     pthread_mutex_lock (&cb->send_lock);
 
+    wg_force_reconnect_check (cb);
+
     if (cb->sock_fd < 0)
     {
         status = wg_callback_init (cb);
@@ -450,18 +486,20 @@ static int wg_config_node (oconfig_item_t *ci)
     int i;
     int status = 0;
 
-    cb = malloc (sizeof (*cb));
+    cb = calloc (1, sizeof (*cb));
     if (cb == NULL)
     {
-        ERROR ("write_graphite plugin: malloc failed.");
+        ERROR ("write_graphite plugin: calloc failed.");
         return (-1);
     }
-    memset (cb, 0, sizeof (*cb));
     cb->sock_fd = -1;
     cb->name = NULL;
     cb->node = strdup (WG_DEFAULT_NODE);
     cb->service = strdup (WG_DEFAULT_SERVICE);
     cb->protocol = strdup (WG_DEFAULT_PROTOCOL);
+    cb->last_reconnect_time = cdtime();
+    cb->reconnect_interval = 0;
+    cb->reconnect_interval_reached = 0;
     cb->log_send_errors = WG_DEFAULT_LOG_SEND_ERRORS;
     cb->prefix = NULL;
     cb->postfix = NULL;
@@ -502,6 +540,8 @@ static int wg_config_node (oconfig_item_t *ci)
                 status = -1;
             }
         }
+        else if (strcasecmp ("ReconnectInterval", child->key) == 0)
+            cf_util_get_cdtime (child, &cb->reconnect_interval);
         else if (strcasecmp ("LogSendErrors", child->key) == 0)
             cf_util_get_boolean (child, &cb->log_send_errors);
         else if (strcasecmp ("Prefix", child->key) == 0)
index 868bca8..8dd37c4 100644 (file)
@@ -69,6 +69,7 @@ struct wh_callback_s
         int format;
 
         CURL *curl;
+        struct curl_slist *headers;
         char curl_errbuf[CURL_ERROR_SIZE];
 
         char  *send_buffer;
@@ -129,8 +130,6 @@ static int wh_send_buffer (wh_callback_t *cb) /* {{{ */
 
 static int wh_callback_init (wh_callback_t *cb) /* {{{ */
 {
-        struct curl_slist *headers;
-
         if (cb->curl != NULL)
                 return (0);
 
@@ -157,14 +156,13 @@ static int wh_callback_init (wh_callback_t *cb) /* {{{ */
         curl_easy_setopt (cb->curl, CURLOPT_NOSIGNAL, 1L);
         curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
 
-        headers = NULL;
-        headers = curl_slist_append (headers, "Accept:  */*");
+        cb->headers = curl_slist_append (cb->headers, "Accept:  */*");
         if (cb->format == WH_FORMAT_JSON)
-                headers = curl_slist_append (headers, "Content-Type: application/json");
+                cb->headers = curl_slist_append (cb->headers, "Content-Type: application/json");
         else
-                headers = curl_slist_append (headers, "Content-Type: text/plain");
-        headers = curl_slist_append (headers, "Expect:");
-        curl_easy_setopt (cb->curl, CURLOPT_HTTPHEADER, headers);
+                cb->headers = curl_slist_append (cb->headers, "Content-Type: text/plain");
+        cb->headers = curl_slist_append (cb->headers, "Expect:");
+        curl_easy_setopt (cb->curl, CURLOPT_HTTPHEADER, cb->headers);
 
         curl_easy_setopt (cb->curl, CURLOPT_ERRORBUFFER, cb->curl_errbuf);
         curl_easy_setopt (cb->curl, CURLOPT_URL, cb->location);
@@ -184,7 +182,7 @@ static int wh_callback_init (wh_callback_t *cb) /* {{{ */
                 if (cb->pass != NULL)
                         credentials_size += strlen (cb->pass);
 
-                cb->credentials = (char *) malloc (credentials_size);
+                cb->credentials = malloc (credentials_size);
                 if (cb->credentials == NULL)
                 {
                         ERROR ("curl plugin: malloc failed.");
@@ -242,7 +240,7 @@ static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */
 
         if (cb->format == WH_FORMAT_COMMAND)
         {
-                if (cb->send_buffer_fill <= 0)
+                if (cb->send_buffer_fill == 0)
                 {
                         cb->send_buffer_init_time = cdtime ();
                         return (0);
@@ -331,6 +329,13 @@ static void wh_callback_free (void *data) /* {{{ */
                 curl_easy_cleanup (cb->curl);
                 cb->curl = NULL;
         }
+
+        if (cb->headers != NULL)
+        {
+                curl_slist_free_all (cb->headers);
+                cb->headers = NULL;
+        }
+
         sfree (cb->name);
         sfree (cb->location);
         sfree (cb->user);
@@ -534,21 +539,40 @@ static int config_set_format (wh_callback_t *cb, /* {{{ */
         return (0);
 } /* }}} int config_set_format */
 
+static int wh_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
+    oconfig_item_t *ci)
+{
+  struct curl_slist *temp = NULL;
+  if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
+  {
+    WARNING ("write_http plugin: `%s' needs exactly one string argument.", name);
+    return (-1);
+  }
+
+  temp = curl_slist_append(*dest, ci->values[0].value.string);
+  if (temp == NULL)
+    return (-1);
+
+  *dest = temp;
+
+  return (0);
+} /* }}} int wh_config_append_string */
+
 static int wh_config_node (oconfig_item_t *ci) /* {{{ */
 {
         wh_callback_t *cb;
         int buffer_size = 0;
         user_data_t user_data;
         char callback_name[DATA_MAX_NAME_LEN];
+        int status = 0;
         int i;
 
-        cb = malloc (sizeof (*cb));
+        cb = calloc (1, sizeof (*cb));
         if (cb == NULL)
         {
-                ERROR ("write_http plugin: malloc failed.");
+                ERROR ("write_http plugin: calloc failed.");
                 return (-1);
         }
-        memset (cb, 0, sizeof (*cb));
         cb->verify_peer = 1;
         cb->verify_host = 1;
         cb->format = WH_FORMAT_COMMAND;
@@ -556,6 +580,8 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
         cb->low_speed_limit = 0;
         cb->timeout = 0;
         cb->log_http_error = 0;
+        cb->headers = NULL;
+
 
         pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
 
@@ -570,30 +596,32 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
                 oconfig_item_t *child = ci->children + i;
 
                 if (strcasecmp ("URL", child->key) == 0)
-                        cf_util_get_string (child, &cb->location);
+                        status = cf_util_get_string (child, &cb->location);
                 else if (strcasecmp ("User", child->key) == 0)
-                        cf_util_get_string (child, &cb->user);
+                        status = cf_util_get_string (child, &cb->user);
                 else if (strcasecmp ("Password", child->key) == 0)
-                        cf_util_get_string (child, &cb->pass);
+                        status = cf_util_get_string (child, &cb->pass);
                 else if (strcasecmp ("VerifyPeer", child->key) == 0)
-                        cf_util_get_boolean (child, &cb->verify_peer);
+                        status = cf_util_get_boolean (child, &cb->verify_peer);
                 else if (strcasecmp ("VerifyHost", child->key) == 0)
-                        cf_util_get_boolean (child, &cb->verify_host);
+                        status = cf_util_get_boolean (child, &cb->verify_host);
                 else if (strcasecmp ("CACert", child->key) == 0)
-                        cf_util_get_string (child, &cb->cacert);
+                        status = cf_util_get_string (child, &cb->cacert);
                 else if (strcasecmp ("CAPath", child->key) == 0)
-                        cf_util_get_string (child, &cb->capath);
+                        status = cf_util_get_string (child, &cb->capath);
                 else if (strcasecmp ("ClientKey", child->key) == 0)
-                        cf_util_get_string (child, &cb->clientkey);
+                        status = cf_util_get_string (child, &cb->clientkey);
                 else if (strcasecmp ("ClientCert", child->key) == 0)
-                        cf_util_get_string (child, &cb->clientcert);
+                        status = cf_util_get_string (child, &cb->clientcert);
                 else if (strcasecmp ("ClientKeyPass", child->key) == 0)
-                        cf_util_get_string (child, &cb->clientkeypass);
+                        status = cf_util_get_string (child, &cb->clientkeypass);
                 else if (strcasecmp ("SSLVersion", child->key) == 0)
                 {
                         char *value = NULL;
 
-                        cf_util_get_string (child, &value);
+                        status = cf_util_get_string (child, &value);
+                        if (status != 0)
+                                break;
 
                         if (value == NULL || strcasecmp ("default", value) == 0)
                                 cb->sslversion = CURL_SSLVERSION_DEFAULT;
@@ -612,28 +640,43 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
                                 cb->sslversion = CURL_SSLVERSION_TLSv1_2;
 #endif
                         else
+                        {
                                 ERROR ("write_http plugin: Invalid SSLVersion "
                                                 "option: %s.", value);
+                                status = EINVAL;
+                        }
 
                         sfree(value);
                 }
                 else if (strcasecmp ("Format", child->key) == 0)
-                        config_set_format (cb, child);
+                        status = config_set_format (cb, child);
                 else if (strcasecmp ("StoreRates", child->key) == 0)
-                        cf_util_get_boolean (child, &cb->store_rates);
+                        status = cf_util_get_boolean (child, &cb->store_rates);
                 else if (strcasecmp ("BufferSize", child->key) == 0)
-                        cf_util_get_int (child, &buffer_size);
+                        status = cf_util_get_int (child, &buffer_size);
                 else if (strcasecmp ("LowSpeedLimit", child->key) == 0)
-                        cf_util_get_int (child, &cb->low_speed_limit);
+                        status = cf_util_get_int (child, &cb->low_speed_limit);
                 else if (strcasecmp ("Timeout", child->key) == 0)
-                        cf_util_get_int (child, &cb->timeout);
+                        status = cf_util_get_int (child, &cb->timeout);
                 else if (strcasecmp ("LogHttpError", child->key) == 0)
-                        cf_util_get_boolean (child, &cb->log_http_error);
+                        status = cf_util_get_boolean (child, &cb->log_http_error);
+                else if (strcasecmp ("Header", child->key) == 0)
+                        status = wh_config_append_string ("Header", &cb->headers, child);
                 else
                 {
                         ERROR ("write_http plugin: Invalid configuration "
                                         "option: %s.", child->key);
+                        status = EINVAL;
                 }
+
+                if (status != 0)
+                        break;
+        }
+
+        if (status != 0)
+        {
+                wh_callback_free (cb);
+                return (status);
         }
 
         if (cb->location == NULL)
index 775e2e0..10ae5a5 100644 (file)
@@ -44,20 +44,19 @@ struct kafka_topic_context {
 #define KAFKA_FORMAT_JSON        0
 #define KAFKA_FORMAT_COMMAND     1
 #define KAFKA_FORMAT_GRAPHITE    2
-    uint8_t                     format;
+    uint8_t                      format;
     unsigned int                 graphite_flags;
     _Bool                        store_rates;
     rd_kafka_topic_conf_t       *conf;
     rd_kafka_topic_t            *topic;
     rd_kafka_conf_t             *kafka_conf;
     rd_kafka_t                  *kafka;
-    int                          has_key;
-    uint32_t                    key;
+    char                        *key;
     char                        *prefix;
     char                        *postfix;
     char                         escape_char;
     char                        *topic_name;
-    pthread_mutex_t            lock;
+    pthread_mutex_t              lock;
 };
 
 static int kafka_handle(struct kafka_topic_context *);
@@ -81,7 +80,7 @@ static int32_t kafka_partition(const rd_kafka_topic_t *rkt,
 {
     uint32_t key = *((uint32_t *)keydata );
     uint32_t target = key % partition_cnt;
-    int32_t   i = partition_cnt;
+    int32_t  i = partition_cnt;
 
     while (--i > 0 && !rd_kafka_topic_partition_available(rkt, target)) {
         target = (target + 1) % partition_cnt;
@@ -106,37 +105,37 @@ static int kafka_handle(struct kafka_topic_context *ctx) /* {{{ */
 
         if ((ctx->kafka = rd_kafka_new(RD_KAFKA_PRODUCER, conf,
                                     errbuf, sizeof(errbuf))) == NULL) {
-               ERROR("write_kafka plugin: cannot create kafka handle.");
-               return 1;
+            ERROR("write_kafka plugin: cannot create kafka handle.");
+            return 1;
         }
 
-       rd_kafka_conf_destroy(ctx->kafka_conf);
-       ctx->kafka_conf = NULL;
+        rd_kafka_conf_destroy(ctx->kafka_conf);
+        ctx->kafka_conf = NULL;
 
-       INFO ("write_kafka plugin: created KAFKA handle : %s", rd_kafka_name(ctx->kafka));
+        INFO ("write_kafka plugin: created KAFKA handle : %s", rd_kafka_name(ctx->kafka));
 
-#ifdef HAVE_LIBRDKAFKA_LOGGER
-       rd_kafka_set_logger(ctx->kafka, kafka_log);
+#if defined(HAVE_LIBRDKAFKA_LOGGER) && !defined(HAVE_LIBRDKAFKA_LOG_CB)
+        rd_kafka_set_logger(ctx->kafka, kafka_log);
 #endif
     }
 
     if (ctx->topic == NULL ) {
-       if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) {
+        if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) {
             ERROR("write_kafka plugin: cannot duplicate kafka topic config");
             return 1;
-       }
+        }
 
-       if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name,
-                                                       topic_conf)) == NULL) {
-               ERROR("write_kafka plugin: cannot create topic : %s\n", 
-                       rd_kafka_err2str(rd_kafka_errno2err(errno)));
-               return errno;
-       }
+        if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name,
+                                            topic_conf)) == NULL) {
+            ERROR("write_kafka plugin: cannot create topic : %s\n",
+            rd_kafka_err2str(rd_kafka_errno2err(errno)));
+            return errno;
+        }
 
-       rd_kafka_topic_conf_destroy(ctx->conf);
-       ctx->conf = NULL;
+        rd_kafka_topic_conf_destroy(ctx->conf);
+        ctx->conf = NULL;
 
-       INFO ("write_kafka plugin: handle created for topic : %s", rd_kafka_topic_name(ctx->topic));
+        INFO ("write_kafka plugin: handle created for topic : %s", rd_kafka_topic_name(ctx->topic));
     }
 
     return(0);
@@ -144,16 +143,17 @@ static int kafka_handle(struct kafka_topic_context *ctx) /* {{{ */
 } /* }}} int kafka_handle */
 
 static int kafka_write(const data_set_t *ds, /* {{{ */
-             const value_list_t *vl,
-             user_data_t *ud)
+          const value_list_t *vl,
+          user_data_t *ud)
 {
-       int                      status = 0;
-    uint32_t    key;
-    char         buffer[8192];
-    size_t bfree = sizeof(buffer);
-    size_t bfill = 0;
-    size_t blen = 0;
-       struct kafka_topic_context      *ctx = ud->data;
+    int      status = 0;
+    void    *key;
+    size_t   keylen = 0;
+    char     buffer[8192];
+    size_t   bfree = sizeof(buffer);
+    size_t   bfill = 0;
+    size_t   blen = 0;
+    struct   kafka_topic_context  *ctx = ud->data;
 
     if ((ds == NULL) || (vl == NULL) || (ctx == NULL))
         return EINVAL;
@@ -177,7 +177,6 @@ static int kafka_write(const data_set_t *ds, /* {{{ */
         blen = strlen(buffer);
         break;
     case KAFKA_FORMAT_JSON:
-
         format_json_initialize(buffer, &bfill, &bfree);
         format_json_value_list(buffer, &bfill, &bfree, ds, vl,
                                ctx->store_rates);
@@ -200,27 +199,25 @@ static int kafka_write(const data_set_t *ds, /* {{{ */
         return -1;
     }
 
-    /*
-     * We partition our stream by metric name
-     */
-    if (ctx->has_key)
-        key = ctx->key;
+    key = ctx->key;
+    if (key != NULL)
+        keylen = strlen (key);
     else
-        key = rand();
+        keylen = 0;
 
     rd_kafka_produce(ctx->topic, RD_KAFKA_PARTITION_UA,
                      RD_KAFKA_MSG_F_COPY, buffer, blen,
-                     &key, sizeof(key), NULL);
+                     key, keylen, NULL);
 
-       return status;
+    return status;
 } /* }}} int kafka_write */
 
 static void kafka_topic_context_free(void *p) /* {{{ */
 {
-       struct kafka_topic_context *ctx = p;
+    struct kafka_topic_context *ctx = p;
 
-       if (ctx == NULL)
-               return;
+    if (ctx == NULL)
+        return;
 
     if (ctx->topic_name != NULL)
         sfree(ctx->topic_name);
@@ -246,17 +243,18 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
     char                         callback_name[DATA_MAX_NAME_LEN];
     char                         errbuf[1024];
     user_data_t                  ud;
-       oconfig_item_t              *child;
+    oconfig_item_t              *child;
     rd_kafka_conf_res_t          ret;
 
-       if ((tctx = calloc(1, sizeof (*tctx))) == NULL) {
-               ERROR ("write_kafka plugin: calloc failed.");
+    if ((tctx = calloc(1, sizeof (*tctx))) == NULL) {
+        ERROR ("write_kafka plugin: calloc failed.");
         return;
-       }
+    }
 
     tctx->escape_char = '.';
     tctx->store_rates = 1;
     tctx->format = KAFKA_FORMAT_JSON;
+    tctx->key = NULL;
 
     if ((tctx->kafka_conf = rd_kafka_conf_dup(conf)) == NULL) {
         sfree(tctx);
@@ -290,48 +288,37 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
         goto errout;
     }
 
-       for (i = 0; i < ci->children_num; i++) {
-               /*
-                * The code here could be simplified but makes room
-                * for easy adding of new options later on.
-                */
-               child = &ci->children[i];
-               status = 0;
-
-               if (strcasecmp ("Property", child->key) == 0) {
-                       if (child->values_num != 2) {
-                               WARNING("kafka properties need both a key and a value.");
+    for (i = 0; i < ci->children_num; i++) {
+        /*
+         * The code here could be simplified but makes room
+         * for easy adding of new options later on.
+         */
+        child = &ci->children[i];
+        status = 0;
+
+        if (strcasecmp ("Property", child->key) == 0) {
+            if (child->values_num != 2) {
+                WARNING("kafka properties need both a key and a value.");
                 goto errout;
-                       }
-                       if (child->values[0].type != OCONFIG_TYPE_STRING ||
-                           child->values[1].type != OCONFIG_TYPE_STRING) {
-                               WARNING("kafka properties needs string arguments.");
+            }
+            if (child->values[0].type != OCONFIG_TYPE_STRING ||
+                child->values[1].type != OCONFIG_TYPE_STRING) {
+                WARNING("kafka properties needs string arguments.");
                 goto errout;
-                       }
+            }
             key = child->values[0].value.string;
             val = child->values[1].value.string;
             ret = rd_kafka_topic_conf_set(tctx->conf,key, val,
                                           errbuf, sizeof(errbuf));
             if (ret != RD_KAFKA_CONF_OK) {
-                               WARNING("cannot set kafka topic property %s to %s: %s.",
+                WARNING("cannot set kafka topic property %s to %s: %s.",
                         key, val, errbuf);
                 goto errout;
-                       }
-
-        } else if (strcasecmp ("Key", child->key) == 0)  {
-            char *tmp_buf = NULL;
-            status = cf_util_get_string(child, &tmp_buf);
-            if (status != 0) {
-                WARNING("write_kafka plugin: invalid key supplied");
-                break;
-            }
-
-            if (strcasecmp(tmp_buf, "Random") != 0) {
-                tctx->has_key = 1;
-                tctx->key = crc32_buffer((u_char *)tmp_buf, strlen(tmp_buf));
             }
-            sfree(tmp_buf);
 
+        } else if (strcasecmp ("Key", child->key) == 0)  {
+            cf_util_get_string (child, &tctx->key);
+            assert (tctx->key != NULL);
         } else if (strcasecmp ("Format", child->key) == 0) {
             status = cf_util_get_string(child, &key);
             if (status != 0)
@@ -397,11 +384,11 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
     ud.data = tctx;
     ud.free_func = kafka_topic_context_free;
 
-       status = plugin_register_write (callback_name, kafka_write, &ud);
-       if (status != 0) {
-               WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
-                               "failed with status %i.",
-                               callback_name, status);
+    status = plugin_register_write (callback_name, kafka_write, &ud);
+    if (status != 0) {
+        WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
+                "failed with status %i.",
+                callback_name, status);
         goto errout;
     }
 
@@ -414,14 +401,14 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
     if (tctx->conf != NULL)
         rd_kafka_topic_conf_destroy(tctx->conf);
     if (tctx->kafka_conf != NULL)
-               rd_kafka_conf_destroy(tctx->kafka_conf);
+        rd_kafka_conf_destroy(tctx->kafka_conf);
     sfree(tctx);
 } /* }}} int kafka_config_topic */
 
 static int kafka_config(oconfig_item_t *ci) /* {{{ */
 {
-       int                          i;
-       oconfig_item_t              *child;
+    int                          i;
+    oconfig_item_t              *child;
     rd_kafka_conf_t             *conf;
     rd_kafka_conf_res_t          ret;
     char                         errbuf[1024];
@@ -430,49 +417,52 @@ static int kafka_config(oconfig_item_t *ci) /* {{{ */
         WARNING("cannot allocate kafka configuration.");
         return -1;
     }
-       for (i = 0; i < ci->children_num; i++)  {
-               child = &ci->children[i];
+    for (i = 0; i < ci->children_num; i++)  {
+        child = &ci->children[i];
 
-               if (strcasecmp("Topic", child->key) == 0) {
-                       kafka_config_topic (conf, child);
-               } else if (strcasecmp(child->key, "Property") == 0) {
-                       char *key = NULL;
-                       char *val = NULL;
+        if (strcasecmp("Topic", child->key) == 0) {
+            kafka_config_topic (conf, child);
+        } else if (strcasecmp(child->key, "Property") == 0) {
+            char *key = NULL;
+            char *val = NULL;
 
-                       if (child->values_num != 2) {
-                               WARNING("kafka properties need both a key and a value.");
+            if (child->values_num != 2) {
+                WARNING("kafka properties need both a key and a value.");
                 goto errout;
-                       }
-                       if (child->values[0].type != OCONFIG_TYPE_STRING ||
-                           child->values[1].type != OCONFIG_TYPE_STRING) {
-                               WARNING("kafka properties needs string arguments.");
+            }
+            if (child->values[0].type != OCONFIG_TYPE_STRING ||
+                child->values[1].type != OCONFIG_TYPE_STRING) {
+                WARNING("kafka properties needs string arguments.");
                 goto errout;
-                       }
-                       if ((key = strdup(child->values[0].value.string)) == NULL) {
-                               WARNING("cannot allocate memory for attribute key.");
+            }
+            if ((key = strdup(child->values[0].value.string)) == NULL) {
+                WARNING("cannot allocate memory for attribute key.");
                 goto errout;
-                       }
-                       if ((val = strdup(child->values[1].value.string)) == NULL) {
-                               WARNING("cannot allocate memory for attribute value.");
+            }
+            if ((val = strdup(child->values[1].value.string)) == NULL) {
+                WARNING("cannot allocate memory for attribute value.");
+                sfree(key);
                 goto errout;
-                       }
+            }
             ret = rd_kafka_conf_set(conf, key, val, errbuf, sizeof(errbuf));
             if (ret != RD_KAFKA_CONF_OK) {
                 WARNING("cannot set kafka property %s to %s: %s",
                         key, val, errbuf);
+                sfree(key);
+                sfree(val);
                 goto errout;
             }
-                       sfree(key);
-                       sfree(val);
-               } else {
-                       WARNING ("write_kafka plugin: Ignoring unknown "
-                                "configuration option \"%s\" at top level.",
-                                child->key);
-               }
-       }
+            sfree(key);
+            sfree(val);
+        } else {
+            WARNING ("write_kafka plugin: Ignoring unknown "
+                 "configuration option \"%s\" at top level.",
+                 child->key);
+        }
+    }
     if (conf != NULL)
         rd_kafka_conf_destroy(conf);
-       return (0);
+    return (0);
  errout:
     if (conf != NULL)
         rd_kafka_conf_destroy(conf);
@@ -481,7 +471,5 @@ static int kafka_config(oconfig_item_t *ci) /* {{{ */
 
 void module_register(void)
 {
-       plugin_register_complex_config ("write_kafka", kafka_config);
+    plugin_register_complex_config ("write_kafka", kafka_config);
 }
-
-/* vim: set sw=8 sts=8 ts=8 noet : */
index 24151ce..9a6fdf2 100644 (file)
@@ -274,10 +274,9 @@ static int wm_config_node (oconfig_item_t *ci) /* {{{ */
   int status;
   int i;
 
-  node = malloc (sizeof (*node));
+  node = calloc (1, sizeof (*node));
   if (node == NULL)
     return (ENOMEM);
-  memset (node, 0, sizeof (*node));
   mongo_init (node->conn);
   node->host = NULL;
   node->store_rates = 1;
index 7ba476c..a79eb36 100644 (file)
@@ -46,6 +46,8 @@ struct wr_node_s
   struct timeval timeout;
   char *prefix;
   int database;
+  int max_set_size;
+  _Bool store_rates;
 
   redisContext *conn;
   pthread_mutex_t lock;
@@ -68,7 +70,6 @@ static int wr_write (const data_set_t *ds, /* {{{ */
   char *value_ptr;
   int status;
   redisReply   *rr;
-  int i;
 
   status = FORMAT_VL (ident, sizeof (ident), vl);
   if (status != 0)
@@ -81,44 +82,12 @@ static int wr_write (const data_set_t *ds, /* {{{ */
   memset (value, 0, sizeof (value));
   value_size = sizeof (value);
   value_ptr = &value[0];
-
-#define APPEND(...) do {                                             \
-  status = snprintf (value_ptr, value_size, __VA_ARGS__);            \
-  if (((size_t) status) > value_size)                                \
-  {                                                                  \
-    value_ptr += value_size;                                         \
-    value_size = 0;                                                  \
-  }                                                                  \
-  else                                                               \
-  {                                                                  \
-    value_ptr += status;                                             \
-    value_size -= status;                                            \
-  }                                                                  \
-} while (0)
-
-  APPEND ("%s:", time);
-
-  for (i = 0; i < ds->ds_num; i++)
-  {
-    if (ds->ds[i].type == DS_TYPE_COUNTER)
-      APPEND ("%llu", vl->values[i].counter);
-    else if (ds->ds[i].type == DS_TYPE_GAUGE)
-      APPEND (GAUGE_FORMAT, vl->values[i].gauge);
-    else if (ds->ds[i].type == DS_TYPE_DERIVE)
-      APPEND ("%"PRIi64, vl->values[i].derive);
-    else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
-      APPEND ("%"PRIu64, vl->values[i].absolute);
-    else
-      assert (23 == 42);
-  }
-
-#undef APPEND
-
-  status = format_values (value_ptr, value_size, ds, vl, /* store rates = */ 0);
-  pthread_mutex_lock (&node->lock);
+  status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
   if (status != 0)
     return (status);
 
+  pthread_mutex_lock (&node->lock);
+
   if (node->conn == NULL)
   {
     node->conn = redisConnectWithTimeout ((char *)node->host, node->port, node->timeout);
@@ -139,7 +108,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */
       pthread_mutex_unlock (&node->lock);
       return (-1);
     }
-   
+
     rr = redisCommand(node->conn, "SELECT %d", node->database);
     if (rr == NULL)
       WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr);
@@ -153,6 +122,15 @@ static int wr_write (const data_set_t *ds, /* {{{ */
   else
     freeReplyObject (rr);
 
+  if (node->max_set_size >= 0)
+  {
+    rr = redisCommand (node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, (-1 * node->max_set_size) - 1);
+    if (rr == NULL)
+      WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, node->conn->errstr);
+    else
+      freeReplyObject (rr);
+  }
+
   /* TODO(octo): This is more overhead than necessary. Use the cache and
    * metadata to determine if it is a new metric and call SADD only once for
    * each metric. */
@@ -193,10 +171,9 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
   int status;
   int i;
 
-  node = malloc (sizeof (*node));
+  node = calloc (1, sizeof (*node));
   if (node == NULL)
     return (ENOMEM);
-  memset (node, 0, sizeof (*node));
   node->host = NULL;
   node->port = 0;
   node->timeout.tv_sec = 0;
@@ -204,6 +181,8 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
   node->conn = NULL;
   node->prefix = NULL;
   node->database = 0;
+  node->max_set_size = -1;
+  node->store_rates = 1;
   pthread_mutex_init (&node->lock, /* attr = */ NULL);
 
   status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name));
@@ -238,6 +217,12 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
     else if (strcasecmp ("Database", child->key) == 0) {
       status = cf_util_get_int (child, &node->database);
     }
+    else if (strcasecmp ("MaxSetSize", child->key) == 0) {
+      status = cf_util_get_int (child, &node->max_set_size);
+    }
+    else if (strcasecmp ("StoreRates", child->key) == 0) {
+      status = cf_util_get_boolean (child, &node->store_rates);
+    }
     else
       WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".",
           child->key);
index 73d202c..2936dfa 100644 (file)
@@ -2,6 +2,7 @@
  * collectd - src/write_riemann.c
  * Copyright (C) 2012,2013  Pierre-Yves Ritschard
  * Copyright (C) 2013       Florian octo Forster
+ * Copyright (C) 2015,2016  Gergely Nagy
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  * Authors:
  *   Pierre-Yves Ritschard <pyr at spootnik.org>
  *   Florian octo Forster <octo at collectd.org>
+ *   Gergely Nagy <algernon at madhouse-project.org>
  */
 
+#include <riemann/riemann-client.h>
+#include <errno.h>
+#include <pthread.h>
+
 #include "collectd.h"
 #include "plugin.h"
 #include "common.h"
 #include "configfile.h"
 #include "utils_cache.h"
-#include "riemann.pb-c.h"
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <netdb.h>
-#include <inttypes.h>
-#include <pthread.h>
+#include "utils_complain.h"
+#include "write_riemann_threshold.h"
 
 #define RIEMANN_HOST           "localhost"
-#define RIEMANN_PORT           "5555"
+#define RIEMANN_PORT           5555
 #define RIEMANN_TTL_FACTOR      2.0
 #define RIEMANN_BATCH_MAX      8192
 
-int write_riemann_threshold_check(const data_set_t *, const value_list_t *, int *);
-
 struct riemann_host {
+    c_complain_t init_complaint;
        char                    *name;
        char                    *event_service_prefix;
-#define F_CONNECT       0x01
-       uint8_t                  flags;
        pthread_mutex_t  lock;
     _Bool            batch_mode;
        _Bool            notifications;
@@ -58,14 +56,19 @@ struct riemann_host {
        _Bool                    store_rates;
        _Bool                    always_append_ds;
        char                    *node;
-       char                    *service;
-       _Bool                    use_tcp;
-       int                          s;
+       int                      port;
+       riemann_client_type_t    client_type;
+       riemann_client_t        *client;
        double                   ttl_factor;
-    Msg             *batch_msg;
     cdtime_t         batch_init;
     int              batch_max;
+    int              batch_timeout;
        int                          reference_count;
+  riemann_message_t    *batch_msg;
+       char                     *tls_ca_file;
+       char                     *tls_cert_file;
+       char                     *tls_key_file;
+       struct timeval timeout;
 };
 
 static char    **riemann_tags;
@@ -73,334 +76,121 @@ static size_t       riemann_tags_num;
 static char    **riemann_attrs;
 static size_t     riemann_attrs_num;
 
-static void riemann_event_protobuf_free (Event *event) /* {{{ */
-{
-       size_t i;
-
-       if (event == NULL)
-               return;
-
-       sfree (event->state);
-       sfree (event->service);
-       sfree (event->host);
-       sfree (event->description);
-
-       strarray_free (event->tags, event->n_tags);
-       event->tags = NULL;
-       event->n_tags = 0;
-
-       for (i = 0; i < event->n_attributes; i++)
-       {
-               sfree (event->attributes[i]->key);
-               sfree (event->attributes[i]->value);
-               sfree (event->attributes[i]);
-       }
-       sfree (event->attributes);
-       event->n_attributes = 0;
-
-       sfree (event);
-} /* }}} void riemann_event_protobuf_free */
-
-static void riemann_msg_protobuf_free(Msg *msg) /* {{{ */
-{
-       size_t i;
-
-       if (msg == NULL)
-               return;
-
-       for (i = 0; i < msg->n_events; i++)
-       {
-               riemann_event_protobuf_free (msg->events[i]);
-               msg->events[i] = NULL;
-       }
-
-       sfree (msg->events);
-       msg->n_events = 0;
-
-       sfree (msg);
-} /* }}} void riemann_msg_protobuf_free */
-
 /* host->lock must be held when calling this function. */
-static int riemann_connect(struct riemann_host *host) /* {{{ */
+static int wrr_connect(struct riemann_host *host) /* {{{ */
 {
-       int                      e;
-       struct addrinfo         *ai, *res, hints;
        char const              *node;
-       char const              *service;
+       int                      port;
 
-       if (host->flags & F_CONNECT)
+       if (host->client)
                return 0;
 
-       memset(&hints, 0, sizeof(hints));
-       memset(&service, 0, sizeof(service));
-       hints.ai_family = AF_UNSPEC;
-       hints.ai_socktype = host->use_tcp ? SOCK_STREAM : SOCK_DGRAM;
-#ifdef AI_ADDRCONFIG
-       hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-
        node = (host->node != NULL) ? host->node : RIEMANN_HOST;
-       service = (host->service != NULL) ? host->service : RIEMANN_PORT;
-
-       if ((e = getaddrinfo(node, service, &hints, &res)) != 0) {
-               ERROR ("write_riemann plugin: Unable to resolve host \"%s\": %s",
-                       node, gai_strerror(e));
+       port = (host->port) ? host->port : RIEMANN_PORT;
+
+       host->client = NULL;
+
+       host->client = riemann_client_create(host->client_type, node, port,
+                                            RIEMANN_CLIENT_OPTION_TLS_CA_FILE, host->tls_ca_file,
+                                            RIEMANN_CLIENT_OPTION_TLS_CERT_FILE, host->tls_cert_file,
+                                            RIEMANN_CLIENT_OPTION_TLS_KEY_FILE, host->tls_key_file,
+                                            RIEMANN_CLIENT_OPTION_NONE);
+       if (host->client == NULL) {
+        c_complain (LOG_ERR, &host->init_complaint,
+                    "write_riemann plugin: Unable to connect to Riemann at %s:%d",
+                    node, port);
                return -1;
        }
-
-       host->s = -1;
-       for (ai = res; ai != NULL; ai = ai->ai_next) {
-               if ((host->s = socket(ai->ai_family,
-                                     ai->ai_socktype,
-                                     ai->ai_protocol)) == -1) {
-                       continue;
-               }
-
-               if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) {
-                       close(host->s);
-                       host->s = -1;
-                       continue;
+       if (host->timeout.tv_sec != 0) {
+               if (riemann_client_set_timeout(host->client, &host->timeout) != 0) {
+                       riemann_client_free(host->client);
+                       host->client = NULL;
+            c_complain (LOG_ERR, &host->init_complaint,
+                        "write_riemann plugin: Unable to connect to Riemann at %s:%d",
+                        node, port);
+                       return -1;
                }
-
-               host->flags |= F_CONNECT;
-               DEBUG("write_riemann plugin: got a successful connection for: %s:%s",
-                               node, service);
-               break;
        }
 
-       freeaddrinfo(res);
+    c_release (LOG_INFO, &host->init_complaint,
+               "write_riemann plugin: Successfully connected to %s:%d",
+               node, port);
 
-       if (host->s < 0) {
-               WARNING("write_riemann plugin: Unable to connect to Riemann at %s:%s",
-                               node, service);
-               return -1;
-       }
        return 0;
-} /* }}} int riemann_connect */
+} /* }}} int wrr_connect */
 
 /* host->lock must be held when calling this function. */
-static int riemann_disconnect (struct riemann_host *host) /* {{{ */
+static int wrr_disconnect(struct riemann_host *host) /* {{{ */
 {
-       if ((host->flags & F_CONNECT) == 0)
+       if (!host->client)
                return (0);
 
-       close (host->s);
-       host->s = -1;
-       host->flags &= ~F_CONNECT;
+       riemann_client_free(host->client);
+       host->client = NULL;
 
        return (0);
-} /* }}} int riemann_disconnect */
-
-static int riemann_send_msg (struct riemann_host *host, const Msg *msg) /* {{{ */
-{
-       int status = 0;
-       u_char *buffer = NULL;
-       size_t  buffer_len;
-
-       status = riemann_connect (host);
-       if (status != 0)
-               return status;
-
-       buffer_len = msg__get_packed_size(msg);
-
-       if (host->use_tcp)
-               buffer_len += 4;
-
-       buffer = malloc (buffer_len);
-       if (buffer == NULL) {
-               ERROR ("write_riemann plugin: malloc failed.");
-               return ENOMEM;
-       }
-       memset (buffer, 0, buffer_len);
-
-       if (host->use_tcp)
-       {
-               uint32_t length = htonl ((uint32_t) (buffer_len - 4));
-               memcpy (buffer, &length, 4);
-               msg__pack(msg, buffer + 4);
-       }
-       else
-       {
-               msg__pack(msg, buffer);
-       }
-
-       status = (int) swrite (host->s, buffer, buffer_len);
-       if (status != 0)
-       {
-               char errbuf[1024];
-               ERROR ("write_riemann plugin: Sending to Riemann at %s:%s failed: %s",
-                               (host->node != NULL) ? host->node : RIEMANN_HOST,
-                               (host->service != NULL) ? host->service : RIEMANN_PORT,
-                               sstrerror (errno, errbuf, sizeof (errbuf)));
-               sfree (buffer);
-               return -1;
-       }
-
-       sfree (buffer);
-       return 0;
-} /* }}} int riemann_send_msg */
-
-static int riemann_recv_ack(struct riemann_host *host) /* {{{ */
-{
-       int status = 0;
-       Msg *msg = NULL;
-       uint32_t header;
-
-       status = (int) sread (host->s, &header, 4);
-
-       if (status != 0)
-               return -1;
-
-       size_t size = ntohl(header);
-
-       // Buffer on the stack since acknowledges are typically small.
-       u_char buffer[size];
-       memset (buffer, 0, size);
-
-       status = (int) sread (host->s, buffer, size);
-
-       if (status != 0)
-               return status;
-
-       msg = msg__unpack (NULL, size, buffer);
-
-       if (msg == NULL)
-               return -1;
-
-       if (!msg->ok)
-       {
-               ERROR ("write_riemann plugin: Sending to Riemann at %s:%s acknowledgement message reported error: %s",
-                               (host->node != NULL) ? host->node : RIEMANN_HOST,
-                               (host->service != NULL) ? host->service : RIEMANN_PORT,
-                               msg->error);
-
-               msg__free_unpacked(msg, NULL);
-               return -1;
-       }
-
-       msg__free_unpacked (msg, NULL);
-       return 0;
-} /* }}} int riemann_recv_ack */
+} /* }}} int wrr_disconnect */
 
 /**
- * Function to send messages (Msg) to riemann.
+ * Function to send messages to riemann.
  *
  * Acquires the host lock, disconnects on errors.
  */
-static int riemann_send(struct riemann_host *host, Msg const *msg) /* {{{ */
+static int wrr_send_nolock(struct riemann_host *host, riemann_message_t *msg) /* {{{ */
 {
        int status = 0;
-       pthread_mutex_lock (&host->lock);
 
-       status = riemann_send_msg(host, msg);
+       status = wrr_connect(host);
        if (status != 0) {
-               riemann_disconnect (host);
-               pthread_mutex_unlock (&host->lock);
+               return status;
+    }
+
+       status = riemann_client_send_message(host->client, msg);
+       if (status != 0) {
+               wrr_disconnect(host);
                return status;
        }
 
        /*
         * For TCP we need to receive message acknowledgemenent.
         */
-       if (host->use_tcp)
+       if (host->client_type != RIEMANN_CLIENT_UDP)
        {
-               status = riemann_recv_ack(host);
+               riemann_message_t *response;
 
-               if (status != 0)
+               response = riemann_client_recv_message(host->client);
+
+               if (response == NULL)
                {
-                       riemann_disconnect (host);
-                       pthread_mutex_unlock (&host->lock);
-                       return status;
+                       wrr_disconnect(host);
+                       return errno;
                }
+               riemann_message_free(response);
        }
 
-       pthread_mutex_unlock (&host->lock);
        return 0;
-} /* }}} int riemann_send */
+} /* }}} int wrr_send */
 
-static int riemann_event_add_tag (Event *event, char const *tag) /* {{{ */
+static int wrr_send(struct riemann_host *host, riemann_message_t *msg)
 {
-       return (strarray_add (&event->tags, &event->n_tags, tag));
-} /* }}} int riemann_event_add_tag */
+    int status = 0;
 
-static int riemann_event_add_attribute(Event *event, /* {{{ */
-               char const *key, char const *value)
-{
-       Attribute **new_attributes;
-       Attribute *a;
-
-       new_attributes = realloc (event->attributes,
-                       sizeof (*event->attributes) * (event->n_attributes + 1));
-       if (new_attributes == NULL)
-       {
-               ERROR ("write_riemann plugin: realloc failed.");
-               return (ENOMEM);
-       }
-       event->attributes = new_attributes;
-
-       a = malloc (sizeof (*a));
-       if (a == NULL)
-       {
-               ERROR ("write_riemann plugin: malloc failed.");
-               return (ENOMEM);
-       }
-       attribute__init (a);
-
-       a->key = strdup (key);
-       if (value != NULL)
-               a->value = strdup (value);
-
-       event->attributes[event->n_attributes] = a;
-       event->n_attributes++;
-
-       return (0);
-} /* }}} int riemann_event_add_attribute */
+    pthread_mutex_lock (&host->lock);
+    status = wrr_send_nolock(host, msg);
+    pthread_mutex_unlock (&host->lock);
+    return status;
+}
 
-static Msg *riemann_notification_to_protobuf(struct riemann_host *host, /* {{{ */
+static riemann_message_t *wrr_notification_to_message(struct riemann_host *host, /* {{{ */
                notification_t const *n)
 {
-       Msg *msg;
-       Event *event;
+       riemann_message_t *msg;
+       riemann_event_t *event;
        char service_buffer[6 * DATA_MAX_NAME_LEN];
        char const *severity;
        notification_meta_t *meta;
        size_t i;
 
-       msg = malloc (sizeof (*msg));
-       if (msg == NULL)
-       {
-               ERROR ("write_riemann plugin: malloc failed.");
-               return (NULL);
-       }
-       memset (msg, 0, sizeof (*msg));
-       msg__init (msg);
-
-       msg->events = malloc (sizeof (*msg->events));
-       if (msg->events == NULL)
-       {
-               ERROR ("write_riemann plugin: malloc failed.");
-               sfree (msg);
-               return (NULL);
-       }
-
-       event = malloc (sizeof (*event));
-       if (event == NULL)
-       {
-               ERROR ("write_riemann plugin: malloc failed.");
-               sfree (msg->events);
-               sfree (msg);
-               return (NULL);
-       }
-       memset (event, 0, sizeof (*event));
-       event__init (event);
-
-       msg->events[0] = event;
-       msg->n_events = 1;
-
-       event->host = strdup (n->host);
-       event->time = CDTIME_T_TO_TIME_T (n->time);
-       event->has_time = 1;
-
        switch (n->severity)
        {
                case NOTIF_OKAY:        severity = "ok"; break;
@@ -408,354 +198,363 @@ static Msg *riemann_notification_to_protobuf(struct riemann_host *host, /* {{{ *
                case NOTIF_FAILURE:     severity = "critical"; break;
                default:                severity = "unknown";
        }
-       event->state = strdup (severity);
 
-       riemann_event_add_tag (event, "notification");
+       format_name(service_buffer, sizeof(service_buffer),
+                   /* host = */ "", n->plugin, n->plugin_instance,
+                   n->type, n->type_instance);
+
+       event = riemann_event_create(RIEMANN_EVENT_FIELD_HOST, n->host,
+                                    RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(n->time),
+                                    RIEMANN_EVENT_FIELD_TAGS, "notification", NULL,
+                                    RIEMANN_EVENT_FIELD_STATE, severity,
+                                    RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
+                                    RIEMANN_EVENT_FIELD_NONE);
+
        if (n->host[0] != 0)
-               riemann_event_add_attribute (event, "host", n->host);
+               riemann_event_string_attribute_add(event, "host", n->host);
        if (n->plugin[0] != 0)
-               riemann_event_add_attribute (event, "plugin", n->plugin);
+               riemann_event_string_attribute_add(event, "plugin", n->plugin);
        if (n->plugin_instance[0] != 0)
-               riemann_event_add_attribute (event, "plugin_instance",
-                               n->plugin_instance);
+               riemann_event_string_attribute_add(event, "plugin_instance", n->plugin_instance);
 
        if (n->type[0] != 0)
-               riemann_event_add_attribute (event, "type", n->type);
+               riemann_event_string_attribute_add(event, "type", n->type);
        if (n->type_instance[0] != 0)
-               riemann_event_add_attribute (event, "type_instance",
-                               n->type_instance);
+               riemann_event_string_attribute_add(event, "type_instance", n->type_instance);
 
        for (i = 0; i < riemann_attrs_num; i += 2)
-               riemann_event_add_attribute(event,
-                                           riemann_attrs[i],
-                                           riemann_attrs[i +1]);
+               riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i+1]);
 
        for (i = 0; i < riemann_tags_num; i++)
-               riemann_event_add_tag (event, riemann_tags[i]);
-
-       format_name (service_buffer, sizeof (service_buffer),
-                       /* host = */ "", n->plugin, n->plugin_instance,
-                       n->type, n->type_instance);
-       event->service = strdup (&service_buffer[1]);
+               riemann_event_tag_add(event, riemann_tags[i]);
 
        if (n->message[0] != 0)
-               riemann_event_add_attribute (event, "description", n->message);
+               riemann_event_string_attribute_add(event, "description", n->message);
 
        /* Pull in values from threshold and add extra attributes */
        for (meta = n->meta; meta != NULL; meta = meta->next)
        {
-               if (strcasecmp ("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE)
+               if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE)
                {
-                       event->metric_d = meta->nm_value.nm_double;
-                       event->has_metric_d = 1;
+                       riemann_event_set(event,
+                                         RIEMANN_EVENT_FIELD_METRIC_D,
+                                         (double) meta->nm_value.nm_double,
+                                         RIEMANN_EVENT_FIELD_NONE);
                        continue;
                }
 
                if (meta->type == NM_TYPE_STRING) {
-                       riemann_event_add_attribute (event, meta->name, meta->nm_value.nm_string);
+                       riemann_event_string_attribute_add(event, meta->name, meta->nm_value.nm_string);
                        continue;
                }
        }
 
-       DEBUG ("write_riemann plugin: Successfully created protobuf for notification: "
-                       "host = \"%s\", service = \"%s\", state = \"%s\"",
-                       event->host, event->service, event->state);
+       msg = riemann_message_create_with_events(event, NULL);
+       if (msg == NULL)
+       {
+               ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
+               riemann_event_free (event);
+               return (NULL);
+       }
+
+       DEBUG("write_riemann plugin: Successfully created message for notification: "
+             "host = \"%s\", service = \"%s\", state = \"%s\"",
+             event->host, event->service, event->state);
        return (msg);
-} /* }}} Msg *riemann_notification_to_protobuf */
+} /* }}} riemann_message_t *wrr_notification_to_message */
 
-static Event *riemann_value_to_protobuf(struct riemann_host const *host, /* {{{ */
-               data_set_t const *ds,
-               value_list_t const *vl, size_t index,
-                                        gauge_t const *rates,
-                                        int status)
+static riemann_event_t *wrr_value_to_event(struct riemann_host const *host, /* {{{ */
+                                          data_set_t const *ds,
+                                          value_list_t const *vl, size_t index,
+                                          gauge_t const *rates,
+                                          int status)
 {
-       Event *event;
+       riemann_event_t *event;
        char name_buffer[5 * DATA_MAX_NAME_LEN];
        char service_buffer[6 * DATA_MAX_NAME_LEN];
-       double ttl;
        size_t i;
 
-       event = malloc (sizeof (*event));
+       event = riemann_event_new();
        if (event == NULL)
        {
-               ERROR ("write_riemann plugin: malloc failed.");
+               ERROR("write_riemann plugin: riemann_event_new() failed.");
                return (NULL);
        }
-       memset (event, 0, sizeof (*event));
-       event__init (event);
 
-       event->host = strdup (vl->host);
-       event->time = CDTIME_T_TO_TIME_T (vl->time);
-       event->has_time = 1;
+       format_name(name_buffer, sizeof(name_buffer),
+                   /* host = */ "", vl->plugin, vl->plugin_instance,
+                   vl->type, vl->type_instance);
+       if (host->always_append_ds || (ds->ds_num > 1))
+       {
+               if (host->event_service_prefix == NULL)
+                       ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
+                                 &name_buffer[1], ds->ds[index].name);
+               else
+                       ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
+                                 host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
+       }
+       else
+       {
+               if (host->event_service_prefix == NULL)
+                       sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
+               else
+                       ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
+                                 host->event_service_prefix, &name_buffer[1]);
+       }
+
+       riemann_event_set(event,
+                         RIEMANN_EVENT_FIELD_HOST, vl->host,
+                         RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(vl->time),
+                         RIEMANN_EVENT_FIELD_TTL, (float) CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
+                         RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES,
+                         "plugin", vl->plugin,
+                         "type", vl->type,
+                         "ds_name", ds->ds[index].name,
+                         NULL,
+                         RIEMANN_EVENT_FIELD_SERVICE, service_buffer,
+                         RIEMANN_EVENT_FIELD_NONE);
 
        if (host->check_thresholds) {
+               const char *state = NULL;
+
                switch (status) {
                        case STATE_OKAY:
-                               event->state = strdup("ok");
+                               state = "ok";
                                break;
                        case STATE_ERROR:
-                               event->state = strdup("critical");
+                               state = "critical";
                                break;
                        case STATE_WARNING:
-                               event->state = strdup("warning");
+                               state = "warning";
                                break;
                        case STATE_MISSING:
-                               event->state = strdup("unknown");
+                               state = "unknown";
                                break;
                }
+               if (state)
+                       riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
+                                         RIEMANN_EVENT_FIELD_NONE);
        }
 
-       ttl = CDTIME_T_TO_DOUBLE (vl->interval) * host->ttl_factor;
-       event->ttl = (float) ttl;
-       event->has_ttl = 1;
-
-       riemann_event_add_attribute (event, "plugin", vl->plugin);
        if (vl->plugin_instance[0] != 0)
-               riemann_event_add_attribute (event, "plugin_instance",
-                               vl->plugin_instance);
-
-       riemann_event_add_attribute (event, "type", vl->type);
+               riemann_event_string_attribute_add(event, "plugin_instance", vl->plugin_instance);
        if (vl->type_instance[0] != 0)
-               riemann_event_add_attribute (event, "type_instance",
-                               vl->type_instance);
+               riemann_event_string_attribute_add(event, "type_instance", vl->type_instance);
 
        if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL))
        {
                char ds_type[DATA_MAX_NAME_LEN];
 
-               ssnprintf (ds_type, sizeof (ds_type), "%s:rate",
-                               DS_TYPE_TO_STRING(ds->ds[index].type));
-               riemann_event_add_attribute (event, "ds_type", ds_type);
+               ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
+                         DS_TYPE_TO_STRING(ds->ds[index].type));
+               riemann_event_string_attribute_add(event, "ds_type", ds_type);
        }
        else
        {
-               riemann_event_add_attribute (event, "ds_type",
-                               DS_TYPE_TO_STRING(ds->ds[index].type));
+               riemann_event_string_attribute_add(event, "ds_type",
+                                       DS_TYPE_TO_STRING(ds->ds[index].type));
        }
-       riemann_event_add_attribute (event, "ds_name", ds->ds[index].name);
+
        {
                char ds_index[DATA_MAX_NAME_LEN];
 
-               ssnprintf (ds_index, sizeof (ds_index), "%zu", index);
-               riemann_event_add_attribute (event, "ds_index", ds_index);
+               ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
+               riemann_event_string_attribute_add(event, "ds_index", ds_index);
        }
 
        for (i = 0; i < riemann_attrs_num; i += 2)
-               riemann_event_add_attribute(event,
-                                           riemann_attrs[i],
-                                           riemann_attrs[i +1]);
+               riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i +1]);
 
        for (i = 0; i < riemann_tags_num; i++)
-               riemann_event_add_tag (event, riemann_tags[i]);
+               riemann_event_tag_add(event, riemann_tags[i]);
 
        if (ds->ds[index].type == DS_TYPE_GAUGE)
        {
-               event->has_metric_d = 1;
-               event->metric_d = (double) vl->values[index].gauge;
+               riemann_event_set(event,
+                                 RIEMANN_EVENT_FIELD_METRIC_D,
+                                 (double) vl->values[index].gauge,
+                                 RIEMANN_EVENT_FIELD_NONE);
        }
        else if (rates != NULL)
        {
-               event->has_metric_d = 1;
-               event->metric_d = (double) rates[index];
+               riemann_event_set(event,
+                                 RIEMANN_EVENT_FIELD_METRIC_D,
+                                 (double) rates[index],
+                                 RIEMANN_EVENT_FIELD_NONE);
        }
        else
        {
-               event->has_metric_sint64 = 1;
+               int64_t metric;
+
                if (ds->ds[index].type == DS_TYPE_DERIVE)
-                       event->metric_sint64 = (int64_t) vl->values[index].derive;
+                       metric = (int64_t) vl->values[index].derive;
                else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
-                       event->metric_sint64 = (int64_t) vl->values[index].absolute;
+                       metric = (int64_t) vl->values[index].absolute;
                else
-                       event->metric_sint64 = (int64_t) vl->values[index].counter;
-       }
+                       metric = (int64_t) vl->values[index].counter;
 
-       format_name (name_buffer, sizeof (name_buffer),
-                       /* host = */ "", vl->plugin, vl->plugin_instance,
-                       vl->type, vl->type_instance);
-       if (host->always_append_ds || (ds->ds_num > 1))
-       {
-               if (host->event_service_prefix == NULL)
-                       ssnprintf (service_buffer, sizeof (service_buffer), "%s/%s",
-                                       &name_buffer[1], ds->ds[index].name);
-               else
-                       ssnprintf (service_buffer, sizeof (service_buffer), "%s%s/%s",
-                                       host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
-       }
-       else
-       {
-               if (host->event_service_prefix == NULL)
-                       sstrncpy (service_buffer, &name_buffer[1], sizeof (service_buffer));
-               else
-                       ssnprintf (service_buffer, sizeof (service_buffer), "%s%s",
-                                       host->event_service_prefix, &name_buffer[1]);
+               riemann_event_set(event,
+                                 RIEMANN_EVENT_FIELD_METRIC_S64,
+                                 (int64_t) metric,
+                                 RIEMANN_EVENT_FIELD_NONE);
        }
 
-       event->service = strdup (service_buffer);
-
-       DEBUG ("write_riemann plugin: Successfully created protobuf for metric: "
-                       "host = \"%s\", service = \"%s\"",
-                       event->host, event->service);
+       DEBUG("write_riemann plugin: Successfully created message for metric: "
+             "host = \"%s\", service = \"%s\"",
+             event->host, event->service);
        return (event);
-} /* }}} Event *riemann_value_to_protobuf */
+} /* }}} riemann_event_t *wrr_value_to_event */
 
-static Msg *riemann_value_list_to_protobuf (struct riemann_host const *host, /* {{{ */
-                                           data_set_t const *ds,
-                                           value_list_t const *vl,
-                                           int *statuses)
+static riemann_message_t *wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */
+                                                   data_set_t const *ds,
+                                                   value_list_t const *vl,
+                                                   int *statuses)
 {
-       Msg *msg;
+       riemann_message_t *msg;
        size_t i;
        gauge_t *rates = NULL;
 
        /* Initialize the Msg structure. */
-       msg = malloc (sizeof (*msg));
+       msg = riemann_message_new();
        if (msg == NULL)
        {
-               ERROR ("write_riemann plugin: malloc failed.");
-               return (NULL);
-       }
-       memset (msg, 0, sizeof (*msg));
-       msg__init (msg);
-
-       /* Set up events. First, the list of pointers. */
-       msg->n_events = vl->values_len;
-       msg->events = calloc (msg->n_events, sizeof (*msg->events));
-       if (msg->events == NULL)
-       {
-               ERROR ("write_riemann plugin: calloc failed.");
-               riemann_msg_protobuf_free (msg);
+               ERROR ("write_riemann plugin: riemann_message_new failed.");
                return (NULL);
        }
 
        if (host->store_rates)
        {
-               rates = uc_get_rate (ds, vl);
+               rates = uc_get_rate(ds, vl);
                if (rates == NULL)
                {
-                       ERROR ("write_riemann plugin: uc_get_rate failed.");
-                       riemann_msg_protobuf_free (msg);
+                       ERROR("write_riemann plugin: uc_get_rate failed.");
+                       riemann_message_free(msg);
                        return (NULL);
                }
        }
 
-       for (i = 0; i < msg->n_events; i++)
+       for (i = 0; i < vl->values_len; i++)
        {
-               msg->events[i] = riemann_value_to_protobuf (host, ds, vl,
-                                                           (int) i, rates, statuses[i]);
-               if (msg->events[i] == NULL)
+               riemann_event_t *event;
+
+               event = wrr_value_to_event(host, ds, vl,
+                                          (int) i, rates, statuses[i]);
+               if (event == NULL)
                {
-                       riemann_msg_protobuf_free (msg);
-                       sfree (rates);
+                       riemann_message_free(msg);
+                       sfree(rates);
                        return (NULL);
                }
+               riemann_message_append_events(msg, event, NULL);
        }
 
-       sfree (rates);
+       sfree(rates);
        return (msg);
-} /* }}} Msg *riemann_value_list_to_protobuf */
-
+} /* }}} riemann_message_t *wrr_value_list_to_message */
 
 /*
  * Always call while holding host->lock !
  */
-static int riemann_batch_flush_nolock (cdtime_t timeout,
-                                       struct riemann_host *host)
+static int wrr_batch_flush_nolock(cdtime_t timeout,
+                                 struct riemann_host *host)
 {
-    cdtime_t    now;
-    int         status = 0;
+       cdtime_t    now;
+       int         status = 0;
 
-    if (timeout > 0) {
-        now = cdtime ();
-        if ((host->batch_init + timeout) > now)
-            return status;
-    }
-    riemann_send_msg(host, host->batch_msg);
-    riemann_msg_protobuf_free(host->batch_msg);
-
-       if (host->use_tcp && ((status = riemann_recv_ack(host)) != 0))
-        riemann_disconnect (host);
+    now = cdtime();
+       if (timeout > 0) {
+               if ((host->batch_init + timeout) > now) {
+                       return status;
+        }
+       }
+       wrr_send_nolock(host, host->batch_msg);
+       riemann_message_free(host->batch_msg);
 
-    host->batch_init = cdtime();
-    host->batch_msg = NULL;
-    return status;
+       host->batch_init = now;
+       host->batch_msg = NULL;
+       return status;
 }
 
-static int riemann_batch_flush (cdtime_t timeout,
+static int wrr_batch_flush(cdtime_t timeout,
         const char *identifier __attribute__((unused)),
         user_data_t *user_data)
 {
-    struct riemann_host *host;
-    int status;
+       struct riemann_host *host;
+       int status;
 
-    if (user_data == NULL)
-        return (-EINVAL);
+       if (user_data == NULL)
+               return (-EINVAL);
 
-    host = user_data->data;
-    pthread_mutex_lock (&host->lock);
-    status = riemann_batch_flush_nolock (timeout, host);
-    if (status != 0)
-        ERROR ("write_riemann plugin: riemann_send failed with status %i",
-               status);
+       host = user_data->data;
+       pthread_mutex_lock(&host->lock);
+       status = wrr_batch_flush_nolock(timeout, host);
+       if (status != 0)
+        c_complain (LOG_ERR, &host->init_complaint,
+                    "write_riemann plugin: riemann_client_send failed with status %i",
+                    status);
+    else
+        c_release (LOG_DEBUG, &host->init_complaint, "write_riemann plugin: batch sent.");
 
-    pthread_mutex_unlock(&host->lock);
-    return status;
+       pthread_mutex_unlock(&host->lock);
+       return status;
 }
 
-static int riemann_batch_add_value_list (struct riemann_host *host, /* {{{ */
-                                         data_set_t const *ds,
-                                         value_list_t const *vl,
-                                         int *statuses)
+static int wrr_batch_add_value_list(struct riemann_host *host, /* {{{ */
+                                   data_set_t const *ds,
+                                   value_list_t const *vl,
+                                   int *statuses)
 {
-       size_t i;
-    Event **events;
-    Msg *msg;
-    size_t len;
-    int ret;
+       riemann_message_t *msg;
+       size_t len;
+       int ret;
+    cdtime_t timeout;
 
-    msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
-    if (msg == NULL)
-        return -1;
+       msg = wrr_value_list_to_message(host, ds, vl, statuses);
+       if (msg == NULL)
+               return -1;
 
-    pthread_mutex_lock(&host->lock);
+       pthread_mutex_lock(&host->lock);
 
-    if (host->batch_msg == NULL) {
-        host->batch_msg = msg;
-    } else {
-        len = msg->n_events + host->batch_msg->n_events;
-        events = realloc(host->batch_msg->events,
-                         (len * sizeof(*host->batch_msg->events)));
-        if (events == NULL) {
-            pthread_mutex_unlock(&host->lock);
-            ERROR ("write_riemann plugin: out of memory");
-            riemann_msg_protobuf_free (msg);
-            return -1;
-        }
-        host->batch_msg->events = events;
+       if (host->batch_msg == NULL) {
+               host->batch_msg = msg;
+       } else {
+               int status;
 
-        for (i = host->batch_msg->n_events; i < len; i++)
-            host->batch_msg->events[i] = msg->events[i - host->batch_msg->n_events];
+               status = riemann_message_append_events_n(host->batch_msg,
+                                                        msg->n_events,
+                                                        msg->events);
+               msg->n_events = 0;
+               msg->events = NULL;
 
-        host->batch_msg->n_events = len;
-        sfree (msg->events);
-        msg->n_events = 0;
-        sfree (msg);
-    }
+               riemann_message_free(msg);
+
+               if (status != 0) {
+                       pthread_mutex_unlock(&host->lock);
+                       ERROR("write_riemann plugin: out of memory");
+                       return -1;
+               }
+       }
 
-       len = msg__get_packed_size(host->batch_msg);
-    ret = 0;
-    if ((host->batch_max < 0) || (((size_t) host->batch_max) <= len)) {
-           ret = riemann_batch_flush_nolock(0, host);
+       len = riemann_message_get_packed_size(host->batch_msg);
+       ret = 0;
+       if ((host->batch_max < 0) || (((size_t) host->batch_max) <= len)) {
+               ret = wrr_batch_flush_nolock(0, host);
+       } else {
+        if (host->batch_timeout > 0) {
+            timeout = TIME_T_TO_CDTIME_T((time_t)host->batch_timeout);
+            ret = wrr_batch_flush_nolock(timeout, host);
+        }
     }
 
-    pthread_mutex_unlock(&host->lock);
-    return ret;
-} /* }}} Msg *riemann_batch_add_value_list */
+       pthread_mutex_unlock(&host->lock);
+       return ret;
+} /* }}} riemann_message_t *wrr_batch_add_value_list */
 
-static int riemann_notification(const notification_t *n, user_data_t *ud) /* {{{ */
+static int wrr_notification(const notification_t *n, user_data_t *ud) /* {{{ */
 {
        int                      status;
        struct riemann_host     *host = ud->data;
-       Msg                     *msg;
+       riemann_message_t       *msg;
 
        if (!host->notifications)
                return 0;
@@ -763,321 +562,365 @@ static int riemann_notification(const notification_t *n, user_data_t *ud) /* {{{
     /*
      * Never batch for notifications, send them ASAP
      */
-       msg = riemann_notification_to_protobuf (host, n);
+       msg = wrr_notification_to_message(host, n);
        if (msg == NULL)
                return (-1);
 
-       status = riemann_send (host, msg);
+       status = wrr_send(host, msg);
        if (status != 0)
-               ERROR ("write_riemann plugin: riemann_send failed with status %i",
-                               status);
-
-       riemann_msg_protobuf_free (msg);
+        c_complain (LOG_ERR, &host->init_complaint,
+                    "write_riemann plugin: riemann_client_send failed with status %i",
+                    status);
+    else
+        c_release (LOG_DEBUG, &host->init_complaint,
+                   "write_riemann plugin: riemann_client_send succeeded");
+
+       riemann_message_free(msg);
        return (status);
-} /* }}} int riemann_notification */
+} /* }}} int wrr_notification */
 
-static int riemann_write(const data_set_t *ds, /* {{{ */
-               const value_list_t *vl,
-               user_data_t *ud)
+static int wrr_write(const data_set_t *ds, /* {{{ */
+             const value_list_t *vl,
+             user_data_t *ud)
 {
        int                      status = 0;
        int                      statuses[vl->values_len];
        struct riemann_host     *host = ud->data;
+       riemann_message_t       *msg;
 
        if (host->check_thresholds) {
                status = write_riemann_threshold_check(ds, vl, statuses);
-               if (status != 0)
-                       return status;
-       } else {
-               memset (statuses, 0, sizeof (statuses));
-       }
-
-       if (host->use_tcp == 1 && host->batch_mode) {
-               riemann_batch_add_value_list (host, ds, vl, statuses);
-       } else {
-               Msg *msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
-               if (msg == NULL)
-                       return (-1);
+    if (status != 0)
+      return status;
+  } else {
+    memset (statuses, 0, sizeof (statuses));
+  }
+
+  if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
+      wrr_batch_add_value_list(host, ds, vl, statuses);
+  } else {
+    msg = wrr_value_list_to_message(host, ds, vl, statuses);
+    if (msg == NULL)
+      return (-1);
 
-               status = riemann_send (host, msg);
-               if (status != 0)
-                       ERROR ("write_riemann plugin: riemann_send failed with status %i", status);
+    status = wrr_send(host, msg);
 
-               riemann_msg_protobuf_free (msg);
-       }
+    riemann_message_free(msg);
+  }
+  return status;
+} /* }}} int wrr_write */
 
-       return status;
-} /* }}} int riemann_write */
-
-static void riemann_free(void *p) /* {{{ */
+static void wrr_free(void *p) /* {{{ */
 {
-       struct riemann_host     *host = p;
+  struct riemann_host  *host = p;
 
-       if (host == NULL)
-               return;
+  if (host == NULL)
+    return;
 
-       pthread_mutex_lock (&host->lock);
+  pthread_mutex_lock(&host->lock);
 
-       host->reference_count--;
-       if (host->reference_count > 0)
-       {
-               pthread_mutex_unlock (&host->lock);
-               return;
-       }
+  host->reference_count--;
+  if (host->reference_count > 0)
+    {
+      pthread_mutex_unlock(&host->lock);
+      return;
+    }
 
-       riemann_disconnect (host);
+  wrr_disconnect(host);
 
-       sfree(host->service);
-       pthread_mutex_destroy (&host->lock);
-       sfree(host);
-} /* }}} void riemann_free */
+  pthread_mutex_destroy(&host->lock);
+  sfree(host);
+} /* }}} void wrr_free */
 
-static int riemann_config_node(oconfig_item_t *ci) /* {{{ */
+static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
 {
-       struct riemann_host     *host = NULL;
-       int                      status = 0;
-       int                      i;
-       oconfig_item_t          *child;
-       char                     callback_name[DATA_MAX_NAME_LEN];
-       user_data_t              ud;
-
-       if ((host = calloc(1, sizeof (*host))) == NULL) {
-               ERROR ("write_riemann plugin: calloc failed.");
-               return ENOMEM;
-       }
-       pthread_mutex_init (&host->lock, NULL);
-       host->reference_count = 1;
-       host->node = NULL;
-       host->service = NULL;
-       host->notifications = 1;
-       host->check_thresholds = 0;
-       host->store_rates = 1;
-       host->always_append_ds = 0;
-       host->use_tcp = 1;
-       host->batch_mode = 1;
-       host->batch_max = RIEMANN_BATCH_MAX; /* typical MSS */
-       host->batch_init = cdtime();
-       host->ttl_factor = RIEMANN_TTL_FACTOR;
-
-       status = cf_util_get_string (ci, &host->name);
-       if (status != 0) {
-               WARNING("write_riemann plugin: Required host name is missing.");
-               riemann_free (host);
-               return -1;
-       }
-
-       for (i = 0; i < ci->children_num; i++) {
-               /*
-                * The code here could be simplified but makes room
-                * for easy adding of new options later on.
-                */
-               child = &ci->children[i];
-               status = 0;
-
-               if (strcasecmp ("Host", child->key) == 0) {
-                       status = cf_util_get_string (child, &host->node);
-                       if (status != 0)
-                               break;
-               } else if (strcasecmp ("Notifications", child->key) == 0) {
-                       status = cf_util_get_boolean(child, &host->notifications);
-                       if (status != 0)
-                               break;
-               } else if (strcasecmp ("EventServicePrefix", child->key) == 0) {
-                       status = cf_util_get_string (child, &host->event_service_prefix);
-                       if (status != 0)
-                               break;
-               } else if (strcasecmp ("CheckThresholds", child->key) == 0) {
-                       status = cf_util_get_boolean(child, &host->check_thresholds);
-                       if (status != 0)
-                               break;
-        } else if (strcasecmp ("Batch", child->key) == 0) {
-            status = cf_util_get_boolean(child, &host->batch_mode);
-            if (status != 0)
-                break;
-        } else if (strcasecmp("BatchMaxSize", child->key) == 0) {
-            status = cf_util_get_int(child, &host->batch_max);
-            if (status != 0)
-                break;
-               } else if (strcasecmp ("Port", child->key) == 0) {
-                       status = cf_util_get_service (child, &host->service);
-                       if (status != 0) {
-                               ERROR ("write_riemann plugin: Invalid argument "
-                                               "configured for the \"Port\" "
-                                               "option.");
-                               break;
-                       }
-               } else if (strcasecmp ("Protocol", child->key) == 0) {
-                       char tmp[16];
-                       status = cf_util_get_string_buffer (child,
-                                       tmp, sizeof (tmp));
-                       if (status != 0)
-                       {
-                               ERROR ("write_riemann plugin: cf_util_get_"
-                                               "string_buffer failed with "
-                                               "status %i.", status);
-                               break;
-                       }
-
-                       if (strcasecmp ("UDP", tmp) == 0)
-                               host->use_tcp = 0;
-                       else if (strcasecmp ("TCP", tmp) == 0)
-                               host->use_tcp = 1;
-                       else
-                               WARNING ("write_riemann plugin: The value "
-                                               "\"%s\" is not valid for the "
-                                               "\"Protocol\" option. Use "
-                                               "either \"UDP\" or \"TCP\".",
-                                               tmp);
-               } else if (strcasecmp ("StoreRates", child->key) == 0) {
-                       status = cf_util_get_boolean (child, &host->store_rates);
-                       if (status != 0)
-                               break;
-               } else if (strcasecmp ("AlwaysAppendDS", child->key) == 0) {
-                       status = cf_util_get_boolean (child,
-                                       &host->always_append_ds);
-                       if (status != 0)
-                               break;
-               } else if (strcasecmp ("TTLFactor", child->key) == 0) {
-                       double tmp = NAN;
-                       status = cf_util_get_double (child, &tmp);
-                       if (status != 0)
-                               break;
-                       if (tmp >= 2.0) {
-                               host->ttl_factor = tmp;
-                       } else if (tmp >= 1.0) {
-                               NOTICE ("write_riemann plugin: The configured "
-                                               "TTLFactor is very small "
-                                               "(%.1f). A value of 2.0 or "
-                                               "greater is recommended.",
-                                               tmp);
-                               host->ttl_factor = tmp;
-                       } else if (tmp > 0.0) {
-                               WARNING ("write_riemann plugin: The configured "
-                                               "TTLFactor is too small to be "
-                                               "useful (%.1f). I'll use it "
-                                               "since the user knows best, "
-                                               "but under protest.",
-                                               tmp);
-                               host->ttl_factor = tmp;
-                       } else { /* zero, negative and NAN */
-                               ERROR ("write_riemann plugin: The configured "
-                                               "TTLFactor is invalid (%.1f).",
-                                               tmp);
-                       }
-               } else {
-                       WARNING("write_riemann plugin: ignoring unknown config "
-                               "option: \"%s\"", child->key);
-               }
-       }
-       if (status != 0) {
-               riemann_free (host);
-               return status;
-       }
-
-       ssnprintf (callback_name, sizeof (callback_name), "write_riemann/%s",
-                       host->name);
-       ud.data = host;
-       ud.free_func = riemann_free;
-
-       pthread_mutex_lock (&host->lock);
-
-       status = plugin_register_write (callback_name, riemann_write, &ud);
+  struct riemann_host  *host = NULL;
+  int                   status = 0;
+  int                   i;
+  oconfig_item_t               *child;
+  char                  callback_name[DATA_MAX_NAME_LEN];
+  user_data_t           ud;
+
+  if ((host = calloc(1, sizeof(*host))) == NULL) {
+    ERROR ("write_riemann plugin: calloc failed.");
+    return ENOMEM;
+  }
+  pthread_mutex_init(&host->lock, NULL);
+  C_COMPLAIN_INIT (&host->init_complaint);
+  host->reference_count = 1;
+  host->node = NULL;
+  host->port = 0;
+  host->notifications = 1;
+  host->check_thresholds = 0;
+  host->store_rates = 1;
+  host->always_append_ds = 0;
+  host->batch_mode = 1;
+  host->batch_max = RIEMANN_BATCH_MAX; /* typical MSS */
+  host->batch_init = cdtime();
+  host->batch_timeout = 0;
+  host->ttl_factor = RIEMANN_TTL_FACTOR;
+  host->client = NULL;
+  host->client_type = RIEMANN_CLIENT_TCP;
+  host->timeout.tv_sec = 0;
+  host->timeout.tv_usec = 0;
+
+  status = cf_util_get_string(ci, &host->name);
+  if (status != 0) {
+    WARNING("write_riemann plugin: Required host name is missing.");
+    wrr_free(host);
+    return -1;
+  }
+
+  for (i = 0; i < ci->children_num; i++) {
+    /*
+     * The code here could be simplified but makes room
+     * for easy adding of new options later on.
+     */
+    child = &ci->children[i];
+    status = 0;
+
+    if (strcasecmp("Host", child->key) == 0) {
+      status = cf_util_get_string(child, &host->node);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("Notifications", child->key) == 0) {
+      status = cf_util_get_boolean(child, &host->notifications);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("EventServicePrefix", child->key) == 0) {
+      status = cf_util_get_string(child, &host->event_service_prefix);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("CheckThresholds", child->key) == 0) {
+      status = cf_util_get_boolean(child, &host->check_thresholds);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("Batch", child->key) == 0) {
+      status = cf_util_get_boolean(child, &host->batch_mode);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("BatchMaxSize", child->key) == 0) {
+      status = cf_util_get_int(child, &host->batch_max);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("BatchFlushTimeout", child->key) == 0) {
+      status = cf_util_get_int(child, &host->batch_timeout);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("Timeout", child->key) == 0) {
+      status = cf_util_get_int(child, (int *)&host->timeout.tv_sec);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("Port", child->key) == 0) {
+      host->port = cf_util_get_port_number(child);
+      if (host->port == -1) {
+        ERROR("write_riemann plugin: Invalid argument "
+              "configured for the \"Port\" "
+              "option.");
+        break;
+      }
+    } else if (strcasecmp("Protocol", child->key) == 0) {
+      char tmp[16];
+      status = cf_util_get_string_buffer(child,
+                                         tmp, sizeof(tmp));
+      if (status != 0)
+        {
+          ERROR("write_riemann plugin: cf_util_get_"
+                "string_buffer failed with "
+                "status %i.", status);
+          break;
+        }
 
-    if (host->use_tcp == 1 && host->batch_mode) {
-        ud.free_func = NULL;
-        plugin_register_flush(callback_name, riemann_batch_flush, &ud);
+      if (strcasecmp("UDP", tmp) == 0)
+        host->client_type = RIEMANN_CLIENT_UDP;
+      else if (strcasecmp("TCP", tmp) == 0)
+        host->client_type = RIEMANN_CLIENT_TCP;
+      else if (strcasecmp("TLS", tmp) == 0)
+        host->client_type = RIEMANN_CLIENT_TLS;
+      else
+        WARNING("write_riemann plugin: The value "
+                "\"%s\" is not valid for the "
+                "\"Protocol\" option. Use "
+                "either \"UDP\", \"TCP\" or \"TLS\".",
+                tmp);
+    } else if (strcasecmp("TLSCAFile", child->key) == 0) {
+      status = cf_util_get_string(child, &host->tls_ca_file);
+      if (status != 0)
+        {
+          ERROR("write_riemann plugin: cf_util_get_"
+                "string_buffer failed with "
+                "status %i.", status);
+          break;
+        }
+    } else if (strcasecmp("TLSCertFile", child->key) == 0) {
+      status = cf_util_get_string(child, &host->tls_cert_file);
+      if (status != 0)
+        {
+          ERROR("write_riemann plugin: cf_util_get_"
+                "string_buffer failed with "
+                "status %i.", status);
+          break;
+        }
+    } else if (strcasecmp("TLSKeyFile", child->key) == 0) {
+      status = cf_util_get_string(child, &host->tls_key_file);
+      if (status != 0)
+        {
+          ERROR("write_riemann plugin: cf_util_get_"
+                "string_buffer failed with "
+                "status %i.", status);
+          break;
+        }
+    } else if (strcasecmp("StoreRates", child->key) == 0) {
+      status = cf_util_get_boolean(child, &host->store_rates);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("AlwaysAppendDS", child->key) == 0) {
+      status = cf_util_get_boolean(child,
+                                   &host->always_append_ds);
+      if (status != 0)
+        break;
+    } else if (strcasecmp("TTLFactor", child->key) == 0) {
+      double tmp = NAN;
+      status = cf_util_get_double(child, &tmp);
+      if (status != 0)
+        break;
+      if (tmp >= 2.0) {
+        host->ttl_factor = tmp;
+      } else if (tmp >= 1.0) {
+        NOTICE("write_riemann plugin: The configured "
+               "TTLFactor is very small "
+               "(%.1f). A value of 2.0 or "
+               "greater is recommended.",
+               tmp);
+        host->ttl_factor = tmp;
+      } else if (tmp > 0.0) {
+        WARNING("write_riemann plugin: The configured "
+                "TTLFactor is too small to be "
+                "useful (%.1f). I'll use it "
+                "since the user knows best, "
+                "but under protest.",
+                tmp);
+        host->ttl_factor = tmp;
+      } else { /* zero, negative and NAN */
+        ERROR("write_riemann plugin: The configured "
+              "TTLFactor is invalid (%.1f).",
+              tmp);
+      }
+    } else {
+      WARNING("write_riemann plugin: ignoring unknown config "
+              "option: \"%s\"", child->key);
+    }
+  }
+  if (status != 0) {
+    wrr_free(host);
+    return status;
+  }
+
+  ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
+            host->name);
+  ud.data = host;
+  ud.free_func = wrr_free;
+
+  pthread_mutex_lock(&host->lock);
+
+  status = plugin_register_write(callback_name, wrr_write, &ud);
+
+  if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
+    ud.free_func = NULL;
+    plugin_register_flush(callback_name, wrr_batch_flush, &ud);
+  }
+  if (status != 0)
+    WARNING("write_riemann plugin: plugin_register_write (\"%s\") "
+            "failed with status %i.",
+            callback_name, status);
+  else /* success */
+    host->reference_count++;
+
+  status = plugin_register_notification(callback_name,
+                                        wrr_notification, &ud);
+  if (status != 0)
+    WARNING("write_riemann plugin: plugin_register_notification (\"%s\") "
+            "failed with status %i.",
+            callback_name, status);
+  else /* success */
+    host->reference_count++;
+
+  if (host->reference_count <= 1)
+    {
+      /* Both callbacks failed => free memory.
+       * We need to unlock here, because riemann_free() will lock.
+       * This is not a race condition, because we're the only one
+       * holding a reference. */
+      pthread_mutex_unlock(&host->lock);
+      wrr_free(host);
+      return (-1);
     }
-       if (status != 0)
-               WARNING ("write_riemann plugin: plugin_register_write (\"%s\") "
-                               "failed with status %i.",
-                               callback_name, status);
-       else /* success */
-               host->reference_count++;
-
-       status = plugin_register_notification (callback_name,
-                       riemann_notification, &ud);
-       if (status != 0)
-               WARNING ("write_riemann plugin: plugin_register_notification (\"%s\") "
-                               "failed with status %i.",
-                               callback_name, status);
-       else /* success */
-               host->reference_count++;
-
-       if (host->reference_count <= 1)
-       {
-               /* Both callbacks failed => free memory.
-                * We need to unlock here, because riemann_free() will lock.
-                * This is not a race condition, because we're the only one
-                * holding a reference. */
-               pthread_mutex_unlock (&host->lock);
-               riemann_free (host);
-               return (-1);
-       }
 
-       host->reference_count--;
-       pthread_mutex_unlock (&host->lock);
+  host->reference_count--;
+  pthread_mutex_unlock(&host->lock);
 
-       return status;
-} /* }}} int riemann_config_node */
+  return status;
+} /* }}} int wrr_config_node */
 
-static int riemann_config(oconfig_item_t *ci) /* {{{ */
+static int wrr_config(oconfig_item_t *ci) /* {{{ */
 {
-       int              i;
-       oconfig_item_t  *child;
-       int              status;
-
-       for (i = 0; i < ci->children_num; i++)  {
-               child = &ci->children[i];
-
-               if (strcasecmp("Node", child->key) == 0) {
-                       riemann_config_node (child);
-               } else if (strcasecmp(child->key, "attribute") == 0) {
-                       char *key = NULL;
-                       char *val = NULL;
-
-                       if (child->values_num != 2) {
-                               WARNING("riemann attributes need both a key and a value.");
-                               return (-1);
-                       }
-                       if (child->values[0].type != OCONFIG_TYPE_STRING ||
-                           child->values[1].type != OCONFIG_TYPE_STRING) {
-                               WARNING("riemann attribute needs string arguments.");
-                               return (-1);
-                       }
-                       if ((key = strdup(child->values[0].value.string)) == NULL) {
-                               WARNING("cannot allocate memory for attribute key.");
-                               return (-1);
-                       }
-                       if ((val = strdup(child->values[1].value.string)) == NULL) {
-                               WARNING("cannot allocate memory for attribute value.");
-                               return (-1);
-                       }
-                       strarray_add(&riemann_attrs, &riemann_attrs_num, key);
-                       strarray_add(&riemann_attrs, &riemann_attrs_num, val);
-                       DEBUG("write_riemann: got attr: %s => %s", key, val);
-                       sfree(key);
-                       sfree(val);
-               } else if (strcasecmp(child->key, "tag") == 0) {
-                       char *tmp = NULL;
-                       status = cf_util_get_string(child, &tmp);
-                       if (status != 0)
-                               continue;
-
-                       strarray_add (&riemann_tags, &riemann_tags_num, tmp);
-                       DEBUG("write_riemann plugin: Got tag: %s", tmp);
-                       sfree (tmp);
-               } else {
-                       WARNING ("write_riemann plugin: Ignoring unknown "
-                                "configuration option \"%s\" at top level.",
-                                child->key);
-               }
-       }
-       return (0);
-} /* }}} int riemann_config */
+  int           i;
+  oconfig_item_t       *child;
+  int           status;
+
+  for (i = 0; i < ci->children_num; i++)  {
+    child = &ci->children[i];
+
+    if (strcasecmp("Node", child->key) == 0) {
+      wrr_config_node (child);
+    } else if (strcasecmp(child->key, "attribute") == 0) {
+      char *key = NULL;
+      char *val = NULL;
+
+      if (child->values_num != 2) {
+        WARNING("riemann attributes need both a key and a value.");
+        return (-1);
+      }
+      if (child->values[0].type != OCONFIG_TYPE_STRING ||
+          child->values[1].type != OCONFIG_TYPE_STRING) {
+        WARNING("riemann attribute needs string arguments.");
+        return (-1);
+      }
+      if ((key = strdup(child->values[0].value.string)) == NULL) {
+        WARNING("cannot allocate memory for attribute key.");
+        return (-1);
+      }
+      if ((val = strdup(child->values[1].value.string)) == NULL) {
+        WARNING("cannot allocate memory for attribute value.");
+        sfree(key);
+        return (-1);
+      }
+      strarray_add(&riemann_attrs, &riemann_attrs_num, key);
+      strarray_add(&riemann_attrs, &riemann_attrs_num, val);
+      DEBUG("write_riemann: got attr: %s => %s", key, val);
+      sfree(key);
+      sfree(val);
+    } else if (strcasecmp(child->key, "tag") == 0) {
+      char *tmp = NULL;
+      status = cf_util_get_string(child, &tmp);
+      if (status != 0)
+        continue;
+
+      strarray_add(&riemann_tags, &riemann_tags_num, tmp);
+      DEBUG("write_riemann plugin: Got tag: %s", tmp);
+      sfree(tmp);
+    } else {
+      WARNING("write_riemann plugin: Ignoring unknown "
+              "configuration option \"%s\" at top level.",
+              child->key);
+    }
+  }
+  return (0);
+} /* }}} int wrr_config */
 
 void module_register(void)
 {
-       plugin_register_complex_config ("write_riemann", riemann_config);
+  plugin_register_complex_config("write_riemann", wrr_config);
 }
 
 /* vim: set sw=8 sts=8 ts=8 noet : */
index 5c8559e..8567288 100644 (file)
  *   Andrés J. Díaz <ajdiaz at connectical.com>
  **/
 
+#include <assert.h>
+#include <ltdl.h>
+#include <pthread.h>
+
 #include "collectd.h"
 #include "common.h"
 #include "plugin.h"
 #include "utils_avltree.h"
 #include "utils_cache.h"
 #include "utils_threshold.h"
-
-#include <assert.h>
-#include <ltdl.h>
-#include <pthread.h>
+#include "write_riemann_threshold.h"
 
 /*
  * Threshold management
diff --git a/src/write_riemann_threshold.h b/src/write_riemann_threshold.h
new file mode 100644 (file)
index 0000000..d3b3fe9
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef WRITE_RIEMANN_THRESHOLD_H
+#define WRITE_RIEMANN_THRESHOLD_H
+
+int write_riemann_threshold_check(const data_set_t *, const value_list_t *, int *);
+
+#endif
index 67c0496..475354c 100644 (file)
@@ -24,6 +24,8 @@
  *   Fabrice A. Marie <fabrice at kibinlabs.com>
  */
 
+#define _GNU_SOURCE
+
 #include "collectd.h"
 #include "plugin.h"
 #include "common.h"
 #include <stddef.h>
 
 #include <stdlib.h>
-#ifndef HAVE_ASPRINTF
-/*
- * Uses asprintf() portable implementation from
- * https://github.com/littlstar/asprintf.c/blob/master/
- * copyright (c) 2014 joseph werle <joseph.werle@gmail.com> under MIT license.
- */
-#include <stdio.h>
-#include <stdarg.h>
-
-int vasprintf(char **str, const char *fmt, va_list args) {
-       int size = 0;
-       va_list tmpa;
-       // copy
-       va_copy(tmpa, args);
-       // apply variadic arguments to
-       // sprintf with format to get size
-       size = vsnprintf(NULL, size, fmt, tmpa);
-       // toss args
-       va_end(tmpa);
-       // return -1 to be compliant if
-       // size is less than 0
-       if (size < 0) { return -1; }
-       // alloc with size plus 1 for `\0'
-       *str = (char *) malloc(size + 1);
-       // return -1 to be compliant
-       // if pointer is `NULL'
-       if (NULL == *str) { return -1; }
-       // format string with original
-       // variadic arguments and set new size
-       size = vsprintf(*str, fmt, args);
-       return size;
-}
-
-int asprintf(char **str, const char *fmt, ...) {
-       int size = 0;
-       va_list args;
-       // init variadic argumens
-       va_start(args, fmt);
-       // format and get size
-       size = vasprintf(str, fmt, args);
-       // toss args
-       va_end(args);
-       return size;
-}
-
-#endif
-
 #define SENSU_HOST             "localhost"
 #define SENSU_PORT             "3030"
 
@@ -222,7 +177,7 @@ static void sensu_close_socket(struct sensu_host *host) /* {{{ */
 static char *build_json_str_list(const char *tag, struct str_list const *list) /* {{{ */
 {
        int res;
-       char *ret_str;
+       char *ret_str = NULL;
        char *temp_str;
        int i;
        if (list->nb_strs == 0) {
@@ -237,6 +192,7 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) /
        res = asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
+               free(ret_str);
                return NULL;
        }
        for (i=1; i<list->nb_strs; i++) {
@@ -258,7 +214,7 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) /
        return ret_str;
 } /* }}} char *build_json_str_list*/
 
-int sensu_format_name2(char *ret, int ret_len,
+static int sensu_format_name2(char *ret, int ret_len,
                const char *hostname,
                const char *plugin, const char *plugin_instance,
                const char *type, const char *type_instance,
@@ -455,7 +411,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        }
 
        // incorporate sensu tags from config if any
-       if (strlen(sensu_tags) != 0) {
+       if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) {
                res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
                free(ret_str);
                if (res == -1) {
@@ -550,7 +506,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
  * http://creativeandcritical.net/str-replace-c/
  * copyright (c) Laird Shaw, under public domain.
  */
-char *replace_str(const char *str, const char *old, /* {{{ */
+static char *replace_str(const char *str, const char *old, /* {{{ */
                const char *new)
 {
        char *ret, *r;
@@ -569,11 +525,10 @@ char *replace_str(const char *str, const char *old, /* {{{ */
        } else
                retlen = strlen(str);
 
-       ret = malloc(retlen + 1);
+       ret = calloc(1, retlen + 1);
        if (ret == NULL)
                return NULL;
        // added to original: not optimized, but keeps valgrind happy.
-       memset(ret, 0, retlen + 1);
 
        r = ret;
        p = str;
@@ -679,6 +634,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
        char *handlers_str = build_json_str_list("handlers", &(host->notification_handlers));
        if (handlers_str == NULL) {
                ERROR("write_sensu plugin: Unable to alloc memory");
+               free(ret_str);
                return NULL;
        }
        // incorporate the handlers
@@ -751,7 +707,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
        }
 
        // incorporate sensu tags from config if any
-       if (strlen(sensu_tags) != 0) {
+       if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) {
                res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
                free(ret_str);
                if (res == -1) {
@@ -780,6 +736,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
                char *msg = replace_json_reserved(n->message);
                if (msg == NULL) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
+                       free(ret_str);
                        return NULL;
                }
                res = asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg);
index 4a62614..46028ba 100644 (file)
@@ -142,7 +142,7 @@ static int wt_flush_nolock(cdtime_t timeout, struct wt_callback *cb)
             return 0;
     }
 
-    if (cb->send_buf_fill <= 0)
+    if (cb->send_buf_fill == 0)
     {
         cb->send_buf_init_time = cdtime();
         return 0;
@@ -211,7 +211,6 @@ static int wt_callback_init(struct wt_callback *cb)
         ERROR("write_tsdb plugin: Connecting to %s:%s failed. "
               "The last error was: %s", node, service,
               sstrerror (errno, errbuf, sizeof(errbuf)));
-        close(cb->sock_fd);
         return -1;
     }
 
@@ -347,7 +346,7 @@ static int wt_format_name(char *ret, int ret_len,
 {
     int status;
     char *temp = NULL;
-    char *prefix = "";
+    const char *prefix = "";
     const char *meta_prefix = "tsdb_prefix";
 
     if (vl->meta) {
@@ -412,9 +411,9 @@ static int wt_send_message (const char* key, const char* value,
     int status;
     size_t message_len;
     char *temp = NULL;
-    char *tags = "";
+    const char *tags = "";
     char message[1024];
-    char *host_tags = cb->host_tags ? cb->host_tags : "";
+    const char *host_tags = cb->host_tags ? cb->host_tags : "";
     const char *meta_tsdb = "tsdb_tags";
 
     /* skip if value is NaN */
@@ -580,13 +579,12 @@ static int wt_config_tsd(oconfig_item_t *ci)
     char callback_name[DATA_MAX_NAME_LEN];
     int i;
 
-    cb = malloc(sizeof(*cb));
+    cb = calloc(1, sizeof(*cb));
     if (cb == NULL)
     {
-        ERROR("write_tsdb plugin: malloc failed.");
+        ERROR("write_tsdb plugin: calloc failed.");
         return -1;
     }
-    memset(cb, 0, sizeof(*cb));
     cb->sock_fd = -1;
     cb->node = NULL;
     cb->service = NULL;
diff --git a/src/xencpu.c b/src/xencpu.c
new file mode 100644 (file)
index 0000000..2b87235
--- /dev/null
@@ -0,0 +1,163 @@
+/**
+ * collectd - src/xencpu.c
+ * Copyright (C) 2016       Pavel Rochnyak
+ *
+ * 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
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Pavel Rochnyak <pavel2000 ngs.ru>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <xenctrl.h>
+
+#ifdef XENCTRL_HAS_XC_INTERFACE
+
+//Xen-4.1+
+#define XC_INTERFACE_INIT_ARGS NULL,NULL,0
+xc_interface *xc_handle;
+
+#else /* XENCTRL_HAS_XC_INTERFACE */
+
+//For xen-3.4/xen-4.0
+#include <string.h>
+#define xc_strerror(xc_interface, errcode) strerror(errcode)
+#define XC_INTERFACE_INIT_ARGS
+typedef int xc_interface;
+xc_interface xc_handle = 0;
+
+#endif /* XENCTRL_HAS_XC_INTERFACE */
+
+uint32_t num_cpus = 0;
+xc_cpuinfo_t *cpu_info;
+static value_to_rate_state_t *cpu_states;
+
+static int xencpu_init (void)
+{
+    xc_handle = xc_interface_open(XC_INTERFACE_INIT_ARGS);
+    if (!xc_handle)
+    {
+        ERROR ("xencpu: xc_interface_open() failed");
+        return (-1);
+    };
+
+    xc_physinfo_t *physinfo;
+
+    physinfo = calloc(1, sizeof(xc_physinfo_t));
+    if (physinfo == NULL)
+    {
+        ERROR ("xencpu plugin: calloc() for physinfo failed.");
+        xc_interface_close(xc_handle);
+        return (ENOMEM);
+    }
+
+    if (xc_physinfo(xc_handle, physinfo) < 0)
+    {
+        ERROR ("xencpu plugin: xc_physinfo() failed");
+        xc_interface_close(xc_handle);
+        free(physinfo);
+        return (-1);
+    };
+
+    num_cpus = physinfo->nr_cpus;
+    free(physinfo);
+
+    INFO ("xencpu plugin: Found %"PRIu32" processors.", num_cpus);
+
+    cpu_info = calloc(num_cpus, sizeof(xc_cpuinfo_t));
+    if (cpu_info == NULL)
+    {
+        ERROR ("xencpu plugin: calloc() for num_cpus failed.");
+        xc_interface_close(xc_handle);
+        return (ENOMEM);
+    }
+
+    cpu_states = calloc (num_cpus, sizeof (value_to_rate_state_t));
+    if (cpu_states == NULL)
+    {
+        ERROR ("xencpu plugin: calloc() for cpu_states failed.");
+        xc_interface_close(xc_handle);
+        free(cpu_info);
+        return (ENOMEM);
+    }
+
+    return (0);
+} /* static int xencpu_init */
+
+static int xencpu_shutdown (void)
+{
+    free(cpu_states);
+    free(cpu_info);
+    xc_interface_close(xc_handle);
+
+    return 0;
+} /* static int xencpu_shutdown */
+
+static void submit_value (int cpu_num, gauge_t percent)
+{
+    value_t values[1];
+    value_list_t vl = VALUE_LIST_INIT;
+
+    values[0].gauge = percent;
+
+    vl.values = values;
+    vl.values_len = 1;
+
+    sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+    sstrncpy (vl.plugin, "xencpu", sizeof (vl.plugin));
+    sstrncpy (vl.type, "percent", sizeof (vl.type));
+    sstrncpy (vl.type_instance, "load", sizeof (vl.type_instance));
+
+    if (cpu_num >= 0) {
+        ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+                "%i", cpu_num);
+    }
+    plugin_dispatch_values (&vl);
+} /* static void submit_value */
+
+static int xencpu_read (void)
+{
+    cdtime_t now = cdtime ();
+
+    int rc, nr_cpus;
+
+    rc = xc_getcpuinfo(xc_handle, num_cpus, cpu_info, &nr_cpus);
+    if (rc < 0) {
+        ERROR ("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc, xc_strerror(xc_handle,errno));
+        return (-1);
+    }
+
+    int cpu, status;
+    for (cpu = 0; cpu < nr_cpus; cpu++) {
+        gauge_t rate = NAN;
+        value_t value = {.derive = cpu_info[cpu].idletime};
+
+        status = value_to_rate (&rate, value, DS_TYPE_DERIVE, now, &cpu_states[cpu]);
+        if (status == 0) {
+            submit_value(cpu, 100 - rate/10000000);
+        }
+    }
+
+    return (0);
+} /* static int xencpu_read */
+
+void module_register (void)
+{
+    plugin_register_init ("xencpu", xencpu_init);
+    plugin_register_read ("xencpu", xencpu_read);
+    plugin_register_shutdown ("xencpu", xencpu_shutdown);
+} /* void module_register */
index a423bb6..29f2acd 100644 (file)
@@ -48,7 +48,7 @@ static void cxmms_submit (const char *type, gauge_t value)
        plugin_dispatch_values (&vl);
 } /* void cxmms_submit */
 
-int cxmms_read (void)
+static int cxmms_read (void)
 {
   gint rate;
   gint freq;
index dd633d5..37a918b 100644 (file)
 
 typedef        llist_t kstat_t;
 
-static long long get_zfs_value(kstat_t *zfs_stats  __attribute__((unused)),
-               char *name)
+static int put_zfs_value (kstat_t *ksp, char const *k, value_t v)
 {
        llentry_t *e;
+       char *k_copy;
+       value_t *v_copy;
 
-       e = llist_search (zfs_stats, name);
+       k_copy = strdup (k);
+       if (k_copy == NULL)
+               return ENOMEM;
+
+       v_copy = malloc (sizeof (*v_copy));
+       if (v_copy == NULL)
+       {
+               sfree (k_copy);
+               return ENOMEM;
+       }
+       *v_copy = v;
+
+       e = llentry_create (k_copy, v_copy);
        if (e == NULL)
        {
-               ERROR ("zfs_arc plugin: `llist_search` failed for key: '%s'.", name);
+               sfree (v_copy);
+               sfree (k_copy);
+               return ENOMEM;
+       }
+
+       llist_append (ksp, e);
+       return 0;
+}
+
+static long long get_zfs_value(kstat_t *ksp, const char *key)
+{
+       llentry_t *e;
+       value_t *v;
+
+       e = llist_search (ksp, key);
+       if (e == NULL)
+       {
+               ERROR ("zfs_arc plugin: `llist_search` failed for key: '%s'.", key);
                return (-1);
        }
 
-       return (*(long long int*)e->value);
+       v = e->value;
+       return ((long long) v->derive);
 }
 
-#elif !defined(__FreeBSD__) // Solaris
+static void free_zfs_values (kstat_t *ksp)
+{
+       llentry_t *e;
+
+       if (ksp == NULL)
+               return;
+
+       for (e = llist_head (ksp); e != NULL; e = e->next)
+       {
+               sfree (e->key);
+               sfree (e->value);
+       }
+
+       llist_destroy (ksp);
+}
+
+#elif defined(KERNEL_SOLARIS)
 extern kstat_ctl_t *kc;
 
 static long long get_zfs_value(kstat_t *ksp, char *name)
@@ -64,7 +111,7 @@ static long long get_zfs_value(kstat_t *ksp, char *name)
 
        return (get_kstat_value(ksp, name));
 }
-#else // FreeBSD
+#elif defined(KERNEL_FREEBSD)
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
@@ -172,75 +219,47 @@ static int za_read (void)
        value_t  l2_io[2];
        kstat_t  *ksp   = NULL;
 
-#if KERNEL_LINUX
-       long long int *llvalues = NULL;
-       char file_contents[1024 * 10];
-       char *fields[3];
-       int numfields;
-       ssize_t len;
+#if defined(KERNEL_LINUX)
+       FILE *fh;
+       char buffer[1024];
+
+       fh = fopen (ZOL_ARCSTATS_FILE, "r");
+       if (fh == NULL)
+       {
+               char errbuf[1024];
+               ERROR ("zfs_arc plugin: Opening \"%s\" failed: %s", ZOL_ARCSTATS_FILE,
+                      sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (-1);
+       }
 
        ksp = llist_create ();
        if (ksp == NULL)
        {
                ERROR ("zfs_arc plugin: `llist_create' failed.");
+               fclose (fh);
                return (-1);
        }
 
-       len = read_file_contents (ZOL_ARCSTATS_FILE, file_contents, sizeof(file_contents));
-       if (len > 1)
+       while (fgets (buffer, sizeof (buffer), fh) != NULL)
        {
+               char *fields[3];
+               value_t v;
+               int status;
 
-               int i=0;
-               char *pnl = file_contents;
-               char *pnnl;
-
-               file_contents[len] = '\0';
-
-               while (pnl != NULL)
-               {
-                       pnl = strchr(pnl, '\n');
-                       i++;
-                       if (pnl && (*pnl != '\0'))
-                               pnl++;
-               }
-
-               if (i > 0)
-               {
-                       llentry_t *e;
-                       llvalues = malloc(sizeof(long long int) * i);
-                       int j = 0;
-
-                       pnl = file_contents;
-                       while (pnl != NULL)
-                       {
-                               pnnl = strchr(pnl, '\n');
-                               if (pnnl != NULL)
-                                       *pnnl = '\0';
-
-                               numfields = strsplit (pnl, fields, 4);
-                               if (numfields == 3)
-                               {
-                                       llvalues[j] = atoll (fields[2]);
-
-                                       e = llentry_create (fields[0], &llvalues[j]);
-                                       if (e == NULL)
-                                       {
-                                               ERROR ("zfs_arc plugin: `llentry_create' failed.");
-                                       }
-                                       else
-                                       {
-                                               llist_append (ksp, e);
-                                       }
-                                       j++;
-                               }
-                               pnl = pnnl;
-                               if (pnl != NULL)
-                                       pnl ++;
-                       }
-               }
+               status = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
+               if (status != 3)
+                       continue;
+
+               status = parse_value (fields[2], &v, DS_TYPE_DERIVE);
+               if (status != 0)
+                       continue;
+
+               put_zfs_value (ksp, fields[0], v);
        }
 
-#elif !defined(__FreeBSD__) // Solaris
+       fclose (fh);
+
+#elif defined(KERNEL_SOLARIS)
        get_kstat (&ksp, "zfs", 0, "arcstats");
        if (ksp == NULL)
        {
@@ -250,10 +269,19 @@ static int za_read (void)
 #endif
 
        /* Sizes */
-       za_read_gauge (ksp, "size",    "cache_size", "arc");
-       za_read_gauge (ksp, "c",    "cache_size", "c");
-       za_read_gauge (ksp, "c_min",    "cache_size", "c_min");
-       za_read_gauge (ksp, "c_max",    "cache_size", "c_max");
+       za_read_gauge (ksp, "anon_size",      "cache_size", "anon_size");
+       za_read_gauge (ksp, "c",              "cache_size", "c");
+       za_read_gauge (ksp, "c_max",          "cache_size", "c_max");
+       za_read_gauge (ksp, "c_min",          "cache_size", "c_min");
+       za_read_gauge (ksp, "hdr_size",       "cache_size", "hdr_size");
+       za_read_gauge (ksp, "metadata_size",  "cache_size", "metadata_size");
+       za_read_gauge (ksp, "mfu_ghost_size", "cache_size", "mfu_ghost_size");
+       za_read_gauge (ksp, "mfu_size",       "cache_size", "mfu_size");
+       za_read_gauge (ksp, "mru_ghost_size", "cache_size", "mru_ghost_size");
+       za_read_gauge (ksp, "mru_size",       "cache_size", "mru_size");
+       za_read_gauge (ksp, "other_size",     "cache_size", "other_size");
+       za_read_gauge (ksp, "p",              "cache_size", "p");
+       za_read_gauge (ksp, "size",           "cache_size", "arc");
 
        /* The "l2_size" value has disappeared from Solaris some time in
         * early 2013, and has only reappeared recently in Solaris 11.2.
@@ -265,14 +293,18 @@ static int za_read (void)
 
        /* Operations */
        za_read_derive (ksp, "deleted",  "cache_operation", "deleted");
-#if __FreeBSD__
+#if defined(KERNEL_FREEBSD)
        za_read_derive (ksp, "allocated","cache_operation", "allocated");
+#if __FreeBSD_version < 1002501
+       /* stolen removed from sysctl kstat.zfs.misc.arcstats on FreeBSD 10.2+ */
        za_read_derive (ksp, "stolen",   "cache_operation", "stolen");
 #endif
+#endif
 
        /* Issue indicators */
        za_read_derive (ksp, "mutex_miss", "mutex_operations", "miss");
        za_read_derive (ksp, "hash_collisions", "hash_collisions", "");
+       za_read_derive (ksp, "memory_throttle_count", "memory_throttle_count", "");
 
        /* Evictions */
        za_read_derive (ksp, "evict_l2_cached",     "cache_eviction", "cached");
@@ -288,6 +320,11 @@ static int za_read (void)
        za_read_derive (ksp, "demand_metadata_misses",   "cache_result", "demand_metadata-miss");
        za_read_derive (ksp, "prefetch_data_misses",     "cache_result", "prefetch_data-miss");
        za_read_derive (ksp, "prefetch_metadata_misses", "cache_result", "prefetch_metadata-miss");
+       za_read_derive (ksp, "mfu_hits",                 "cache_result", "mfu-hit");
+       za_read_derive (ksp, "mfu_ghost_hits",           "cache_result", "mfu_ghost-hit");
+       za_read_derive (ksp, "mru_hits",                 "cache_result", "mru-hit");
+       za_read_derive (ksp, "mru_ghost_hits",           "cache_result", "mru_ghost-hit");
+       za_read_derive (ksp, "prefetch_metadata_misses", "cache_result", "prefetch_metadata-miss");
 
        /* Ratios */
        arc_hits   = (gauge_t) get_zfs_value(ksp, "hits");
@@ -305,14 +342,7 @@ static int za_read (void)
        za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
 
 #if defined(KERNEL_LINUX)
-       if (llvalues != NULL)
-       {
-               free(llvalues);
-       }
-       if (ksp != NULL)
-       {
-               llist_destroy (ksp);
-       }
+       free_zfs_values (ksp);
 #endif
 
        return (0);
@@ -320,7 +350,7 @@ static int za_read (void)
 
 static int za_init (void) /* {{{ */
 {
-#if !defined(__FreeBSD__) && !defined(KERNEL_LINUX) // Solaris
+#if defined(KERNEL_SOLARIS)
        /* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */
        if (kc == NULL)
        {
index 15eae6a..0e9fee3 100644 (file)
@@ -115,12 +115,13 @@ zone_find_stats(c_avl_tree_t *tree, zoneid_t zoneid)
        zoneid_t     *key = NULL;
 
        if (c_avl_get(tree, (void **)&zoneid, (void **)&ret)) {
-               if (!(ret = malloc(sizeof(zone_stats_t)))) {
+               if (!(ret = malloc(sizeof(*ret)))) {
                        WARNING("zone plugin: no memory");
                        return(NULL);
                }
-               if (!(key = malloc(sizeof(zoneid_t)))) {
+               if (!(key = malloc(sizeof(*key)))) {
                        WARNING("zone plugin: no memory");
+                       free(ret);
                        return(NULL);
                }
                *key = zoneid;
index abdbf20..89ec6d2 100644 (file)
@@ -108,8 +108,8 @@ static int zookeeper_connect (void)
        struct addrinfo ai_hints;
        struct addrinfo *ai;
        struct addrinfo *ai_list;
-       char *host;
-       char *port;
+       const char *host;
+       const char *port;
 
        memset ((void *) &ai_hints, '\0', sizeof (ai_hints));
        ai_hints.ai_family   = AF_UNSPEC;
@@ -159,8 +159,7 @@ static int zookeeper_connect (void)
 
 static int zookeeper_query (char *buffer, size_t buffer_size)
 {
-       int sk = -1;
-       int status;
+       int sk, status;
        size_t buffer_fill;
 
        sk = zookeeper_connect();
@@ -198,11 +197,6 @@ static int zookeeper_query (char *buffer, size_t buffer_size)
                }
 
                buffer_fill += (size_t) status;
-               if (status == 0)
-               {
-                       /* done reading from the socket */
-                       break;
-               }
        } /* while (recv) */
 
        status = 0;
index b09be8e..d7c6a76 100755 (executable)
@@ -1,13 +1,13 @@
 #!/bin/sh
 
-DEFAULT_VERSION="5.5.0.git"
+DEFAULT_VERSION="5.5.1.git"
 
-VERSION="`git describe 2> /dev/null | grep collectd | sed -e 's/^collectd-//'`"
+if [ -d .git ]; then
+       VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"
+fi
 
 if test -z "$VERSION"; then
        VERSION="$DEFAULT_VERSION"
 fi
 
-VERSION="`echo \"$VERSION\" | sed -e 's/-/./g'`"
-
 printf "%s" "$VERSION"