Merge branch 'pr/1649'
authorFlorian Forster <octo@collectd.org>
Wed, 21 Sep 2016 06:48:56 +0000 (08:48 +0200)
committerFlorian Forster <octo@collectd.org>
Wed, 21 Sep 2016 06:48:56 +0000 (08:48 +0200)
250 files changed:
.clang-format [new file with mode: 0644]
.github/issue_template.md [new file with mode: 0644]
.gitignore
AUTHORS
CONTRIBUTING.md
ChangeLog
NEWS [deleted file]
README
TODO [deleted file]
bindings/java/org/collectd/java/GenericJMXConfValue.java
bindings/perl/lib/Collectd.pm
configure.ac
contrib/examples/myplugin.c
contrib/migrate-4-5.px
contrib/redhat/collectd.spec
proto/collectd.proto
proto/types.proto
src/Makefile.am
src/aggregation.c
src/amqp.c
src/apache.c
src/apcups.c
src/apple_sensors.c
src/aquaero.c
src/ascent.c
src/barometer.c
src/battery.c
src/battery_statefs.c [new file with mode: 0644]
src/bind.c
src/ceph.c
src/ceph_test.c
src/cgroups.c
src/chrony.c
src/collectd-lua.pod [new file with mode: 0644]
src/collectd-nagios.c
src/collectd-perl.pod
src/collectd-python.pod
src/collectd-tg.c
src/collectd.conf.in
src/collectd.conf.pod
src/collectdctl.c
src/collectdmon.c
src/conntrack.c
src/contextswitch.c
src/cpu.c
src/cpufreq.c
src/cpusleep.c [new file with mode: 0644]
src/cpython.h
src/csv.c
src/curl.c
src/curl_json.c
src/curl_xml.c
src/daemon/collectd.c
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/types_list.c
src/daemon/utils_avltree.h
src/daemon/utils_avltree_test.c
src/daemon/utils_cache.c
src/daemon/utils_complain.c
src/daemon/utils_heap.h
src/daemon/utils_heap_test.c
src/daemon/utils_ignorelist.c
src/daemon/utils_match.c
src/daemon/utils_random.c
src/daemon/utils_subst.c
src/daemon/utils_subst_test.c
src/daemon/utils_tail.c
src/daemon/utils_tail_match.c
src/daemon/utils_threshold.c
src/daemon/utils_time.c
src/daemon/utils_time.h
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/entropy.c
src/ethstat.c
src/exec.c
src/fhcount.c
src/filecount.c
src/fscache.c
src/gmond.c
src/gps.c [new file with mode: 0644]
src/grpc.cc
src/hddtemp.c
src/hugepages.c [new file with mode: 0644]
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/client.h
src/libcollectdclient/network.c
src/libcollectdclient/network_buffer.c
src/liboconfig/oconfig.c
src/liboconfig/oconfig.h
src/liboconfig/parser.y
src/liboconfig/scanner.l
src/load.c
src/log_logstash.c
src/logfile.c
src/lpar.c
src/lua.c [new file with mode: 0644]
src/lvm.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/md.c
src/memcachec.c
src/memcached.c
src/memory.c
src/mic.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_desktop.c
src/notify_email.c
src/notify_nagios.c
src/ntpd.c
src/numa.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/pinba.proto
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/routeros.c
src/rrdcached.c
src/rrdtool.c
src/sensors.c
src/serial.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/tape.c
src/target_notification.c
src/target_replace.c
src/target_scale.c
src/target_set.c
src/target_v5upgrade.c
src/tcpconns.c
src/teamspeak2.c
src/ted.c
src/thermal.c
src/threshold.c
src/tokyotyrant.c
src/turbostat.c
src/types.db
src/unixsock.c
src/uptime.c
src/users.c
src/utils_cmd_flush.c
src/utils_cmd_getthreshold.c
src/utils_cmd_getval.c
src/utils_cmd_listval.c
src/utils_cmd_putnotif.c
src/utils_cmd_putval.c
src/utils_crc32.c
src/utils_curl_stats.c
src/utils_curl_stats.h
src/utils_db_query.c
src/utils_db_query.h
src/utils_dns.c
src/utils_fbhash.c
src/utils_format_graphite.c
src/utils_format_graphite.h
src/utils_format_json.c
src/utils_format_json.h
src/utils_format_json_test.c [new file with mode: 0644]
src/utils_format_kairosdb.c
src/utils_format_kairosdb.h
src/utils_latency.c
src/utils_latency.h
src/utils_latency_test.c
src/utils_lua.c [new file with mode: 0644]
src/utils_lua.h [new file with mode: 0644]
src/utils_mount.c
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_log.c
src/write_mongodb.c
src/write_redis.c
src/write_riemann.c
src/write_riemann_threshold.c
src/write_sensu.c
src/write_tsdb.c
src/xencpu.c
src/xmms.c
src/zfs_arc.c
src/zone.c
src/zookeeper.c
version-gen.sh

diff --git a/.clang-format b/.clang-format
new file mode 100644 (file)
index 0000000..70f50ad
--- /dev/null
@@ -0,0 +1,5 @@
+---
+BasedOnStyle: LLVM
+IncludeCategories:
+  - Regex: '"collectd.h"'
+  - Priority: -1
diff --git a/.github/issue_template.md b/.github/issue_template.md
new file mode 100644 (file)
index 0000000..49d24b3
--- /dev/null
@@ -0,0 +1,16 @@
+*   Version of collectd:
+*   Operating system / distribution:
+
+## Expected behavior
+
+(Description of the behavior / output that you expected)
+
+## Actual behavior
+
+(Description of the behavior / output that you observed)
+
+## Steps to reproduce
+
+*   step 1
+*   step 2
+*   step 3
index d742389..8154d73 100644 (file)
@@ -81,6 +81,12 @@ bindings/java/org/collectd/java/*.class
 # lint stuff
 *.ln
 
+#ide stuff
+.vscode
+
+# cscope stuff
+cscope.*
+
 # Unit tests
 src/daemon/test-suite.log
 src/tests/
diff --git a/AUTHORS b/AUTHORS
index bdffa92..28220e7 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -20,13 +20,13 @@ Pierre-Yves Ritschard <pyr at spootnik.org>
  - Normalization in the CPU plugin.
  - Relative values in the Load plugin.
 
-Ruben Kerkhof <ruben@rubenkerkhof.com>
+Ruben Kerkhof <ruben at rubenkerkhof.com>
  - Bugfixes and enhancements in many places all around the project.
- - Fedora package.
+ - Fedora and EPEL packages.
 
 Sebastian "tokkee" Harl <sh at tokkee.org>
  - Bugfixes and enhancements in many places all around the project.
- - gprc plugin.
+ - grpc plugin.
  - perl plugin.
  - postgresql plugin.
  - users plugin.
@@ -163,6 +163,9 @@ Jérôme Renard <jerome.renard at gmail.com>
 Jiri Tyr <jiri.tyr at gmail.com>
  - fhcount plugin.
 
+Julien Ammous <j.ammous at gmail.com>
+ - Lua plugin.
+
 Kevin Bowling <kbowling at llnw.com>
  - write_tsdb plugin for http://opentsdb.net/
 
@@ -219,6 +222,9 @@ Michał Mirosław <mirq-linux at rere.qmqm.pl>
 Mirko Buffoni <briareos at eswat.org>
  - Port/Socket selection in the MySQL plugin.
 
+Nicolas Jourden <nicolas.jourden at laposte.net>
+ - gps plugin.
+
 Niki W. Waibel <niki.waibel at newlogic.com>
  - Initial autotools fixes.
  - libltdl code.
index befb76e..eeb174b 100644 (file)
@@ -1,38 +1,57 @@
-# 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**).
-
+# Contribution guidelines
+
+Thanks for taking the time to contribute to the [collectd
+project](https://collectd.org/)! This document tries to give some guidance to
+make the process of contributing to *collectd* as pleasant and possible.
+
+## Bug reports
+
+Please report bugs as [GitHub
+Issues](https://github.com/collectd/collectd/issues). Try to answer the
+following questions:
+
+*   Which version of *collectd* are you using?
+*   Which operating system (distribution) are you using at which version?
+*   What is the expected behavior / output?
+*   What is the actual (observed) behavior / output?
+*   How can we reproduce the problem you're having?
+*   If *collectd* crashes, try to get a
+    [stack trace](https://collectd.org/wiki/index.php/Core_file).
+
+Please monitor your issue for a couple of days and reply to questions. To keep
+the project manageable have to do some housekeeping, meaning we will close
+issues that have become stale.
+
+## Code contributions
+
+Please open a [GitHub Pull Request](https://github.com/collectd/collectd/pulls)
+(PR) to contribute bug fixes, features, cleanups, new plugins, … Patches sent to
+the mailing list have a tendency to fall through the cracks.
+
+*   *Focus:* Fix *one thing* in your PR. The smaller your change, the faster it
+    will be reviewed and merged.
+*   *Coding style:* Please run `clang-format -style=file -i $FILE` on new files.
+    For existing files, please blend into surrounding code, i.e. mimic the
+    coding style of the code around your changes.
+*   *Documentation:* New config options need to be documented in two places: the
+    manpage (`src/collectd.conf.pod`) and the example config
+    (`src/collectd.conf.in`).
+*   *Continuous integration:* Once your PR is created, our continuous
+    integration environment will try to build it on a number of platforms. If
+    this reports a failure, please investigate and fix the problem. We will at
+    best do a very casual review for failing PRs.
+*   *Don't rebase:* Rebasing your branch destroys the review history. If a review
+    takes a long time, we may ask you to rebase on a more recent *master*, but
+    please don't do it without being asked.
+*   *types.db:* One of the most common mistakes made by new contributors is the
+    addition of (many) new *types* in the file `src/types.db`. The majority of
+    usecases can be met with one of the existing entries. If you plan to add new
+    entries to `src/types.db`, you should talk to us early in the design
+    process.
+
+## Other resources
+
+*   [Mailing list](http://mailman.verplant.org/listinfo/collectd)
+*   [#collectd IRC channel](https://webchat.freenode.net/?channels=#collectd)
+    on *freenode*.
+*   [Old patch submission guideline](https://collectd.org/wiki/index.php/Submitting_patches)
index 25257d7..5155954 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,161 @@
+2016-09-11, Version 5.6.0
+       * Build system: An option to to avoid building the DF plugin against XFS
+         has been added. Thanks to Ruben Kerkhof. #1878
+       * Build system: Autoconf ≥ 2.60, a C99-capable compiler and pkg-config
+         are now required. Thanks to Ruben Kerkhof.
+       * Build system: Building with "-Werror" is now optional. Thanks to Ruben
+         Kerkhof. #1222
+       * Build system: Many compilation issues on non-Linux platforms have been
+         fixed, leading to wider plugin support. Thanks to Ruben Kerkhof,
+         Dagobert Michelsen, Havard Eidnes and Robert Viduya.
+       * Build system: The configuration summary now also ends up in
+         config.log. Thanks to Sebastian Harl.
+       * collectd: All command-line options now override global options from
+         the config file. Thanks to Sebastian Harl. #366
+       * collectd: A number of unit tests for commonly used functions have been
+         added. Thanks to Florian Forster.
+       * collectd: Plugins start up and read timeouts are now logged. Thanks to
+         Marc Fournier. #1293, #1254
+       * collectd: Support for a timeout has been added to "FLUSH" callbacks.
+         Thanks to Manuel Luis Sanmartín Rozada.
+       * collectd: The "-T" command line switch now reports more errors. Thanks
+         to Corey Kosak. #1642
+       * collectd: The max size of value list elements ("DATA_MAX_NAME_LEN")
+         has been doubled and is now configurable at build time. Thanks to Amy
+         Lin, Florian Forster and Radu Brumariu. #1120
+       * Set target: The "MetaData" option has been added. Thanks to Yves
+         Mettier and Kevin Bowling. #1106, #1656, #1913
+       * AMQP, Write_HTTP, Write_Kafka plugins: Support for libyajl < 2 has
+         been added. Thanks to Florian Forster.
+       * APC UPS plugin: Parsing of end markers has been fixed. Thanks to
+         Florian Forster #617
+       * APC UPS plugin: The "PersistentConnection" option has been added.
+         Thanks to Florian Forster #617
+       * ceph, DNS, Exec, IPTables, Ping, turbostat plugins: When running
+         unprivileged, these plugins will now warn about insuffiscient
+         permissions or capabilities(7). Thanks to Marc Fournier. #1530
+       * Chrony plugin: This new plugin collects NTP data from the chrony NTP
+         server. Thanks to Claudius Zingerli. #1548
+       * cpusleep plugin: This new plugin measures time spent by CPU in deep
+         sleep mode. Thanks to Rinigus. #1826
+       * CPU plugin: The "ReportNumCpu" option has been added. Thanks to Fabien
+         Wernli.
+       * cURL, cURL-JSON, cURL-XML plugins: The new "Statistics" reports
+         various per-HTTP connection timers. Thanks to Sebastian Harl. #1004
+       * DBI plugin: The "Interval" option has been added to "Database" blocks.
+         Thanks to Michal Bebjak.
+       * Disk plugin: Support for FreeBSD has been added. Thanks to Xin Li,
+         Brad Davis, Ruben Kerfhof and Kevin Bowling.
+       * Empty Counter match: Support for derives has been implemented. Thanks
+         to Florian Forster. #1813
+       * GenericJMX plugin: Support for TabularData and the "PluginName" option
+         have been added. Thanks to David Crane. #1290, #1291
+       * GPS plugin: This new plugin reports the number of sattelites seen by
+         and precision of a GPS receiver. Thanks to Nicolas Jourden. #1346
+       * gRPC plugin: This new client and server plugin allows sending and
+         receiving metrics using the gRPC protocol. Comparable to the UnixSock
+         plugin, but using TCP and TLS. Thanks to Sebastian Harl and Florian
+         Forster.
+       * Interface plugin: Reporting dropped packets has been added. Thanks to
+         Marc Falzon. #1555
+       * Interface plugin: The "ReportInactive" has been added, letting users
+         skip inactive network interfaces. Thanks to Rinigus. #1791
+       * Interface plugin: The new, Solaris-only "UniqueName" option has been
+         added. Thanks to Yoga Ramalingam. #1416
+       * Lua plugin: This new language binding allows writing plugins using the
+         Lua programming language. Thanks to Julien Ammous, Florian Forster and
+         Ruben Kerkhof.
+       * Memory plugin: Reporting of ARC memory on Solaris has been added.
+         Thanks to Brian ONeill.
+       * MQTT plugin: This new plugin sends metrics to and/or receives metrics
+         from an MQTT broker. Thanks to Marc Falzon, Jan-Piet Mens, Nicholas
+         Humfrey and Florian Forster. #805, #1124
+       * MySQL plugin: Connection to the database server can now be done over
+         SSL. Thanks to Brian Lalor. #1256
+       * MySQL plugin: Monitoring slow queries has been added. Thanks to skob.
+         #1773
+       * MySQL plugin: mysql_bpool_pages-flushed has been renamed to
+         mysql_bpool_counters-pages_flushed because the value is cumulative.
+         Thanks to Marek Becka.
+       * MySQL plugin: Support for Galera statistics has been added. Thanks to
+         Rachid Zarouali. #1849
+       * MySQL plugin: Support for InnoDB metrics was improved. Thanks to Aman
+         Gupta. #1111
+       * MySQL plugin: The "mysql_sort" type has been split into 3 different
+         types. Thanks to Pavel Rochnyack. #1592
+       * Network plugin: Decryption error logging has been improved. Thanks to
+         Pavel Rochnyack. #1735
+       * Notify Nagios plugin: This new plugin sends notifications to Nagios as
+         a passive check result. Thanks to Florian Forster.
+       * NTPd plugin: The plugin now detects if the ntp daemon reports
+         nanoseconds instead of microseconds. Thanks to Matwey V. Kornilov.
+         #1783
+       * OpenLDAP plugin: Several connection-related improvements have been
+         made. Thanks to Marc Fournier. #1308
+       * OpenLDAP plugin: Support for "simple authentication" has been added.
+         Thanks to Marek Becka. #1087
+       * Ping plugin: The "Size" option has been added, allowing the ICMP data
+         payload size to be configured. Thanks to Witold Baryluk. #1395
+       * PostgreSQL, DBI, Oracle plugins: The new "PluginInstanceFrom" option
+         has been added. Thanks to Pavel Rochnyack. #1707
+       * PowerDNS plugin: The recursor metrics have been updated to 3.7.3 and
+         missing rr types have been added. Thanks to Ruben Kerkhof.
+       * Processes plugin: Counting of context switches was added for Linux.
+         Thanks to Manuel Luis Sanmartín Rozada. #1036
+       * Processes plugin: Improve reliability of thread counts on Linux.
+         Thanks to Manuel Luis Sanmartín Rozada.
+       * Python plugin: Minimal Python version requirement has been bumped to
+         2.6. Thanks to Ruben Kerkhof. #1864
+       * Redis plugin: Several additional metrics are now collected. Thanks to
+         Marc Falzon and Matteo Contrini. #1807, #1483
+       * Sensors plugin: The "UseLabels" option has been added. Thanks to
+         Christian Fetzer.
+       * SMART plugin: The new "IgnoreSleepMode" option has been added. Thanks
+         to Scott Talbert. #1770
+       * SMART plugin: The new "UseSerial" option allows identifying devices in
+         a stable way. Thanks to Scott Talbert. #1794
+       * SNMP plugin: The "IpAddress" can now be used for instances. Thanks to
+         Vincent Bernat. #1397
+       * StatsD plugin: Latency calculation histogram is now able to shrink
+         automatically to optimal size. Thanks to Pavel Rochnyack. #1622
+       * StatsD plugin: The "CounterSum" option has been added. Thanks to
+         Florian Forster. #929, #1282, #1311
+       * UUID plugin: The plugin now also looks in in smbios system table and
+         "/sys/class/dmi". Thanks to Ruben Kerkhof. #1490
+       * virt plugin: The "PluginInstanceFormat" option has been added. Thanks
+         to Ruben Kerkhof. #1100
+       * Write Graphite plugin: The "ReconnectInterval" option has been added.
+         Thanks to Toni Moreno and Florian Forster.
+       * Write HTTP plugin: A KairosDB formatter has been added. Thanks to
+         Aurélien Rougemont. #1809
+       * Write HTTP plugin: Notifications are now handled by this plugin.
+         Thanks to Florian Forster.
+       * Write HTTP plugin: The "LogHttpError" option has been added. Thanks to
+         vzubko.
+       * Write HTTP plugin: The new "Headers" option allows setting custom HTTP
+         headers in outgoing requests. Thanks to Brandon Arp. #1634
+       * Write Kafka plugin: Key handling has been made more comprehensive and
+         reliable. Thanks to Florian Forster, Pierre-Yves Ritschard and Vincent
+         Bernat. #1765, #1695, #1393
+       * Write Redis plugin: The "Database", "MaxSetSize", "Prefix" and
+         "StoreRates" options have been added. Thanks to Brian Kelly and
+         Sebastian Pfahl.
+       * Write Riemann plugin: The new "BatchFlushTimeout" and "Timeout" option
+         have been added. Thanks to Pierre-Yves Ritschard and Gergely Nagy.
+       * Write Riemann plugin: This plugin now requires the riemann-c-client
+         library, version 1.6.0+. This adds support for submitting values to
+         Riemann over TLS. Thanks to Gergely Nagy. #986
+       * Write TSDB, Write Sensu, Write Riemann, Write Graphite, Write TSDB
+         plugin: TCP keepalive is now enabled, helping graceful recovery from
+         unclean network disconnections. Thanks to Marc Fournier. #1549
+       * XenCPU plugin: This new plugin collects XEN Hypervisor CPU stats.
+         Thanks to Pavel Rochnyack. #1608
+       * ZFS ARC plugin: Several new statistics have been added and a couple of
+         obsolete ones removed. Thanks to Brad Davis, Brian ONeill and Ruben
+         Kerkhof.
+       * Zone plugin: This new plugin reads per-zone CPU usage on Solaris.
+         Thanks to Mathijs Mohlmann and Dagobert Michelsen.
+
 2016-07-25, Version 5.5.2
        * collectd: A division by zero has been fixed in the
          "plugin_dispatch_multivalue()" function. Thanks to Corey Kosak.
          Marc Fournier and Wilfried Goesgens. #552
        * Zookeeper plugin: This new plugin reads data from the Apache Zookeeper
          "MNTR" command. Thanks to Jeremy Katz. #826
-=======
+
+2016-07-26, Version 5.4.3
+       * Build system: A deprecation warning has been removed. Thanks to
+         Florian Forster.
+       * Build system: An ordering issue when build the AMQP plugin was
+         corrected. Thanks to Shahul Hameed.
+       * Build system: Building the gmond plugin against recent libganglia
+         versions has been added. Thanks to Marc Fournier. #1129
+       * Build system: "collectd-tg" now builds on AIX. Thanks to Manuel Luis
+         Sanmartín Rozada. #542
+       * Build system: "version-gen.sh" portablility was improved. Thanks to
+         Marc Fournier and Ruben Kerkhof.
+       * Build system: Compiling utils_dns.c on Solaris has beed fixed. Thanks
+         to Yves Mettier, Dagobert Michelsen and Florian Forster. #348
+       * Build system: Default JDK detection got improved. Thanks to Ruben
+         Kerkhof and Marc Fournier.
+       * Build system: Detection and handling of librrd 1.6 and later has been
+         fixed. Thanks to Ruben Kerkhof.
+       * Build system: notify_email build options got corrected to make it
+         build on non-GNU libc systems. Thanks to Marc Fournier.
+       * Build system: Protobuf building and logging has been improved. Thanks
+         to Ruben Kerkhof.
+       * Build system: The "make distcheck" target was fixed to properly handle
+         java build artifacts. Thanks to Florian Forster.
+       * Build system: The configure script got fixed to work properly when
+         called with "CC="gcc -Wall -Werror"" . Thanks to Marc Fournier.
+       * Build system: The configure script will now fail if pkg-config isn't
+         available. Thanks to Ruben Kerkhof.
+       * Build system: The users plugin now builds properly on Solaris when
+         libstatgrab is available. Thanks to Dagobert Michelsen. #1061
+       * Build system: Various fixes have been done to improve library
+         detection on FreeBSD. Thanks to Ruben Kerkhof.
+       * collectd2html: Several perl errors have been corrected. Thanks to Ruud
+         van Melick. #1103
+       * collectd: A global gauge format-string is now used to avoid loss of
+         precision. Thanks to Florian Forster. #1039
+       * collectd: A race condition at plugin initialization time was fixed.
+         Thanks to Jan Andres. #1316
+       * collectd: Autoloading now properly sets plugin context, allowing
+         plugins to determine the interval. Thanks to Florian Forster. #1069
+       * collectd: Empty "Plugin" blocks are now supported by the configuration
+         file parser. Thanks to Manuel Luis Sanmartín Rozada. #1035
+       * collectd: The address of the Free Software Foundation has been fixed
+         in GPL license headers. Thanks to Ruben Kerkhof.
+       * collectd: Writing to a closed TCP socket is now properly handled.
+         Thanks to Tamás Földesi. #1104
+       * Documentation: iptables plugin: IPv6 configuration option has been
+         added to the collectd.conf(5) manpage. Thanks to 'Marc Fournier''.
+         #1496
+       * AMQP plugin: The plugin was fixed to build against librabbitmq 0.6.0.
+         Thanks to Remi Collet. #1008
+       * Apache plugin: A warning about a possible misconfiguration has been
+         added. Thanks to Marc Fournier.
+       * Apache plugin: The plugin was extended to parse the whole response,
+         required to support Apache versions greater than 2.4.17. Thanks to
+         Marc Fournier and Florian Forster. #1170, #1343
+       * APC UPS plugin: Log messages are now prefixed with the plugin name.
+         Thanks to Sergey. #1329
+       * Bind plugin: The type_instance now gets properly sanitized. Thanks to
+         Thomas Kho. #992
+       * CPU plugin: Error messages on MacOSX have been improved. Thanks to
+         Florian Forster. #22
+       * cURL plugin: A typo in an error message got corrected. Thanks to Marc
+         Fournier.
+       * cURL, cURL-JSON and cURL-XML plugins: A memory leak when allocating
+         more memory fails has been fixed. Thanks to Brandon Arp.
+       * DF plugin: An bug preventing filesystems which don't report inodes
+         such as btrfs has been corrected. Thanks to Marek Becka. #1096
+       * DF plugin: Duplicate entries are no longer reported twice. Thanks to
+         Stefan Brüns and Florian Forster. #1402
+       * DF plugin: Legacy code for skipping "rootfs" mount points has been
+         removed. Thanks to Marc Fournier. #1402
+       * DF plugin: Legacy references to the "ReportReserved" option have been
+         removed. Thanks to Marc Fournier.
+       * DF plugin: Reading the mtab now uses a reentrant function when
+         possible. Thanks to Ruben Kerkhof. #1163
+       * Ethstat plugin: Code to strip leading whitespace from device names.
+         This works around an issue in the VMXNet3 driver. Thanks to Thomas
+         Guthmann. #1059
+       * Exec plugin: A file descriptor leak when the plugin is configured to
+         run as a non-existing user was corrected. Thanks to Gautam BT and Marc
+         Fournier. #762
+       * Exec plugin: A problem in the error handling of an fdopen() failure
+         has been fixed. Thanks to @ciomaire.
+       * Interface plugin: Documentation about regular expressions in the
+         ignore list has been added. Thanks to Jakub Jankowski.
+       * IRQ plugin: The "FIQ" line is now skipped as it doesn't contain any
+         counter. Thanks to Ruben Kerkhof. #971
+       * Modbus plugin: The debug output has been disabled by default. It is
+         now only enabled when building with "--enable-debug". Thanks to Eric
+         Sandeen and Marc Fournier.
+       * MongoDB plugin: A memory leak has been fixed and some adaptations to
+         the current API of the mongo-c-driver have been made. Thanks to
+         Florian Forster. #956
+       * Network plugin: A check for the initialization of secure memory has
+         been added. Previously, failure to initialize this memory was ignored.
+         Thanks to @yujokang. #1665
+       * Network plugin: A heap overflow has been fixed in the server code.
+         This issue can be triggered remotely and is potentially exploitable.
+         Thanks to Emilien Gaspar. CVE-2016-6254
+       * Network plugin: The TimeToLive option handling was made more robust.
+         Thanks to Tim Laszlo. #654
+       * NTPd plugin: Documentation about the required "mode 7" has been added.
+         Thanks to Jakub Jankowski.
+       * NTPd plugin: Reporting of "time_offset-loop" was corrected to match
+         the values from ntpq/ntpdc. Thanks to Pierre Fersing and Florian
+         Forster. #1300
+       * OpenVPN plugin: The plugin was fixe to avoid signaling an error when
+         no clients were connected. Thanks to Florian Forster. #731
+       * Perl plugin: Init callbacks have been changed to run essentially
+         single-threaded to avoid race conditions by init functions which
+         create additional threads. Thanks to Pavel Rochnyack. #1706
+       * PF plugin and DNS plugin: These plugins have been fixed to build
+         properly on OpenBSD again. Thanks to Ruben Kerkhof.
+       * Processes plugin: A compilation error on systems without "regex.h" has
+         been fixed. Thanks to Corey Kosak.
+       * Processes plugin: A memory leak on Solaris has been fixed. Thanks to
+         Jim Quinn.
        * Processes plugin and Swap plugin: These plugins have been corrected to
          also work inside FreeBSD jails. Thanks to biancalana. #1019
        * Processes plugin: A warning about too long process names has been
          libasan, FBInfer, coverity-scan, clang and gcc-6: Thanks to Ruben
          Kerkhof, Florian Forster, Marc Fournier, Corey Kosak, Laurent,
          Claudius Zingerli and Fabien Wernli.
->>>>>>> collectd-5.4
 
 2015-02-26, Version 5.4.2
        * Build system: Numerous fixes. Thanks to Bjørn Nordbø, Jim Radford,
diff --git a/NEWS b/NEWS
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/README b/README
index 481d144..9afbec6 100644 (file)
--- a/README
+++ b/README
@@ -67,6 +67,9 @@ Features
     - cpufreq
       CPU frequency (For laptops with speed step or a similar technology)
 
+    - cpusleep
+      CPU sleep: Time spent in suspend (For mobile devices which enter suspend automatically)
+
     - curl
       Parse statistics from websites using regular expressions.
 
@@ -125,12 +128,20 @@ Features
     - gmond
       Receive multicast traffic from Ganglia instances.
 
+    - gps
+      Monitor gps related data through gpsd.
+
     - grpc
       Receive values over the network using the gRPC framework.
 
     - hddtemp
       Hard disk temperatures using hddtempd.
 
+    - hugepages
+      Report the number of used and free hugepages. More info on
+      hugepages can be found here:
+      https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt.
+
     - interface
       Interface traffic: Number of octets, packets and errors for each
       interface.
@@ -165,6 +176,12 @@ Features
       Detailed CPU statistics of the “Logical Partitions” virtualization
       technique built into IBM's POWER processors.
 
+    - lua
+      The Lua plugin implements a Lua interpreter into collectd. This
+      makes it possible to write plugins in Lua which are executed by
+      collectd without the need to start a heavy interpreter every interval.
+      See collectd-lua(5) for details.
+
     - lvm
       Size of “Logical Volumes” (LV) and “Volume Groups” (VG) of Linux'
       “Logical Volume Manager” (LVM).
@@ -419,6 +436,10 @@ Features
       diskspace but is extremely portable and can be analysed with almost
       every program that can analyse anything. Even Microsoft's Excel..
 
+    - lua
+      It's possible to implement write plugins in Lua using the Lua
+      plugin. See collectd-lua(5) for details.
+
     - network
       Send the data to a remote host to save the data somehow. This is useful
       for large setups where the data should be saved by a dedicated machine.
@@ -700,6 +721,10 @@ Prerequisites
     Used by the `network' plugin for encryption and authentication.
     <http://www.gnupg.org/>
 
+  * libgps (optional)
+    Used by the `gps' plugin.
+    <http://developer.berlios.de/projects/gpsd/>
+
   * libhal (optional)
     If present, the `uuid' plugin will check for UUID from HAL.
     <http://hal.freedesktop.org/>
@@ -722,6 +747,10 @@ Prerequisites
     Used by the `openldap' plugin.
     <http://www.openldap.org/>
 
+  * liblua (optional)
+    Used by the `lua' plugin. Currently, Lua 5.1 and later are supported.
+    <https://www.lua.org/>
+
   * liblvm2 (optional)
     Used by the `lvm' plugin.
     <ftp://sources.redhat.com/pub/lvm2/>
@@ -796,7 +825,7 @@ Prerequisites
     <http://code.google.com/p/protobuf-c/>
 
   * libpython (optional)
-    Used by the `python' plugin. Currently, Python 2.3 and later and Python 3
+    Used by the `python' plugin. Currently, Python 2.6 and later and Python 3
     are supported.
     <http://www.python.org/>
 
@@ -1145,6 +1174,5 @@ Author
   Sebastian tokkee Harl <sh at tokkee.org>,
   and many contributors (see `AUTHORS').
 
-  Please send bug reports and patches to the mailing list, see `Contact'
-  above.
-
+  Please use GitHub reporting bugs and submitting pull requests.
+  See CONTRIBUTING.md for details.
diff --git a/TODO b/TODO
deleted file mode 100644 (file)
index 009eb7f..0000000
--- a/TODO
+++ /dev/null
@@ -1,21 +0,0 @@
-* Finalize the onewire plugin.
-* Custom notification messages?
-* Implement moving-average calculation for the threshold stuff.
-
-src/battery.c: commend not working code.
-
-Wishlist:
-* Port nfs module to solaris
-* Port tape module to Linux
-* Port the apple_sensors plugin to Linux/PPC.
-* Maybe look into porting the serial module
-* Build Darwin package
-* Maybe let the network plugin configure whether or not notifications should be
-  sent/received.
-* Maybe find a way for processes connected to the unixsock plugin to receive
-  notifications, too.
-
-http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_IOKitLib_API/chapter_5_section_1.html
-http://developer.apple.com/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/index.html#//apple_ref/doc/uid/TP0000011
-http://www.gauchosoft.com/Software/X%20Resource%20Graph/
-http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification/
index 25b70d4..63b7628 100644 (file)
@@ -313,9 +313,8 @@ class GenericJMXConfValue
 
     key = attrName.remove (0);
 
-    TabularData tabularData = (TabularData) parent;
-    Collection<CompositeData> table =
-        (Collection<CompositeData>)tabularData.values();
+    @SuppressWarnings("unchecked")
+    Collection<CompositeData> table = (Collection<CompositeData>) parent.values();
     for (CompositeData compositeData : table)
     {
       if (key.equals(compositeData.get("key")))
index c1adf44..7e89e45 100644 (file)
@@ -172,7 +172,6 @@ sub plugin_call_all {
        my $type = shift;
 
        my %plugins;
-       my $interval;
 
        our $cb_name = undef;
 
@@ -181,13 +180,13 @@ sub plugin_call_all {
        }
 
        if (TYPE_LOG != $type) {
-               DEBUG ("Collectd::plugin_call: type = \"$type\" ("
+               DEBUG ("Collectd::plugin_call_all: type = \"$type\" ("
                        . $types{$type} . "), args=\""
                        . join(', ', map { defined($_) ? $_ : '<undef>' } @_) . "\"");
        }
 
        if (! defined $plugins[$type]) {
-               ERROR ("Collectd::plugin_call: unknown type \"$type\"");
+               ERROR ("Collectd::plugin_call_all: unknown type \"$type\"");
                return;
        }
 
@@ -196,21 +195,9 @@ sub plugin_call_all {
                %plugins = %{$plugins[$type]};
        }
 
-       $interval = plugin_get_interval ();
-
        foreach my $plugin (keys %plugins) {
-               my $p = $plugins{$plugin};
-
-               my $status = 0;
-
-               if ($p->{'wait_left'} > 0) {
-                       $p->{'wait_left'} -= $interval;
-               }
-
-               next if ($p->{'wait_left'} > 0);
-
-               $cb_name = $p->{'cb_name'};
-               $status = call_by_name (@_);
+               $cb_name = $plugins{$plugin};
+               my $status = call_by_name (@_);
 
                if (! $status) {
                        my $err = undef;
@@ -230,23 +217,7 @@ sub plugin_call_all {
                }
 
                if ($status) {
-                       $p->{'wait_left'} = 0;
-                       $p->{'wait_time'} = $interval;
-               }
-               elsif (TYPE_READ == $type) {
-                       if ($p->{'wait_time'} < $interval) {
-                               $p->{'wait_time'} = $interval;
-                       }
-
-                       $p->{'wait_left'} = $p->{'wait_time'};
-                       $p->{'wait_time'} *= 2;
-
-                       if ($p->{'wait_time'} > 86400) {
-                               $p->{'wait_time'} = 86400;
-                       }
-
-                       WARNING ("${plugin}->read() failed with status $status. "
-                               . "Will suspend it for $p->{'wait_left'} seconds.");
+                       #NOOP
                }
                elsif (TYPE_INIT == $type) {
                        ERROR ("${plugin}->init() failed with status $status. "
@@ -309,21 +280,29 @@ sub plugin_register {
        }
        elsif ((TYPE_DATASET != $type) && (! ref $data)) {
                my $pkg = scalar caller;
-
-               my %p : shared;
-
                if ($data !~ m/^$pkg\:\:/) {
                        $data = $pkg . "::" . $data;
                }
-
-               %p = (
-                       wait_time => plugin_get_interval (),
-                       wait_left => 0,
-                       cb_name   => $data,
-               );
-
+               if (TYPE_READ == $type) {
+                       return plugin_register_read($name, $data);
+               }
+               if (TYPE_WRITE == $type) {
+                       return plugin_register_write($name, $data);
+               }
+               if (TYPE_LOG == $type) {
+                       return plugin_register_log($name, $data);
+               }
+               if (TYPE_NOTIF == $type) {
+                       return plugin_register_notification($name, $data);
+               }
+               if (TYPE_FLUSH == $type) {
+                       #For collectd-5.6 only
+                       lock %{$plugins[$type]};
+                       $plugins[$type]->{$name} = $data;
+                       return plugin_register_flush($name, $data);
+               }
                lock %{$plugins[$type]};
-               $plugins[$type]->{$name} = \%p;
+               $plugins[$type]->{$name} = $data;
        }
        else {
                ERROR ("Collectd::plugin_register: Invalid data.");
@@ -351,6 +330,21 @@ sub plugin_unregister {
                lock %cf_callbacks;
                delete $cf_callbacks{$name};
        }
+       elsif (TYPE_READ == $type) {
+               return plugin_unregister_read ($name);
+       }
+       elsif (TYPE_WRITE == $type) {
+               return plugin_unregister_write($name);
+       }
+       elsif (TYPE_LOG == $type) {
+               return plugin_unregister_log ($name);
+       }
+       elsif (TYPE_NOTIF == $type) {
+               return plugin_unregister_notification($name);
+       }
+       elsif (TYPE_FLUSH == $type) {
+               return plugin_unregister_flush($name);
+       }
        elsif (defined $plugins[$type]) {
                lock %{$plugins[$type]};
                delete $plugins[$type]->{$name};
index 42e5588..31c842a 100644 (file)
@@ -1,4 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
+AC_PREREQ([2.60])
 AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)])
 AC_CONFIG_SRCDIR(src/target_set.c)
 AC_CONFIG_HEADERS(src/config.h)
@@ -42,7 +43,9 @@ AC_SYS_LARGEFILE
 #
 # Checks for programs.
 #
-AC_PROG_CC
+AC_PROG_CC_C99([],
+  [AC_MSG_ERROR([No compiler found that supports C99])]
+)
 AC_PROG_CXX
 AC_PROG_CPP
 AC_PROG_EGREP
@@ -76,11 +79,12 @@ then
        AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison])
 fi
 
+AC_ARG_VAR([PROTOC], [path to the protoc binary])
 AC_PATH_PROG([PROTOC], [protoc])
 have_protoc3="no"
 if test "x$PROTOC" != "x"; then
        AC_MSG_CHECKING([for protoc 3.0.0+])
-       if $PROTOC --version | grep -q libprotoc.3; then
+       if $PROTOC --version | $EGREP libprotoc.3 >/dev/null; then
                protoc3="yes (`$PROTOC --version`)"
                have_protoc3="yes"
        else
@@ -90,29 +94,18 @@ if test "x$PROTOC" != "x"; then
 fi
 AM_CONDITIONAL(HAVE_PROTOC3, test "x$have_protoc3" = "xyes")
 
+AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary])
 AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin])
 AM_CONDITIONAL(HAVE_GRPC_CPP, test "x$GRPC_CPP_PLUGIN" != "x")
 
-AC_CHECK_PROG([have_protoc_c], [protoc-c], [yes], [no])
-if test "x$have_protoc_c" = "xno"
-then
-       have_protoc_c="no (protoc-c compiler not found)"
-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"
+AC_ARG_VAR([PROTOC_C], [path to the protoc-c binary])
+AC_PATH_PROG([PROTOC_C], [protoc-c])
+if test "x$PROTOC_C" = "x"
 then
-       AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack],
-                    [have_protoc_c="yes"],
-                    [have_protoc_c="no (libprotobuf-c not found)"])
-
+  have_protoc_c="no (protoc-c compiler not found)"
+else
+  have_protoc_c="yes"
 fi
-AM_CONDITIONAL(HAVE_PROTOC_C, test "x$have_protoc_c" = "xyes")
 
 AC_MSG_CHECKING([for kernel type ($host_os)])
 case $host_os in
@@ -493,6 +486,7 @@ then
 #include <linux/major.h>
 #include <linux/types.h>
 ])
+       AC_CHECK_HEADERS([sys/sysmacros.h])
 else
        have_linux_raid_md_u_h="no"
 fi
@@ -689,10 +683,26 @@ AC_CHECK_HEADERS([ \
   wordexp.h \
 ])
 
-AC_CHECK_HEADERS([xfs/xqm.h], [], [],
-[
-#define _GNU_SOURCE
-])
+# --enable-xfs {{{
+AC_ARG_ENABLE([xfs],
+  [AS_HELP_STRING([--enable-xfs], [xfs support in df plugin @<:@default=yes@:>@])],
+  [],
+  [enable_xfs="auto"]
+)
+
+if test "x$enable_xfs" != "xno"; then
+  AC_CHECK_HEADERS([xfs/xqm.h],
+    [],
+    [
+      if test "x$enable_xfs" = "xyes"; then
+        AC_MSG_ERROR([xfs/xqm.h not found])
+      fi
+    ],
+    [[#define _GNU_SOURCE]]
+  )
+fi
+
+# }}}
 
 # For the dns plugin
 AC_CHECK_HEADERS(arpa/nameser.h)
@@ -755,6 +765,23 @@ AC_CHECK_HEADERS(net/pfvar.h,
 have_termios_h="no"
 AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"])
 
+# For cpusleep plugin
+AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported],
+                      [c_cv_have_clock_boottime_monotonic],
+                      AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+[[
+#include <time.h>
+]],
+[[
+ struct timespec b, m;
+ clock_gettime(CLOCK_BOOTTIME, &b );
+ clock_gettime(CLOCK_MONOTONIC, &m );
+]]
+                      )],
+                      [c_cv_have_clock_boottime_monotonic="yes"],
+                      [c_cv_have_clock_boottime_monotonic="no"]))
+
+
 # For the turbostat plugin
 have_asm_msrindex_h="no"
 AC_CHECK_HEADERS(asm/msr-index.h, [have_asm_msrindex_h="yes"])
@@ -794,7 +821,7 @@ AC_HEADER_TIME
 #
 # Checks for library functions.
 #
-AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale)
+AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale asprintf)
 
 AC_FUNC_STRERROR_R
 
@@ -1360,6 +1387,20 @@ AC_ARG_WITH(useragent, [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User a
 
 # }}}
 
+# --with-data-max-name-len {{{
+AC_ARG_WITH(data-max-name-len, [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])],
+[
+    if test "x$withval" != "x" && test $withval -gt 0
+    then
+        AC_DEFINE_UNQUOTED(DATA_MAX_NAME_LEN, [$withval], [Maximum length of data buffers])
+    else
+        AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given])
+    fi
+],
+[   AC_DEFINE(DATA_MAX_NAME_LEN, 128, [Maximum length of data buffers])]
+)
+# }}}
+
 have_getfsstat="no"
 AC_CHECK_FUNCS(getfsstat, [have_getfsstat="yes"])
 have_getvfsstat="no"
@@ -1437,15 +1478,15 @@ if test "x$have_getmntent" = "xc"; then
 fi
 if test "x$have_getmntent" = "xsun"; then
        AC_DEFINE(HAVE_SUN_GETMNTENT, 1,
-                 [Define if the function getmntent exists. It's the version from libsun.])
+                 [Define if the function getmntent exists. It is the version from libsun.])
 fi
 if test "x$have_getmntent" = "xseq"; then
        AC_DEFINE(HAVE_SEQ_GETMNTENT, 1,
-                 [Define if the function getmntent exists. It's the version from libseq.])
+                 [Define if the function getmntent exists. It is the version from libseq.])
 fi
 if test "x$have_getmntent" = "xgen"; then
        AC_DEFINE(HAVE_GEN_GETMNTENT, 1,
-                 [Define if the function getmntent exists. It's the version from libgen.])
+                 [Define if the function getmntent exists. It is the version from libgen.])
 fi
 
 # Check for htonll
@@ -2260,60 +2301,144 @@ AC_SUBST(GCRYPT_LIBS)
 AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes")
 # }}}
 
-# --with-grpc {{{
-AC_ARG_WITH(grpc, [AS_HELP_STRING([--without-grpc], [Disable gRPC (default: autodetect).])],
+# --with-libgps {{{
+with_libgps_cflags=""
+with_libgps_ldflags=""
+AC_ARG_WITH(libgps, [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])],
 [
-       with_grpc="$withval"
+       if test "x$withval" != "xno" && test "x$withval" != "xyes"
+       then
+               with_libgps_cflags="-I$withval/include"
+               with_libgps_ldflags="-L$withval/lib"
+               with_libgps="yes"
+       else
+               with_libgps="$withval"
+       fi
 ],
 [
-       with_grpc="yes"
+       with_libgps="yes"
 ])
+if test "x$with_libgps" = "xyes"
+then
+       SAVE_CFLAGS="$CFLAGS"
+       CFLAGS="$CFLAGS $with_libgps_cflags"
+
+       AC_CHECK_HEADERS(gps.h, [with_libgps="yes"], [with_libgps="no (gps.h not found)"])
 
-if test "x$with_grpc" = "xyes"
+       CFLAGS="$SAVE_CFLAGS"
+fi
+if test "x$with_libgps" = "xyes"
 then
-       if test "x$have_protoc3" != "xyes"
-       then
-               with_grpc="no (requires protoc 3.0.0+)"
-       else if test "x$GRPC_CPP_PLUGIN" = "x"
-       then
-               with_grpc"no (requires grpc_cpp_plugin)"
-       fi; fi
+       SAVE_CFLAGS="$CFLAGS"
+       SAVE_LDFLAGS="$LDFLAGS"
+       CFLAGS="$CFLAGS $with_libgps_cflags"
+       LDFLAGS="$LDFLAGS $with_libgps_ldflags"
+
+       AC_CHECK_LIB(gps, gps_open, [with_libgps="yes"], [with_libgps="no (symbol gps_open not found)"])
+
+       CFLAGS="$SAVE_CFLAGS"
+       LDFLAGS="$SAVE_LDFLAGS"
 fi
+if test "x$with_libgps" = "xyes"
+then
+       BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags"
+       BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags"
+       BUILD_WITH_LIBGPS_LIBS="-lgps"
+       AC_SUBST(BUILD_WITH_LIBGPS_CFLAGS)
+       AC_SUBST(BUILD_WITH_LIBGPS_LDFLAGS)
+       AC_SUBST(BUILD_WITH_LIBGPS_LIBS)
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBGPS, test "x$with_libgps" = "xyes")
+# }}}
 
-if test "x$with_grpc" = "xyes"
+# --with-libgrpc++ {{{
+with_libgrpcpp_cppflags=""
+with_libgrpcpp_ldflags=""
+AC_ARG_WITH([libgrpc++], [AS_HELP_STRING([--with-libgrpc++@<:@=PREFIX@:>@], [Path to libgrpc++.])],
+  [
+    with_grpcpp="$withval"
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"
+    then
+      with_libgrpcpp_cppflags="-I$withval/include"
+      with_libgrpcpp_ldflags="-L$withval/lib"
+      with_libgrpcpp="yes"
+    fi
+    if test "x$withval" = "xno"
+    then
+      with_libgrpcpp="no (disabled on command line)"
+    fi
+  ],
+  [withval="yes"]
+)
+if test "x$withval" = "xyes"
 then
-       AC_MSG_CHECKING([whether $CXX accepts -std=c++11])
-       if test_cxx_flags -std=c++11; then
-               AC_MSG_RESULT([yes])
-       else
-               AC_MSG_RESULT([no])
-               with_grpc="no (requires C++11 support)"
-       fi
+PKG_CHECK_MODULES([GRPCPP], [grpc++],
+  [with_libgrpcpp="yes"],
+  [with_libgrpcpp="no (pkg-config could not find libgrpc++)"]
+)
 fi
 
-if test "x$with_grpc" = "xyes"
+if test "x$withval" != "xno"
 then
-       AC_LANG_PUSH(C++)
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_CXXFLAGS="$CXXFLAGS"
-       CPPFLAGS="$CPPFLAGS -std=c++11"
-       CXXFLAGS="$CXXFLAGS -std=c++11"
-       AC_CHECK_HEADERS([grpc++/grpc++.h], [],
-                       [with_grpc="no (grpc++/grpc++.h not found)"])
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       CXXFLAGS="$SAVE_CXXFLAGS"
-       AC_LANG_POP(C++)
+  AC_MSG_CHECKING([whether $CXX accepts -std=c++11])
+  if test_cxx_flags -std=c++11; then
+    AC_MSG_RESULT([yes])
+  else
+    AC_MSG_RESULT([no])
+    with_libgrpcpp="no (requires C++11 support)"
+  fi
 fi
-with_libgrpc="no"
-if test "x$with_grpc" = "xyes"
+
+if test "x$with_libgrpcpp" = "xyes"
 then
-       AC_LANG_PUSH(C++)
-       AC_CHECK_LIB([grpc], [grpc_register_plugin],
-                       [with_libgrpc="yes"],
-                       [with_grpc="no (libgrpc not found)"],
-                       [-lgpr -lprotobuf])
-       AC_LANG_POP(C++)
+  AC_LANG_PUSH(C++)
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
+  AC_CHECK_HEADERS([grpc++/grpc++.h], [],
+    [with_libgrpcpp="no (<grpc++/grpc++.h> not found)"]
+  )
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  AC_LANG_POP(C++)
 fi
+if test "x$with_libgrpcpp" = "xyes"
+then
+  AC_LANG_PUSH(C++)
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  SAVE_LIBS="$LIBS"
+  CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS"
+  LDFLAGS="$with_libgrpcpp_ldflags"
+  if test "x$GRPCPP_LIBS" = "x"
+  then
+    LIBS="-lgrpc++"
+  else
+    LIBS="$GRPCPP_LIBS"
+  fi
+  AC_LINK_IFELSE(
+    [AC_LANG_PROGRAM(
+      [[#include <grpc++/grpc++.h>]],
+      [[grpc::ServerBuilder sb;]]
+    )],
+    [
+      with_libgrpcpp="yes"
+      if test "x$GRPCPP_LIBS" = "x"
+      then
+        GRPCPP_LIBS="-lgrpc++"
+      fi
+    ],
+    [with_libgrpcpp="no (libgrpc++ not found)"]
+  )
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
+  LIBS="$SAVE_LIBS"
+  AC_LANG_POP(C++)
+fi
+BUILD_WITH_LIBGRPCPP_CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS"
+BUILD_WITH_LIBGRPCPP_LDFLAGS="$with_libgrpcpp_ldflags"
+BUILD_WITH_LIBGRPCPP_LIBS="$GRPCPP_LIBS"
+AC_SUBST([BUILD_WITH_LIBGRPCPP_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBGRPCPP_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBGRPCPP_LIBS])
 # }}}
 
 # --with-libiptc {{{
@@ -2340,11 +2465,6 @@ AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to l
        fi
 ])
 
-if test "x$with_libiptc" = "xpkgconfig" && test "x$PKG_CONFIG" = "x"
-then
-       with_libiptc="no (Don't have pkg-config)"
-fi
-
 if test "x$with_libiptc" = "xpkgconfig"
 then
        $PKG_CONFIG --exists 'libiptc' 2>/dev/null
@@ -2721,6 +2841,86 @@ fi
 AM_CONDITIONAL(BUILD_WITH_LIBLDAP, test "x$with_libldap" = "xyes")
 # }}}
 
+# --with-liblua {{{
+AC_ARG_VAR([LIBLUA_PKG_CONFIG_NAME], [Name of liblua used by pkg-config])
+if test "x$LIBLUA_PKG_CONFIG_NAME" != "x"
+then
+  PKG_CHECK_MODULES([LUA], [$LIBLUA_PKG_CONFIG_NAME],
+    [with_liblua="yes"],
+    [with_liblua="no"]
+  )
+else
+  PKG_CHECK_MODULES([LUA], [lua],
+    [with_liblua="yes"],
+    [
+      PKG_CHECK_MODULES([LUA], [lua-5.3],
+        [with_liblua="yes"],
+        [
+         PKG_CHECK_MODULES([LUA], [lua5.3],
+            [with_liblua="yes"],
+            [
+              PKG_CHECK_MODULES([LUA], [lua-5.2],
+                [with_liblua="yes"],
+                [
+                  PKG_CHECK_MODULES([LUA], [lua5.2],
+                    [with_liblua="yes"],
+                    [
+                      PKG_CHECK_MODULES([LUA], [lua-5.1],
+                        [with_liblua="yes"],
+                        [
+                          PKG_CHECK_MODULES([LUA], [lua5.1],
+                            [with_liblua="yes"],
+                            [with_liblua="no (pkg-config cannot find liblua)"]
+                          )
+                        ]
+                      )
+                    ]
+                  )
+                ]
+              )
+            ]
+          )
+        ]
+      )
+    ]
+  )
+fi
+
+if test "x$with_liblua" = "xyes"
+then
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $LUA_CFLAGS"
+
+  AC_CHECK_HEADERS([lua.h lauxlib.h lualib.h],
+    [with_liblua="yes"],
+    [with_liblua="no (header not found)"]
+  )
+
+  CFLAGS="$SAVE_CFLAGS"
+fi
+
+if test "x$with_liblua" = "xyes"
+then
+  SAVE_LIBS="$LIBS"
+  LIBS="$LIBS $LUA_LIBS"
+
+  AC_CHECK_FUNC([lua_settop],
+    [with_liblua="yes"],
+    [with_liblua="no (symbol 'lua_settop' not found)"]
+  )
+
+  LIBS="$SAVE_LIBS"
+fi
+
+if test "x$with_liblua" = "xyes"
+then
+    BUILD_WITH_LIBLUA_CFLAGS="$LUA_CFLAGS"
+    BUILD_WITH_LIBLUA_LIBS="$LUA_LIBS"
+fi
+AC_SUBST(BUILD_WITH_LIBLUA_CFLAGS)
+AC_SUBST(BUILD_WITH_LIBLUA_LIBS)
+# }}}
+
 # --with-liblvm2app {{{
 with_liblvm2app_cppflags=""
 with_liblvm2app_ldflags=""
@@ -2857,13 +3057,6 @@ AC_ARG_WITH(libmodbus, [AS_HELP_STRING([--with-libmodbus@<:@=PREFIX@:>@], [Path
 # configure using pkg-config
 if test "x$with_libmodbus" = "xuse_pkgconfig"
 then
-       if test "x$PKG_CONFIG" = "x"
-       then
-               with_libmodbus="no (Don't have pkg-config)"
-       fi
-fi
-if test "x$with_libmodbus" = "xuse_pkgconfig"
-then
        AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG])
        $PKG_CONFIG --exists 'libmodbus' 2>/dev/null
        if test $? -ne 0
@@ -3154,10 +3347,6 @@ AC_ARG_WITH(libmnl, [AS_HELP_STRING([--with-libmnl@<:@=PREFIX@:>@], [Path to lib
         with_libmnl="no (Linux only library)"
  fi
 ])
-if test "x$PKG_CONFIG" = "x"
-then
-       with_libmnl="no (Don't have pkg-config)"
-fi
 if test "x$with_libmnl" = "xyes"
 then
        if $PKG_CONFIG --exists libmnl 2>/dev/null; then
@@ -3314,9 +3503,6 @@ AM_CONDITIONAL(BUILD_WITH_LIBNETAPP, test "x$with_libnetapp" = "xyes")
 # }}}
 
 # --with-libnetsnmp {{{
-with_snmp_config="net-snmp-config"
-with_snmp_cflags=""
-with_snmp_libs=""
 AC_ARG_WITH(libnetsnmp, [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Path to the Net-SNMPD library.])],
 [
        if test "x$withval" = "xno"
@@ -3326,57 +3512,42 @@ AC_ARG_WITH(libnetsnmp, [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Pat
        then
                with_libnetsnmp="yes"
        else
-               if test -x "$withval"
-               then
-                       with_snmp_config="$withval"
-                       with_libnetsnmp="yes"
-               else
-                       with_snmp_config="$withval/bin/net-snmp-config"
-                       with_libnetsnmp="yes"
-               fi
+               with_libnetsnmp_cppflags="-I$withval/include"
+               with_libnetsnmp_ldflags="-I$withval/lib"
+               with_libnetsnmp="yes"
        fi; fi
 ],
 [with_libnetsnmp="yes"])
 if test "x$with_libnetsnmp" = "xyes"
 then
-       with_snmp_cflags=`$with_snmp_config --cflags 2>/dev/null`
-       snmp_config_status=$?
-
-       if test $snmp_config_status -ne 0
-       then
-               with_libnetsnmp="no ($with_snmp_config failed)"
-       else
-               SAVE_CPPFLAGS="$CPPFLAGS"
-               CPPFLAGS="$CPPFLAGS $with_snmp_cflags"
+       SAVE_CPPFLAGS="$CPPFLAGS"
+       CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags"
 
-               AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"])
+       AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"])
 
-               CPPFLAGS="$SAVE_CPPFLAGS"
-       fi
+       CPPFLAGS="$SAVE_CPPFLAGS"
 fi
 if test "x$with_libnetsnmp" = "xyes"
 then
-       with_snmp_libs=`$with_snmp_config --libs 2>/dev/null`
-       snmp_config_status=$?
+       SAVE_LDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
 
-       if test $snmp_config_status -ne 0
-       then
-               with_libnetsnmp="no ($with_snmp_config failed)"
-       else
-               AC_CHECK_LIB(netsnmp, init_snmp,
+       AC_CHECK_LIB(netsnmp, init_snmp,
                [with_libnetsnmp="yes"],
                [with_libnetsnmp="no (libnetsnmp not found)"],
                [$with_snmp_libs])
-       fi
+
+       LDFLAGS="$SAVE_LDFLAGS"
 fi
 if test "x$with_libnetsnmp" = "xyes"
 then
-       BUILD_WITH_LIBSNMP_CFLAGS="$with_snmp_cflags"
-       BUILD_WITH_LIBSNMP_LIBS="$with_snmp_libs"
-       AC_SUBST(BUILD_WITH_LIBSNMP_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBSNMP_LIBS)
+       BUILD_WITH_LIBNETSNMP_CPPFLAGS="$with_libnetsnmp_cppflags"
+       BUILD_WITH_LIBNETSNMP_LDFLAGS="$with_libnetsnmp_ldflags"
+       BUILD_WITH_LIBNETSNMP_LIBS="-lnetsnmp"
 fi
-AM_CONDITIONAL(BUILD_WITH_LIBNETSNMP, test "x$with_libnetsnmp" = "xyes")
+AC_SUBST(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
+AC_SUBST(BUILD_WITH_LIBNETSNMP_LDFLAGS)
+AC_SUBST(BUILD_WITH_LIBNETSNMP_LIBS)
 # }}}
 
 # --with-liboconfig {{{
@@ -3409,7 +3580,7 @@ save_LDFLAGS="$LDFLAGS"
 save_CPPFLAGS="$CPPFLAGS"
 LDFLAGS="$liboconfig_LDFLAGS"
 CPPFLAGS="$liboconfig_CPPFLAGS"
-AC_CHECK_LIB(oconfig, oconfig_parse_fh,
+AC_CHECK_LIB(oconfig, oconfig_parse_file,
 [
        with_liboconfig="yes"
        with_own_liboconfig="no"
@@ -3693,7 +3864,7 @@ then
   SAVE_CFLAGS="$CFLAGS"
   SAVE_LIBS="$LIBS"
 dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string)
-  PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ccopts`
+  PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e perl_inc`
   PERL_LIBS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ldopts`
   CFLAGS="$CFLAGS $PERL_CFLAGS"
   LIBS="$LIBS $PERL_LIBS"
 AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes")
 # }}}
 
-# --with-python {{{
-with_python_prog=""
-with_python_path="$PATH"
-AC_ARG_WITH(python, [AS_HELP_STRING([--with-python@<:@=PREFIX@:>@], [Path to the python interpreter.])],
-[
- if test "x$withval" = "xyes" || test "x$withval" = "xno"
- then
-        with_python="$withval"
- else if test -x "$withval"
- then
-        with_python_prog="$withval"
-        with_python_path="`dirname \"$withval\"`$PATH_SEPARATOR$with_python_path"
-        with_python="yes"
- else if test -d "$withval"
- then
-        with_python_path="$withval$PATH_SEPARATOR$with_python_path"
-        with_python="yes"
- else
-        AC_MSG_WARN([Argument not recognized: $withval])
- fi; fi; fi
-], [with_python="yes"])
-
-SAVE_PATH="$PATH"
-SAVE_CPPFLAGS="$CPPFLAGS"
-SAVE_LDFLAGS="$LDFLAGS"
-SAVE_LIBS="$LIBS"
-
-PATH="$with_python_path"
-
-if test "x$with_python" = "xyes" && test "x$with_python_prog" = "x"
+# --with-libprotobuf {{{
+with_libprotobuf_cppflags=""
+with_libprotobuf_ldflags=""
+AC_ARG_WITH([libprotobuf], [AS_HELP_STRING([--with-libprotobuf@<:@=PREFIX@:>@], [Path to libprotobuf.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"
+    then
+      with_libprotobuf_cppflags="-I$withval/include"
+      with_libprotobuf_ldflags="-L$withval/lib"
+      with_libprotobuf="yes"
+    fi
+    if test "x$withval" = "xno"
+    then
+      with_libprotobuf="no (disabled on command line)"
+    fi
+  ],
+  [withval="yes"]
+)
+if test "x$withval" = "xyes"
 then
-       AC_MSG_CHECKING([for python])
-       with_python_prog="`which python 2>/dev/null`"
-       if test "x$with_python_prog" = "x"
-       then
-               AC_MSG_RESULT([not found])
-               with_python="no (interpreter not found)"
-       else
-               AC_MSG_RESULT([$with_python_prog])
-       fi
+PKG_CHECK_MODULES([PROTOBUF], [protobuf],
+  [with_libprotobuf="yes"],
+  [with_libprotobuf="no (pkg-config could not find libprotobuf)"]
+)
 fi
 
-if test "x$with_python" = "xyes"
+if test "x$withval" != "xno"
 then
-       AC_MSG_CHECKING([for Python CPPFLAGS])
-       python_include_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_python_inc())" | "$with_python_prog" 2>&1`
-       python_config_status=$?
-
-       if test "$python_config_status" -ne 0 || test "x$python_include_path" = "x"
-       then
-               AC_MSG_RESULT([failed with status $python_config_status (output: $python_include_path)])
-               with_python="no"
-       else
-               AC_MSG_RESULT([$python_include_path])
-       fi
+  SAVE_LDFLAGS="$LDFLAGS"
+  SAVE_LIBS="$LIBS"
+  LDFLAGS="$with_libprotobuf_ldflags"
+  LIBS="$PROTOBUF_LIBS $LIBS"
+  AC_LANG_PUSH([C++])
+  AC_CHECK_LIB([protobuf], [main],
+    [
+      SAVE_CPPFLAGS="$CPPFLAGS"
+      CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS"
+      if test "x$PROTOBUF_LIBS" = "x"
+      then
+        PROTOBUF_LIBS="-lprotobuf"
+      fi
+      AC_CHECK_HEADERS([google/protobuf/util/time_util.h],
+        [with_libprotobuf="yes"],
+        [with_libprotobuf="no (<google/protobuf/util/time_util.h> not found)"]
+      )
+      CPPFLAGS="$SAVE_CPPFLAGS"
+    ],
+    [with_libprotobuf="no (libprotobuf not found)"]
+  )
+  AC_LANG_POP([C++])
+  LDFLAGS="$SAVE_LDFLAGS"
+  LIBS="$SAVE_LIBS"
 fi
+BUILD_WITH_LIBPROTOBUF_CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS"
+BUILD_WITH_LIBPROTOBUF_LDFLAGS="$with_libprotobuf_ldflags"
+BUILD_WITH_LIBPROTOBUF_LIBS="$PROTOBUF_LIBS"
+AC_SUBST([BUILD_WITH_LIBPROTOBUF_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBPROTOBUF_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBPROTOBUF_LIBS])
+# }}}
 
-if test "x$with_python" = "xyes"
+# --with-libprotobuf-c {{{
+with_libprotobuf_c_cppflags=""
+with_libprotobuf_c_ldflags=""
+AC_ARG_WITH([libprotobuf-c], [AS_HELP_STRING([--with-libprotobuf-c@<:@=PREFIX@:>@], [Path to libprotobuf-c.])],
+  [
+    if test "x$withval" != "xno" && test "x$withval" != "xyes"
+    then
+      with_libprotobuf_c_cppflags="-I$withval/include"
+      with_libprotobuf_c_ldflags="-L$withval/lib"
+      with_libprotobuf_c="yes"
+    fi
+    if test "x$withval" = "xno"
+    then
+      with_libprotobuf_c="no (disabled on command line)"
+    fi
+  ],
+  [withval="yes"]
+)
+if test "x$withval" = "xyes"
 then
-       CPPFLAGS="-I$python_include_path $CPPFLAGS"
-       AC_CHECK_HEADERS(Python.h,
-                        [with_python="yes"],
-                        [with_python="no ('Python.h' not found)"])
+PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c],
+  [with_libprotobuf_c="yes"],
+  [with_libprotobuf_c="no (pkg-config could not find libprotobuf-c)"]
+)
 fi
 
-if test "x$with_python" = "xyes"
+if test "x$withval" != "xno"
 then
-       AC_MSG_CHECKING([for Python LDFLAGS])
-       python_library_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"LIBDIR\").__getitem__(0))" | "$with_python_prog" 2>&1`
-       python_config_status=$?
-
-       if test "$python_config_status" -ne 0 || test "x$python_library_path" = "x"
-       then
-               AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_path)])
-               with_python="no"
-       else
-               AC_MSG_RESULT([$python_library_path])
-       fi
+  SAVE_LDFLAGS="$LDFLAGS"
+  SAVE_LIBS="$LIBS"
+  LDFLAGS="$with_libprotobuf_c_ldflags"
+  LIBS="$PROTOBUF_C_LIBS $LIBS"
+  AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack],
+    [
+      SAVE_CPPFLAGS="$CPPFLAGS"
+      CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS"
+      if test "x$PROTOBUF_C_LIBS" = "x"
+      then
+        PROTOBUF_C_LIBS="-lprotobuf-c"
+      fi
+      AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h],
+        [
+          with_libprotobuf_c="yes"
+          break
+        ],
+        [with_libprotobuf_c="no (<protobuf-c.h> not found)"]
+      )
+      CPPFLAGS="$SAVE_CPPFLAGS"
+    ],
+    [with_libprotobuf_c="no (libprotobuf-c not found)"]
+  )
+  LDFLAGS="$SAVE_LDFLAGS"
+  LIBS="$SAVE_LIBS"
 fi
+BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS"
+BUILD_WITH_LIBPROTOBUF_C_LDFLAGS="$with_libprotobuf_c_ldflags"
+BUILD_WITH_LIBPROTOBUF_C_LIBS="$PROTOBUF_C_LIBS"
+AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LIBS])
+# }}}
 
-if test "x$with_python" = "xyes"
-then
-       AC_MSG_CHECKING([for Python LIBS])
-       python_library_flags=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"BLDLIBRARY\").__getitem__(0))" | "$with_python_prog" 2>&1`
-       python_config_status=$?
+# --with-libpython {{{
+AC_ARG_VAR([LIBPYTHON_CPPFLAGS], [Preprocessor flags for libpython])
+AC_ARG_VAR([LIBPYTHON_LDFLAGS], [Linker flags for libpython])
+AC_ARG_VAR([LIBPYTHON_LIBS], [Libraries for libpython])
 
-       if test "$python_config_status" -ne 0 || test "x$python_library_flags" = "x"
-       then
-               AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_flags)])
-               with_python="no"
-       else
-               AC_MSG_RESULT([$python_library_flags])
-       fi
+AC_ARG_WITH([libpython],
+  [AS_HELP_STRING([--with-libpython],
+    [if we should build with libpython @<:@default=yes@:>@])
+  ],
+  [with_libpython="$withval"],
+  [with_libpython="check"]
+)
+if test "$with_libpython" != "no"; then
+  if test "$LIBPYTHON_CPPFLAGS" = "" && test "$LIBPYTHON_LDFLAGS" = ""; then
+    AC_ARG_VAR([PYTHON_CONFIG], [path to python-config])
+    AC_PATH_PROGS([PYTHON_CONFIG],
+      [python3-config python2-config python-config]
+    )
+    if test "$PYTHON_CONFIG" = ""; then
+      if test "$with_libpython" = "yes"; then
+        AC_MSG_ERROR([Unable to find python-config])
+      fi
+      with_libpython="no"
+    fi
+  fi
 fi
 
-if test "x$with_python" = "xyes"
-then
-       LDFLAGS="-L$python_library_path $LDFLAGS"
-       LIBS="$python_library_flags $LIBS"
-
-       AC_CHECK_FUNC(PyObject_CallFunction,
-                     [with_python="yes"],
-                     [with_python="no (Symbol 'PyObject_CallFunction' not found)"])
+if test "$PYTHON_CONFIG" != ""; then
+  LIBPYTHON_CPPFLAGS="`${PYTHON_CONFIG} --includes`"
+  if test $? -ne 0; then
+    with_libpython="no"
+  fi
+  LIBPYTHON_LDFLAGS="`${PYTHON_CONFIG} --ldflags`"
+  if test $? -ne 0; then
+    with_libpython="no"
+  fi
+  LIBPYTHON_LIBS="`${PYTHON_CONFIG} --libs`"
+  if test $? -ne 0; then
+    with_libpython="no"
+  fi
 fi
 
-PATH="$SAVE_PATH"
-CPPFLAGS="$SAVE_CPPFLAGS"
-LDFLAGS="$SAVE_LDFLAGS"
-LIBS="$SAVE_LIBS"
-
-if test "x$with_python" = "xyes"
-then
-       BUILD_WITH_PYTHON_CPPFLAGS="-I$python_include_path"
-       BUILD_WITH_PYTHON_LDFLAGS="-L$python_library_path"
-       BUILD_WITH_PYTHON_LIBS="$python_library_flags"
-       AC_SUBST(BUILD_WITH_PYTHON_CPPFLAGS)
-       AC_SUBST(BUILD_WITH_PYTHON_LDFLAGS)
-       AC_SUBST(BUILD_WITH_PYTHON_LIBS)
+if test "$with_libpython" != "xno"; then
+  SAVE_CPPFLAGS="$CPPFLAGS"
+  SAVE_LDFLAGS="$LDFLAGS"
+  SAVE_LIBS="$LIBS"
+  CPPFLAGS="$LIBPYTHON_CPPFLAGS $CPPFLAGS"
+  LDFLAGS="$LIBPYTHON_LDFLAGS $LDFLAGS"
+  LIBS="$LIBPYTHON_LIBS $LIBS"
+  AC_CHECK_HEADERS([Python.h],
+    [
+      AC_MSG_CHECKING([for libpython])
+      AC_LINK_IFELSE([AC_LANG_PROGRAM(
+          [[#include <Python.h>]],
+          [[Py_Initialize();]])
+        ],
+        [with_libpython="yes"],
+        [with_libpython="no"]
+      )
+      AC_MSG_RESULT([$with_libpython])
+    ],
+    [with_libpython="no"]
+  )
+  CPPFLAGS="$SAVE_CPPFLAGS"
+  LDFLAGS="$SAVE_LDFLAGS"
+  LIBS="$SAVE_LIBS"
 fi
-# }}} --with-python
+# }}} --with-libpython
 
 # --with-librabbitmq {{{
 with_librabbitmq_cppflags=""
@@ -4429,74 +4671,13 @@ fi
 AM_CONDITIONAL(BUILD_WITH_LM_SENSORS, test "x$with_libsensors" = "xyes")
 # }}}
 
-# --with-libsigrok {{{
-with_libsigrok_cflags=""
-with_libsigrok_ldflags=""
-AC_ARG_WITH(libsigrok, [AS_HELP_STRING([--with-libsigrok@<:@=PREFIX@:>@], [Path to libsigrok.])],
-[
-       if test "x$withval" = "xno"
-       then
-               with_libsigrok="no"
-       else
-               with_libsigrok="yes"
-               if test "x$withval" != "xyes"
-               then
-                       with_libsigrok_cflags="-I$withval/include"
-                       with_libsigrok_ldflags="-L$withval/lib"
-               fi
-       fi
-],[with_libsigrok="yes"])
-
-# libsigrok has a glib dependency
-if test "x$with_libsigrok" = "xyes"
-then
-m4_ifdef([AM_PATH_GLIB_2_0],
-       [
-        AM_PATH_GLIB_2_0([2.28.0],
-               [with_libsigrok_cflags="$with_libsigrok_cflags $GLIB_CFLAGS"; with_libsigrok_ldflags="$with_libsigrok_ldflags $GLIB_LIBS"])
-       ],
-       [
-        with_libsigrok="no (glib not available)"
-       ]
+# libsigrok {{{
+AC_SUBST([LIBSIGROK_CFLAGS])
+AC_SUBST([LIBSIGROK_LIBS])
+PKG_CHECK_MODULES([LIBSIGROK], [libsigrok < 0.4],
+  [with_libsigrok="yes"],
+  [with_libsigrok="no (pkg-config could not find libsigrok)"]
 )
-fi
-
-# libsigrok headers
-if test "x$with_libsigrok" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libsigrok_cflags"
-
-       AC_CHECK_HEADERS(libsigrok/libsigrok.h, [], [with_libsigrok="no (libsigrok/libsigrok.h not found)"])
-
-       CPPFLAGS="$SAVE_CPPFLAGS"
-fi
-
-# libsigrok library
-if test "x$with_libsigrok" = "xyes"
-then
-       SAVE_CPPFLAGS="$CPPFLAGS"
-       SAVE_LDFLAGS="$LDFLAGS"
-       CPPFLAGS="$CPPFLAGS $with_libsigrok_cflags"
-       LDFLAGS="$LDFLAGS $with_libsigrok_ldflags"
-
-       AC_CHECK_LIB(sigrok, sr_init,
-       [
-               AC_DEFINE(HAVE_LIBSIGROK, 1, [Define to 1 if you have the sigrok library (-lsigrok).])
-       ],
-       [with_libsigrok="no (libsigrok not found)"])
-
-       CPPFLAGS="$SAVE_CPPFLAGS"
-       LDFLAGS="$SAVE_LDFLAGS"
-fi
-if test "x$with_libsigrok" = "xyes"
-then
-       BUILD_WITH_LIBSIGROK_CFLAGS="$with_libsigrok_cflags"
-       BUILD_WITH_LIBSIGROK_LDFLAGS="$with_libsigrok_ldflags"
-       AC_SUBST(BUILD_WITH_LIBSIGROK_CFLAGS)
-       AC_SUBST(BUILD_WITH_LIBSIGROK_LDFLAGS)
-fi
-AM_CONDITIONAL(BUILD_WITH_LIBSIGROK, test "x$with_libsigrok" = "xyes")
 # }}}
 
 # --with-libstatgrab {{{
@@ -4524,23 +4705,16 @@ AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [P
 if test "x$with_libstatgrab" = "xyes" \
   && test "x$with_libstatgrab_pkg_config" = "xyes"
 then
-  if test "x$PKG_CONFIG" != "x"
+  AC_MSG_CHECKING([pkg-config for libstatgrab])
+  temp_result="found"
+  $PKG_CONFIG --exists libstatgrab 2>/dev/null
+  if test "$?" != "0"
   then
-    AC_MSG_CHECKING([pkg-config for libstatgrab])
-    temp_result="found"
-    $PKG_CONFIG --exists libstatgrab 2>/dev/null
-    if test "$?" != "0"
-    then
-      with_libstatgrab_pkg_config="no"
-      with_libstatgrab="no (pkg-config doesn't know libstatgrab)"
-      temp_result="not found"
-    fi
-    AC_MSG_RESULT([$temp_result])
-  else
-    AC_MSG_NOTICE([pkg-config not available, trying to guess flags for the statgrab library.])
     with_libstatgrab_pkg_config="no"
-    with_libstatgrab_ldflags="$with_libstatgrab_ldflags -lstatgrab"
+    with_libstatgrab="no (pkg-config doesn't know libstatgrab)"
+    temp_result="not found"
   fi
+  AC_MSG_RESULT([$temp_result])
 fi
 
 if test "x$with_libstatgrab" = "xyes" \
@@ -4839,13 +5013,6 @@ fi
 # configure using pkg-config
 if test "x$with_libupsclient" = "xuse_pkgconfig"
 then
-       if test "x$PKG_CONFIG" = "x"
-       then
-               with_libupsclient="no (Don't have pkg-config)"
-       fi
-fi
-if test "x$with_libupsclient" = "xuse_pkgconfig"
-then
        AC_MSG_NOTICE([Checking for libupsclient using $PKG_CONFIG])
        $PKG_CONFIG --exists 'libupsclient' 2>/dev/null
        if test $? -ne 0
@@ -5167,13 +5334,6 @@ AC_ARG_WITH(libvarnish, [AS_HELP_STRING([--with-libvarnish@<:@=PREFIX@:>@], [Pat
 # configure using pkg-config
 if test "x$with_libvarnish" = "xuse_pkgconfig"
 then
-       if test "x$PKG_CONFIG" = "x"
-       then
-               with_libvarnish="no (Don't have pkg-config)"
-       fi
-fi
-if test "x$with_libvarnish" = "xuse_pkgconfig"
-then
        AC_MSG_NOTICE([Checking for varnishapi using $PKG_CONFIG])
        $PKG_CONFIG --exists 'varnishapi' 2>/dev/null
        if test $? -ne 0
@@ -5233,23 +5393,20 @@ with_libxml2_ldflags=""
 with_libvirt="no (pkg-config isn't available)"
 with_libvirt_cflags=""
 with_libvirt_ldflags=""
-if test "x$PKG_CONFIG" != "x"
+$PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
+if test "$?" = "0"
 then
-       $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null
-       if test "$?" = "0"
-       then
-               with_libxml2="yes"
-       else
-               with_libxml2="no (pkg-config doesn't know libxml-2.0)"
-       fi
+       with_libxml2="yes"
+else
+       with_libxml2="no (pkg-config doesn't know libxml-2.0)"
+fi
 
-       $PKG_CONFIG --exists libvirt 2>/dev/null
-       if test "$?" = "0"
-       then
-               with_libvirt="yes"
-       else
-               with_libvirt="no (pkg-config doesn't know libvirt)"
-       fi
+$PKG_CONFIG --exists libvirt 2>/dev/null
+if test "$?" = "0"
+then
+       with_libvirt="yes"
+else
+       with_libvirt="no (pkg-config doesn't know libvirt)"
 fi
 if test "x$with_libxml2" = "xyes"
 then
@@ -5348,17 +5505,6 @@ with_libopenipmipthread="yes"
 with_libopenipmipthread_cflags=""
 with_libopenipmipthread_libs=""
 
-AC_MSG_CHECKING([for pkg-config])
-temp_result="no"
-if test "x$PKG_CONFIG" = "x"
-then
-       with_libopenipmipthread="no"
-       temp_result="no"
-else
-       temp_result="$PKG_CONFIG"
-fi
-AC_MSG_RESULT([$temp_result])
-
 if test "x$with_libopenipmipthread" = "xyes"
 then
        AC_MSG_CHECKING([for libOpenIPMIpthread])
@@ -5485,7 +5631,7 @@ PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
                [with_libnotify="no (pkg-config doesn't know libnotify)"]
 )
 
-PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.8.0],
+PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.6.0],
  [with_libriemann_client="yes"],
  [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"])
 
@@ -5626,6 +5772,7 @@ plugin_conntrack="no"
 plugin_contextswitch="no"
 plugin_cpu="no"
 plugin_cpufreq="no"
+plugin_cpusleep="no"
 plugin_curl_json="no"
 plugin_curl_xml="no"
 plugin_df="no"
@@ -5636,6 +5783,9 @@ plugin_entropy="no"
 plugin_ethstat="no"
 plugin_fhcount="no"
 plugin_fscache="no"
+plugin_gps="no"
+plugin_grpc="no"
+plugin_hugepages="no"
 plugin_interface="no"
 plugin_ipmi="no"
 plugin_ipvs="no"
@@ -5647,8 +5797,10 @@ plugin_multimeter="no"
 plugin_nfs="no"
 plugin_numa="no"
 plugin_perl="no"
+plugin_pinba="no"
 plugin_processes="no"
 plugin_protocols="no"
+plugin_python="no"
 plugin_serial="no"
 plugin_smart="no"
 plugin_swap="no"
@@ -5682,6 +5834,7 @@ then
        plugin_entropy="yes"
        plugin_fhcount="yes"
        plugin_fscache="yes"
+       plugin_hugepages="yes"
        plugin_interface="yes"
        plugin_ipc="yes"
        plugin_irq="yes"
@@ -5710,6 +5863,11 @@ then
        then
                plugin_turbostat="yes"
        fi
+       
+       if test "x$c_cv_have_clock_boottime_monotonic" = "xyes"
+       then
+               plugin_cpusleep="yes"
+       fi
 fi
 
 if test "x$ac_system" = "xOpenBSD"
@@ -5911,11 +6069,21 @@ then
        plugin_ethstat="yes"
 fi
 
+if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x"
+then
+       plugin_grpc="yes"
+fi
+
 if test "x$have_getifaddrs" = "xyes"
 then
        plugin_interface="yes"
 fi
 
+if test "x$with_libgps" = "xyes"
+then
+       plugin_gps="yes"
+fi
+
 if test "x$have_getloadavg" = "xyes"
 then
        plugin_load="yes"
@@ -5931,6 +6099,11 @@ then
        plugin_perl="yes"
 fi
 
+if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes"
+then
+       plugin_pinba="yes"
+fi
+
 # Mac OS X memory interface
 if test "x$have_host_statistics" = "xyes"
 then
@@ -5961,6 +6134,11 @@ then
        plugin_processes="yes"
 fi
 
+if test "x$with_libpython" != "xno"
+then
+       plugin_python="yes"
+fi
+
 if test "x$with_libatasmart" = "xyes" && test "x$with_libudev" = "xyes"
 then
        plugin_smart="yes"
@@ -6042,6 +6220,7 @@ AC_PLUGIN([conntrack],           [$plugin_conntrack],       [nf_conntrack statis
 AC_PLUGIN([contextswitch],       [$plugin_contextswitch],   [context switch statistics])
 AC_PLUGIN([cpu],                 [$plugin_cpu],             [CPU usage statistics])
 AC_PLUGIN([cpufreq],             [$plugin_cpufreq],         [CPU frequency statistics])
+AC_PLUGIN([cpusleep],            [$plugin_cpusleep],        [CPU sleep statistics])
 AC_PLUGIN([csv],                 [yes],                     [CSV output plugin])
 AC_PLUGIN([curl],                [$with_libcurl],           [CURL generic web statistics])
 AC_PLUGIN([curl_json],           [$plugin_curl_json],       [CouchDB statistics])
@@ -6060,8 +6239,10 @@ AC_PLUGIN([fhcount],             [$plugin_fhcount],         [File handles statis
 AC_PLUGIN([filecount],           [yes],                     [Count files in directories])
 AC_PLUGIN([fscache],             [$plugin_fscache],         [fscache statistics])
 AC_PLUGIN([gmond],               [$with_libganglia],        [Ganglia plugin])
-AC_PLUGIN([grpc],                [$with_grpc],              [gRPC plugin])
+AC_PLUGIN([gps],                 [$plugin_gps],             [GPS plugin])
+AC_PLUGIN([grpc],                [$plugin_grpc],            [gRPC plugin])
 AC_PLUGIN([hddtemp],             [yes],                     [Query hddtempd])
+AC_PLUGIN([hugepages],           [$plugin_hugepages],       [Hugepages statistics])
 AC_PLUGIN([interface],           [$plugin_interface],       [Interface traffic statistics])
 AC_PLUGIN([ipc],                 [$plugin_ipc],             [IPC statistics])
 AC_PLUGIN([ipmi],                [$plugin_ipmi],            [IPMI sensor statistics])
@@ -6073,6 +6254,7 @@ AC_PLUGIN([load],                [$plugin_load],            [System load])
 AC_PLUGIN([log_logstash],        [$plugin_log_logstash],    [Logstash json_event compatible logging])
 AC_PLUGIN([logfile],             [yes],                     [File logging plugin])
 AC_PLUGIN([lpar],                [$with_perfstat],          [AIX logical partitions statistics])
+AC_PLUGIN([lua],                 [$with_liblua],            [Lua plugin])
 AC_PLUGIN([lvm],                 [$with_liblvm2app],        [LVM statistics])
 AC_PLUGIN([madwifi],             [$have_linux_wireless_h],  [Madwifi wireless statistics])
 AC_PLUGIN([match_empty_counter], [yes],                     [The empty counter match])
@@ -6109,13 +6291,13 @@ 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([pinba],               [$plugin_pinba],           [Pinba statistics])
 AC_PLUGIN([ping],                [$with_liboping],          [Network latency statistics])
 AC_PLUGIN([postgresql],          [$with_libpq],             [PostgreSQL database statistics])
 AC_PLUGIN([powerdns],            [yes],                     [PowerDNS statistics])
 AC_PLUGIN([processes],           [$plugin_processes],       [Process statistics])
 AC_PLUGIN([protocols],           [$plugin_protocols],       [Protocol (IP, TCP, ...) statistics])
-AC_PLUGIN([python],              [$with_python],            [Embed a Python interpreter])
+AC_PLUGIN([python],              [$plugin_python],          [Embed a Python interpreter])
 AC_PLUGIN([redis],               [$with_libhiredis],        [Redis plugin])
 AC_PLUGIN([routeros],            [$with_librouteros],       [RouterOS plugin])
 AC_PLUGIN([rrdcached],           [$librrd_rrdc_update],     [RRDTool output plugin])
@@ -6291,6 +6473,18 @@ AC_ARG_WITH(perl-bindings, [AS_HELP_STRING([--with-perl-bindings@<:@=OPTIONS@:>@
                with_perl_bindings="no (no perl interpreter found)"
        fi
 ])
+
+if test "x$with_perl_bindings" = "xyes"
+then
+       AC_MSG_CHECKING([for the ExtUtils::MakeMaker module])
+       if $PERL -MExtUtils::MakeMaker -e '' 2>/dev/null; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               with_perl_bindings="no (ExtUtils::MakeMaker not found)"
+       fi
+fi
+
 if test "x$with_perl_bindings" = "xyes"
 then
        PERL_BINDINGS="perl"
@@ -6380,7 +6574,8 @@ AC_MSG_RESULT([    libdpdk . . . . . . . $with_libdpdk])
 AC_MSG_RESULT([    libesmtp  . . . . . . $with_libesmtp])
 AC_MSG_RESULT([    libganglia  . . . . . $with_libganglia])
 AC_MSG_RESULT([    libgcrypt . . . . . . $with_libgcrypt])
-AC_MSG_RESULT([    libgrpc . . . . . . . $with_libgrpc])
+AC_MSG_RESULT([    libgps  . . . . . . . $with_libgps])
+AC_MSG_RESULT([    libgrpc++ . . . . . . $with_libgrpcpp])
 AC_MSG_RESULT([    libhal  . . . . . . . $with_libhal])
 AC_MSG_RESULT([    libhiredis  . . . . . $with_libhiredis])
 AC_MSG_RESULT([    libi2c-dev  . . . . . $with_libi2c])
@@ -6390,6 +6585,7 @@ AC_MSG_RESULT([    libjvm  . . . . . . . $with_java])
 AC_MSG_RESULT([    libkstat  . . . . . . $with_kstat])
 AC_MSG_RESULT([    libkvm  . . . . . . . $with_libkvm])
 AC_MSG_RESULT([    libldap . . . . . . . $with_libldap])
+AC_MSG_RESULT([    liblua  . . . . . . . $with_liblua])
 AC_MSG_RESULT([    liblvm2app  . . . . . $with_liblvm2app])
 AC_MSG_RESULT([    libmemcached  . . . . $with_libmemcached])
 AC_MSG_RESULT([    libmnl  . . . . . . . $with_libmnl])
@@ -6408,6 +6604,9 @@ AC_MSG_RESULT([    libpcap . . . . . . . $with_libpcap])
 AC_MSG_RESULT([    libperfstat . . . . . $with_perfstat])
 AC_MSG_RESULT([    libperl . . . . . . . $with_libperl])
 AC_MSG_RESULT([    libpq . . . . . . . . $with_libpq])
+AC_MSG_RESULT([    libprotobuf . . . . . $with_libprotobuf])
+AC_MSG_RESULT([    libprotobuf-c . . . . $with_libprotobuf_c])
+AC_MSG_RESULT([    libpython . . . . . . $with_libpython])
 AC_MSG_RESULT([    librabbitmq . . . . . $with_librabbitmq])
 AC_MSG_RESULT([    libriemann-client . . $with_libriemann_client])
 AC_MSG_RESULT([    librdkafka  . . . . . $with_librdkafka])
@@ -6427,8 +6626,7 @@ AC_MSG_RESULT([    libxmms . . . . . . . $with_libxmms])
 AC_MSG_RESULT([    libyajl . . . . . . . $with_libyajl])
 AC_MSG_RESULT([    oracle  . . . . . . . $with_oracle])
 AC_MSG_RESULT([    protobuf-c  . . . . . $have_protoc_c])
-AC_MSG_RESULT([    protoc 3  . . . . . . $protoc3])
-AC_MSG_RESULT([    python  . . . . . . . $with_python])
+AC_MSG_RESULT([    protoc 3  . . . . . . $have_protoc3])
 AC_MSG_RESULT()
 AC_MSG_RESULT([  Features:])
 AC_MSG_RESULT([    daemon mode . . . . . $enable_daemon])
@@ -6455,6 +6653,7 @@ AC_MSG_RESULT([    conntrack . . . . . . $enable_conntrack])
 AC_MSG_RESULT([    contextswitch . . . . $enable_contextswitch])
 AC_MSG_RESULT([    cpu . . . . . . . . . $enable_cpu])
 AC_MSG_RESULT([    cpufreq . . . . . . . $enable_cpufreq])
+AC_MSG_RESULT([    cpusleep  . . . . . . $enable_cpusleep])
 AC_MSG_RESULT([    csv . . . . . . . . . $enable_csv])
 AC_MSG_RESULT([    curl  . . . . . . . . $enable_curl])
 AC_MSG_RESULT([    curl_json . . . . . . $enable_curl_json])
@@ -6473,8 +6672,10 @@ AC_MSG_RESULT([    fhcount . . . . . . . $enable_fhcount])
 AC_MSG_RESULT([    filecount . . . . . . $enable_filecount])
 AC_MSG_RESULT([    fscache . . . . . . . $enable_fscache])
 AC_MSG_RESULT([    gmond . . . . . . . . $enable_gmond])
+AC_MSG_RESULT([    gps . . . . . . . . . $enable_gps])
 AC_MSG_RESULT([    grpc  . . . . . . . . $enable_grpc])
 AC_MSG_RESULT([    hddtemp . . . . . . . $enable_hddtemp])
+AC_MSG_RESULT([    hugepages . . . . . . $enable_hugepages])
 AC_MSG_RESULT([    interface . . . . . . $enable_interface])
 AC_MSG_RESULT([    ipc . . . . . . . . . $enable_ipc])
 AC_MSG_RESULT([    ipmi  . . . . . . . . $enable_ipmi])
@@ -6486,6 +6687,7 @@ AC_MSG_RESULT([    load  . . . . . . . . $enable_load])
 AC_MSG_RESULT([    logfile . . . . . . . $enable_logfile])
 AC_MSG_RESULT([    log_logstash  . . . . $enable_log_logstash])
 AC_MSG_RESULT([    lpar  . . . . . . . . $enable_lpar])
+AC_MSG_RESULT([    lua . . . . . . . . . $enable_lua])
 AC_MSG_RESULT([    lvm . . . . . . . . . $enable_lvm])
 AC_MSG_RESULT([    madwifi . . . . . . . $enable_madwifi])
 AC_MSG_RESULT([    match_empty_counter . $enable_match_empty_counter])
index 9539062..71fb5f8 100644 (file)
@@ -39,6 +39,7 @@
 #endif /* ! HAVE_CONFIG */
 
 #include <collectd/collectd.h>
+
 #include <collectd/common.h>
 #include <collectd/plugin.h>
 
@@ -84,36 +85,50 @@ static int my_init (void)
 } /* static int my_init (void) */
 
 /*
- * This function is called in regular intervalls to collect the data.
+ * This is a utility function used by the read callback to populate a
+ * value_list_t and pass it to plugin_dispatch_values.
  */
-static int my_read (void)
+static int my_submit (gauge_t value)
 {
-       value_t values[1]; /* the size of this list should equal the number of
-                                                 data sources */
        value_list_t vl = VALUE_LIST_INIT;
 
-       /* do the magic to read the data */
-       values[0].gauge = random ();
-
-       vl.values     = values;
+       /* Convert the gauge_t to a value_t and add it to the value_list_t. */
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
-       vl.time       = time (NULL);
+
+       /* Only set vl.time yourself if you update multiple metrics (i.e. you
+        * have multiple calls to plugin_dispatch_values()) and they need to all
+        * have the same timestamp. */
+       /* vl.time = cdtime(); */
+
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin));
 
        /* it is strongly recommended to use a type defined in the types.db file
         * instead of a custom type */
-       sstrncpy (vl.type, "myplugin", sizeof (vl.plugin));
+       sstrncpy (vl.type, "myplugin", sizeof (vl.type));
        /* optionally set vl.plugin_instance and vl.type_instance to reasonable
         * values (default: "") */
 
        /* dispatch the values to collectd which passes them on to all registered
         * write functions */
-       plugin_dispatch_values (&vl);
+       return plugin_dispatch_values (&vl);
+}
+
+/*
+ * This function is called in regular intervalls to collect the data.
+ */
+static int my_read (void)
+{
+       /* do the magic to read the data */
+       gauge_t value = random ();
+
+       if (my_submit (value) != 0)
+               WARNING ("myplugin plugin: Dispatching a random value failed.");
 
        /* A return value != 0 indicates an error and the plugin will be skipped
         * for an increasing amount of time. */
-    return 0;
+       return 0;
 } /* static int my_read (void) */
 
 /*
index c2a9555..8e5a7ed 100755 (executable)
@@ -104,8 +104,6 @@ our %TypesCounterToDerive = # {{{
   protocol_counter => ["value"],
   ps_cputime => ["user", "syst"],
   ps_pagefaults => ["minflt", "majflt"],
-  ps_code => ["value"],
-  ps_data => ["value"],
   serial_octets => ["rx", "tx"],
   swap_io => ["value"],
   virt_cpu_total => ["ns"],
index 10546c8..73e69c7 100644 (file)
@@ -53,6 +53,7 @@
 %define with_contextswitch 0%{!?_without_contextswitch:1}
 %define with_cpu 0%{!?_without_cpu:1}
 %define with_cpufreq 0%{!?_without_cpufreq:1}
+%define with_cpusleep 0%{!?_without_cpusleep:1}
 %define with_csv 0%{!?_without_csv:1}
 %define with_curl 0%{!?_without_curl:1}
 %define with_curl_json 0%{!?_without_curl_json:1}
@@ -70,7 +71,9 @@
 %define with_filecount 0%{!?_without_filecount:1}
 %define with_fscache 0%{!?_without_fscache:1}
 %define with_gmond 0%{!?_without_gmond:1}
+%define with_gps 0%{!?_without_gps:1}
 %define with_hddtemp 0%{!?_without_hddtemp:1}
+%define with_hugepages 0%{!?_without_hugepages:1}
 %define with_interface 0%{!?_without_interface:1}
 %define with_ipc 0%{!?_without_ipc:1}
 %define with_ipmi 0%{!?_without_ipmi:1}
@@ -81,6 +84,7 @@
 %define with_load 0%{!?_without_load:1}
 %define with_log_logstash 0%{!?_without_log_logstash:1}
 %define with_logfile 0%{!?_without_logfile:1}
+%define with_lua 0%{!?_without_lua:1}
 %define with_lvm 0%{!?_without_lvm:1}
 %define with_madwifi 0%{!?_without_madwifi:1}
 %define with_mbmon 0%{!?_without_mbmon:1}
 
 # Plugins not buildable on RHEL < 7
 %if 0%{?rhel} && 0%{?rhel} < 7
+%define with_cpusleep 0
+%define with_gps 0
 %define with_mqtt 0
 %define with_rrdcached 0
 %define with_xmms 0
 
 Summary:       Statistics collection and monitoring daemon
 Name:          collectd
-Version:       5.5.2
-Release:       1%{?dist}
+Version:       5.7.0
+Release:       2%{?dist}
 URL:           https://collectd.org
 Source:                https://collectd.org/files/%{name}-%{version}.tar.bz2
 License:       GPLv2
 Group:         System Environment/Daemons
 BuildRoot:     %{_tmppath}/%{name}-%{version}-root
-BuildRequires: libgcrypt-devel, kernel-headers, libtool-ltdl-devel, libcap-devel
+BuildRequires: libgcrypt-devel, kernel-headers, libtool-ltdl-devel, libcap-devel, which
 Vendor:                collectd development team <collectd@verplant.org>
 
 %if 0%{?fedora} || 0%{?rhel} >= 7
@@ -416,6 +422,16 @@ The gmond plugin subscribes to a Multicast group to receive data from gmond,
 the client daemon of the Ganglia project.
 %endif
 
+%if %{with_gps}
+%package gps
+Summary:       GPS plugin for collectd
+Group:         System Environment/Daemons
+Requires:      %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: gpsd-devel
+%description gps
+This plugin monitor gps related data through gpsd.
+%endif
+
 %if %{with_grpc}
 %package grpc
 Summary:       GRPC plugin for collectd
@@ -481,6 +497,17 @@ BuildRequires: yajl-devel
 This plugin logs in logstash JSON format
 %endif
 
+%if %{with_lua}
+%package lua
+Summary:       Lua plugin for collectd
+Group:         System Environment/Daemons
+Requires:      %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: lua-devel
+%description lua
+The Lua plugin embeds a Lua interpreter into collectd and exposes the
+application programming interface (API) to Lua scripts.
+%endif
+
 %if %{with_lvm}
 %package lvm
 Summary:       LVM plugin for collectd
@@ -976,6 +1003,12 @@ Collectd utilities
 %define _with_cpufreq --disable-cpufreq
 %endif
 
+%if %{with_cpusleep}
+%define _with_cpusleep --enable-cpusleep
+%else
+%define _with_cpusleep --disable-cpusleep
+%endif
+
 %if %{with_csv}
 %define _with_csv --enable-csv
 %else
@@ -1084,6 +1117,12 @@ Collectd utilities
 %define _with_gmond --disable-gmond
 %endif
 
+%if %{with_gps}
+%define _with_gps --enable-gps
+%else
+%define _with_gps --disable-gps
+%endif
+
 %if %{with_grpc}
 %define _with_grpc --enable-grpc
 %else
@@ -1096,6 +1135,12 @@ Collectd utilities
 %define _with_hddtemp --disable-hddtemp
 %endif
 
+%if %{with_hugepages}
+%define _with_hugepages --enable-hugepages
+%else
+%define _with_hugepages --disable-hugepages
+%endif
+
 %if %{with_interface}
 %define _with_interface --enable-interface
 %else
@@ -1168,6 +1213,12 @@ Collectd utilities
 %define _with_lpar --disable-lpar
 %endif
 
+%if %{with_lua}
+%define _with_lua --enable-lua
+%else
+%define _with_lua --disable-lua
+%endif
+
 %if %{with_lvm}
 %define _with_lvm --enable-lvm
 %else
@@ -1387,6 +1438,7 @@ Collectd utilities
 %if %{with_python}
        %if 0%{?rhel} && 0%{?rhel} < 6
 %define _with_python --enable-python --with-python=%{_bindir}/python2.6
+%define _python_config PYTHON_CONFIG="%{_bindir}/python2.6-config"
        %else
 %define _with_python --enable-python
        %endif
@@ -1665,6 +1717,7 @@ Collectd utilities
 %endif
 
 %configure CFLAGS="%{optflags} -DLT_LAZY_OR_NOW=\"RTLD_LAZY|RTLD_GLOBAL\"" \
+       %{?_python_config} \
        --disable-static \
        --without-included-ltdl \
        --enable-all-plugins=yes \
@@ -1694,6 +1747,7 @@ Collectd utilities
        %{?_with_conntrack} \
        %{?_with_contextswitch} \
        %{?_with_cpufreq} \
+       %{?_with_cpusleep} \
        %{?_with_cpu} \
        %{?_with_csv} \
        %{?_with_curl_json} \
@@ -1712,8 +1766,10 @@ Collectd utilities
        %{?_with_filecount} \
        %{?_with_fscache} \
        %{?_with_gmond} \
+       %{?_with_gps} \
        %{?_with_grpc} \
        %{?_with_hddtemp} \
+       %{?_with_hugepages} \
        %{?_with_interface} \
        %{?_with_ipc} \
        %{?_with_ipmi} \
@@ -1725,6 +1781,7 @@ Collectd utilities
        %{?_with_log_logstash} \
        %{?_with_logfile} \
        %{?_with_lpar} \
+       %{?_with_lua} \
        %{?_with_lvm} \
        %{?_with_madwifi} \
        %{?_with_mbmon} \
@@ -1851,6 +1908,10 @@ rm -f %{buildroot}%{_datadir}/collectd/java/generic-jmx.jar
 rm -f %{buildroot}%{_mandir}/man5/collectd-java.5*
 %endif
 
+%if ! %{with_lua}
+rm -f %{buildroot}%{_mandir}/man5/collectd-lua.5*
+%endif
+
 %if ! %{with_perl}
 rm -f %{buildroot}%{_mandir}/man5/collectd-perl.5*
 rm -f %{buildroot}%{_mandir}/man3/Collectd::Unixsock.3pm*
@@ -1962,6 +2023,9 @@ fi
 %if %{with_cpufreq}
 %{_libdir}/%{name}/cpufreq.so
 %endif
+%if %{with_cpusleep}
+%{_libdir}/%{name}/cpusleep.so
+%endif
 %if %{with_csv}
 %{_libdir}/%{name}/csv.so
 %endif
@@ -1989,6 +2053,9 @@ fi
 %if %{with_fscache}
 %{_libdir}/%{name}/fscache.so
 %endif
+%if %{with_hugepages}
+%{_libdir}/%{name}/hugepages.so
+%endif
 %if %{with_interface}
 %{_libdir}/%{name}/interface.so
 %endif
@@ -2233,6 +2300,11 @@ fi
 %{_libdir}/%{name}/gmond.so
 %endif
 
+%if %{with_gps}
+%files gps
+%{_libdir}/%{name}/gps.so
+%endif
+
 %if %{with_grpc}
 %files grpc
 %{_libdir}/%{name}/grpc.so
@@ -2271,6 +2343,12 @@ fi
 %{_libdir}/%{name}/log_logstash.so
 %endif
 
+%if %{with_lua}
+%files lua
+%{_mandir}/man5/collectd-lua*
+%{_libdir}/%{name}/lua.so
+%endif
+
 %if %{with_lvm}
 %files lvm
 %{_libdir}/%{name}/lvm.so
@@ -2445,6 +2523,15 @@ fi
 %doc contrib/
 
 %changelog
+* Tue Aug 23 2016 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.0-1
+- New PRE-RELEASE version
+- New plugins enabled by default: hugepages
+
+* Sun Aug 14 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.6.0-1
+- New PRE-RELEASE version
+- New plugins enabled by default: chrony, cpusleep, gps, lua, mqtt, notify_nagios
+- New plugins disabled by default: grpc, xencpu, zone
+
 * Tue Jul 26 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.5.2-1
 - New upstream version
 - Contains fix for CVE-2016-6254
@@ -2452,8 +2539,6 @@ fi
 
 * Sat Jun 04 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> 5.5.1-1
 - New upstream version
-- New plugins enabled by default: chrony, mqtt, notify_nagios
-- New plugins disabled by default: grpc, zone, xencpu
 
 * Wed May 27 2015 Marc Fournier <marc.fournier@camptocamp.com> 5.5.0-1
 - New upstream version
index 608fcbb..614d1bd 100644 (file)
 syntax = "proto3";
 
 package collectd;
+option go_package = "collectd.org/rpc/proto";
 
 import "types.proto";
-import "google/protobuf/timestamp.proto";
 
 service Collectd {
-       // Dispatch collected values to collectd.
-       rpc DispatchValues(DispatchValuesRequest) returns (DispatchValuesReply);
-
-       // Query a list of values available from collectd's value cache.
-       rpc QueryValues(QueryValuesRequest) returns (QueryValuesReply);
+  // PutValues reads the value lists from the PutValuesRequest stream.
+  // The gRPC server embedded into collectd will inject them into the system
+  // just like the network plugin.
+  rpc PutValues(stream PutValuesRequest)
+      returns (PutValuesResponse);
+
+  // QueryValues returns a stream of matching value lists from collectd's
+  // internal cache.
+  rpc QueryValues(QueryValuesRequest) returns (stream QueryValuesResponse);
 }
 
-// The arguments to DispatchValues.
-message DispatchValuesRequest {
-       collectd.types.ValueList values = 1;
+// The arguments to PutValues.
+message PutValuesRequest {
+  // value_list is the metric to be sent to the server.
+  collectd.types.ValueList value_list = 1;
 }
 
-// The response from DispatchValues.
-message DispatchValuesReply {
-}
+// The response from PutValues.
+message PutValuesResponse {}
 
 // The arguments to QueryValues.
 message QueryValuesRequest {
-       // Query by the fields of the identifier. Only return values matching the
-       // specified shell wildcard patterns (see fnmatch(3)). Use '*' to match
-       // any value.
-       collectd.types.Identifier identifier = 1;
+  // Query by the fields of the identifier. Only return values matching the
+  // specified shell wildcard patterns (see fnmatch(3)). Use '*' to match
+  // any value.
+  collectd.types.Identifier identifier = 1;
 }
 
 // The response from QueryValues.
-message QueryValuesReply {
-       repeated collectd.types.ValueList values = 1;
-}
+message QueryValuesResponse { collectd.types.ValueList value_list = 1; }
index 4a852e4..952c541 100644 (file)
 syntax = "proto3";
 
 package collectd.types;
+option go_package = "collectd.org/rpc/proto/types";
 
 import "google/protobuf/duration.proto";
 import "google/protobuf/timestamp.proto";
 
 message Identifier {
-       string host = 1;
-       string plugin = 2;
-       string plugin_instance = 3;
-       string type = 4;
-       string type_instance = 5;
+  string host = 1;
+  string plugin = 2;
+  string plugin_instance = 3;
+  string type = 4;
+  string type_instance = 5;
 }
 
 message Value {
-       oneof value {
-               uint64 counter = 1;
-               double gauge = 2;
-               int64 derive = 3;
-               uint64 absolute = 4;
-       };
+  oneof value {
+    uint64 counter = 1;
+    double gauge = 2;
+    int64 derive = 3;
+    uint64 absolute = 4;
+  };
 }
 
 message ValueList {
-       repeated Value value = 1;
+  repeated Value values = 1;
 
-       google.protobuf.Timestamp time = 2;
-       google.protobuf.Duration interval = 3;
+  google.protobuf.Timestamp time = 2;
+  google.protobuf.Duration interval = 3;
 
-       Identifier identifier = 4;
+  Identifier identifier = 4;
+
+  repeated string ds_names = 5;
 }
index 1b56c11..99a7c02 100644 (file)
@@ -27,6 +27,21 @@ noinst_LTLIBRARIES =
 check_PROGRAMS =
 TESTS =
 
+noinst_LTLIBRARIES += libformat_json.la
+libformat_json_la_SOURCES   = utils_format_json.c utils_format_json.h
+libformat_json_la_CPPFLAGS  = $(AM_CPPFLAGS)
+libformat_json_la_LDFLAGS   = $(AM_LDFLAGS)
+libformat_json_la_LIBADD    =
+if BUILD_WITH_LIBYAJL
+libformat_json_la_CPPFLAGS += $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+libformat_json_la_LDFLAGS  += $(BUILD_WITH_LIBYAJL_LDFLAGS)
+libformat_json_la_LIBADD   += $(BUILD_WITH_LIBYAJL_LIBS)
+check_PROGRAMS += test_format_json
+TESTS += test_format_json
+test_format_json_SOURCES = utils_format_json_test.c testing.h
+test_format_json_LDADD = libformat_json.la daemon/libmetadata.la daemon/libplugin_mock.la -lm
+endif
+
 noinst_LTLIBRARIES += liblatency.la
 liblatency_la_SOURCES = utils_latency.c utils_latency.h
 check_PROGRAMS += test_utils_latency
@@ -141,11 +156,10 @@ 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_format_graphite.c utils_format_graphite.h \
-                 utils_format_json.c utils_format_json.h
+                 utils_format_graphite.c utils_format_graphite.h
 amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
 amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS)
-amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS)
+amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) libformat_json.la
 endif
 
 if BUILD_PLUGIN_APACHE
@@ -156,6 +170,7 @@ apache_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
 apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
 endif
 
+
 if BUILD_PLUGIN_APCUPS
 pkglib_LTLIBRARIES += apcups.la
 apcups_la_SOURCES = apcups.c
@@ -198,7 +213,7 @@ endif
 
 if BUILD_PLUGIN_BATTERY
 pkglib_LTLIBRARIES += battery.la
-battery_la_SOURCES = battery.c
+battery_la_SOURCES = battery.c battery_statefs.c
 battery_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 if BUILD_WITH_LIBIOKIT
 battery_la_LDFLAGS += -framework IOKit
@@ -279,6 +294,12 @@ cpufreq_la_SOURCES = cpufreq.c
 cpufreq_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
+if BUILD_PLUGIN_CPUSLEEP
+pkglib_LTLIBRARIES += cpusleep.la
+cpusleep_la_SOURCES = cpusleep.c
+cpusleep_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
 if BUILD_PLUGIN_CSV
 pkglib_LTLIBRARIES += csv.la
 csv_la_SOURCES = csv.c
@@ -430,14 +451,21 @@ gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS)
 gmond_la_LIBADD = $(GANGLIA_LIBS)
 endif
 
+if BUILD_PLUGIN_GPS
+pkglib_LTLIBRARIES += gps.la
+gps_la_SOURCES = gps.c
+gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS)
+gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS)
+gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS)
+endif
+
 if BUILD_PLUGIN_GRPC
 pkglib_LTLIBRARIES += grpc.la
 grpc_la_SOURCES = grpc.cc
 nodist_grpc_la_SOURCES = collectd.grpc.pb.cc collectd.pb.cc types.pb.cc
-grpc_la_CPPFLAGS = $(AM_CPPFLAGS) -std=c++11
-grpc_la_CXXFLAGS = $(AM_CXXFLAGS) -std=c++11
-grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-grpc_la_LIBADD = -lgrpc++ -lgrpc -lgpr -lprotobuf
+grpc_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS)
+grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS)
+grpc_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS)
 endif
 
 if BUILD_PLUGIN_HDDTEMP
@@ -450,6 +478,12 @@ hddtemp_la_LIBADD += -lsocket
 endif
 endif
 
+if BUILD_PLUGIN_HUGEPAGES
+pkglib_LTLIBRARIES += hugepages.la
+hugepages_la_SOURCES = hugepages.c
+hugepages_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
 if BUILD_PLUGIN_INTERFACE
 pkglib_LTLIBRARIES += interface.la
 interface_la_SOURCES = interface.c
@@ -555,6 +589,15 @@ lpar_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 lpar_la_LIBADD = -lperfstat
 endif
 
+if BUILD_PLUGIN_LUA
+pkglib_LTLIBRARIES += lua.la
+lua_la_SOURCES = lua.c \
+                utils_lua.c utils_lua.h
+lua_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBLUA_CFLAGS)
+lua_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+lua_la_LIBADD = $(BUILD_WITH_LIBLUA_LIBS)
+endif
+
 if BUILD_PLUGIN_LVM
 pkglib_LTLIBRARIES += lvm.la
 lvm_la_SOURCES = lvm.c
@@ -837,6 +880,10 @@ perl_la_SOURCES = perl.c
 # Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own
 # version of that type if HAS_BOOL is not defined... *sigh*
 perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1
+# Despite off_t being 64 bit wide on 64 bit platforms, Perl insist on using
+# off64_t which is only exposed when _LARGEFILE64_SOURCE is defined... *sigh*
+# On older platforms we also need _REENTRANT. _GNU_SOURCE sets both of these.
+perl_la_CPPFLAGS += -D_GNU_SOURCE
 perl_la_CFLAGS  = $(AM_CFLAGS) \
                $(PERL_CFLAGS) \
                -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\"
@@ -860,8 +907,9 @@ if BUILD_PLUGIN_PINBA
 pkglib_LTLIBRARIES += pinba.la
 pinba_la_SOURCES = pinba.c
 nodist_pinba_la_SOURCES = pinba.pb-c.c pinba.pb-c.h
-pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-pinba_la_LIBADD = -lprotobuf-c
+pinba_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS)
+pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS)
+pinba_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS)
 endif
 
 if BUILD_PLUGIN_PING
@@ -891,13 +939,11 @@ endif
 if BUILD_PLUGIN_PYTHON
 pkglib_LTLIBRARIES += python.la
 python_la_SOURCES = python.c pyconfig.c pyvalues.c cpython.h
-python_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_PYTHON_CPPFLAGS)
-python_la_CFLAGS = $(AM_CFLAGS)
+python_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBPYTHON_CPPFLAGS)
 if COMPILER_IS_GCC
-python_la_CFLAGS += -fno-strict-aliasing -Wno-strict-aliasing
+python_la_CPPFLAGS += -fno-strict-aliasing -Wno-strict-aliasing
 endif
-python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_PYTHON_LDFLAGS)
-python_la_LIBADD = $(BUILD_WITH_PYTHON_LIBS)
+python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBPYTHON_LDFLAGS)
 endif
 
 if BUILD_PLUGIN_PROCESSES
@@ -965,9 +1011,9 @@ endif
 if BUILD_PLUGIN_SIGROK
 pkglib_LTLIBRARIES += sigrok.la
 sigrok_la_SOURCES = sigrok.c
-sigrok_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSIGROK_CFLAGS)
-sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSIGROK_LDFLAGS)
-sigrok_la_LIBADD = -lsigrok
+sigrok_la_CFLAGS = $(AM_CFLAGS) $(LIBSIGROK_CFLAGS)
+sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+sigrok_la_LIBADD = $(LIBSIGROK_LIBS)
 endif
 
 if BUILD_PLUGIN_SMART
@@ -983,13 +1029,9 @@ endif
 if BUILD_PLUGIN_SNMP
 pkglib_LTLIBRARIES += snmp.la
 snmp_la_SOURCES = snmp.c
-snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-snmp_la_CFLAGS = $(AM_CFLAGS)
-snmp_la_LIBADD =
-if BUILD_WITH_LIBNETSNMP
-snmp_la_CFLAGS += $(BUILD_WITH_LIBSNMP_CFLAGS)
-snmp_la_LIBADD += $(BUILD_WITH_LIBSNMP_LIBS)
-endif
+snmp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMP_CPPFLAGS)
+snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMP_LDFLAGS)
+snmp_la_LIBADD = $(BUILD_WITH_LIBNETSNMP_LIBS)
 endif
 
 if BUILD_PLUGIN_STATSD
@@ -1221,31 +1263,29 @@ endif
 if BUILD_PLUGIN_WRITE_GRAPHITE
 pkglib_LTLIBRARIES += write_graphite.la
 write_graphite_la_SOURCES = write_graphite.c \
-                        utils_format_graphite.c utils_format_graphite.h \
-                        utils_format_json.c utils_format_json.h
+                        utils_format_graphite.c utils_format_graphite.h
 write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+write_graphite_la_LIBADD = libformat_json.la
 endif
 
 if BUILD_PLUGIN_WRITE_HTTP
 pkglib_LTLIBRARIES += write_http.la
 write_http_la_SOURCES = write_http.c \
-                       utils_format_json.c utils_format_json.h \
                        utils_format_kairosdb.c utils_format_kairosdb.h
-write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
 write_http_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_http_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
+write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS)
+write_http_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) libformat_json.la
 endif
 
 if BUILD_PLUGIN_WRITE_KAFKA
 pkglib_LTLIBRARIES += write_kafka.la
 write_kafka_la_SOURCES = write_kafka.c \
                         utils_format_graphite.c utils_format_graphite.h \
-                        utils_format_json.c utils_format_json.h \
                         utils_cmd_putval.c utils_cmd_putval.h \
                         utils_crc32.c utils_crc32.h
 write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS)
 write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS)
-write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS)
+write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) libformat_json.la
 endif
 
 if BUILD_PLUGIN_WRITE_LOG
@@ -1253,6 +1293,7 @@ pkglib_LTLIBRARIES += write_log.la
 write_log_la_SOURCES = write_log.c \
                         utils_format_graphite.c utils_format_graphite.h
 write_log_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+write_log_la_LIBADD = libformat_json.la
 endif
 
 if BUILD_PLUGIN_WRITE_MONGODB
@@ -1338,6 +1379,7 @@ dist_man_MANS = collectd.1 \
                collectd-exec.5 \
                collectdctl.1 \
                collectd-java.5 \
+               collectd-lua.5 \
                collectdmon.1 \
                collectd-nagios.1 \
                collectd-perl.5 \
@@ -1353,6 +1395,7 @@ EXTRA_DIST =      collectd.conf.pod \
                collectd-exec.pod \
                collectdctl.pod \
                collectd-java.pod \
+               collectd-lua.pod \
                collectdmon.pod \
                collectd-nagios.pod \
                collectd-perl.pod \
@@ -1400,7 +1443,7 @@ 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
-       $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto
+       $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/pinba.proto
 endif
 
 install-exec-hook:
index c4c1627..2744c89 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 #include "meta_data.h"
 #include "utils_cache.h" /* for uc_get_rate() */
 #include "utils_subst.h"
@@ -346,7 +345,6 @@ static int agg_instance_read_func (agg_instance_t *inst, /* {{{ */
   else
     sstrncpy (vl->plugin_instance, func, sizeof (vl->plugin_instance));
 
-  memset (&v, 0, sizeof (v));
   status = rate_to_value (&v, rate, state, inst->ds_type, t);
   if (status != 0)
   {
@@ -484,9 +482,7 @@ static void agg_lookup_free_obj_callback (void *user_obj) /* {{{ */
 static int agg_config_handle_group_by (oconfig_item_t const *ci, /* {{{ */
     aggregation_t *agg)
 {
-  int i;
-
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     char const *value;
 
@@ -522,7 +518,6 @@ static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */
   aggregation_t *agg;
   _Bool is_valid;
   int status;
-  int i;
 
   agg = calloc (1, sizeof (*agg));
   if (agg == NULL)
@@ -539,7 +534,7 @@ static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */
   sstrncpy (agg->ident.type_instance, "/.*/",
       sizeof (agg->ident.type_instance));
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -677,8 +672,6 @@ static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */
 
 static int agg_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
   pthread_mutex_lock (&agg_instance_list_lock);
 
   if (lookup == NULL)
@@ -695,7 +688,7 @@ static int agg_config (oconfig_item_t *ci) /* {{{ */
     }
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -713,7 +706,6 @@ static int agg_config (oconfig_item_t *ci) /* {{{ */
 
 static int agg_read (void) /* {{{ */
 {
-  agg_instance_t *this;
   cdtime_t t;
   int success;
 
@@ -734,7 +726,7 @@ static int agg_read (void) /* {{{ */
     return (0);
   }
 
-  for (this = agg_instance_list_head; this != NULL; this = this->next)
+  for (agg_instance_t *this = agg_instance_list_head; this != NULL; this = this->next)
   {
     int status;
 
index 99dca90..06fd1f1 100644 (file)
@@ -27,6 +27,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_cmd_putval.h"
@@ -527,13 +528,11 @@ static int camqp_connect (camqp_config_t *conf) /* {{{ */
 
 static int camqp_shutdown (void) /* {{{ */
 {
-    size_t i;
-
     DEBUG ("amqp plugin: Shutting down %zu subscriber threads.",
             subscriber_threads_num);
 
     subscriber_threads_running = 0;
-    for (i = 0; i < subscriber_threads_num; i++)
+    for (size_t i = 0; i < subscriber_threads_num; i++)
     {
         /* FIXME: Sending a signal is not very elegant here. Maybe find out how
          * to use a timeout in the thread and check for the variable in regular
@@ -763,17 +762,20 @@ static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */
 static int camqp_write_locked (camqp_config_t *conf, /* {{{ */
         const char *buffer, const char *routing_key)
 {
-    amqp_basic_properties_t props;
     int status;
 
     status = camqp_connect (conf);
     if (status != 0)
         return (status);
 
-    memset (&props, 0, sizeof (props));
-    props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG
-        | AMQP_BASIC_DELIVERY_MODE_FLAG
-        | AMQP_BASIC_APP_ID_FLAG;
+    amqp_basic_properties_t props = {
+        ._flags = AMQP_BASIC_CONTENT_TYPE_FLAG
+            | AMQP_BASIC_DELIVERY_MODE_FLAG
+            | AMQP_BASIC_APP_ID_FLAG,
+        .delivery_mode = conf->delivery_mode,
+        .app_id = amqp_cstring_bytes("collectd")
+    };
+
     if (conf->format == CAMQP_FORMAT_COMMAND)
         props.content_type = amqp_cstring_bytes("text/collectd");
     else if (conf->format == CAMQP_FORMAT_JSON)
@@ -782,8 +784,6 @@ static int camqp_write_locked (camqp_config_t *conf, /* {{{ */
         props.content_type = amqp_cstring_bytes("text/graphite");
     else
         assert (23 == 42);
-    props.delivery_mode = conf->delivery_mode;
-    props.app_id = amqp_cstring_bytes("collectd");
 
     status = amqp_basic_publish(conf->connection,
                 /* channel = */ 1,
@@ -814,15 +814,12 @@ static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
     if ((ds == NULL) || (vl == NULL) || (conf == NULL))
         return (EINVAL);
 
-    memset (buffer, 0, sizeof (buffer));
-
     if (conf->routing_key != NULL)
     {
         sstrncpy (routing_key, conf->routing_key, sizeof (routing_key));
     }
     else
     {
-        size_t i;
         ssnprintf (routing_key, sizeof (routing_key), "collectd/%s/%s/%s/%s/%s",
                 vl->host,
                 vl->plugin, vl->plugin_instance,
@@ -830,7 +827,7 @@ static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
 
         /* Switch slashes (the only character forbidden by collectd) and dots
          * (the separation character used by AMQP). */
-        for (i = 0; routing_key[i] != 0; i++)
+        for (size_t i = 0; routing_key[i] != 0; i++)
         {
             if (routing_key[i] == '.')
                 routing_key[i] = '/';
@@ -920,7 +917,6 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
 {
     camqp_config_t *conf;
     int status;
-    int i;
 
     conf = calloc (1, sizeof (*conf));
     if (conf == NULL)
@@ -967,7 +963,7 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
         return (status);
     }
 
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
@@ -1074,11 +1070,13 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
     if (publish)
     {
         char cbname[128];
-        user_data_t ud = { conf, camqp_config_free };
-
         ssnprintf (cbname, sizeof (cbname), "amqp/%s", conf->name);
 
-        status = plugin_register_write (cbname, camqp_write, &ud);
+        status = plugin_register_write (cbname, camqp_write,
+                &(user_data_t) {
+                    .data = conf,
+                    .free_func = camqp_config_free,
+                });
         if (status != 0)
         {
             camqp_config_free (conf);
@@ -1100,9 +1098,7 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */
 
 static int camqp_config (oconfig_item_t *ci) /* {{{ */
 {
-    int i;
-
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
index 40d0efe..578b8de 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <curl/curl.h>
 
@@ -174,7 +174,6 @@ static size_t apache_header_callback (void *buf, size_t size, size_t nmemb,
 static int config_add (oconfig_item_t *ci)
 {
        apache_t *st;
-       int i;
        int status;
 
        st = calloc (1, sizeof (*st));
@@ -194,7 +193,7 @@ static int config_add (oconfig_item_t *ci)
        }
        assert (st->name != NULL);
 
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -240,24 +239,22 @@ static int config_add (oconfig_item_t *ci)
 
        if (status == 0)
        {
-               user_data_t ud;
                char callback_name[3*DATA_MAX_NAME_LEN];
 
-               memset (&ud, 0, sizeof (ud));
-               ud.data = st;
-               ud.free_func = apache_free;
-
-               memset (callback_name, 0, sizeof (callback_name));
                ssnprintf (callback_name, sizeof (callback_name),
                                "apache/%s/%s",
                                (st->host != NULL) ? st->host : hostname_g,
-                               (st->name != NULL) ? st->name : "default"),
+                               (st->name != NULL) ? st->name : "default");
 
                status = plugin_register_complex_read (/* group = */ NULL,
                                /* name      = */ callback_name,
                                /* callback  = */ apache_read_host,
                                /* interval  = */ 0,
-                               /* user_data = */ &ud);
+                               &(user_data_t) {
+                                       .data = st,
+                                       .free_func = apache_free,
+                               });
+
        }
 
        if (status != 0)
@@ -272,9 +269,8 @@ static int config_add (oconfig_item_t *ci)
 static int config (oconfig_item_t *ci)
 {
        int status = 0;
-       int i;
 
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -415,19 +411,15 @@ static void submit_value (const char *type, const char *type_instance,
 } /* void submit_value */
 
 static void submit_derive (const char *type, const char *type_instance,
-               derive_t c, apache_t *st)
+               derive_t d, apache_t *st)
 {
-       value_t v;
-       v.derive = c;
-       submit_value (type, type_instance, v, st);
+       submit_value (type, type_instance, (value_t) { .derive = d }, st);
 } /* void submit_derive */
 
 static void submit_gauge (const char *type, const char *type_instance,
                gauge_t g, apache_t *st)
 {
-       value_t v;
-       v.gauge = g;
-       submit_value (type, type_instance, v, st);
+       submit_value (type, type_instance, (value_t) { .gauge = g }, st);
 } /* void submit_gauge */
 
 static void submit_scoreboard (char *buf, apache_t *st)
@@ -465,8 +457,7 @@ static void submit_scoreboard (char *buf, apache_t *st)
        long long response_start = 0LL;
        long long response_end   = 0LL;
 
-       int i;
-       for (i = 0; buf[i] != '\0'; i++)
+       for (int i = 0; buf[i] != '\0'; i++)
        {
                if (buf[i] == '.') open++;
                else if (buf[i] == '_') waiting++;
index 9f7476b..821bd65 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"      /* rrd_update_file */
 #include "plugin.h"      /* plugin_register, plugin_submit */
-#include "configfile.h"  /* cf_register */
 
 #if HAVE_SYS_TYPES_H
 # include <sys/types.h>
@@ -115,15 +115,14 @@ static int net_open (char const *node, char const *service)
 {
        int              sd;
        int              status;
-       struct addrinfo  ai_hints;
        struct addrinfo *ai_return;
        struct addrinfo *ai_list;
 
-       /* Resolve name */
-       memset (&ai_hints, 0, sizeof (ai_hints));
        /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */
-       ai_hints.ai_family   = AF_INET;
-       ai_hints.ai_socktype = SOCK_STREAM;
+       struct addrinfo ai_hints = {
+               .ai_family = AF_INET,
+               .ai_socktype = SOCK_STREAM
+       };
 
        status = getaddrinfo (node, service, &ai_hints, &ai_return);
        if (status != 0)
@@ -381,10 +380,9 @@ 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++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -418,12 +416,9 @@ static int apcups_config (oconfig_item_t *ci)
 
 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;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "apcups", sizeof (vl.plugin));
index 7ed2016..06ca7a8 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -82,15 +83,9 @@ static int as_init (void)
 static void as_submit (const char *type, const char *type_instance,
                double val)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       DEBUG ("type = %s; type_instance = %s; val = %f;",
-                       type, type_instance, val);
-
-       values[0].gauge = val;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = val };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "apple_sensors", sizeof (vl.plugin));
@@ -113,8 +108,6 @@ static int as_read (void)
        char   inst[128];
        int    value_int;
        double value_double;
-       int    i;
-
        if (!io_master_port || (io_master_port == MACH_PORT_NULL))
                return (-1);
 
@@ -169,7 +162,7 @@ static int as_read (void)
                                        kCFStringEncodingASCII))
                        continue;
                inst[sizeof (inst) - 1] = '\0';
-               for (i = 0; i < 128; i++)
+               for (int i = 0; i < 128; i++)
                {
                        if (inst[i] == '\0')
                                break;
index 5db988e..08271f8 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -33,9 +34,7 @@ static char *conf_device = NULL;
 
 static int aquaero_config (oconfig_item_t *ci)
 {
-       int i;
-
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -61,16 +60,13 @@ static void aquaero_submit (const char *type, const char *type_instance,
                double value)
 {
        const char *instance = conf_device?conf_device:"default";
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
        /* Don't report undefined values. */
        if (value == AQ5_FLOAT_UNDEF)
                return;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -87,9 +83,8 @@ static void aquaero_submit_array (const char *type,
                const char *type_instance_prefix, double *value_array, int len)
 {
        char type_instance[DATA_MAX_NAME_LEN];
-       int i;
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                if (value_array[i] == AQ5_FLOAT_UNDEF)
                        continue;
@@ -106,7 +101,6 @@ static int aquaero_read (void)
        aq5_settings_t aq_sett;
        char *err_msg = NULL;
        char type_instance[DATA_MAX_NAME_LEN];
-       int i;
 
        if (libaquaero5_poll(conf_device, &aq_data, &err_msg) < 0)
        {
@@ -147,7 +141,7 @@ static int aquaero_read (void)
                        AQ5_NUM_OTHER_SENSORS);
 
        /* Fans */
-       for (i = 0; i < AQ5_NUM_FAN; i++)
+       for (int i = 0; i < AQ5_NUM_FAN; i++)
        {
                if ((aq_sett.fan_data_source[i] == NONE)
                                || (aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF))
index 9124c26..16568e6 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <curl/curl.h>
 #include <libxml/parser.h>
@@ -126,12 +126,9 @@ static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 static int ascent_submit_gauge (const char *plugin_instance, /* {{{ */
     const char *type, const char *type_instance, gauge_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "ascent", sizeof (vl.plugin));
@@ -181,20 +178,19 @@ static size_t ascent_curl_callback (void *buf, size_t size, size_t nmemb, /* {{{
 
 static int ascent_submit_players (player_stats_t *ps) /* {{{ */
 {
-  size_t i;
   gauge_t value;
 
-  for (i = 0; i < RACES_LIST_LENGTH; i++)
+  for (size_t i = 0; i < RACES_LIST_LENGTH; i++)
     if (races_list[i] != NULL)
       ascent_submit_gauge ("by-race", "players", races_list[i],
           (gauge_t) ps->races[i]);
 
-  for (i = 0; i < CLASSES_LIST_LENGTH; i++)
+  for (size_t i = 0; i < CLASSES_LIST_LENGTH; i++)
     if (classes_list[i] != NULL)
       ascent_submit_gauge ("by-class", "players", classes_list[i],
           (gauge_t) ps->classes[i]);
 
-  for (i = 0; i < GENDERS_LIST_LENGTH; i++)
+  for (size_t i = 0; i < GENDERS_LIST_LENGTH; i++)
     if (genders_list[i] != NULL)
       ascent_submit_gauge ("by-gender", "players", genders_list[i],
           (gauge_t) ps->genders[i]);
@@ -328,9 +324,7 @@ static int ascent_xml_read_int (xmlDoc *doc, xmlNode *node, /* {{{ */
 static int ascent_xml_sessions_plr (xmlDoc *doc, xmlNode *node, /* {{{ */
     player_info_t *pi)
 {
-  xmlNode *child;
-
-  for (child = node->xmlChildrenNode; child != NULL; child = child->next)
+  for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next)
   {
     if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0)
         || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0))
@@ -364,12 +358,11 @@ static int ascent_xml_sessions_plr (xmlDoc *doc, xmlNode *node, /* {{{ */
 
 static int ascent_xml_sessions (xmlDoc *doc, xmlNode *node) /* {{{ */
 {
-  xmlNode *child;
-  player_stats_t ps;
+  player_stats_t ps = {
+    .level_sum = 0
+  };
 
-  memset (&ps, 0, sizeof (ps));
-
-  for (child = node->xmlChildrenNode; child != NULL; child = child->next)
+  for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next)
   {
     if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0)
         || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0))
@@ -396,9 +389,7 @@ static int ascent_xml_sessions (xmlDoc *doc, xmlNode *node) /* {{{ */
 
 static int ascent_xml_status (xmlDoc *doc, xmlNode *node) /* {{{ */
 {
-  xmlNode *child;
-
-  for (child = node->xmlChildrenNode; child != NULL; child = child->next)
+  for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next)
   {
     if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0)
         || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0))
@@ -438,7 +429,6 @@ static int ascent_xml (const char *data) /* {{{ */
 {
   xmlDoc *doc;
   xmlNode *cur;
-  xmlNode *child;
 
 #if 0
   doc = xmlParseMemory (data, strlen (data),
@@ -469,7 +459,7 @@ static int ascent_xml (const char *data) /* {{{ */
     return (-1);
   }
 
-  for (child = cur->xmlChildrenNode; child != NULL; child = child->next)
+  for (xmlNode *child = cur->xmlChildrenNode; child != NULL; child = child->next)
   {
     if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0)
         || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0))
index f14ac04..998932d 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_cache.h"
 #include "plugin.h"
@@ -29,6 +30,7 @@
 #include <unistd.h>
 #include <linux/i2c-dev.h>
 #include <math.h>
+#include <sys/ioctl.h>
 
 /* ------------ MPL115 defines ------------ */
 /* I2C address of the MPL115 sensor */
@@ -407,7 +409,6 @@ static int get_reference_temperature(double * result)
 
     gauge_t * values = NULL;   /**< rate values */
     size_t    values_num = 0;  /**< number of rate values */
-    size_t i;
 
     gauge_t values_history[REF_TEMP_AVG_NUM];
 
@@ -445,7 +446,7 @@ static int get_reference_temperature(double * result)
             list->initialized = 1;
             list->num_values = values_num;
 
-            for(i=0; i<values_num; ++i)
+            for(size_t i=0; i<values_num; ++i)
             {
                 DEBUG ("barometer: get_reference_temperature - rate %zu: %lf **",
                        i, values[i]);
@@ -474,7 +475,7 @@ static int get_reference_temperature(double * result)
             continue;
         }
 
-        for(i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
+        for(size_t i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
         {
             DEBUG ("barometer: get_reference_temperature - history %zu: %lf",
                    i, values_history[i]);
@@ -499,7 +500,7 @@ static int get_reference_temperature(double * result)
                 continue;
             }
 
-            for(i=0; i<values_num; ++i)
+            for(size_t i=0; i<values_num; ++i)
             {
                 DEBUG ("barometer: get_reference_temperature - rate last %zu: %lf **",
                        i, values[i]);
@@ -1580,8 +1581,7 @@ static int MPL115_collectd_barometer_read (void)
        already available. */
     if(!avg_initialized)
     {
-        int i;
-        for(i=0; i<config_oversample-1; ++i)
+        for(int i=0; i<config_oversample-1; ++i)
         {
             result = MPL115_read_averaged(&pressure, &temperature);
             if(result)
index 4e0c06f..ebf41de 100644 (file)
@@ -24,6 +24,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
 # define SYSFS_FACTOR 0.000001
 #endif /* KERNEL_LINUX */
 
+int battery_read_statefs (void); /* defined in battery_statefs; used by StateFS backend */
+
 static _Bool report_percent = 0;
 static _Bool report_degraded = 0;
+static _Bool query_statefs = 0;
 
 static void battery_submit2 (char const *plugin_instance, /* {{{ */
                char const *type, char const *type_instance, gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "battery", sizeof (vl.plugin));
@@ -201,7 +202,6 @@ static void get_via_io_power_sources (double *ret_charge, /* {{{ */
        CFTypeRef       ps_obj;
 
        double temp_double;
-       int i;
 
        ps_raw       = IOPSCopyPowerSourcesInfo ();
        ps_array     = IOPSCopyPowerSourcesList (ps_raw);
@@ -209,7 +209,7 @@ static void get_via_io_power_sources (double *ret_charge, /* {{{ */
 
        DEBUG ("ps_array_len == %i", ps_array_len);
 
-       for (i = 0; i < ps_array_len; i++)
+       for (int i = 0; i < ps_array_len; i++)
        {
                ps_obj  = CFArrayGetValueAtIndex (ps_array, i);
                ps_dict = IOPSGetPowerSourceDescription (ps_raw, ps_obj);
@@ -274,7 +274,6 @@ static void get_via_generic_iokit (double *ret_capacity_full, /* {{{ */
        CFDictionaryRef bat_root_dict;
        CFArrayRef      bat_info_arry;
        CFIndex         bat_info_arry_len;
-       CFIndex         bat_info_arry_pos;
        CFDictionaryRef bat_info_dict;
 
        double temp_double;
@@ -309,7 +308,7 @@ static void get_via_generic_iokit (double *ret_capacity_full, /* {{{ */
                }
                bat_info_arry_len = CFArrayGetCount (bat_info_arry);
 
-               for (bat_info_arry_pos = 0;
+               for (CFIndex bat_info_arry_pos = 0;
                                bat_info_arry_pos < bat_info_arry_len;
                                bat_info_arry_pos++)
                {
@@ -360,6 +359,9 @@ static int battery_read (void) /* {{{ */
        gauge_t capacity_full = NAN; /* Total capacity */
        gauge_t capacity_design = NAN; /* Full design capacity */
 
+       if (query_statefs)
+               return battery_read_statefs ();
+
 #if HAVE_IOKIT_PS_IOPOWERSOURCES_H
        get_via_io_power_sources (&charge_rel, &current, &voltage);
 #endif
@@ -387,47 +389,17 @@ static int sysfs_file_to_buffer(char const *dir, /* {{{ */
                char const *basename,
                char *buffer, size_t buffer_size)
 {
-       int status;
-       FILE *fp;
        char filename[PATH_MAX];
+       int status;
 
        ssnprintf (filename, sizeof (filename), "%s/%s/%s",
                        dir, power_supply, basename);
 
-       /* No file isn't the end of the world -- not every system will be
-        * reporting the same set of statistics */
-       if (access (filename, R_OK) != 0)
-               return ENOENT;
-
-       fp = fopen (filename, "r");
-       if (fp == NULL)
-       {
-               status = errno;
-               if (status != ENOENT)
-               {
-                       char errbuf[1024];
-                       WARNING ("battery plugin: fopen (%s) failed: %s", filename,
-                                       sstrerror (status, errbuf, sizeof (errbuf)));
-               }
+       status = (int) read_file_contents (filename, buffer, buffer_size);
+       if (status < 0)
                return status;
-       }
-
-       if (fgets (buffer, buffer_size, fp) == NULL)
-       {
-               status = errno;
-               if (status != ENODEV)
-               {
-                       char errbuf[1024];
-                       WARNING ("battery plugin: fgets (%s) failed: %s", filename,
-                                       sstrerror (status, errbuf, sizeof (errbuf)));
-               }
-               fclose (fp);
-               return status;
-       }
 
        strstripnewline (buffer);
-
-       fclose (fp);
        return 0;
 } /* }}} int sysfs_file_to_buffer */
 
@@ -713,11 +685,10 @@ static int read_acpi (void) /* {{{ */
 
 static int read_pmu (void) /* {{{ */
 {
-       int i;
-
+       int i = 0;
        /* The upper limit here is just a safeguard. If there is a system with
         * more than 100 batteries, this can easily be increased. */
-       for (i = 0; i < 100; i++)
+       for (; i < 100; i++)
        {
                FILE *fh;
 
@@ -780,6 +751,9 @@ static int battery_read (void) /* {{{ */
 {
        int status;
 
+       if (query_statefs)
+               return battery_read_statefs ();
+
        DEBUG ("battery plugin: Trying sysfs ...");
        status = read_sysfs ();
        if (status == 0)
@@ -802,9 +776,7 @@ static int battery_read (void) /* {{{ */
 
 static int battery_config (oconfig_item_t *ci)
 {
-       int i;
-
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -812,6 +784,8 @@ static int battery_config (oconfig_item_t *ci)
                        cf_util_get_boolean (child, &report_percent);
                else if (strcasecmp ("ReportDegraded", child->key) == 0)
                        cf_util_get_boolean (child, &report_degraded);
+               else if (strcasecmp ("QueryStateFS", child->key) == 0)
+                       cf_util_get_boolean (child, &query_statefs);
                else
                        WARNING ("battery plugin: Ignoring unknown "
                                        "configuration option \"%s\".",
diff --git a/src/battery_statefs.c b/src/battery_statefs.c
new file mode 100644 (file)
index 0000000..03729fd
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * collectd - src/statefs_battery.c
+ * Copyright (C) 2016 rinigus
+ *
+ *
+The MIT License (MIT)
+
+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:
+ *   rinigus <http://github.com/rinigus>
+
+ Battery stats are collected from StateFS Battery namespace. Reported
+ units are as follows:
+
+ capacity %
+ charge %
+ current A
+ energy Wh
+ power W
+ temperature C
+ timefull and timelow seconds
+ voltage V
+
+ Provider at
+ https://git.merproject.org/mer-core/statefs-providers/blob/master/src/power_udev/provider_power_udev.cpp
+
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <stdio.h>
+
+#define STATEFS_ROOT "/run/state/namespaces/Battery/"
+
+static void battery_submit(const char *type, gauge_t value,
+                           const char *type_instance) {
+  value_list_t vl = VALUE_LIST_INIT;
+
+  vl.values = &(value_t) { .gauge = value };
+  vl.values_len = 1;
+  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+  sstrncpy(vl.plugin, "battery", sizeof(vl.plugin));
+  /* statefs supports 1 battery at present */
+  sstrncpy(vl.plugin_instance, "0", sizeof(vl.plugin_instance));
+  sstrncpy(vl.type, type, sizeof(vl.type));
+  if (type_instance != NULL)
+    sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+  plugin_dispatch_values(&vl);
+}
+
+/* cannot be static, is referred to from battery.c */
+int battery_read_statefs(void) {
+  value_t v;
+  int success = 0;
+
+  if (parse_value_file(STATEFS_ROOT "ChargePercentage", &v, DS_TYPE_GAUGE) == 0) {
+    battery_submit("charge", v.gauge, NULL);
+    success++;
+  } else if (parse_value_file(STATEFS_ROOT "Capacity", &v, DS_TYPE_GAUGE) == 0) {
+    // Use capacity as a charge estimate if ChargePercentage is not available
+    battery_submit("charge", v.gauge, NULL);
+    success++;
+  } else {
+    WARNING("battery plugin: Neither \""STATEFS_ROOT"ChargePercentage\" "
+            "nor \""STATEFS_ROOT"Capacity\" could be read.");
+  }
+
+  struct {
+    char *path;
+    char *type;
+    char *type_instance;
+    gauge_t factor;
+  } metrics[] = {
+    {STATEFS_ROOT "Current",       "current",     NULL,  1e-6}, // from uA to A
+    {STATEFS_ROOT "Energy",        "energy_wh",   NULL,  1e-6}, // from uWh to Wh
+    {STATEFS_ROOT "Power",         "power",       NULL,  1e-6}, // from uW to W
+    {STATEFS_ROOT "Temperature",   "temperature", NULL,   0.1}, // from 10xC to C
+    {STATEFS_ROOT "TimeUntilFull", "duration",    "full", 1.0},
+    {STATEFS_ROOT "TimeUntilLow",  "duration",    "low",  1.0},
+    {STATEFS_ROOT "Voltage",       "voltage",     NULL,  1e-6}, // from uV to V
+  };
+
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE(metrics); i++) {
+    if (parse_value_file(metrics[i].path, &v, DS_TYPE_GAUGE) != 0) {
+      WARNING("battery plugin: Reading \"%s\" failed.", metrics[i].path);
+      continue;
+    }
+
+    battery_submit(metrics[i].type, v.gauge * metrics[i].factor, metrics[i].type_instance);
+    success++;
+  }
+
+  if (success == 0) {
+    ERROR("battery plugin: statefs backend: none of the statistics are available");
+    return (-1);
+  }
+
+  return (0);
+}
index 7d26208..09de4a3 100644 (file)
@@ -36,9 +36,9 @@
 #endif /* STRPTIME_NEEDS_STANDARDS */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 /* Some versions of libcurl don't include this themselves and then don't have
  * fd_set available. */
@@ -247,12 +247,9 @@ static int memsummary_translation_table_length =
 static void submit (time_t ts, const char *plugin_instance, /* {{{ */
     const char *type, const char *type_instance, value_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0] = value;
-
-  vl.values = values;
+  vl.values = &value;
   vl.values_len = 1;
   if (config_parse_time)
     vl.time = TIME_T_TO_CDTIME_T (ts);
@@ -309,12 +306,11 @@ static int bind_xml_table_callback (const char *name, value_t value, /* {{{ */
     time_t current_time, void *user_data)
 {
   translation_table_ptr_t *table = (translation_table_ptr_t *) user_data;
-  size_t i;
 
   if (table == NULL)
     return (-1);
 
-  for (i = 0; i < table->table_length; i++)
+  for (size_t i = 0; i < table->table_length; i++)
   {
     if (strcmp (table->table[i].xml_name, name) != 0)
       continue;
@@ -417,7 +413,7 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */
   xmlNode *node;
   char *str_ptr;
   char *tmp;
-  struct tm tm;
+  struct tm tm = { 0 };
 
   xpathObj = xmlXPathEvalExpression (BAD_CAST xpath_expression, xpathCtx);
   if (xpathObj == NULL)
@@ -458,7 +454,6 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */
     return (-1);
   }
 
-  memset (&tm, 0, sizeof(tm));
   tmp = strptime (str_ptr, "%Y-%m-%dT%T", &tm);
   xmlFree(str_ptr);
   if (tmp == NULL)
@@ -491,7 +486,6 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ *
 {
   xmlXPathObject *xpathObj = NULL;
   int num_entries;
-  int i;
 
   xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx);
   if (xpathObj == NULL)
@@ -503,19 +497,18 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ *
 
   num_entries = 0;
   /* Iterate over all matching nodes. */
-  for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++)
+  for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++)
   {
     xmlNode *name_node = NULL;
     xmlNode *counter = NULL;
     xmlNode *parent;
-    xmlNode *child;
 
     parent = xpathObj->nodesetval->nodeTab[i];
     DEBUG ("bind plugin: bind_parse_generic_name_value: parent->name = %s;",
         (char *) parent->name);
 
     /* Iterate over all child nodes. */
-    for (child = parent->xmlChildrenNode;
+    for (xmlNode *child = parent->xmlChildrenNode;
         child != NULL;
         child = child->next)
     {
@@ -578,7 +571,6 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ *
 {
   xmlXPathObject *xpathObj = NULL;
   int num_entries;
-  int i;
 
   xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx);
   if (xpathObj == NULL)
@@ -590,12 +582,10 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ *
 
   num_entries = 0;
   /* Iterate over all matching nodes. */
-  for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++)
+  for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++)
   {
-    xmlNode *child;
-
     /* Iterate over all child nodes. */
-    for (child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
+    for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
         child != NULL;
         child = child->next)
     {
@@ -649,7 +639,6 @@ static int bind_parse_generic_name_attr_value_list (const char *xpath_expression
 {
   xmlXPathObject *xpathObj = NULL;
   int num_entries;
-  int i;
 
   xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx);
   if (xpathObj == NULL)
@@ -661,12 +650,10 @@ static int bind_parse_generic_name_attr_value_list (const char *xpath_expression
 
   num_entries = 0;
   /* Iterate over all matching nodes. */
-  for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++)
+  for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++)
   {
-    xmlNode *child;
-
     /* Iterate over all child nodes. */
-    for (child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
+    for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
         child != NULL;
         child = child->next)
     {
@@ -714,7 +701,6 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */
 {
   xmlXPathObject *path_obj;
   char *zone_name = NULL;
-  int i;
   size_t j;
 
   if (version >= 3)
@@ -738,7 +724,7 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */
       return (-1);
     }
 
-    for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++)
+    for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++)
     {
       zone_name = (char *) xmlNodeListGetString (doc,
           path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1);
@@ -817,7 +803,6 @@ static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */
 {
   xmlXPathObject *zone_nodes = NULL;
   xmlXPathContext *zone_path_context;
-  int i;
 
   zone_path_context = xmlXPathNewContext (doc);
   if (zone_path_context == NULL)
@@ -834,7 +819,7 @@ static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < zone_nodes->nodesetval->nodeNr; i++)
+  for (int i = 0; i < zone_nodes->nodesetval->nodeNr; i++)
   {
     node = zone_nodes->nodesetval->nodeTab[i];
     assert (node != NULL);
@@ -855,7 +840,6 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */
 {
   char *view_name = NULL;
   cb_view_t *view;
-  int i;
   size_t j;
 
   if (version == 3)
@@ -887,7 +871,7 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */
       return (-1);
     }
 
-    for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++)
+    for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++)
     {
       view_name = (char *) xmlNodeListGetString (doc,
           path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1);
@@ -1010,7 +994,6 @@ static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */
 {
   xmlXPathObject *view_nodes = NULL;
   xmlXPathContext *view_path_context;
-  int i;
 
   view_path_context = xmlXPathNewContext (doc);
   if (view_path_context == NULL)
@@ -1027,7 +1010,7 @@ static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < view_nodes->nodesetval->nodeNr; i++)
+  for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++)
   {
     xmlNode *node;
 
@@ -1441,7 +1424,6 @@ static int bind_xml (const char *data) /* {{{ */
   xmlXPathContext *xpathCtx = NULL;
   xmlXPathObject *xpathObj = NULL;
   int ret = -1;
-  int i;
 
   doc = xmlParseMemory (data, strlen (data));
   if (doc == NULL)
@@ -1471,7 +1453,7 @@ static int bind_xml (const char *data) /* {{{ */
   }
   else
   {
-    for (i = 0; i < xpathObj->nodesetval->nodeNr; i++)
+    for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++)
     {
       xmlNode *node;
       char *attr_version;
@@ -1533,7 +1515,7 @@ static int bind_xml (const char *data) /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < xpathObj->nodesetval->nodeNr; i++)
+  for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++)
   {
     xmlNode *node;
     char *attr_version;
@@ -1636,7 +1618,6 @@ static int bind_config_add_view_zone (cb_view_t *view, /* {{{ */
 static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */
 {
   cb_view_t *tmp;
-  int i;
 
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
@@ -1668,7 +1649,7 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -1693,9 +1674,7 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */
 
 static int bind_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
index 04a3974..64d8785 100644 (file)
@@ -27,6 +27,7 @@
 #define _BSD_SOURCE
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -37,6 +38,9 @@
 #if HAVE_YAJL_YAJL_VERSION_H
 #include <yajl/yajl_version.h>
 #endif
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
 
 #include <limits.h>
 #include <poll.h>
@@ -163,7 +167,7 @@ static int convert_special_metrics = 1;
 static struct ceph_daemon **g_daemons = NULL;
 
 /** Number of elements in g_daemons */
-static int g_num_daemons = 0;
+static size_t g_num_daemons = 0;
 
 /**
  * A set of data that we build up in memory while parsing the JSON.
@@ -258,7 +262,10 @@ static int ceph_cb_boolean(void *ctx, int bool_val)
 
 #define BUFFER_ADD(dest, src) do { \
     size_t dest_size = sizeof (dest); \
-    strncat ((dest), (src), dest_size - strlen (dest)); \
+    size_t dest_len = strlen (dest); \
+    if (dest_size > dest_len) { \
+        sstrncpy ((dest) + dest_len, (src), dest_size - dest_len); \
+    } \
     (dest)[dest_size - 1] = 0; \
 } while (0)
 
@@ -267,16 +274,14 @@ ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len)
 {
     yajl_struct *state = (yajl_struct*) ctx;
     char buffer[number_len+1];
-    char key[2 * DATA_MAX_NAME_LEN];
+    char key[2 * DATA_MAX_NAME_LEN] = { 0 };
     _Bool latency_type = 0;
-    size_t i;
     int status;
 
     memcpy(buffer, number_val, number_len);
-    buffer[sizeof(buffer) - 1] = 0;
+    buffer[sizeof(buffer) - 1] = '\0';
 
-    memset (key, 0, sizeof (key));
-    for (i = 0; i < state->depth; i++)
+    for (size_t i = 0; i < state->depth; i++)
     {
         if (state->stack[i] == NULL)
             continue;
@@ -292,6 +297,11 @@ ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len)
     {
         latency_type = 1;
 
+        /* depth >= 2  =>  (stack[-1] != NULL && stack[-2] != NULL) */
+        assert ((state->depth < 2)
+                || ((state->stack[state->depth - 1] != NULL)
+                    && (state->stack[state->depth - 2] != NULL)));
+
         /* 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
@@ -422,8 +432,7 @@ static void ceph_daemon_print(const struct ceph_daemon *d)
 
 static void ceph_daemons_print(void)
 {
-    int i;
-    for(i = 0; i < g_num_daemons; ++i)
+    for(size_t i = 0; i < g_num_daemons; ++i)
     {
         ceph_daemon_print(g_daemons[i]);
     }
@@ -431,15 +440,15 @@ static void ceph_daemons_print(void)
 
 static void ceph_daemon_free(struct ceph_daemon *d)
 {
-    int i = 0;
-    for(; i < d->last_idx; i++)
+    for(int i = 0; i < d->last_idx; i++)
     {
         sfree(d->last_poll_data[i]);
     }
     sfree(d->last_poll_data);
     d->last_poll_data = NULL;
     d->last_idx = 0;
-    for(i = 0; i < d->ds_num; i++)
+
+    for(int i = 0; i < d->ds_num; i++)
     {
         sfree(d->ds_names[i]);
     }
@@ -548,10 +557,9 @@ static _Bool has_suffix (char const *str, char const *suffix)
 /* 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, '.'))
+    for (const char *ptr = key; ptr != NULL; ptr = strchr (ptr + 1, '.'))
         parts_num++;
 
     return parts_num;
@@ -593,7 +601,6 @@ static int ceph_daemon_add_ds_entry(struct ceph_daemon *d, const char *name,
 {
     uint32_t type;
     char ds_name[DATA_MAX_NAME_LEN];
-    memset(ds_name, 0, sizeof(ds_name));
 
     if(convert_special_metrics)
     {
@@ -684,10 +691,9 @@ static int cc_handle_bool(struct oconfig_item_s *item, int *dest)
 
 static int cc_add_daemon_config(oconfig_item_t *ci)
 {
-    int ret, i;
-    struct ceph_daemon *nd, cd;
+    int ret;
+    struct ceph_daemon *nd, cd = { 0 };
     struct ceph_daemon **tmp;
-    memset(&cd, 0, sizeof(struct ceph_daemon));
 
     if((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
     {
@@ -702,7 +708,7 @@ static int cc_add_daemon_config(oconfig_item_t *ci)
         return ret;
     }
 
-    for(i=0; i < ci->children_num; i++)
+    for(int i=0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
@@ -753,15 +759,16 @@ static int cc_add_daemon_config(oconfig_item_t *ci)
         return ENOMEM;
     }
     memcpy(nd, &cd, sizeof(*nd));
-    g_daemons[g_num_daemons++] = nd;
+    g_daemons[g_num_daemons] = nd;
+    g_num_daemons++;
     return 0;
 }
 
 static int ceph_config(oconfig_item_t *ci)
 {
-    int ret, i;
+    int ret;
 
-    for(i = 0; i < ci->children_num; ++i)
+    for(int i = 0; i < ci->children_num; ++i)
     {
         oconfig_item_t *child = ci->children + i;
         if(strcasecmp("Daemon", child->key) == 0)
@@ -898,8 +905,7 @@ static int update_last(struct ceph_daemon *d, const char *ds_n, int index,
  */
 static int backup_search_for_last_avg(struct ceph_daemon *d, const char *ds_n)
 {
-    int i = 0;
-    for(; i < d->last_idx; i++)
+    for(int i = 0; i < d->last_idx; i++)
     {
         if(strcmp(d->last_poll_data[i]->ds_name, ds_n) == 0)
         {
@@ -959,12 +965,11 @@ static double get_last_avg(struct ceph_daemon *d, const char *ds_n, int index,
  */
 static uint32_t backup_search_for_type(struct ceph_daemon *d, char *ds_name)
 {
-    int idx = 0;
-    for(; idx < d->ds_num; idx++)
+    for(int i = 0; i < d->ds_num; i++)
     {
-        if(strcmp(d->ds_names[idx], ds_name) == 0)
+        if(strcmp(d->ds_names[i], ds_name) == 0)
         {
-            return d->ds_types[idx];
+            return d->ds_types[i];
         }
     }
     return DSET_TYPE_UNFOUND;
@@ -983,7 +988,6 @@ static int node_handler_fetch_data(void *arg, const char *val, const char *key)
     int index = vtmp->index;
 
     char ds_name[DATA_MAX_NAME_LEN];
-    memset(ds_name, 0, sizeof(ds_name));
 
     if (parse_keys (ds_name, sizeof (ds_name), key))
     {
@@ -1086,7 +1090,7 @@ static int node_handler_fetch_data(void *arg, const char *val, const char *key)
 
 static int cconn_connect(struct cconn *io)
 {
-    struct sockaddr_un address;
+    struct sockaddr_un address = { 0 };
     int flags, fd, err;
     if(io->state != CSTATE_UNCONNECTED)
     {
@@ -1101,7 +1105,6 @@ static int cconn_connect(struct cconn *io)
             "failed: error %d", err);
         return err;
     }
-    memset(&address, 0, sizeof(struct sockaddr_un));
     address.sun_family = AF_UNIX;
     snprintf(address.sun_path, sizeof(address.sun_path), "%s",
             io->d->asok_path);
@@ -1461,19 +1464,26 @@ static int milli_diff(const struct timeval *t1, const struct timeval *t2)
  */
 static int cconn_main_loop(uint32_t request_type)
 {
-    int i, ret, some_unreachable = 0;
+    int ret, some_unreachable = 0;
     struct timeval end_tv;
     struct cconn io_array[g_num_daemons];
 
-    DEBUG("ceph plugin: entering cconn_main_loop(request_type = %d)", request_type);
+    DEBUG ("ceph plugin: entering cconn_main_loop(request_type = %"PRIu32")", request_type);
+
+    if (g_num_daemons < 1)
+    {
+        ERROR ("ceph plugin: No daemons configured. See the \"Daemon\" config option.");
+        return ENOENT;
+    }
 
     /* create cconn array */
-    memset(io_array, 0, sizeof(io_array));
-    for(i = 0; i < g_num_daemons; ++i)
+    for (size_t i = 0; i < g_num_daemons; i++)
     {
-        io_array[i].d = g_daemons[i];
-        io_array[i].request_type = request_type;
-        io_array[i].state = CSTATE_UNCONNECTED;
+        io_array[i] = (struct cconn) {
+            .d = g_daemons[i],
+            .request_type = request_type,
+            .state = CSTATE_UNCONNECTED,
+        };
     }
 
     /** Calculate the time at which we should give up */
@@ -1488,13 +1498,13 @@ static int cconn_main_loop(uint32_t request_type)
         struct pollfd fds[g_num_daemons];
         memset(fds, 0, sizeof(fds));
         nfds = 0;
-        for(i = 0; i < g_num_daemons; ++i)
+        for(size_t i = 0; i < g_num_daemons; ++i)
         {
             struct cconn *io = io_array + i;
             ret = cconn_prepare(io, fds + nfds);
             if(ret < 0)
             {
-                WARNING("ceph plugin: cconn_prepare(name=%s,i=%d,st=%d)=%d",
+                WARNING("ceph plugin: cconn_prepare(name=%s,i=%zu,st=%d)=%d",
                         io->d->name, i, io->state, ret);
                 cconn_close(io);
                 io->request_type = ASOK_REQ_NONE;
@@ -1526,13 +1536,14 @@ static int cconn_main_loop(uint32_t request_type)
             ERROR("ceph plugin: poll(2) error: %d", ret);
             goto done;
         }
-        for(i = 0; i < nfds; ++i)
+        for(int i = 0; i < nfds; ++i)
         {
             struct cconn *io = polled_io_array[i];
             int revents = fds[i].revents;
             if(revents == 0)
             {
                 /* do nothing */
+                continue;
             }
             else if(cconn_validate_revents(io, revents))
             {
@@ -1557,7 +1568,7 @@ static int cconn_main_loop(uint32_t request_type)
             }
         }
     }
-    done: for(i = 0; i < g_num_daemons; ++i)
+    done: for(size_t i = 0; i < g_num_daemons; ++i)
     {
         cconn_close(io_array + i);
     }
@@ -1580,18 +1591,35 @@ static int ceph_read(void)
 /******* lifecycle *******/
 static int ceph_init(void)
 {
-    int ret;
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_DAC_OVERRIDE)
+  if (check_capability (CAP_DAC_OVERRIDE) != 0)
+  {
+    if (getuid () == 0)
+      WARNING ("ceph plugin: Running collectd as root, but the "
+          "CAP_DAC_OVERRIDE capability is missing. The plugin's read "
+          "function will probably fail. Is your init system dropping "
+          "capabilities?");
+    else
+      WARNING ("ceph plugin: collectd doesn't have the CAP_DAC_OVERRIDE "
+          "capability. If you don't want to run collectd as root, try running "
+          "\"setcap cap_dac_override=ep\" on the collectd binary.");
+  }
+#endif
+
     ceph_daemons_print();
 
-    ret = cconn_main_loop(ASOK_REQ_VERSION);
+    if (g_num_daemons < 1)
+    {
+        ERROR ("ceph plugin: No daemons configured. See the \"Daemon\" config option.");
+        return ENOENT;
+    }
 
-    return (ret) ? ret : 0;
+    return cconn_main_loop(ASOK_REQ_VERSION);
 }
 
 static int ceph_shutdown(void)
 {
-    int i;
-    for(i = 0; i < g_num_daemons; ++i)
+    for(size_t i = 0; i < g_num_daemons; ++i)
     {
         ceph_daemon_free(g_daemons[i]);
     }
index 199d40e..91f084f 100644 (file)
@@ -169,7 +169,7 @@ DEF_TEST(parse_keys)
 
   for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
   {
-    char got[DATA_MAX_NAME_LEN];
+    char got[64];
 
     CHECK_ZERO (parse_keys (got, sizeof (got), cases[i].str));
     EXPECT_EQ_STR (cases[i].want, got);
index 6d41972..f7c7e0d 100644 (file)
@@ -22,9 +22,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_mount.h"
 #include "utils_ignorelist.h"
 
@@ -206,18 +206,16 @@ static int cgroups_config (const char *key, const char *value)
 
 static int cgroups_read (void)
 {
-       cu_mount_t *mnt_list;
-       cu_mount_t *mnt_ptr;
+       cu_mount_t *mnt_list = NULL;
        _Bool cgroup_found = 0;
 
-       mnt_list = NULL;
        if (cu_mount_getlist (&mnt_list) == NULL)
        {
                ERROR ("cgroups plugin: cu_mount_getlist failed.");
                return (-1);
        }
 
-       for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next)
+       for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next)
        {
                /* Find the cgroup mountpoint which contains the cpuacct
                 * controller. */
index 012fd9a..353ede7 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"             /* auxiliary functions */
 #include "plugin.h"             /* plugin_register_*, plugin_dispatch_values */
 
@@ -306,15 +307,15 @@ static int
 connect_client(const char *p_hostname,
                const char *p_service, int p_family, int p_socktype)
 {
-  struct addrinfo hints, *res = NULL, *ressave = NULL;
+  struct addrinfo *res, *ressave;
   int n, sockfd;
 
-  memset(&hints, 0, sizeof(struct addrinfo));
-
-  hints.ai_family = p_family;
-  hints.ai_socktype = p_socktype;
+  struct addrinfo ai_hints = {
+    .ai_family = p_family,
+    .ai_socktype = p_socktype
+  };
 
-  n = getaddrinfo(p_hostname, p_service, &hints, &res);
+  n = getaddrinfo(p_hostname, p_service, &ai_hints, &res);
 
   if (n < 0)
   {
@@ -451,8 +452,8 @@ chrony_connect(void)
 
   if (chrony_set_timeout())
   {
-    ERROR(PLUGIN_NAME ": Error setting timeout to %lds. Errno = %d",
-          g_chrony_timeout, errno);
+    ERROR(PLUGIN_NAME ": Error setting timeout to %llds. Errno = %d",
+          (long long)g_chrony_timeout, errno);
     return CHRONY_RC_FAIL;
   }
   return CHRONY_RC_OK;
@@ -676,12 +677,9 @@ ntohf(tFloat p_float)
 static void
 chrony_push_data(const char *p_type, const char *p_type_inst, double p_value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = p_value;    /* TODO: Check type??? (counter, gauge, derive, absolute) */
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = p_value };
   vl.values_len = 1;
 
   /* XXX: Shall g_chrony_host/g_chrony_port be reflected in the plugin's output? */
@@ -852,8 +850,7 @@ chrony_request_daemon_stats(void)
   }
 #if COLLECT_DEBUG
   {
-    char src_addr[IPV6_STR_MAX_SIZE];
-    memset(src_addr, 0, sizeof(src_addr));
+    char src_addr[IPV6_STR_MAX_SIZE] = { 0 };
     niptoha(&chrony_resp.body.tracking.addr, src_addr, sizeof(src_addr));
     DEBUG(PLUGIN_NAME ": Daemon stat: .addr = %s, .ref_id= %u, .stratum = %u, .leap_status = %u, .ref_time = %u:%u:%u, .current_correction = %f, .last_offset = %f, .rms_offset = %f, .freq_ppm = %f, .skew_ppm = %f, .root_delay = %f, .root_dispersion = %f, .last_update_interval = %f", src_addr, ntohs(chrony_resp.body.tracking.f_ref_id),  
           ntohs(chrony_resp.body.tracking.f_stratum),
@@ -937,8 +934,7 @@ chrony_request_source_data(int p_src_idx, int *p_is_reachable)
   tChrony_Request chrony_req;
   tChrony_Response chrony_resp;
 
-  char src_addr[IPV6_STR_MAX_SIZE];
-  memset(src_addr, 0, sizeof(src_addr));
+  char src_addr[IPV6_STR_MAX_SIZE] = { 0 };
 
   chrony_init_req(&chrony_req);
   chrony_req.body.source_data.f_index = htonl(p_src_idx);
@@ -997,8 +993,7 @@ chrony_request_source_stats(int p_src_idx, const int *p_is_reachable)
   tChrony_Response chrony_resp;
   double skew_ppm, frequency_error, time_offset;
 
-  char src_addr[IPV6_STR_MAX_SIZE];
-  memset(src_addr, 0, sizeof(src_addr));
+  char src_addr[IPV6_STR_MAX_SIZE] = { 0 };
 
   if (*p_is_reachable == 0)
   {
@@ -1055,7 +1050,7 @@ chrony_read(void)
 {
   /* collectd read callback: Perform data acquisition */
   int rc;
-  unsigned int now_src, n_sources;
+  unsigned int n_sources;
 
   if (g_chrony_seq_is_initialized == 0)
   {
@@ -1077,7 +1072,7 @@ chrony_read(void)
   if (rc != CHRONY_RC_OK)
     return rc;
 
-  for (now_src = 0; now_src < n_sources; ++now_src)
+  for (unsigned int now_src = 0; now_src < n_sources; ++now_src)
   {
     int is_reachable;
     rc = chrony_request_source_data(now_src, &is_reachable);
diff --git a/src/collectd-lua.pod b/src/collectd-lua.pod
new file mode 100644 (file)
index 0000000..7a25655
--- /dev/null
@@ -0,0 +1,163 @@
+# 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.
+
+=encoding UTF-8
+
+=head1 NAME
+
+collectd-lua - Documentation of collectd's C<Lua plugin>
+
+=head1 SYNOPSIS
+
+  LoadPlugin lua
+  # ...
+  <Plugin lua>
+    BasePath "/path/to/your/lua/scripts"
+    Script "script1.lua"
+    Script "script2.lua"
+  </Plugin>
+
+=head1 DESCRIPTION
+
+The C<Lua plugin> embeds a Lua interpreter into collectd and provides an
+interface to collectd's plugin system. This makes it possible to write plugins
+for collectd in Lua. This is a lot more efficient than executing a
+Lua script every time you want to read a value with the C<exec plugin> (see
+L<collectd-exec(5)>) and provides a lot more functionality, too.
+
+The minimum required Lua version is I<5.1>.
+
+=head1 CONFIGURATION
+
+=over 4
+
+=item B<LoadPlugin> I<Lua>
+
+Loads the Lua plugin.
+
+=item B<BasePath> I<Name>
+
+The directory the C<Lua plugin> looks in to find script B<Script>.
+If set, this is also prepended to B<package.path>.
+
+=item B<Script> I<Name>
+
+The script the C<Lua plugin> is going to run.
+If B<BasePath> is not specified, this needs to be an absolute path.
+
+=back
+
+=head1 WRITING YOUR OWN PLUGINS
+
+Writing your own plugins is quite simple. collectd manages plugins by means of
+B<dispatch functions> which call the appropriate B<callback functions>
+registered by the plugins. Any plugin basically consists of the implementation
+of these callback functions and initializing code which registers the
+functions with collectd. See the section "EXAMPLES" below for a really basic
+example. The following types of B<callback functions> are implemented in the
+Lua plugin (all of them are optional):
+
+=over 4
+
+=item read functions
+
+These are used to collect the actual data. It is called once
+per interval (see the B<Interval> configuration option of collectd). Usually
+it will call B<collectd.dispatch_values> to dispatch the values to collectd
+which will pass them on to all registered B<write functions>. If this function
+does not return 0 the plugin will be skipped for an increasing
+amount of time until it returns normally again.
+
+=item write functions
+
+These are used to write the dispatched values. They are called
+once for every value that was dispatched by any plugin.
+
+=back
+
+=head1 FUNCTIONS
+
+The following functions are provided to Lua modules:
+
+=over 4
+
+=item register_read(callback)
+
+The callback will be called without arguments.
+If this callback function does not return 0 the next call will be delayed by
+an increasing interval.
+
+=item register_write
+
+The callback function will be called with one argument passed, which will be a
+table of values.
+If this callback function does not return 0 next call will be delayed by
+an increasing interval.
+
+=item log_error, log_warning, log_notice, log_info, log_debug(I<message>)
+
+Log a message with the specified severity.
+
+=back
+
+=head1 EXAMPLES
+
+=over 4
+
+A very simple read function might look like:
+
+  function read()
+    collectd.log_info("read function called")
+    t = {
+        host = 'localhost',
+        plugin = 'myplugin',
+        type = 'counter',
+        values = {42},
+    }
+    collectd.dispatch_values(t)
+    return 0
+  end
+
+A very simple write function might look like:
+
+  function write(vl)
+    for i = 1, #vl.values do
+      collectd.log_info(vl.host .. '.' .. vl.plugin .. '.' .. vl.type .. ' ' .. vl.values[i])
+    end
+    return 0
+  end
+
+To register those functions with collectd:
+
+  collectd.register_read(read)
+  collectd.register_write(write)
+
+=back
+
+=head1 SEE ALSO
+
+L<collectd(1)>,
+L<collectd.conf(5)>,
+L<lua(1)>,
+
+=head1 AUTHOR
+
+The C<Lua plugin> has been written by
+Julien Ammous E<lt>j.ammous<nbsp>atE<nbsp>gmail.comE<gt>,
+Florian Forster E<lt>octoE<nbsp>atE<nbsp>collectd.orgE<gt> and
+Ruben Kerkhof E<lt>ruben<nbsp>atE<nbsp>rubenkerkhof.com<gt> and
+
+This manpage has been written by Ruben Kerkhof
+E<lt>ruben<nbsp>atE<nbsp>rubenkerkhof.com<gt>.
+It is based on the L<collectd-perl(5)> manual page by
+Florian Forster E<lt>octoE<nbsp>atE<nbsp>collectd.orgE<gt> and
+Sebastian Harl E<lt>shE<nbsp>atE<nbsp>tokkee.orgE<gt>.
+
+=cut
index dd90737..12187f3 100644 (file)
@@ -128,8 +128,6 @@ static int filter_ds (size_t *values_num,
        gauge_t *new_values;
        char   **new_names;
 
-       size_t i;
-
        if (match_ds_g == NULL)
                return (RET_OKAY);
 
@@ -148,7 +146,7 @@ static int filter_ds (size_t *values_num,
                return (RET_UNKNOWN);
        }
 
-       for (i = 0; i < match_ds_num_g; i++)
+       for (size_t i = 0; i < match_ds_num_g; i++)
        {
                size_t j;
 
@@ -182,7 +180,7 @@ static int filter_ds (size_t *values_num,
        }
 
        free (*values);
-       for (i = 0; i < *values_num; i++)
+       for (size_t i = 0; i < *values_num; i++)
                free ((*values_names)[i]);
        free (*values_names);
 
@@ -283,7 +281,6 @@ static int do_listval (lcc_connection_t *connection)
        char *hostname = NULL;
 
        int status;
-       size_t i;
 
        status = lcc_listval (connection, &ret_ident, &ret_ident_num);
        if (status != 0) {
@@ -301,7 +298,7 @@ static int do_listval (lcc_connection_t *connection)
                return (RET_UNKNOWN);
        }
 
-       for (i = 0; i < ret_ident_num; ++i) {
+       for (size_t i = 0; i < ret_ident_num; ++i) {
                char id[1024];
 
                if ((hostname_g != NULL) && (strcasecmp (hostname_g, ret_ident[i].host)))
@@ -345,9 +342,8 @@ static int do_check_con_none (size_t values_num,
        int num_okay = 0;
        const char *status_str = "UNKNOWN";
        int status_code = RET_UNKNOWN;
-       size_t i;
 
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
        {
                if (isnan (values[i]))
                {
@@ -390,7 +386,7 @@ static int do_check_con_none (size_t values_num,
        if (values_num > 0)
        {
                printf (" |");
-               for (i = 0; i < values_num; i++)
+               for (size_t i = 0; i < values_num; i++)
                        printf (" %s=%f;;;;", values_names[i], values[i]);
        }
        printf ("\n");
@@ -401,7 +397,6 @@ static int do_check_con_none (size_t values_num,
 static int do_check_con_average (size_t values_num,
                double *values, char **values_names)
 {
-       size_t i;
        double total;
        int total_num;
        double average;
@@ -410,7 +405,7 @@ static int do_check_con_average (size_t values_num,
 
        total = 0.0;
        total_num = 0;
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
        {
                if (isnan (values[i]))
                {
@@ -451,7 +446,7 @@ static int do_check_con_average (size_t values_num,
        }
 
        printf ("%s: %g average |", status_str, average);
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
                printf (" %s=%f;;;;", values_names[i], values[i]);
        printf ("\n");
 
@@ -461,7 +456,6 @@ static int do_check_con_average (size_t values_num,
 static int do_check_con_sum (size_t values_num,
                double *values, char **values_names)
 {
-       size_t i;
        double total;
        int total_num;
        const char *status_str = "UNKNOWN";
@@ -469,7 +463,7 @@ static int do_check_con_sum (size_t values_num,
 
        total = 0.0;
        total_num = 0;
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
        {
                if (isnan (values[i]))
                {
@@ -508,7 +502,7 @@ static int do_check_con_sum (size_t values_num,
        }
 
        printf ("%s: %g sum |", status_str, total);
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
                printf (" %s=%f;;;;", values_names[i], values[i]);
        printf ("\n");
 
@@ -518,7 +512,6 @@ static int do_check_con_sum (size_t values_num,
 static int do_check_con_percentage (size_t values_num,
                double *values, char **values_names)
 {
-       size_t i;
        double sum = 0.0;
        double percentage;
 
@@ -531,7 +524,7 @@ static int do_check_con_percentage (size_t values_num,
                return (RET_WARNING);
        }
 
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
        {
                if (isnan (values[i]))
                {
@@ -571,7 +564,7 @@ static int do_check_con_percentage (size_t values_num,
        }
 
        printf ("%s: %lf percent |", status_str, percentage);
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
                printf (" %s=%lf;;;;", values_names[i], values[i]);
        return (status_code);
 } /* int do_check_con_percentage */
@@ -583,14 +576,12 @@ static int do_check (lcc_connection_t *connection)
        size_t   values_num;
        char ident_str[1024];
        lcc_identifier_t ident;
-       size_t i;
        int status;
 
        snprintf (ident_str, sizeof (ident_str), "%s/%s",
                        hostname_g, value_string_g);
        ident_str[sizeof (ident_str) - 1] = 0;
 
-       memset (&ident, 0, sizeof (ident));
        status = lcc_string_to_identifier (connection, &ident, ident_str);
        if (status != 0)
        {
@@ -628,7 +619,7 @@ static int do_check (lcc_connection_t *connection)
 
        free (values);
        if (values_names != NULL)
-               for (i = 0; i < values_num; i++)
+               for (size_t i = 0; i < values_num; i++)
                        free (values_names[i]);
        free (values_names);
 
index 0102e92..9af3c0c 100644 (file)
@@ -75,6 +75,20 @@ Adds I<Dir> to the B<@INC> array. This is the same as using the B<-IDir>
 command line option or B<use lib Dir> in the source code. Please note that it
 only has effect on plugins loaded after this option.
 
+=item B<RegisterLegacyFlush> I<true|false>
+
+The C<Perl plugin> used to register one flush callback (called B<"perl">) and
+call all Perl-based flush handlers when this callback was called. Newer versions
+of the plugin wrap the Perl flush handlers and register them directly with the
+daemon I<in addition> to the legacy B<"perl"> callback. This allows to call
+specific Perl flush handlers, but has the downside that flushing I<all> plugins
+now calls the Perl flush handlers twice (once directly and once via the legacy
+callback). Unfortunately, removing the B<"perl"> callback would break backwards
+compatibility.
+
+This option allows you to disable the legacy B<"perl"> flush callback if you care
+about the double call and don't call the B<"perl"> callback in your setup.
+
 =back
 
 =head1 WRITING YOUR OWN PLUGINS
@@ -759,18 +773,6 @@ dispatched by the perl plugin after upgrades.
 
 =back
 
-=head1 KNOWN BUGS
-
-=over 4
-
-=item *
-
-Currently, it is not possible to flush a single Perl plugin only. You can
-either flush all Perl plugins or none at all and you have to use C<perl> as
-plugin name when doing so.
-
-=back
-
 =head1 SEE ALSO
 
 L<collectd(1)>,
index 773a6cd..16b26af 100644 (file)
@@ -37,7 +37,7 @@ for collectd in Python. This is a lot more efficient than executing a
 Python-script every time you want to read a value with the C<exec plugin> (see
 L<collectd-exec(5)>) and provides a lot more functionality, too.
 
-The minimum required Python version is I<2.3>.
+The minimum required Python version is I<2.6>.
 
 =head1 CONFIGURATION
 
@@ -94,11 +94,12 @@ way of entering your commands. The daemonized collectd won't do that.
 
 =item *
 
-B<2.> collectd will block I<SIGINT>. Pressing I<Ctrl+C> will usually cause
+B<2.> Python will be handling I<SIGINT>. Pressing I<Ctrl+C> will usually cause
 collectd to shut down. This would be problematic in an interactive session,
-therefore this signal will be blocked. You can still use it to interrupt
-syscalls like sleep and pause but it won't generate a I<KeyboardInterrupt>
-exception either.
+therefore Python will be handling it in interactive sessions. This allows you
+to use I<Ctrl+C> to interrupt Python code without killing collectd. This also
+means you can catch I<KeyboardInterrupt> exceptions which does not work during
+normal operation.
 
 To quit collectd send I<EOF> (press I<Ctrl+D> at the beginning of a new line).
 
@@ -658,6 +659,8 @@ Any Python module will start similar to:
 
 A very simple read function might look like:
 
+  import random
+
   def read(data=None):
     vl = collectd.Values(type='gauge')
     vl.plugin='python.spam'
@@ -671,28 +674,12 @@ A very simple write function might look like:
 
 To register those functions with collectd:
 
-  collectd.register_read(read);
-  collectd.register_write(write);
+  collectd.register_read(read)
+  collectd.register_write(write)
 
 See the section L<"CLASSES"> above for a complete documentation of the data
 types used by the read, write and match functions.
 
-=head1 NOTES
-
-=over 4
-
-=item *
-
-Please feel free to send in new plugins to collectd's mailing list at
-E<lt>collectdE<nbsp>atE<nbsp>collectd.orgE<gt> for review and, possibly,
-inclusion in the main distribution. In the latter case, we will take care of
-keeping the plugin up to date and adapting it to new versions of collectd.
-
-Before submitting your plugin, please take a look at
-L<http://collectd.org/dev-info.shtml>.
-
-=back
-
 =head1 CAVEATS
 
 =over 4
index 513d4ff..7db9fe7 100644 (file)
@@ -337,7 +337,6 @@ static int read_options (int argc, char **argv) /* {{{ */
 
 int main (int argc, char **argv) /* {{{ */
 {
-  int i;
   double last_time;
   int values_sent = 0;
 
@@ -383,7 +382,7 @@ int main (int argc, char **argv) /* {{{ */
 
   fprintf (stdout, "Creating %i values ... ", conf_num_values);
   fflush (stdout);
-  for (i = 0; i < conf_num_values; i++)
+  for (int i = 0; i < conf_num_values; i++)
   {
     lcc_value_list_t *vl;
 
index 94b0c0d..0495067 100644 (file)
 #@BUILD_PLUGIN_CONTEXTSWITCH_TRUE@LoadPlugin contextswitch
 @BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
 #@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq
+#@BUILD_PLUGIN_CPUSLEEP_TRUE@LoadPlugin cpusleep
 @LOAD_PLUGIN_CSV@LoadPlugin csv
 #@BUILD_PLUGIN_CURL_TRUE@LoadPlugin curl
 #@BUILD_PLUGIN_CURL_JSON_TRUE@LoadPlugin curl_json
 #@BUILD_PLUGIN_FILECOUNT_TRUE@LoadPlugin filecount
 #@BUILD_PLUGIN_FSCACHE_TRUE@LoadPlugin fscache
 #@BUILD_PLUGIN_GMOND_TRUE@LoadPlugin gmond
+#@BUILD_PLUGIN_GPS_TRUE@LoadPlugin gps
 #@BUILD_PLUGIN_GRPC_TRUE@LoadPlugin grpc
 #@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
+#@BUILD_PLUGIN_HUGEPAGES_TRUE@LoadPlugin hugepages
 @BUILD_PLUGIN_INTERFACE_TRUE@@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
 #@BUILD_PLUGIN_IPC_TRUE@LoadPlugin ipc
 #@BUILD_PLUGIN_IPMI_TRUE@LoadPlugin ipmi
 #@BUILD_PLUGIN_JAVA_TRUE@LoadPlugin java
 @BUILD_PLUGIN_LOAD_TRUE@@BUILD_PLUGIN_LOAD_TRUE@LoadPlugin load
 #@BUILD_PLUGIN_LPAR_TRUE@LoadPlugin lpar
+#@BUILD_PLUGIN_LUA_TRUE@LoadPlugin lua
 #@BUILD_PLUGIN_LVM_TRUE@LoadPlugin lvm
 #@BUILD_PLUGIN_MADWIFI_TRUE@LoadPlugin madwifi
 #@BUILD_PLUGIN_MBMON_TRUE@LoadPlugin mbmon
 #<Plugin "battery">
 #  ValuesPercentage false
 #  ReportDegraded false
+#  QueryStateFS false
 #</Plugin>
 
 #<Plugin "bind">
 #  </Metric>
 #</Plugin>
 
+#<Plugin gps>
+#  Host "127.0.0.1"
+#  Port "2947"
+#  Timeout 0.015
+#  PauseConnect 5
+#</Plugin>
+
 #<Plugin grpc>
-#      WorkerThreads 5
+#      <Server "example.com" "50051">
+#              EnableSSL true
+#              SSLCACertificateFile "/path/to/root.pem"
+#              SSLCertificateFile "/path/to/server.pem"
+#              SSLCertificateKeyFile "/path/to/server.key"
+#      </Server>
 #      <Listen "0.0.0.0" "50051">
 #              EnableSSL true
-#              SSLRootCerts "/path/to/root.pem"
-#              SSLServerCert "/path/to/server.pem"
-#              SSLServerKey "/path/to/server.key"
+#              SSLCACertificateFile "/path/to/root.pem"
+#              SSLCertificateFile "/path/to/client.pem"
+#              SSLCertificateKeyFile "/path/to/client.key"
 #      </Listen>
 #</Plugin>
 
 #  Port "7634"
 #</Plugin>
 
+#<Plugin hugepages>
+#    ReportPerNodeHP  true
+#    ReportRootHP     true
+#    ValuesPages      true
+#    ValuesBytes      false
+#    ValuesPercentage false
+#</Plugin>
+
 #<Plugin interface>
 #      Interface "eth0"
 #      IgnoreSelected false
+#      ReportInactive true
 #      UniqueName false
 #</Plugin>
 
 #      ReportBySerial false
 #</Plugin>
 
+#<Plugin lua>
+#      BasePath "@prefix@/share/@PACKAGE_NAME@/lua"
+#      Script "script1.lua"
+#      Script "script2.lua"
+#</Plugin>
+
 #<Plugin madwifi>
 #      Interface "wlan0"
 #      IgnoreSelected false
 #              User "db_user"
 #              Password "secret"
 #              Database "db_name"
+#              SSLKey "/path/to/key.pem"
+#              SSLCert "/path/to/cert.pem"
+#              SSLCA "/path/to/ca.pem"
+#              SSLCAPath "/path/to/cas/"
+#              SSLCipher "DHE-RSA-AES256-SHA"
 #              MasterStats true
 #              ConnectTimeout 10
 #              InnodbStats true
 #              SlaveStats true
 #              SlaveNotifications true
 #      </Database>
+#      <Database galera>
+#              Alias "galera"
+#              Host "localhost"
+#              Socket "/var/run/mysql/mysqld.sock"
+#              WsrepStats true
+#      </Database>
 #</Plugin>
 
 #<Plugin netapp>
 #    StoreRates true
 #    AlwaysAppendDS false
 #    EscapeCharacter "_"
+#    SeparateInstances false
+#    DropDuplicateFields false
 #  </Node>
 #</Plugin>
 
 #              Header "X-Custom-Header: custom_value"
 #              SSLVersion "TLSv1"
 #              Format "Command"
+#              Metrics true
+#              Notifications false
 #              StoreRates false
 #              BufferSize 4096
 #              LowSpeedLimit 0
index 9b659c6..00cd781 100644 (file)
@@ -241,6 +241,12 @@ Path to the plugins (shared objects) of collectd.
 Set one or more files that contain the data-set descriptions. See
 L<types.db(5)> for a description of the format of this file.
 
+If this option is not specified, a default file is read. If you need to define
+custom types in addition to the types defined in the default file, you need to
+explicitly load both. In other words, if the B<TypesDB> option is encountered
+the default behavior is disabled and if you need the default types you have to
+also explicitly load them.
+
 =item B<Interval> I<Seconds>
 
 Configures the interval in which to query the read plugins. Obviously smaller
@@ -1108,6 +1114,13 @@ When set to B<true>, the battery plugin will report three values: B<charged>
 and "remaining capacity") and B<degraded> (difference between "design capacity"
 and "last full capacity").
 
+=item B<QueryStateFS> B<false>|B<true>
+
+When set to B<true>, the battery plugin will only read statistics
+related to battery performance as exposed by StateFS at
+/run/state. StateFS is used in Mer-based Sailfish OS, for
+example.
+
 =back
 
 =head2 Plugin C<bind>
@@ -1447,6 +1460,11 @@ are set to B<true>. In this case, by default, metrics will be reported as
 Jiffies. By setting this option to B<true>, you can request percentage values
 in the un-aggregated (per-CPU, per-state) mode as well.
 
+=item B<ReportNumCpu> B<false>|B<true>
+
+When set to B<true>, reports the number of available CPUs.
+Defaults to B<false>.
+
 =back
 
 =head2 Plugin C<cpufreq>
@@ -1457,6 +1475,16 @@ installed) to get the current CPU frequency. If this file does not exist make
 sure B<cpufreqd> (L<http://cpufreqd.sourceforge.net/>) or a similar tool is
 installed and an "cpu governor" (that's a kernel module) is loaded.
 
+=head2 Plugin C<cpusleep>
+
+This plugin doesn't have any options. It reads CLOCK_BOOTTIME and
+CLOCK_MONOTONIC and reports the difference between these clocks. Since
+BOOTTIME clock increments while device is suspended and MONOTONIC
+clock does not, the derivative of the difference between these clocks
+gives the relative amount of time the device has spent in suspend
+state. The recorded value is in milliseconds of sleep per seconds of
+wall clock.
+
 =head2 Plugin C<csv>
 
 =over 4
@@ -1760,6 +1788,11 @@ The following options are valid within B<URL> blocks:
 
 =over 4
 
+=item B<Host> I<Name>
+
+Use I<Name> as the host name when submitting values. Defaults to the global
+host name setting.
+
 =item B<Instance> I<Instance>
 
 Sets the plugin instance to I<Instance>.
@@ -2462,7 +2495,7 @@ I<TypeInstance> will be used.
 
 =item B<MappedOnly> B<true>|B<false>
 
-When set to B<true>, only metrics that can be mapped to to a I<type> will be
+When set to B<true>, only metrics that can be mapped to a I<type> will be
 collected, all other metrics will be ignored. Defaults to B<false>.
 
 =back
@@ -2692,6 +2725,78 @@ source, this is optional. Otherwise the option is required.
 
 =back
 
+=head2 Plugin C<gps>
+
+The C<gps plugin> connects to gpsd on the host machine.
+The host, port, timeout and pause are configurable.
+
+This is useful if you run an NTP server using a GPS for source and you want to
+monitor it.
+
+Mind your GPS must send $--GSA for having the data reported!
+
+The following elements are collected:
+
+=over 4
+
+=item B<satellites>
+
+Number of satellites used for fix (type instance "used") and in view (type
+instance "visible"). 0 means no GPS satellites are visible.
+
+=item B<dilution_of_precision>
+
+Vertical and horizontal dilution (type instance "horizontal" or "vertical").
+It should be between 0 and 3.
+Look at the documentation of your GPS to know more.
+
+=back
+
+Synopsis:
+
+ LoadPlugin gps
+ <Plugin "gps">
+   # Connect to localhost on gpsd regular port:
+   Host "127.0.0.1"
+   Port "2947"
+   # 15 ms timeout
+   Timeout 0.015
+   # PauseConnect of 5 sec. between connection attempts.
+   PauseConnect 5
+ </Plugin>
+
+Available configuration options:
+
+=over 4
+
+=item B<Host> I<Host>
+
+The host on which gpsd daemon runs. Defaults to B<localhost>.
+
+=item B<Port> I<Port>
+
+Port to connect to gpsd on the host machine. Defaults to B<2947>.
+
+=item B<Timeout> I<Seconds>
+
+Timeout in seconds (default 0.015 sec).
+
+The GPS data stream is fetch by the plugin form the daemon.
+It waits for data to be available, if none arrives it times out
+and loop for another reading.
+Mind to put a low value gpsd expects value in the micro-seconds area
+(recommended is 500 us) since the waiting function is blocking.
+Value must be between 500 us and 5 sec., if outside that range the
+default value is applied.
+
+This only applies from gpsd release-2.95.
+
+=item B<PauseConnect> I<Seconds>
+
+Pause to apply between attempts of connection to gpsd in seconds (default 5 sec).
+
+=back
+
 =head2 Plugin C<grpc>
 
 The I<grpc> plugin provides an RPC interface to submit values to or query
@@ -2702,6 +2807,33 @@ The B<gRPC> homepage can be found at L<https://grpc.io/>.
 
 =over 4
 
+=item B<Server> I<Host> I<Port>
+
+The B<Server> statement sets the address of a server to which to send metrics
+via the C<DispatchValues> function.
+
+The argument I<Host> may be a hostname, an IPv4 address, or an IPv6 address.
+
+Optionally, B<Server> may be specified as a configuration block which supports
+the following options:
+
+=over 4
+
+=item B<EnableSSL> B<false>|B<true>
+
+Whether to require SSL for outgoing connections. Default: false.
+
+=item B<SSLCACertificateFile> I<Filename>
+
+=item B<SSLCertificateFile> I<Filename>
+
+=item B<SSLCertificateKeyFile> I<Filename>
+
+Filenames specifying SSL certificate and key material to be used with SSL
+connections.
+
+=back
+
 =item B<Listen> I<Host> I<Port>
 
 The B<Listen> statement sets the network address to bind to. When multiple
@@ -2719,22 +2851,17 @@ supports the following options:
 
 Whether to enable SSL for incoming connections. Default: false.
 
-=item B<SSLRootCerts> I<Filename>
+=item B<SSLCACertificateFile> I<Filename>
 
-=item B<SSLServerKey> I<Filename>
+=item B<SSLCertificateFile> I<Filename>
 
-=item B<SSLServerCert> I<Filename>
+=item B<SSLCertificateKeyFile> I<Filename>
 
 Filenames specifying SSL certificate and key material to be used with SSL
 connections.
 
 =back
 
-=item B<WorkerThreads> I<Num>
-
-Number of threads to start for handling incoming connections. The default
-value is B<5>.
-
 =back
 
 =head2 Plugin C<hddtemp>
@@ -2760,6 +2887,47 @@ TCP-Port to connect to. Defaults to B<7634>.
 
 =back
 
+=head2 Plugin C<hugepages>
+
+To collect B<hugepages> information, collectd reads directories
+"/sys/devices/system/node/*/hugepages" and
+"/sys/kernel/mm/hugepages".
+Reading of these directories can be disabled by the following
+options (default is enabled).
+
+=over 4
+
+=item B<ReportPerNodeHP> B<true>|B<false>
+
+If enabled, information will be collected from the hugepage
+counters in "/sys/devices/system/node/*/hugepages".
+This is used to check the per-node hugepage statistics on
+a NUMA system.
+
+=item B<ReportRootHP> B<true>|B<false>
+
+If enabled, information will be collected from the hugepage
+counters in "/sys/kernel/mm/hugepages".
+This can be used on both NUMA and non-NUMA systems to check
+the overall hugepage statistics.
+
+=item B<ValuesPages> B<true>|B<false>
+
+Whether to report hugepages metrics in number of pages.
+Defaults to B<true>.
+
+=item B<ValuesBytes> B<false>|B<true>
+
+Whether to report hugepages metrics in bytes.
+Defaults to B<false>.
+
+=item B<ValuesPercentage> B<false>|B<true>
+
+Whether to report hugepages metrics as percentage.
+Defaults to B<false>.
+
+=back
+
 =head2 Plugin C<interface>
 
 =over 4
@@ -2796,6 +2964,18 @@ 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<ReportInactive> I<true>|I<false>
+
+When set to I<false>, only interfaces with non-zero traffic will be
+reported. Note that the check is done by looking into whether a
+package was sent at any time from boot and the corresponding counter
+is non-zero. So, if the interface has been sending data in the past
+since boot, but not during the reported time-interval, it will still
+be reported.
+
+The default value is I<true> and results in collection of the data
+from all interfaces that are selected by B<Interface> and
+B<IgnoreSelected> options.
 
 =item B<UniqueName> I<true>|I<false>
 
@@ -3050,6 +3230,12 @@ Defaults to false.
 
 =back
 
+=head2 Plugin C<lua>
+
+This plugin embeds a Lua interpreter into collectd and provides an interface
+to collectd's plugin system. See L<collectd-lua(5)> for its documentation.
+
+
 =head2 Plugin C<mbmon>
 
 The C<mbmon plugin> uses mbmon to retrieve temperature, voltage, etc.
@@ -3701,6 +3887,11 @@ Synopsis:
       Port "3306"
       MasterStats true
       ConnectTimeout 10
+      SSLKey "/path/to/key.pem"
+      SSLCert "/path/to/cert.pem"
+      SSLCA "/path/to/ca.pem"
+      SSLCAPath "/path/to/cas/"
+      SSLCipher "DHE-RSA-AES256-SHA"
     </Database>
 
     <Database bar>
@@ -3710,12 +3901,20 @@ Synopsis:
       SlaveStats true
       SlaveNotifications true
     </Database>
+
+   <Database galera>
+      Alias "galera"
+      Host "localhost"
+      Socket "/var/run/mysql/mysqld.sock"
+      WsrepStats true
+   </Database>
   </Plugin>
 
 A B<Database> block defines one connection to a MySQL database. It accepts a
 single argument which specifies the name of the database. None of the other
 options are required. MySQL will use default values as documented in the
-section "mysql_real_connect()" in the B<MySQL reference manual>.
+"mysql_real_connect()" and "mysql_ssl_set()" sections in the
+B<MySQL reference manual>.
 
 =over 4
 
@@ -3780,10 +3979,36 @@ privileges. See the B<User> documentation above. Defaults to B<false>.
 If enabled, the plugin sends a notification if the replication slave I/O and /
 or SQL threads are not running. Defaults to B<false>.
 
+=item B<WsrepStats> I<true|false>
+ Enable the collection of wsrep plugin statistics, used in Master-Master
+ replication setups like in MySQL Galera/Percona XtraDB Cluster.
+ User needs only privileges to execute 'SHOW GLOBAL STATUS'
 =item B<ConnectTimeout> I<Seconds>
 
 Sets the connect timeout for the MySQL client.
 
+=item B<SSLKey> I<Path>
+
+If provided, the X509 key in PEM format.
+
+=item B<SSLCert> I<Path>
+
+If provided, the X509 cert in PEM format.
+
+=item B<SSLCA> I<Path>
+
+If provided, the CA file in PEM format (check OpenSSL docs).
+
+=item B<SSLCAPath> I<Path>
+
+If provided, the CA directory (check OpenSSL docs).
+
+=item B<SSLCipher> I<String>
+
+If provided, the SSL cipher to use.
+
 =back
 
 =head2 Plugin C<netapp>
@@ -5583,7 +5808,7 @@ values are made available through those parameters:
 
 =item B<$1>
 
-The timestamp of the queried value as a floating point number.
+The timestamp of the queried value as an RFC 3339-formatted local time.
 
 =item B<$2>
 
@@ -7098,7 +7323,7 @@ port in numeric form.
 =item B<AllPortsSummary> I<true>|I<false>
 
 If this option is set to I<true> a summary of statistics from all connections
-are collectd. This option defaults to I<false>.
+are collected. This option defaults to I<false>.
 
 =back
 
@@ -7675,6 +7900,32 @@ If set to B<true>, append the name of the I<Data Source> (DS) to the "metric"
 identifier. If set to B<false> (the default), this is only done when there is
 more than one DS.
 
+=item B<DropDuplicateFields> B<false>|B<true>
+
+If set to B<true>, detect and remove duplicate components in Graphite metric
+names. For example, the metric name  C<host.load.load.shortterm> will
+be shortened to C<host.load.shortterm>.
+
+=back
+
+=head2 Plugin C<write_log>
+
+The C<write_log> plugin writes metrics as INFO log messages.
+
+This plugin supports two output formats: I<Graphite> and I<JSON>.
+
+Synopsis:
+
+ <Plugin write_log>
+   Format Graphite
+ </Plugin>
+
+=over 4
+
+=item B<Format> I<Format>
+
+The output format to use. Can be one of C<Graphite> or C<JSON>.
+
 =back
 
 =head2 Plugin C<write_tsdb>
@@ -7879,6 +8130,14 @@ create output in the I<JavaScript Object Notation> (JSON). When set to KAIROSDB
 
 Defaults to B<Command>.
 
+=item B<Metrics> B<true>|B<false>
+
+Controls whether I<metrics> are POSTed to this location. Defaults to B<true>.
+
+=item B<Notifications> B<false>|B<true>
+
+Controls whether I<notifications> are POSTed to this location. Defaults to B<false>.
+
 =item B<StoreRates> B<true|false>
 
 If set to B<true>, convert counter values to rates. If set to B<false> (the
@@ -8942,6 +9201,8 @@ Available options:
 
 =item B<TypeInstance> I<Regex>
 
+=item B<MetaData> I<String> I<Regex>
+
 Match values where the given regular expressions match the various fields of
 the identifier of a value. If multiple regular expressions are given, B<all>
 regexen must match for a value to match.
@@ -9230,6 +9491,10 @@ Available options:
 
 =item B<TypeInstance> I<Regex> I<Replacement>
 
+=item B<MetaData> I<String> I<Regex> I<Replacement>
+
+=item B<DeleteMetaData> I<String> I<Regex>
+
 Match the appropriate field with the given regular expression I<Regex>. If the
 regular expression matches, that part that matches is replaced with
 I<Replacement>. If multiple places of the input buffer match a given regular
@@ -9266,11 +9531,39 @@ Available options:
 
 =item B<TypeInstance> I<String>
 
-=item B<MetaDataSet> I<String> I<String>
+=item B<MetaData> I<String> I<String>
+
+Set the appropriate field to the given string. The strings for plugin instance,
+type instance, and meta data 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.
+
+The following placeholders will be replaced by an appropriate value:
+
+=over 4
+
+=item B<%{host}>
+
+=item B<%{plugin}>
+
+=item B<%{plugin_instance}>
+
+=item B<%{type}>
+
+=item B<%{type_instance}>
+
+These placeholders are replaced by the identifier field of the same name.
+
+=item B<%{meta:>I<name>B<}>
+
+These placeholders are replaced by the meta data value with the given name.
+
+=back
+
+Please note that these placeholders are B<case sensitive>!
+
+=item B<DeleteMetaData> 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.
+Delete the named meta data field.
 
 =back
 
index 18b3917..8c88479 100644 (file)
 
 #include "libcollectdclient/collectd/client.h"
 
+#ifndef PREFIX
+# define PREFIX "/opt/" PACKAGE_NAME
+#endif
+
+#ifndef LOCALSTATEDIR
+# define LOCALSTATEDIR PREFIX "/var"
+#endif
+
 #define DEFAULT_SOCK LOCALSTATEDIR"/run/"PACKAGE_NAME"-unixsock"
 
 extern char *optarg;
@@ -185,7 +193,6 @@ static int getval (lcc_connection_t *c, int argc, char **argv)
   char   **ret_values_names = NULL;
 
   int status;
-  size_t i;
 
   assert (strcasecmp (argv[0], "getval") == 0);
 
@@ -194,7 +201,6 @@ static int getval (lcc_connection_t *c, int argc, char **argv)
     return (-1);
   }
 
-  memset (&ident, 0, sizeof (ident));
   status = parse_identifier (c, argv[1], &ident);
   if (status != 0)
     return (status);
@@ -204,7 +210,7 @@ static int getval (lcc_connection_t *c, int argc, char **argv)
     if (ret_values != NULL) \
       free (ret_values); \
     if (ret_values_names != NULL) { \
-      for (i = 0; i < ret_values_num; ++i) \
+      for (size_t i = 0; i < ret_values_num; ++i) \
         free (ret_values_names[i]); \
       free (ret_values_names); \
     } \
@@ -219,7 +225,7 @@ static int getval (lcc_connection_t *c, int argc, char **argv)
     BAIL_OUT (-1);
   }
 
-  for (i = 0; i < ret_values_num; ++i)
+  for (size_t i = 0; i < ret_values_num; ++i)
     printf ("%s=%e\n", ret_values_names[i], ret_values[i]);
   BAIL_OUT (0);
 #undef BAIL_OUT
@@ -236,7 +242,6 @@ static int flush (lcc_connection_t *c, int argc, char **argv)
   size_t plugins_num = 0;
 
   int status;
-  int i;
 
   assert (strcasecmp (argv[0], "flush") == 0);
 
@@ -251,7 +256,7 @@ static int flush (lcc_connection_t *c, int argc, char **argv)
     return (s); \
   } while (0)
 
-  for (i = 1; i < argc; ++i) {
+  for (int i = 1; i < argc; ++i) {
     char *key, *value;
 
     key   = argv[i];
@@ -315,7 +320,7 @@ static int flush (lcc_connection_t *c, int argc, char **argv)
     plugins[0] = NULL;
   }
 
-  for (i = 0; i < plugins_num; ++i) {
+  for (size_t i = 0; i < plugins_num; ++i) {
     if (identifiers_num == 0) {
       status = lcc_flush (c, plugins[i], NULL, timeout);
       if (status != 0)
@@ -323,9 +328,7 @@ static int flush (lcc_connection_t *c, int argc, char **argv)
             (plugins[i] == NULL) ? "(all)" : plugins[i], lcc_strerror (c));
     }
     else {
-      int j;
-
-      for (j = 0; j < identifiers_num; ++j) {
+      for (size_t j = 0; j < identifiers_num; ++j) {
         status = lcc_flush (c, plugins[i], identifiers + j, timeout);
         if (status != 0) {
           char id[1024];
@@ -350,7 +353,6 @@ static int listval (lcc_connection_t *c, int argc, char **argv)
   size_t            ret_ident_num = 0;
 
   int status;
-  size_t i;
 
   assert (strcasecmp (argv[0], "listval") == 0);
 
@@ -373,7 +375,7 @@ static int listval (lcc_connection_t *c, int argc, char **argv)
     BAIL_OUT (status);
   }
 
-  for (i = 0; i < ret_ident_num; ++i) {
+  for (size_t i = 0; i < ret_ident_num; ++i) {
     char id[1024];
 
     status = lcc_identifier_to_string (c, id, sizeof (id), ret_ident + i);
@@ -399,7 +401,6 @@ static int putval (lcc_connection_t *c, int argc, char **argv)
   size_t  values_len = 0;
 
   int status;
-  int i;
 
   assert (strcasecmp (argv[0], "putval") == 0);
 
@@ -416,7 +417,7 @@ static int putval (lcc_connection_t *c, int argc, char **argv)
   if (status != 0)
     return (status);
 
-  for (i = 2; i < argc; ++i) {
+  for (int i = 2; i < argc; ++i) {
     char *tmp;
 
     tmp = strchr (argv[i], (int)'=');
index 13304f2..61daa58 100644 (file)
 
 #include <unistd.h>
 
+#ifndef PREFIX
+# define PREFIX "/opt/" PACKAGE_NAME
+#endif
+
+#ifndef LOCALSTATEDIR
+# define LOCALSTATEDIR PREFIX "/var"
+#endif
+
 #ifndef COLLECTDMON_PIDFILE
 # define COLLECTDMON_PIDFILE LOCALSTATEDIR"/run/collectdmon.pid"
 #endif /* ! COLLECTDMON_PIDFILE */
index 486b001..4a72b2f 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -73,62 +74,26 @@ static void conntrack_submit (const char *type, const char *type_instance,
 static int conntrack_read (void)
 {
        value_t conntrack, conntrack_max, conntrack_pct;
-       FILE *fh;
-       char buffer[64];
-       size_t buffer_len;
-
-       fh = fopen (old_files?CONNTRACK_FILE_OLD:CONNTRACK_FILE, "r");
-       if (fh == NULL)
-               return (-1);
 
-       memset (buffer, 0, sizeof (buffer));
-       if (fgets (buffer, sizeof (buffer), fh) == NULL)
+       char const *path = old_files ? CONNTRACK_FILE_OLD : CONNTRACK_FILE;
+       if (parse_value_file (path, &conntrack, DS_TYPE_GAUGE) != 0)
        {
-               fclose (fh);
+               ERROR ("conntrack plugin: Reading \"%s\" failed.", path);
                return (-1);
        }
-       fclose (fh);
-
-       /* strip trailing newline. */
-       buffer_len = strlen (buffer);
-       while ((buffer_len > 0) && isspace ((int) buffer[buffer_len - 1]))
-       {
-               buffer[buffer_len - 1] = 0;
-               buffer_len--;
-       }
-
-       if (parse_value (buffer, &conntrack, DS_TYPE_GAUGE) != 0)
-               return (-1);
 
-       conntrack_submit ("conntrack", NULL, conntrack);
-
-       fh = fopen (old_files?CONNTRACK_MAX_FILE_OLD:CONNTRACK_MAX_FILE, "r");
-       if (fh == NULL)
-               return (-1);
-
-       memset (buffer, 0, sizeof (buffer));
-       if (fgets (buffer, sizeof (buffer), fh) == NULL)
+       path = old_files ? CONNTRACK_MAX_FILE_OLD : CONNTRACK_MAX_FILE;
+       if (parse_value_file (path, &conntrack_max, DS_TYPE_GAUGE) != 0)
        {
-               fclose (fh);
+               ERROR ("conntrack plugin: Reading \"%s\" failed.", path);
                return (-1);
        }
-       fclose (fh);
-
-       /* strip trailing newline. */
-       buffer_len = strlen (buffer);
-       while ((buffer_len > 0) && isspace ((int) buffer[buffer_len - 1]))
-       {
-               buffer[buffer_len - 1] = 0;
-               buffer_len--;
-       }
-
-       if (parse_value (buffer, &conntrack_max, DS_TYPE_GAUGE) != 0)
-               return (-1);
 
-       conntrack_submit ("conntrack", "max", conntrack_max);
        conntrack_pct.gauge = (conntrack.gauge / conntrack_max.gauge) * 100;
-       conntrack_submit ("percent", "used", conntrack_pct);
 
+       conntrack_submit ("conntrack", NULL,   conntrack);
+       conntrack_submit ("conntrack", "max",  conntrack_max);
+       conntrack_submit ("percent",   "used", conntrack_pct);
 
        return (0);
 } /* static int conntrack_read */
index 344f76e..3bd6d9f 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
 
 static void cs_submit (derive_t context_switches)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = (derive_t) context_switches;
-
-       vl.values = values;
+       vl.values = &(value_t) { .derive = context_switches };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "contextswitch", sizeof (vl.plugin));
index 9c432d1..fbd0714 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -28,6 +28,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -191,11 +192,13 @@ static size_t global_cpu_num = 0;
 static _Bool report_by_cpu = 1;
 static _Bool report_by_state = 1;
 static _Bool report_percent = 0;
+static _Bool report_num_cpu = 0;
 
 static const char *config_keys[] =
 {
        "ReportByCpu",
        "ReportByState",
+       "ReportNumCpu",
        "ValuesPercentage"
 };
 static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
@@ -208,6 +211,8 @@ static int cpu_config (char const *key, char const *value) /* {{{ */
                report_percent = IS_TRUE (value) ? 1 : 0;
        else if (strcasecmp (key, "ReportByState") == 0)
                report_by_state = IS_TRUE (value) ? 1 : 0;
+       else if (strcasecmp (key, "ReportNumCpu") == 0)
+               report_num_cpu = IS_TRUE (value) ? 1 : 0;
        else
                return (-1);
 
@@ -320,12 +325,9 @@ static int init (void)
 
 static void submit_value (int cpu_num, int cpu_state, const char *type, value_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       memcpy(&values[0], &value, sizeof(value));
-
-       vl.values = values;
+       vl.values = &value;
        vl.values_len = 1;
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -341,26 +343,22 @@ static void submit_value (int cpu_num, int cpu_state, const char *type, value_t
        plugin_dispatch_values (&vl);
 }
 
-static void submit_percent(int cpu_num, int cpu_state, gauge_t percent)
+static void submit_percent (int cpu_num, int cpu_state, gauge_t value)
 {
-       value_t value;
-
        /* This function is called for all known CPU states, but each read
         * method will only report a subset. The remaining states are left as
         * NAN and we ignore them here. */
-       if (isnan (percent))
+       if (isnan (value))
                return;
 
-       value.gauge = percent;
-       submit_value (cpu_num, cpu_state, "percent", value);
+       submit_value (cpu_num, cpu_state, "percent",
+                       (value_t) { .gauge = value });
 }
 
-static void submit_derive(int cpu_num, int cpu_state, derive_t derive)
+static void submit_derive (int cpu_num, int cpu_state, derive_t value)
 {
-       value_t value;
-
-       value.derive = derive;
-       submit_value (cpu_num, cpu_state, "cpu", value);
+       submit_value (cpu_num, cpu_state, "cpu",
+                       (value_t) { .derive = value });
 }
 
 /* Takes the zero-index number of a CPU and makes sure that the module-global
@@ -405,19 +403,16 @@ static cpu_state_t *get_cpu_state (size_t cpu_num, size_t state) /* {{{ */
  * array. */
 static void aggregate (gauge_t *sum_by_state) /* {{{ */
 {
-       size_t cpu_num;
-       size_t state;
-
-       for (state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
+       for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
                sum_by_state[state] = NAN;
 
-       for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+       for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
        {
                cpu_state_t *this_cpu_states = get_cpu_state (cpu_num, 0);
 
                this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate = NAN;
 
-               for (state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
+               for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
                {
                        if (!this_cpu_states[state].has_value)
                                continue;
@@ -442,7 +437,6 @@ static void aggregate (gauge_t *sum_by_state) /* {{{ */
 static void cpu_commit_one (int cpu_num, /* {{{ */
                gauge_t rates[static COLLECTD_CPU_STATE_MAX])
 {
-       size_t state;
        gauge_t sum;
 
        sum = rates[COLLECTD_CPU_STATE_ACTIVE];
@@ -455,20 +449,33 @@ static void cpu_commit_one (int cpu_num, /* {{{ */
                return;
        }
 
-       for (state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
+       for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
        {
                gauge_t percent = 100.0 * rates[state] / sum;
                submit_percent (cpu_num, state, percent);
        }
 } /* }}} void cpu_commit_one */
 
+/* Commits the number of cores */
+static void cpu_commit_num_cpu (gauge_t value) /* {{{ */
+{
+       value_list_t vl = VALUE_LIST_INIT;
+
+       vl.values = &(value_t) { .gauge = value };
+       vl.values_len = 1;
+
+       sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+       sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin));
+       sstrncpy (vl.type, "count", sizeof (vl.type));
+
+       plugin_dispatch_values (&vl);
+} /* }}} void cpu_commit_num_cpu */
+
 /* Resets the internal aggregation. This is called by the read callback after
  * each iteration / after each call to cpu_commit(). */
 static void cpu_reset (void) /* {{{ */
 {
-       size_t i;
-
-       for (i = 0; i < cpu_states_num; i++)
+       for (size_t i = 0; i < cpu_states_num; i++)
                cpu_states[i].has_value = 0;
 
        global_cpu_num = 0;
@@ -477,13 +484,9 @@ static void cpu_reset (void) /* {{{ */
 /* Legacy behavior: Dispatches the raw derive values without any aggregation. */
 static void cpu_commit_without_aggregation (void) /* {{{ */
 {
-       int state;
-
-       for (state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
+       for (int state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
        {
-               size_t cpu_num;
-
-               for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+               for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
                {
                        cpu_state_t *s = get_cpu_state (cpu_num, state);
 
@@ -501,7 +504,9 @@ static void cpu_commit (void) /* {{{ */
        gauge_t global_rates[COLLECTD_CPU_STATE_MAX] = {
                NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN /* Batman! */
        };
-       size_t cpu_num;
+
+       if (report_num_cpu)
+               cpu_commit_num_cpu ((gauge_t) global_cpu_num);
 
        if (report_by_state && report_by_cpu && !report_percent)
        {
@@ -517,15 +522,14 @@ static void cpu_commit (void) /* {{{ */
                return;
        }
 
-       for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+       for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
        {
                cpu_state_t *this_cpu_states = get_cpu_state (cpu_num, 0);
                gauge_t local_rates[COLLECTD_CPU_STATE_MAX] = {
                        NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN
                };
-               size_t state;
 
-               for (state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
+               for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
                        if (this_cpu_states[state].has_value)
                                local_rates[state] = this_cpu_states[state].rate;
 
@@ -541,7 +545,7 @@ static int cpu_stage (size_t cpu_num, size_t state, derive_t d, cdtime_t now) /*
        int status;
        cpu_state_t *s;
        gauge_t rate = NAN;
-       value_t val = {.derive = d};
+       value_t val = { .derive = d };
 
        if (state >= COLLECTD_CPU_STATE_ACTIVE)
                return (EINVAL);
@@ -569,8 +573,6 @@ static int cpu_read (void)
        cdtime_t now = cdtime ();
 
 #if PROCESSOR_CPU_LOAD_INFO /* {{{ */
-       int cpu;
-
        kern_return_t status;
 
        processor_cpu_load_info_data_t cpu_info;
@@ -578,7 +580,7 @@ static int cpu_read (void)
 
        host_t cpu_host;
 
-       for (cpu = 0; cpu < cpu_list_len; cpu++)
+       for (mach_msg_type_number_t cpu = 0; cpu < cpu_list_len; cpu++)
        {
                cpu_host = 0;
                cpu_info_len = PROCESSOR_BASIC_INFO_COUNT;
@@ -653,13 +655,12 @@ static int cpu_read (void)
 /* }}} #endif defined(KERNEL_LINUX) */
 
 #elif defined(HAVE_LIBKSTAT) /* {{{ */
-       int cpu;
        static cpu_stat_t cs;
 
        if (kc == NULL)
                return (-1);
 
-       for (cpu = 0; cpu < numcpu; cpu++)
+       for (int cpu = 0; cpu < numcpu; cpu++)
        {
                if (kstat_read (kc, ksp[cpu], &cs) == -1)
                        continue; /* error message? */
@@ -675,7 +676,6 @@ static int cpu_read (void)
        uint64_t cpuinfo[numcpu][CPUSTATES];
        size_t cpuinfo_size;
        int status;
-       int i;
 
        if (numcpu < 1)
        {
@@ -688,7 +688,7 @@ static int cpu_read (void)
 
 #if defined(KERN_CPTIME2)
        if (numcpu > 1) {
-               for (i = 0; i < numcpu; i++) {
+               for (int i = 0; i < numcpu; i++) {
                        int mib[] = {CTL_KERN, KERN_CPTIME2, i};
 
                        cpuinfo_size = sizeof (cpuinfo[0]);
@@ -721,12 +721,12 @@ static int cpu_read (void)
                        return (-1);
                }
 
-               for(i = 0; i < CPUSTATES; i++) {
+               for(int i = 0; i < CPUSTATES; i++) {
                        cpuinfo[0][i] = cpuinfo_tmp[i];
                }
        }
 
-       for (i = 0; i < numcpu; i++) {
+       for (int i = 0; i < numcpu; i++) {
                cpu_stage (i, COLLECTD_CPU_STATE_USER,      (derive_t) cpuinfo[i][CP_USER], now);
                cpu_stage (i, COLLECTD_CPU_STATE_NICE,      (derive_t) cpuinfo[i][CP_NICE], now);
                cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM,    (derive_t) cpuinfo[i][CP_SYS], now);
@@ -738,7 +738,6 @@ static int cpu_read (void)
 #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) /* {{{ */
        long cpuinfo[maxcpu][CPUSTATES];
        size_t cpuinfo_size;
-       int i;
 
        memset (cpuinfo, 0, sizeof (cpuinfo));
 
@@ -751,7 +750,7 @@ static int cpu_read (void)
                return (-1);
        }
 
-       for (i = 0; i < numcpu; i++) {
+       for (int i = 0; i < numcpu; i++) {
                cpu_stage (i, COLLECTD_CPU_STATE_USER,      (derive_t) cpuinfo[i][CP_USER], now);
                cpu_stage (i, COLLECTD_CPU_STATE_NICE,      (derive_t) cpuinfo[i][CP_NICE], now);
                cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM,    (derive_t) cpuinfo[i][CP_SYS], now);
@@ -801,7 +800,7 @@ static int cpu_read (void)
 
 #elif defined(HAVE_PERFSTAT) /* {{{ */
        perfstat_id_t id;
-       int i, cpus;
+       int cpus;
 
        numcpu =  perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
        if(numcpu == -1)
@@ -828,7 +827,7 @@ static int cpu_read (void)
                return (-1);
        }
 
-       for (i = 0; i < cpus; i++)
+       for (int i = 0; i < cpus; i++)
        {
                cpu_stage (i, COLLECTD_CPU_STATE_IDLE,   (derive_t) perfcpu[i].idle, now);
                cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM, (derive_t) perfcpu[i].sys,  now);
index b92b1d0..a2cc3ad 100644 (file)
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
-#define MODULE_NAME "cpufreq"
-
 static int num_cpu = 0;
 
 static int cpufreq_init (void)
@@ -58,73 +57,39 @@ static int cpufreq_init (void)
        return (0);
 } /* int cpufreq_init */
 
-static void cpufreq_submit (int cpu_num, double value)
+static void cpufreq_submit (int cpu_num, value_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &value;
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "cpufreq", sizeof (vl.plugin));
        sstrncpy (vl.type, "cpufreq", sizeof (vl.type));
-       ssnprintf (vl.type_instance, sizeof (vl.type_instance),
-                       "%i", cpu_num);
+       ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%i", cpu_num);
 
        plugin_dispatch_values (&vl);
 }
 
 static int cpufreq_read (void)
 {
-        int status;
-       unsigned long long val;
-       int i = 0;
-       FILE *fp;
-       char filename[256];
-       char buffer[16];
-
-       for (i = 0; i < num_cpu; i++)
+       for (int i = 0; i < num_cpu; i++)
        {
-               status = ssnprintf (filename, sizeof (filename),
-                               "/sys/devices/system/cpu/cpu%d/cpufreq/"
-                               "scaling_cur_freq", i);
-               if ((status < 1) || ((unsigned int)status >= sizeof (filename)))
-                       return (-1);
-
-               if ((fp = fopen (filename, "r")) == NULL)
-               {
-                       char errbuf[1024];
-                       WARNING ("cpufreq: fopen (%s): %s", filename,
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-                       return (-1);
-               }
+               char filename[PATH_MAX];
+               ssnprintf (filename, sizeof (filename),
+                               "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i);
 
-               if (fgets (buffer, 16, fp) == NULL)
+               value_t v;
+               if (parse_value_file (filename, &v, DS_TYPE_GAUGE) != 0)
                {
-                       char errbuf[1024];
-                       WARNING ("cpufreq: fgets: %s",
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-                       fclose (fp);
-                       return (-1);
+                       WARNING ("cpufreq plugin: Reading \"%s\" failed.", filename);
+                       continue;
                }
 
-               if (fclose (fp))
-               {
-                       char errbuf[1024];
-                       WARNING ("cpufreq: fclose: %s",
-                                       sstrerror (errno, errbuf,
-                                               sizeof (errbuf)));
-               }
-
-
-               /* You're seeing correctly: The file is reporting kHz values.. */
-               val = atoll (buffer) * 1000;
+               /* convert kHz to Hz */
+               v.gauge *= 1000.0;
 
-               cpufreq_submit (i, val);
+               cpufreq_submit (i, v);
        }
 
        return (0);
diff --git a/src/cpusleep.c b/src/cpusleep.c
new file mode 100644 (file)
index 0000000..5de0e47
--- /dev/null
@@ -0,0 +1,76 @@
+/**
+ * collectd - src/cpusleep.c
+ * Copyright (C) 2016 rinigus
+ *
+ * The MIT License (MIT)
+ *
+ * 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:
+ *      rinigus <http://github.com/rinigus>
+ *
+ * CPU sleep is reported in milliseconds of sleep per second of wall
+ * time. For that, the time difference between BOOT and MONOTONIC clocks
+ * is reported using derive type.
+**/
+
+#include "collectd.h"
+
+#include "common.h"
+#include "plugin.h"
+#include <time.h>
+
+static void cpusleep_submit(derive_t cpu_sleep) {
+  value_list_t vl = VALUE_LIST_INIT;
+
+  vl.values = &(value_t) { .derive = cpu_sleep };
+  vl.values_len = 1;
+  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+  sstrncpy(vl.plugin, "cpusleep", sizeof(vl.plugin));
+  sstrncpy(vl.type, "total_time_in_ms", sizeof(vl.type));
+
+  plugin_dispatch_values(&vl);
+}
+
+static int cpusleep_read(void) {
+  struct timespec b, m;
+  if (clock_gettime(CLOCK_BOOTTIME, &b) < 0) {
+    ERROR("cpusleep plugin: clock_boottime failed");
+    return (-1);
+  }
+
+  if (clock_gettime(CLOCK_MONOTONIC, &m) < 0) {
+    ERROR("cpusleep plugin: clock_monotonic failed");
+    return (-1);
+  }
+
+  // to avoid false positives in counter overflow due to reboot,
+  // derive is used. Sleep is calculated in milliseconds
+  derive_t diffsec = b.tv_sec - m.tv_sec;
+  derive_t diffnsec = b.tv_nsec - m.tv_nsec;
+  derive_t sleep = diffsec * 1000 + diffnsec / 1000000;
+
+  cpusleep_submit(sleep);
+
+  return (0);
+}
+
+void module_register(void) {
+  plugin_register_read("cpusleep", cpusleep_read);
+} /* void module_register */
index 880fa4c..070d33a 100644 (file)
        PyGILState_Release(gil_state);\
 }
 
-/* Python 2.4 has this macro, older versions do not. */
-#ifndef Py_VISIT
-#define Py_VISIT(o) do {\
-       int _vret;\
-       if ((o) != NULL) {\
-               _vret = visit((o), arg);\
-               if (_vret != 0)\
-               return _vret;\
-       }\
-} while (0)
-#endif
-
-/* Python 2.4 has this macro, older versions do not. */
-#ifndef Py_CLEAR
-#define Py_CLEAR(o) do {\
-       PyObject *tmp = o;\
-       (o) = NULL;\
-       Py_XDECREF(tmp);\
-} while (0)
-#endif
-
-/* Python 2.4 has this macro, older versions do not. */
-#ifndef Py_RETURN_NONE
-# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
 /* This macro is a shortcut for calls like
  * x = PyObject_Repr(x);
  * This can't be done like this example because this would leak
@@ -170,7 +144,7 @@ typedef struct {
        PyObject *values;    /* Sequence */
        PyObject *children;  /* Sequence */
 } Config;
-PyTypeObject ConfigType;
+extern PyTypeObject ConfigType;
 
 typedef struct {
        PyObject_HEAD        /* No semicolon! */
@@ -181,7 +155,7 @@ typedef struct {
        char type[DATA_MAX_NAME_LEN];
        char type_instance[DATA_MAX_NAME_LEN];
 } PluginData;
-PyTypeObject PluginDataType;
+extern PyTypeObject PluginDataType;
 #define PluginData_New() PyObject_CallFunctionObjArgs((PyObject *) &PluginDataType, (void *) 0)
 
 typedef struct {
@@ -190,7 +164,7 @@ typedef struct {
        PyObject *meta;      /* dict */
        double interval;
 } Values;
-PyTypeObject ValuesType;
+extern PyTypeObject ValuesType;
 #define Values_New() PyObject_CallFunctionObjArgs((PyObject *) &ValuesType, (void *) 0)
 
 typedef struct {
@@ -198,12 +172,12 @@ typedef struct {
        int severity;
        char message[NOTIF_MAX_MSG_LEN];
 } Notification;
-PyTypeObject NotificationType;
+extern PyTypeObject NotificationType;
 #define Notification_New() PyObject_CallFunctionObjArgs((PyObject *) &NotificationType, (void *) 0)
 
 typedef PyLongObject Signed;
-PyTypeObject SignedType;
+extern PyTypeObject SignedType;
 
 typedef PyLongObject Unsigned;
-PyTypeObject UnsignedType;
+extern PyTypeObject UnsignedType;
 
index 7b513e7..e008ecf 100644 (file)
--- a/src/csv.c
+++ b/src/csv.c
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "utils_cache.h"
@@ -45,7 +46,6 @@ static int value_list_to_string (char *buffer, int buffer_len,
 {
        int offset;
        int status;
-       size_t i;
        gauge_t *rates = NULL;
 
        assert (0 == strcmp (ds->type, vl->type));
@@ -58,7 +58,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
                return (-1);
        offset = status;
 
-       for (i = 0; i < ds->ds_num; i++)
+       for (size_t i = 0; i < ds->ds_num; i++)
        {
                if ((ds->ds[i].type != DS_TYPE_COUNTER)
                                && (ds->ds[i].type != DS_TYPE_GAUGE)
@@ -187,7 +187,6 @@ static int value_list_to_filename (char *buffer, size_t buffer_size,
 static int csv_create_file (const char *filename, const data_set_t *ds)
 {
        FILE *csv;
-       size_t i;
 
        if (check_create_dir (filename))
                return (-1);
@@ -203,7 +202,7 @@ static int csv_create_file (const char *filename, const data_set_t *ds)
        }
 
        fprintf (csv, "epoch");
-       for (i = 0; i < ds->ds_num; i++)
+       for (size_t i = 0; i < ds->ds_num; i++)
                fprintf (csv, ",%s", ds->ds[i].name);
 
        fprintf (csv, "\n");
@@ -269,7 +268,7 @@ static int csv_write (const data_set_t *ds, const value_list_t *vl,
        char         values[4096];
        FILE        *csv;
        int          csv_fd;
-       struct flock fl;
+       struct flock fl = { 0 };
        int          status;
 
        if (0 != strcmp (ds->type, vl->type)) {
@@ -288,12 +287,10 @@ static int csv_write (const data_set_t *ds, const value_list_t *vl,
 
        if (use_stdio)
        {
-               size_t i;
-
                escape_string (filename, sizeof (filename));
 
                /* Replace commas by colons for PUTVAL compatible output. */
-               for (i = 0; i < sizeof (values); i++)
+               for (size_t i = 0; i < sizeof (values); i++)
                {
                        if (values[i] == 0)
                                break;
@@ -342,9 +339,6 @@ static int csv_write (const data_set_t *ds, const value_list_t *vl,
        }
        csv_fd = fileno (csv);
 
-       memset (&fl, '\0', sizeof (fl));
-       fl.l_start  = 0;
-       fl.l_len    = 0; /* till end of file */
        fl.l_pid    = getpid ();
        fl.l_type   = F_WRLCK;
        fl.l_whence = SEEK_SET;
index d9ced60..8401e6c 100644 (file)
@@ -22,9 +22,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_curl_stats.h"
 #include "utils_match.h"
 #include "utils_time.h"
@@ -269,7 +269,6 @@ static int cc_config_add_match (web_page_t *page, /* {{{ */
 {
   web_match_t *match;
   int status;
-  int i;
 
   if (ci->values_num != 0)
   {
@@ -284,7 +283,7 @@ static int cc_config_add_match (web_page_t *page, /* {{{ */
   }
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -433,7 +432,6 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */
 {
   web_page_t *page;
   int status;
-  int i;
 
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
@@ -468,7 +466,7 @@ static int cc_config_add_page (oconfig_item_t *ci) /* {{{ */
 
   /* Process all children */
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -566,12 +564,11 @@ static int cc_config (oconfig_item_t *ci) /* {{{ */
   int success;
   int errors;
   int status;
-  int i;
 
   success = 0;
   errors = 0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -611,14 +608,11 @@ static int cc_init (void) /* {{{ */
 } /* }}} int cc_init */
 
 static void cc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */
-    const cu_match_value_t *mv)
+    value_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0] = mv->value;
-
-  vl.values = values;
+  vl.values = &value;
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "curl", sizeof (vl.plugin));
@@ -632,12 +626,9 @@ static void cc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */
 
 static void cc_submit_response_code (const web_page_t *wp, long code) /* {{{ */
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = code;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = (gauge_t) code };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "curl", sizeof (vl.plugin));
@@ -650,12 +641,9 @@ static void cc_submit_response_code (const web_page_t *wp, long code) /* {{{ */
 static void cc_submit_response_time (const web_page_t *wp, /* {{{ */
     cdtime_t response_time)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = CDTIME_T_TO_DOUBLE (response_time);
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = CDTIME_T_TO_DOUBLE (response_time) };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "curl", sizeof (vl.plugin));
@@ -667,7 +655,6 @@ static void cc_submit_response_time (const web_page_t *wp, /* {{{ */
 
 static int cc_read_page (web_page_t *wp) /* {{{ */
 {
-  web_match_t *wm;
   int status;
   cdtime_t start = 0;
 
@@ -700,7 +687,7 @@ static int cc_read_page (web_page_t *wp) /* {{{ */
     }
   }
 
-  for (wm = wp->matches; wm != NULL; wm = wm->next)
+  for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next)
   {
     cu_match_value_t *mv;
 
@@ -718,7 +705,7 @@ static int cc_read_page (web_page_t *wp) /* {{{ */
       continue;
     }
 
-    cc_submit (wp, wm, mv);
+    cc_submit (wp, wm, mv->value);
     match_value_reset (mv);
   } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */
 
@@ -727,9 +714,7 @@ static int cc_read_page (web_page_t *wp) /* {{{ */
 
 static int cc_read (void) /* {{{ */
 {
-  web_page_t *wp;
-
-  for (wp = pages_g; wp != NULL; wp = wp->next)
+  for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next)
     cc_read_page (wp);
 
   return (0);
index 55db387..4dab1ab 100644 (file)
@@ -22,9 +22,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_avltree.h"
 #include "utils_complain.h"
 #include "utils_curl_stats.h"
@@ -144,6 +144,9 @@ static int cj_get_type (cj_key_t *key)
 {
   const data_set_t *ds;
 
+  if ((key == NULL) || !CJ_IS_KEY (key))
+    return -EINVAL;
+
   ds = plugin_get_ds (key->type);
   if (ds == NULL)
   {
@@ -227,12 +230,15 @@ static int cj_cb_number (void *ctx,
   buffer[sizeof (buffer) - 1] = 0;
 
   if ((key == NULL) || !CJ_IS_KEY (key)) {
-    if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/)
+    if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) {
       NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects"
               " a map.", buffer);
+      return (CJ_CB_CONTINUE);
+    }
+
     cj_cb_inc_array_index (ctx, /* update_key = */ 1);
     key = db->state[db->depth].key;
-    if (key == NULL) {
+    if ((key == NULL) || !CJ_IS_KEY (key)) {
       return (CJ_CB_CONTINUE);
     }
   }
@@ -470,7 +476,6 @@ static int cj_config_add_key (cj_t *db, /* {{{ */
 {
   cj_key_t *key;
   int status;
-  int i;
 
   if ((ci->values_num != 1)
       || (ci->values[0].type != OCONFIG_TYPE_STRING))
@@ -506,7 +511,7 @@ static int cj_config_add_key (cj_t *db, /* {{{ */
   }
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -662,7 +667,6 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
 {
   cj_t *db;
   int status = 0;
-  int i;
 
   if ((ci->values_num != 1)
       || (ci->values[0].type != OCONFIG_TYPE_STRING))
@@ -699,7 +703,7 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
   }
 
   /* Fill the `cj_t' structure.. */
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -760,7 +764,6 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
   /* If all went well, register this database for reading */
   if (status == 0)
   {
-    user_data_t ud;
     char *cb_name;
 
     if (db->instance == NULL)
@@ -769,16 +772,15 @@ static int cj_config_add_url (oconfig_item_t *ci) /* {{{ */
     DEBUG ("curl_json plugin: Registering new read callback: %s",
            db->instance);
 
-    memset (&ud, 0, sizeof (ud));
-    ud.data = (void *) db;
-    ud.free_func = cj_free;
-
     cb_name = ssnprintf_alloc ("curl_json-%s-%s",
                db->instance, db->url ? db->url : db->sock);
 
     plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read,
                                   /* interval = */ db->interval,
-                                  &ud);
+                                  &(user_data_t) {
+                                    .data = db,
+                                    .free_func = cj_free,
+                                  });
     sfree (cb_name);
   }
   else
@@ -796,12 +798,11 @@ static int cj_config (oconfig_item_t *ci) /* {{{ */
   int success;
   int errors;
   int status;
-  int i;
 
   success = 0;
   errors = 0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -850,8 +851,8 @@ static void cj_submit (cj_t *db, cj_key_t *key, value_t *value) /* {{{ */
 
   if (key->instance == NULL)
   {
-    int i, len = 0;
-    for (i = 0; i < db->depth; i++)
+    int len = 0;
+    for (int i = 0; i < db->depth; i++)
       len += ssnprintf(vl.type_instance+len, sizeof(vl.type_instance)-len,
                        i ? "-%s" : "%s", db->state[i+1].name);
   }
index e0e4a62..924665c 100644 (file)
@@ -20,9 +20,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_curl_stats.h"
 #include "utils_llist.h"
 
@@ -177,7 +177,6 @@ static void cx_list_free (llist_t *list) /* {{{ */
 static void cx_free (void *arg) /* {{{ */
 {
   cx_t *db;
-  size_t i;
 
   DEBUG ("curl_xml plugin: cx_free (arg = %p);", arg);
 
@@ -206,7 +205,7 @@ static void cx_free (void *arg) /* {{{ */
   curl_slist_free_all (db->headers);
   curl_stats_destroy (db->stats);
 
-  for (i = 0; i < db->namespaces_num; i++)
+  for (size_t i = 0; i < db->namespaces_num; i++)
   {
     sfree (db->namespaces[i].prefix);
     sfree (db->namespaces[i].url);
@@ -368,14 +367,13 @@ static int cx_handle_all_value_xpaths (xmlXPathContextPtr xpath_ctx, /* {{{ */
 {
   value_t values[xpath->values_len];
   int status;
-  size_t i;
 
   assert (xpath->values_len > 0);
   assert (xpath->values_len == vl->values_len);
   assert (xpath->values_len == ds->ds_num);
   vl->values = values;
 
-  for (i = 0; i < xpath->values_len; i++)
+  for (size_t i = 0; i < xpath->values_len; i++)
   {
     status = cx_handle_single_value_xpath (xpath_ctx, xpath, ds, vl, i);
     if (status != 0)
@@ -488,7 +486,6 @@ static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
     char *base_xpath, cx_xpath_t *xpath)
 {
   int total_nodes;
-  int i;
 
   xmlXPathObjectPtr base_node_obj = NULL;
   xmlNodeSetPtr base_nodes = NULL;
@@ -529,7 +526,7 @@ static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
   if (plugin_instance != NULL)
     sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
 
-  for (i = 0; i < total_nodes; i++)
+  for (int i = 0; i < total_nodes; i++)
   {
     int status;
 
@@ -583,7 +580,6 @@ static int cx_parse_stats_xml(xmlChar* xml, cx_t *db) /* {{{ */
   int status;
   xmlDocPtr doc;
   xmlXPathContextPtr xpath_ctx;
-  size_t i;
 
   /* Load the XML */
   doc = xmlParseDoc(xml);
@@ -601,7 +597,7 @@ static int cx_parse_stats_xml(xmlChar* xml, cx_t *db) /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < db->namespaces_num; i++)
+  for (size_t i = 0; i < db->namespaces_num; i++)
   {
     cx_namespace_t const *ns = db->namespaces + i;
     status = xmlXPathRegisterNs (xpath_ctx,
@@ -682,15 +678,13 @@ static int cx_read (user_data_t *ud) /* {{{ */
 static int cx_config_add_values (const char *name, cx_xpath_t *xpath, /* {{{ */
                                       oconfig_item_t *ci)
 {
-  int i;
-
   if (ci->values_num < 1)
   {
     WARNING ("curl_xml plugin: `ValuesFrom' needs at least one argument.");
     return (-1);
   }
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
     if (ci->values[i].type != OCONFIG_TYPE_STRING)
     {
       WARNING ("curl_xml plugin: `ValuesFrom' needs only string argument.");
@@ -706,7 +700,7 @@ static int cx_config_add_values (const char *name, cx_xpath_t *xpath, /* {{{ */
   xpath->values_len = (size_t) ci->values_num;
 
   /* populate cx_values_t structure */
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     xpath->values[i].path_len = sizeof (ci->values[i].value.string);
     sstrncpy (xpath->values[i].path, ci->values[i].value.string, sizeof (xpath->values[i].path));
@@ -721,7 +715,6 @@ static int cx_config_add_xpath (cx_t *db, oconfig_item_t *ci) /* {{{ */
   char *name;
   llentry_t *le;
   int status;
-  int i;
 
   xpath = calloc (1, sizeof (*xpath));
   if (xpath == NULL)
@@ -747,7 +740,7 @@ static int cx_config_add_xpath (cx_t *db, oconfig_item_t *ci) /* {{{ */
   }
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -926,7 +919,6 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */
 {
   cx_t *db;
   int status = 0;
-  int i;
 
   if ((ci->values_num != 1)
       || (ci->values[0].type != OCONFIG_TYPE_STRING))
@@ -963,7 +955,7 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */
   }
 
   /* Fill the `cx_t' structure.. */
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -1024,7 +1016,6 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */
   /* If all went well, register this database for reading */
   if (status == 0)
   {
-    user_data_t ud;
     char *cb_name;
 
     if (db->instance == NULL)
@@ -1033,13 +1024,14 @@ static int cx_config_add_url (oconfig_item_t *ci) /* {{{ */
     DEBUG ("curl_xml plugin: Registering new read callback: %s",
            db->instance);
 
-    memset (&ud, 0, sizeof (ud));
-    ud.data = (void *) db;
-    ud.free_func = cx_free;
-
     cb_name = ssnprintf_alloc ("curl_xml-%s-%s", db->instance, db->url);
+
     plugin_register_complex_read (/* group = */ "curl_xml", cb_name, cx_read,
-                                  /* interval = */ 0, &ud);
+        /* interval = */ 0,
+        &(user_data_t) {
+          .data = db,
+          .free_func = cx_free,
+        });
     sfree (cb_name);
   }
   else
@@ -1058,12 +1050,11 @@ static int cx_config (oconfig_item_t *ci) /* {{{ */
   int success;
   int errors;
   int status;
-  int i;
 
   success = 0;
   errors = 0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
index 2fce643..8573579 100644 (file)
@@ -26,8 +26,8 @@
  **/
 
 #include "collectd.h"
-#include "common.h"
 
+#include "common.h"
 #include "plugin.h"
 #include "configfile.h"
 
@@ -97,9 +97,7 @@ static int init_hostname (void)
 {
        const char *str;
 
-       struct addrinfo  ai_hints;
        struct addrinfo *ai_list;
-       struct addrinfo *ai_ptr;
        int status;
 
        str = global_option_get ("Hostname");
@@ -120,8 +118,9 @@ static int init_hostname (void)
        if (IS_FALSE (str))
                return (0);
 
-       memset (&ai_hints, '\0', sizeof (ai_hints));
-       ai_hints.ai_flags = AI_CANONNAME;
+       struct addrinfo ai_hints = {
+               .ai_flags = AI_CANONNAME
+       };
 
        status = getaddrinfo (hostname_g, NULL, &ai_hints, &ai_list);
        if (status != 0)
@@ -134,7 +133,7 @@ static int init_hostname (void)
                return (-1);
        }
 
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                if (ai_ptr->ai_canonname == NULL)
                        continue;
@@ -441,7 +440,7 @@ static int notify_systemd (void)
 {
     int                  fd;
     const char          *notifysocket;
-    struct sockaddr_un   su;
+    struct sockaddr_un   su = { 0 };
     size_t               su_size;
     char                 buffer[] = "READY=1\n";
 
@@ -471,7 +470,6 @@ static int notify_systemd (void)
         return 0;
     }
 
-    memset (&su, 0, sizeof (su));
     su.sun_family = AF_UNIX;
     if (notifysocket[0] != '@')
     {
@@ -509,16 +507,11 @@ static int notify_systemd (void)
 
 int main (int argc, char **argv)
 {
-       struct sigaction sig_int_action;
-       struct sigaction sig_term_action;
-       struct sigaction sig_usr1_action;
-       struct sigaction sig_pipe_action;
        const char *configfile = CONFIGFILE;
        int test_config  = 0;
        int test_readall = 0;
        const char *basedir;
 #if COLLECT_DAEMON
-       struct sigaction sig_chld_action;
        pid_t pid;
        int daemonize    = 1;
 #endif
@@ -618,8 +611,10 @@ int main (int argc, char **argv)
        /*
         * fork off child
         */
-       memset (&sig_chld_action, '\0', sizeof (sig_chld_action));
-       sig_chld_action.sa_handler = SIG_IGN;
+       struct sigaction sig_chld_action = {
+               .sa_handler = SIG_IGN
+       };
+
        sigaction (SIGCHLD, &sig_chld_action, NULL);
 
     /*
@@ -685,15 +680,19 @@ int main (int argc, char **argv)
        } /* if (daemonize) */
 #endif /* COLLECT_DAEMON */
 
-       memset (&sig_pipe_action, '\0', sizeof (sig_pipe_action));
-       sig_pipe_action.sa_handler = SIG_IGN;
+       struct sigaction sig_pipe_action = {
+               .sa_handler = SIG_IGN
+       };
+
        sigaction (SIGPIPE, &sig_pipe_action, NULL);
 
        /*
         * install signal handlers
         */
-       memset (&sig_int_action, '\0', sizeof (sig_int_action));
-       sig_int_action.sa_handler = sig_int_handler;
+       struct sigaction sig_int_action = {
+               .sa_handler = sig_int_handler
+       };
+
        if (0 != sigaction (SIGINT, &sig_int_action, NULL)) {
                char errbuf[1024];
                ERROR ("Error: Failed to install a signal handler for signal INT: %s",
@@ -701,8 +700,10 @@ int main (int argc, char **argv)
                return (1);
        }
 
-       memset (&sig_term_action, '\0', sizeof (sig_term_action));
-       sig_term_action.sa_handler = sig_term_handler;
+       struct sigaction sig_term_action = {
+               .sa_handler = sig_term_handler
+       };
+
        if (0 != sigaction (SIGTERM, &sig_term_action, NULL)) {
                char errbuf[1024];
                ERROR ("Error: Failed to install a signal handler for signal TERM: %s",
@@ -710,8 +711,10 @@ int main (int argc, char **argv)
                return (1);
        }
 
-       memset (&sig_usr1_action, '\0', sizeof (sig_usr1_action));
-       sig_usr1_action.sa_handler = sig_usr1_handler;
+       struct sigaction sig_usr1_action = {
+               .sa_handler = sig_usr1_handler
+       };
+
        if (0 != sigaction (SIGUSR1, &sig_usr1_action, NULL)) {
                char errbuf[1024];
                ERROR ("Error: Failed to install a signal handler for signal USR1: %s",
index f9b1433..654a5a0 100644 (file)
@@ -32,6 +32,7 @@
 #endif
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_cache.h"
 # include <netinet/in.h>
 #endif
 
+#if HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
+
 /* for ntohl and htonl */
 #if HAVE_ARPA_INET_H
 # include <arpa/inet.h>
 #endif
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #ifdef HAVE_LIBKSTAT
 extern kstat_ctl_t *kc;
 #endif
@@ -325,57 +334,65 @@ int strsplit (char *string, char **fields, size_t size)
        return ((int) i);
 }
 
-int strjoin (char *buffer, size_t buffer_size,
-               char **fields, size_t fields_num,
-               const char *sep)
-{
-       size_t avail;
-       char *ptr;
-       size_t sep_len;
-       size_t i;
+int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num,
+            const char *sep) {
+  size_t avail = 0;
+  char *ptr = buffer;
+  size_t sep_len = 0;
 
-       if ((buffer_size < 1) || (fields_num == 0))
-               return (-1);
+  size_t buffer_req = 0;
 
-       memset (buffer, 0, buffer_size);
-       ptr = buffer;
-       avail = buffer_size - 1;
+  if (((fields_num != 0) && (fields == NULL)) ||
+      ((buffer_size != 0) && (buffer == NULL)))
+    return (-EINVAL);
 
-       sep_len = 0;
-       if (sep != NULL)
-               sep_len = strlen (sep);
+  if (buffer != NULL)
+    buffer[0] = 0;
 
-       for (i = 0; i < fields_num; i++)
-       {
-               size_t field_len;
+  if (buffer_size != 0)
+    avail = buffer_size - 1;
 
-               if ((i > 0) && (sep_len > 0))
-               {
-                       if (avail < sep_len)
-                               return (-1);
+  if (sep != NULL)
+    sep_len = strlen(sep);
 
-                       memcpy (ptr, sep, sep_len);
-                       ptr += sep_len;
-                       avail -= sep_len;
-               }
+  for (size_t i = 0; i < fields_num; i++) {
+    size_t field_len = strlen(fields[i]);
 
-               field_len = strlen (fields[i]);
-               if (avail < field_len)
-                       return (-1);
+    if (i != 0)
+      buffer_req += sep_len;
+    buffer_req += field_len;
 
-               memcpy (ptr, fields[i], field_len);
-               ptr += field_len;
-               avail -= field_len;
-       }
+    if ((i != 0) && (sep_len > 0)) {
+      if (sep_len >= avail) {
+        /* prevent subsequent iterations from writing to the
+         * buffer. */
+        avail = 0;
+        continue;
+      }
+
+      memcpy(ptr, sep, sep_len);
+
+      ptr += sep_len;
+      avail -= sep_len;
+    }
+
+    if (field_len > avail)
+      field_len = avail;
+
+    memcpy(ptr, fields[i], field_len);
+    ptr += field_len;
+
+    avail -= field_len;
+    if (ptr != NULL)
+      *ptr = 0;
+  }
 
-       assert (buffer[buffer_size - 1] == 0);
-       return ((int) strlen (buffer));
+  return (int)buffer_req;
 }
 
 int escape_string (char *buffer, size_t buffer_size)
 {
   char *temp;
-  size_t i;
   size_t j;
 
   /* Check if we need to escape at all first */
@@ -393,7 +410,7 @@ int escape_string (char *buffer, size_t buffer_size)
   temp[0] = '"';
   j = 1;
 
-  for (i = 0; i < buffer_size; i++)
+  for (size_t i = 0; i < buffer_size; i++)
   {
     if (buffer[i] == 0)
     {
@@ -427,9 +444,7 @@ int escape_string (char *buffer, size_t buffer_size)
 
 int strunescape (char *buf, size_t buf_len)
 {
-       size_t i;
-
-       for (i = 0; (i < buf_len) && (buf[i] != '\0'); ++i)
+       for (size_t i = 0; (i < buf_len) && (buf[i] != '\0'); ++i)
        {
                if (buf[i] != '\\')
                        continue;
@@ -483,7 +498,6 @@ size_t strstripnewline (char *buffer)
 int escape_slashes (char *buffer, size_t buffer_size)
 {
        size_t buffer_len;
-       size_t i;
 
        buffer_len = strlen (buffer);
 
@@ -505,7 +519,7 @@ int escape_slashes (char *buffer, size_t buffer_size)
                buffer_len--;
        }
 
-       for (i = 0; i < buffer_len; i++)
+       for (size_t i = 0; i < buffer_len; i++)
        {
                if (buffer[i] == '/')
                        buffer[i] = '_';
@@ -516,9 +530,7 @@ int escape_slashes (char *buffer, size_t buffer_size)
 
 void replace_special (char *buffer, size_t buffer_size)
 {
-       size_t i;
-
-       for (i = 0; i < buffer_size; i++)
+       for (size_t i = 0; i < buffer_size; i++)
        {
                if (buffer[i] == 0)
                        return;
@@ -592,7 +604,6 @@ int check_create_dir (const char *file_orig)
        int   last_is_file = 1;
        int   path_is_absolute = 0;
        size_t len;
-       int   i;
 
        /*
         * Sanity checks first
@@ -638,7 +649,7 @@ int check_create_dir (const char *file_orig)
        /*
         * For each component, do..
         */
-       for (i = 0; i < (fields_num - last_is_file); i++)
+       for (int i = 0; i < (fields_num - last_is_file); i++)
        {
                /*
                 * Do not create directories that start with a dot. This
@@ -937,7 +948,6 @@ int format_values (char *ret, size_t ret_len, /* {{{ */
 {
         size_t offset = 0;
         int status;
-        size_t i;
         gauge_t *rates = NULL;
 
         assert (0 == strcmp (ds->type, vl->type));
@@ -963,7 +973,7 @@ int format_values (char *ret, size_t ret_len, /* {{{ */
 
         BUFFER_ADD ("%.3f", CDTIME_T_TO_DOUBLE (vl->time));
 
-        for (i = 0; i < ds->ds_num; i++)
+        for (size_t i = 0; i < ds->ds_num; i++)
         {
                 if (ds->ds[i].type == DS_TYPE_GAUGE)
                         BUFFER_ADD (":"GAUGE_FORMAT, vl->values[i].gauge);
@@ -1199,6 +1209,28 @@ int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds)
        return (0);
 } /* int parse_values */
 
+int parse_value_file (char const *path, value_t *ret_value, int ds_type)
+{
+       FILE *fh;
+       char buffer[256];
+
+       fh = fopen (path, "r");
+       if (fh == NULL)
+               return (-1);
+
+       if (fgets (buffer, sizeof (buffer), fh) == NULL)
+       {
+               fclose (fh);
+               return (-1);
+       }
+
+       fclose (fh);
+
+       strstripnewline (buffer);
+
+       return parse_value (buffer, ret_value, ds_type);
+} /* int parse_value_file */
+
 #if !HAVE_GETPWNAM_R
 int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
                size_t buflen, struct passwd **pwbufp)
@@ -1517,17 +1549,15 @@ int value_to_rate (gauge_t *ret_rate, /* {{{ */
 int service_name_to_port_number (const char *service_name)
 {
        struct addrinfo *ai_list;
-       struct addrinfo *ai_ptr;
-       struct addrinfo ai_hints;
        int status;
        int service_number;
 
        if (service_name == NULL)
                return (-1);
 
-       ai_list = NULL;
-       memset (&ai_hints, 0, sizeof (ai_hints));
-       ai_hints.ai_family = AF_UNSPEC;
+       struct addrinfo ai_hints = {
+               .ai_family = AF_UNSPEC
+       };
 
        status = getaddrinfo (/* node = */ NULL, service_name,
                        &ai_hints, &ai_list);
@@ -1539,7 +1569,7 @@ int service_name_to_port_number (const char *service_name)
        }
 
        service_number = -1;
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                if (ai_ptr->ai_family == AF_INET)
                {
@@ -1567,6 +1597,46 @@ int service_name_to_port_number (const char *service_name)
        return (-1);
 } /* int service_name_to_port_number */
 
+void set_sock_opts (int sockfd) /* {{{ */
+{
+       int status;
+       int socktype;
+
+       socklen_t socklen = sizeof (socklen_t);
+       int so_keepalive = 1;
+
+       status = getsockopt (sockfd, SOL_SOCKET, SO_TYPE, &socktype, &socklen);
+       if (status != 0)
+       {
+               WARNING ("set_sock_opts: failed to determine socket type");
+               return;
+       }
+
+       if (socktype == SOCK_STREAM)
+       {
+               status = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+                               &so_keepalive, sizeof (so_keepalive));
+               if (status != 0)
+                       WARNING ("set_sock_opts: failed to set socket keepalive flag");
+
+#ifdef TCP_KEEPIDLE
+               int tcp_keepidle = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 100 + 1);
+               status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+                               &tcp_keepidle, sizeof (tcp_keepidle));
+               if (status != 0)
+                       WARNING ("set_sock_opts: failed to set socket tcp keepalive time");
+#endif
+
+#ifdef TCP_KEEPINTVL
+               int tcp_keepintvl = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 1000 + 1);
+               status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+                               &tcp_keepintvl, sizeof (tcp_keepintvl));
+               if (status != 0)
+                       WARNING ("set_sock_opts: failed to set socket tcp keepalive interval");
+#endif
+       }
+} /* }}} void set_sock_opts */
+
 int strtoderive (const char *string, derive_t *ret_value) /* {{{ */
 {
        derive_t tmp;
@@ -1630,9 +1700,56 @@ int strarray_add (char ***ret_array, size_t *ret_array_len, char const *str) /*
 
 void strarray_free (char **array, size_t array_len) /* {{{ */
 {
-       size_t i;
-
-       for (i = 0; i < array_len; i++)
+       for (size_t i = 0; i < array_len; i++)
                sfree (array[i]);
        sfree (array);
 } /* }}} void strarray_free */
+
+#ifdef HAVE_SYS_CAPABILITY_H
+int check_capability (int capability) /* {{{ */
+{
+#ifdef _LINUX_CAPABILITY_VERSION_3
+       cap_user_header_t cap_header = calloc(1, sizeof (*cap_header));
+       if (cap_header == NULL)
+       {
+               ERROR("check_capability: calloc failed");
+               return (-1);
+       }
+
+       cap_user_data_t cap_data = calloc(1, sizeof (*cap_data));
+       if (cap_data == NULL)
+       {
+               ERROR("check_capability: calloc failed");
+               sfree(cap_header);
+               return (-1);
+       }
+
+       cap_header->pid = getpid();
+       cap_header->version = _LINUX_CAPABILITY_VERSION;
+       if (capget(cap_header, cap_data) < 0)
+       {
+               ERROR("check_capability: capget failed");
+               sfree(cap_header);
+               sfree(cap_data);
+               return (-1);
+       }
+
+       if ((cap_data->effective & (1 << capability)) == 0)
+       {
+               sfree(cap_header);
+               sfree(cap_data);
+               return (-1);
+       }
+       else
+       {
+               sfree(cap_header);
+               sfree(cap_data);
+               return (0);
+       }
+#else
+       WARNING ("check_capability: unsupported capability implementation. "
+           "Some plugin(s) may require elevated privileges to work properly.");
+       return (0);
+#endif /* _LINUX_CAPABILITY_VERSION_3 */
+} /* }}} int check_capability */
+#endif /* HAVE_SYS_CAPABILITY_H */
index 6981d21..6d01ca4 100644 (file)
@@ -29,6 +29,7 @@
 #define COMMON_H
 
 #include "collectd.h"
+
 #include "plugin.h"
 
 #if HAVE_PWD_H
@@ -146,10 +147,12 @@ int strsplit (char *string, char **fields, size_t size);
  *   is equivalent to the Perl built-in `join'.
  *
  * PARAMETERS
- *   `dst'         Buffer where the result is stored.
+ *   `dst'         Buffer where the result is stored. Can be NULL if you need to
+ *                 determine the required buffer size only.
  *   `dst_len'     Length of the destination buffer. No more than this many
  *                 bytes will be written to the memory pointed to by `dst',
- *                 including the trailing null-byte.
+ *                 including the trailing null-byte. Must be zero if dst is
+ *                 NULL.
  *   `fields'      Array of strings to be joined.
  *   `fields_num'  Number of elements in the `fields' array.
  *   `sep'         String to be inserted between any two elements of `fields'.
@@ -157,9 +160,10 @@ int strsplit (char *string, char **fields, size_t size);
  *                 Instead of passing "" (empty string) one can pass NULL.
  *
  * RETURN VALUE
- *   Returns the number of characters in `dst', NOT including the trailing
- *   null-byte. If an error occurred (empty array or `dst' too small) a value
- *   smaller than zero will be returned.
+ *   Returns the number of characters in the resulting string, excluding a
+ *   tailing null byte. If this value is greater than or equal to "dst_len", the
+ *   result in "dst" is truncated (but still null terminated). On error a
+ *   negative value is returned.
  */
 int strjoin (char *dst, size_t dst_len, char **fields, size_t fields_num, const char *sep);
 
@@ -321,6 +325,11 @@ int parse_identifier_vl (const char *str, value_list_t *vl);
 int parse_value (const char *value, value_t *ret_value, int ds_type);
 int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds);
 
+/* parse_value_file reads "path" and parses its content as an integer or
+ * floating point, depending on "ds_type". On success, the value is stored in
+ * "ret_value" and zero is returned. On failure, a non-zero value is returned. */
+int parse_value_file (char const *path, value_t *ret_value, int ds_type);
+
 #if !HAVE_GETPWNAM_R
 int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
                size_t buflen, struct passwd **pwbufp);
@@ -360,6 +369,9 @@ int value_to_rate (gauge_t *ret_rate, value_t value, int ds_type, cdtime_t t,
  * (in the range [1-65535]). Returns less than zero on error. */
 int service_name_to_port_number (const char *service_name);
 
+/* Sets various, non-default, socket options */
+void set_sock_opts (int sockfd);
+
 /** Parse a string to a derive_t value. Returns zero on success or non-zero on
  * failure. If failure is returned, ret_value is not touched. */
 int strtoderive (const char *string, derive_t *ret_value);
@@ -371,4 +383,12 @@ int strtogauge (const char *string, gauge_t *ret_value);
 int strarray_add (char ***ret_array, size_t *ret_array_len, char const *str);
 void strarray_free (char **array, size_t array_len);
 
+#ifdef HAVE_SYS_CAPABILITY_H
+/** Check if the current process benefits from the capability passed in
+ * argument. Returns zero if it does, less than zero if it doesn't or on error.
+ * See capabilities(7) for the list of possible capabilities.
+ * */
+int check_capability (int capability);
+#endif /* HAVE_SYS_CAPABILITY_H */
+
 #endif /* COMMON_H */
index 68958f3..44e198d 100644 (file)
@@ -148,46 +148,54 @@ DEF_TEST(strsplit)
   return (0);
 }
 
-DEF_TEST(strjoin)
-{
-  char buffer[16];
-  char *fields[4];
-  int status;
-
-  fields[0] = "foo";
-  fields[1] = "bar";
-  fields[2] = "baz";
-  fields[3] = "qux";
-
-  status = strjoin (buffer, sizeof (buffer), fields, 2, "!");
-  OK(status == 7);
-  EXPECT_EQ_STR ("foo!bar", buffer);
-
-  status = strjoin (buffer, sizeof (buffer), fields, 1, "!");
-  OK(status == 3);
-  EXPECT_EQ_STR ("foo", buffer);
-
-  status = strjoin (buffer, sizeof (buffer), fields, 0, "!");
-  OK(status < 0);
-
-  status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht");
-  OK(status == 10);
-  EXPECT_EQ_STR ("foorchtbar", buffer);
-
-  status = strjoin (buffer, sizeof (buffer), fields, 4, "");
-  OK(status == 12);
-  EXPECT_EQ_STR ("foobarbazqux", buffer);
+DEF_TEST(strjoin) {
+  struct {
+    char **fields;
+    size_t fields_num;
+    char *separator;
+
+    int want_return;
+    char *want_buffer;
+  } cases
+      [] = {
+          /* Normal case. */
+          {(char *[]){"foo", "bar"}, 2, "!", 7, "foo!bar"},
+          /* One field only. */
+          {(char *[]){"foo"}, 1, "!", 3, "foo"},
+          /* No fields at all. */
+          {NULL, 0, "!", 0, ""},
+          /* Longer separator. */
+          {(char *[]){"foo", "bar"}, 2, "rcht", 10, "foorchtbar"},
+          /* Empty separator. */
+          {(char *[]){"foo", "bar"}, 2, "", 6, "foobar"},
+          /* NULL separator. */
+          {(char *[]){"foo", "bar"}, 2, NULL, 6, "foobar"},
+          /* buffer not large enough -> string is truncated. */
+          {(char *[]){"aaaaaa", "bbbbbb", "c!"}, 3, "-", 16, "aaaaaa-bbbbbb-c"},
+          /* buffer not large enough -> last field fills buffer completely. */
+          {(char *[]){"aaaaaaa", "bbbbbbb", "!"}, 3, "-", 17,
+           "aaaaaaa-bbbbbbb"},
+          /* buffer not large enough -> string does *not* end in separator. */
+          {(char *[]){"aaaa", "bbbb", "cccc", "!"}, 4, "-", 16,
+           "aaaa-bbbb-cccc"},
+          /* buffer not large enough -> string does not end with partial
+             separator. */
+          {(char *[]){"aaaaaa", "bbbbbb", "!"}, 3, "+-", 17, "aaaaaa+-bbbbbb"},
+      };
+
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
+    char buffer[16];
+    int status;
 
-  status = strjoin (buffer, sizeof (buffer), fields, 4, "!");
-  OK(status == 15);
-  EXPECT_EQ_STR ("foo!bar!baz!qux", buffer);
+    memset(buffer, 0xFF, sizeof(buffer));
+    status = strjoin(buffer, sizeof(buffer), cases[i].fields,
+                     cases[i].fields_num, cases[i].separator);
+    EXPECT_EQ_INT(cases[i].want_return, status);
+    EXPECT_EQ_STR(cases[i].want_buffer, buffer);
+  }
 
-  fields[0] = "0123";
-  fields[1] = "4567";
-  fields[2] = "8901";
-  fields[3] = "2345";
-  status = strjoin (buffer, sizeof (buffer), fields, 4, "-");
-  OK(status < 0);
+  /* use (NULL, 0) to determine required buffer size. */
+  EXPECT_EQ_INT(3, strjoin(NULL, 0, (char *[]){"a", "b"}, 2, "-"));
 
   return (0);
 }
@@ -203,9 +211,8 @@ DEF_TEST(escape_slashes)
     {"trailing/slash/", "trailing_slash_"},
     {"foo//bar", "foo__bar"},
   };
-  size_t i;
 
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
     char buffer[32];
 
     strncpy (buffer, cases[i].str, sizeof (buffer));
@@ -230,9 +237,8 @@ DEF_TEST(escape_string)
     {"012345 78901234", "\"012345 789012\""},
     {"012345 78901\"34", "\"012345 78901\""},
   };
-  size_t i;
 
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
     char buffer[16];
 
     strncpy (buffer, cases[i].str, sizeof (buffer));
@@ -301,8 +307,7 @@ DEF_TEST(parse_values)
     {"T:42.0",           -1,  NAN},
   };
 
-  size_t i;
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
   {
     data_source_t dsrc = {
       .name = "value",
@@ -361,9 +366,8 @@ DEF_TEST(value_to_rate)
     /* 64bit wrap-around. */
     {30, 40, DS_TYPE_COUNTER, {.counter = 18446744073709551558ULL}, {.counter =   42}, 10.0},
   };
-  size_t i;
 
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
     value_to_rate_state_t state = { cases[i].v0, TIME_T_TO_CDTIME_T (cases[i].t0) };
     gauge_t got;
 
index b9860bd..a31fb64 100644 (file)
@@ -155,7 +155,7 @@ static int cf_dispatch (const char *type, const char *orig_key,
        char *key;
        char *value;
        int ret;
-       int i;
+       int i = 0;
 
        if (orig_key == NULL)
                return (EINVAL);
@@ -231,8 +231,6 @@ static int dispatch_global_option (const oconfig_item_t *ci)
 
 static int dispatch_value_typesdb (oconfig_item_t *ci)
 {
-       int i = 0;
-
        assert (strcasecmp (ci->key, "TypesDB") == 0);
 
        cf_default_typesdb = 0;
@@ -242,7 +240,7 @@ static int dispatch_value_typesdb (oconfig_item_t *ci)
                return (-1);
        }
 
-       for (i = 0; i < ci->values_num; ++i)
+       for (int i = 0; i < ci->values_num; ++i)
        {
                if (OCONFIG_TYPE_STRING != ci->values[i].type) {
                        WARNING ("configfile: TypesDB: Skipping %i. argument which "
@@ -270,10 +268,9 @@ static int dispatch_value_plugindir (oconfig_item_t *ci)
 
 static int dispatch_loadplugin (oconfig_item_t *ci)
 {
-       int i;
        const char *name;
        unsigned int flags = 0;
-       plugin_ctx_t ctx;
+       plugin_ctx_t ctx = { 0 };
        plugin_ctx_t old_ctx;
        int ret_val;
 
@@ -289,12 +286,11 @@ static int dispatch_loadplugin (oconfig_item_t *ci)
                name = "virt";
 
        /* default to the global interval set before loading this plugin */
-       memset (&ctx, 0, sizeof (ctx));
        ctx.interval = cf_get_default_interval ();
        ctx.flush_interval = 0;
        ctx.flush_timeout = 0;
 
-       for (i = 0; i < ci->children_num; ++i)
+       for (int i = 0; i < ci->children_num; ++i)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -326,12 +322,11 @@ static int dispatch_value_plugin (const char *plugin, oconfig_item_t *ci)
        char  buffer[4096];
        char *buffer_ptr;
        int   buffer_free;
-       int i;
 
        buffer_ptr = buffer;
        buffer_free = sizeof (buffer);
 
-       for (i = 0; i < ci->values_num; i++)
+       for (int i = 0; i < ci->values_num; i++)
        {
                int status = -1;
 
@@ -360,16 +355,15 @@ static int dispatch_value_plugin (const char *plugin, oconfig_item_t *ci)
 static int dispatch_value (oconfig_item_t *ci)
 {
        int ret = 0;
-       int i;
 
-       for (i = 0; i < cf_value_map_num; i++)
+       for (int i = 0; i < cf_value_map_num; i++)
                if (strcasecmp (cf_value_map[i].key, ci->key) == 0)
                {
                        ret = cf_value_map[i].func (ci);
                        break;
                }
 
-       for (i = 0; i < cf_global_options_num; i++)
+       for (int i = 0; i < cf_global_options_num; i++)
                if (strcasecmp (cf_global_options[i].key, ci->key) == 0)
                {
                        ret = dispatch_global_option (ci);
@@ -381,11 +375,8 @@ static int dispatch_value (oconfig_item_t *ci)
 
 static int dispatch_block_plugin (oconfig_item_t *ci)
 {
-       int i;
        const char *name;
 
-       cf_complex_callback_t *cb;
-
        if (strcasecmp (ci->key, "Plugin") != 0)
                return (-1);
        if (ci->values_num < 1)
@@ -406,12 +397,11 @@ static int dispatch_block_plugin (oconfig_item_t *ci)
 
        if (IS_TRUE (global_option_get ("AutoLoadPlugin")))
        {
-               plugin_ctx_t ctx;
+               plugin_ctx_t ctx = { 0 };
                plugin_ctx_t old_ctx;
                int status;
 
                /* default to the global interval set before loading this plugin */
-               memset (&ctx, 0, sizeof (ctx));
                ctx.interval = cf_get_default_interval ();
 
                old_ctx = plugin_set_ctx (ctx);
@@ -428,7 +418,7 @@ static int dispatch_block_plugin (oconfig_item_t *ci)
        }
 
        /* Check for a complex callback first */
-       for (cb = complex_callback_head; cb != NULL; cb = cb->next)
+       for (cf_complex_callback_t *cb = complex_callback_head; cb != NULL; cb = cb->next)
        {
                if (strcasecmp (name, cb->type) == 0)
                {
@@ -443,7 +433,7 @@ static int dispatch_block_plugin (oconfig_item_t *ci)
        }
 
        /* Hm, no complex plugin found. Dispatch the values one by one */
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                if (ci->children[i].children == NULL)
                        dispatch_value_plugin (name, ci->children + i);
@@ -479,7 +469,6 @@ static int cf_ci_replace_child (oconfig_item_t *dst, oconfig_item_t *src,
                int offset)
 {
        oconfig_item_t *temp;
-       int i;
 
        assert (offset >= 0);
        assert (dst->children_num > offset);
@@ -487,7 +476,7 @@ static int cf_ci_replace_child (oconfig_item_t *dst, oconfig_item_t *src,
        /* Free the memory used by the replaced child. Usually that's the
         * `Include "blah"' statement. */
        temp = dst->children + offset;
-       for (i = 0; i < temp->values_num; i++)
+       for (int i = 0; i < temp->values_num; i++)
        {
                if (temp->values[i].type == OCONFIG_TYPE_STRING)
                {
@@ -588,17 +577,13 @@ static oconfig_item_t *cf_read_generic (const char *path,
 
 static int cf_include_all (oconfig_item_t *root, int depth)
 {
-       int i;
-
-       for (i = 0; i < root->children_num; i++)
+       for (int i = 0; i < root->children_num; i++)
        {
                oconfig_item_t *new;
                oconfig_item_t *old;
 
                char *pattern = NULL;
 
-               int j;
-
                if (strcasecmp (root->children[i].key, "Include") != 0)
                        continue;
 
@@ -611,7 +596,7 @@ static int cf_include_all (oconfig_item_t *root, int depth)
                        continue;
                }
 
-               for (j = 0; j < old->children_num; ++j)
+               for (int j = 0; j < old->children_num; ++j)
                {
                        oconfig_item_t *child = old->children + j;
 
@@ -705,7 +690,6 @@ static oconfig_item_t *cf_read_dir (const char *dir,
        char **filenames = NULL;
        int filenames_num = 0;
        int status;
-       int i;
 
        assert (depth < CF_MAX_DEPTH);
 
@@ -742,7 +726,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                                        " name is too long.",
                                        dir, de->d_name);
                        closedir (dh);
-                       for (i = 0; i < filenames_num; ++i)
+                       for (int i = 0; i < filenames_num; ++i)
                                free (filenames[i]);
                        free (filenames);
                        free (root);
@@ -755,7 +739,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
                if (tmp == NULL) {
                        ERROR ("configfile: realloc failed.");
                        closedir (dh);
-                       for (i = 0; i < filenames_num - 1; ++i)
+                       for (int i = 0; i < filenames_num - 1; ++i)
                                free (filenames[i]);
                        free (filenames);
                        free (root);
@@ -775,7 +759,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
        qsort ((void *) filenames, filenames_num, sizeof (*filenames),
                        cf_compare_string);
 
-       for (i = 0; i < filenames_num; ++i)
+       for (int i = 0; i < filenames_num; ++i)
        {
                oconfig_item_t *temp;
                char *name = filenames[i];
@@ -808,7 +792,7 @@ static oconfig_item_t *cf_read_dir (const char *dir,
  *
  * There are two versions of this function: If `wordexp' exists shell wildcards
  * will be expanded and the function will include all matches found. If
- * `wordexp' (or, more precisely, it's header file) is not available the
+ * `wordexp' (or, more precisely, its header file) is not available the
  * simpler function is used which does not do any such expansion.
  */
 #if HAVE_WORDEXP_H
@@ -819,7 +803,6 @@ static oconfig_item_t *cf_read_generic (const char *path,
        int status;
        const char *path_ptr;
        wordexp_t we;
-       size_t i;
 
        if (depth >= CF_MAX_DEPTH)
        {
@@ -847,7 +830,7 @@ static oconfig_item_t *cf_read_generic (const char *path,
        qsort ((void *) we.we_wordv, we.we_wordc, sizeof (*we.we_wordv),
                        cf_compare_string);
 
-       for (i = 0; i < we.we_wordc; i++)
+       for (size_t i = 0; i < we.we_wordc; i++)
        {
                oconfig_item_t *temp;
                struct stat statbuf;
@@ -931,7 +914,6 @@ static oconfig_item_t *cf_read_generic (const char *path,
 int global_option_set (const char *option, const char *value, _Bool from_cli)
 {
        int i;
-
        DEBUG ("option = %s; value = %s;", option, value);
 
        for (i = 0; i < cf_global_options_num; i++)
@@ -967,7 +949,6 @@ int global_option_set (const char *option, const char *value, _Bool from_cli)
 const char *global_option_get (const char *option)
 {
        int i;
-
        for (i = 0; i < cf_global_options_num; i++)
                if (strcasecmp (cf_global_options[i].key, option) == 0)
                        break;
@@ -1028,9 +1009,7 @@ cdtime_t cf_get_default_interval (void)
 
 void cf_unregister (const char *type)
 {
-       cf_callback_t *this, *prev;
-
-       for (prev = NULL, this = first_callback;
+       for (cf_callback_t *prev = NULL, *this = first_callback;
                        this != NULL;
                        prev = this, this = this->next)
                if (strcasecmp (this->type, type) == 0)
@@ -1047,9 +1026,7 @@ void cf_unregister (const char *type)
 
 void cf_unregister_complex (const char *type)
 {
-       cf_complex_callback_t *this, *prev;
-
-       for (prev = NULL, this = complex_callback_head;
+       for (cf_complex_callback_t *prev = NULL, *this = complex_callback_head;
                        this != NULL;
                        prev = this, this = this->next)
                if (strcasecmp (this->type, type) == 0)
@@ -1126,7 +1103,6 @@ int cf_register_complex (const char *type, int (*callback) (oconfig_item_t *))
 int cf_read (const char *filename)
 {
        oconfig_item_t *conf;
-       int i;
        int ret = 0;
 
        conf = cf_read_generic (filename, /* pattern = */ NULL, /* depth = */ 0);
@@ -1142,7 +1118,7 @@ int cf_read (const char *filename)
                return (-1);
        }
 
-       for (i = 0; i < conf->children_num; i++)
+       for (int i = 0; i < conf->children_num; i++)
        {
                if (conf->children[i].children == NULL)
                {
index 924d97c..a13bc09 100644 (file)
@@ -28,6 +28,7 @@
 #define CONFIGFILE_H
 
 #include "collectd.h"
+
 #include "utils_time.h"
 #include "liboconfig/oconfig.h"
 
@@ -92,7 +93,6 @@ int cf_read (const char *filename);
 int global_option_set (const char *option, const char *value, _Bool from_cli);
 const char *global_option_get (const char *option);
 long global_option_get_long (const char *option, long default_value);
-long global_option_get_long_in_range (const char *option, long default_value, long min, long max);
 
 cdtime_t global_option_get_time (char const *option, cdtime_t default_value);
 
index a622af9..cee479a 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "configfile.h"
 #include "plugin.h"
 #include "utils_complain.h"
@@ -356,7 +357,6 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */
   fc_rule_t *rule;
   char rule_name[2*DATA_MAX_NAME_LEN] = "Unnamed rule";
   int status = 0;
-  int i;
 
   if (ci->values_num > 1)
   {
@@ -385,7 +385,7 @@ static int fc_config_add_rule (fc_chain_t *chain, /* {{{ */
         ci->values[0].value.string);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -446,7 +446,6 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */
 {
   fc_chain_t *chain = NULL;
   int status = 0;
-  int i;
   int new_chain = 1;
 
   if ((ci->values_num != 1)
@@ -474,7 +473,7 @@ static int fc_config_add_chain (const oconfig_item_t *ci) /* {{{ */
     sstrncpy (chain->name, ci->values[0].value.string, sizeof (chain->name));
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -624,16 +623,13 @@ static int fc_bit_return_invoke (const data_set_t __attribute__((unused)) *ds, /
 static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
     void **user_data)
 {
-  int i;
-
   fc_writer_t *plugin_list = NULL;
   size_t plugin_list_len = 0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     fc_writer_t *temp;
-    int j;
 
     if (strcasecmp ("Plugin", child->key) != 0)
     {
@@ -643,7 +639,7 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
       continue;
     }
 
-    for (j = 0; j < child->values_num; j++)
+    for (int j = 0; j < child->values_num; j++)
     {
       char *plugin;
 
@@ -684,14 +680,13 @@ static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
 static int fc_bit_write_destroy (void **user_data) /* {{{ */
 {
   fc_writer_t *plugin_list;
-  size_t i;
 
   if ((user_data == NULL) || (*user_data == NULL))
     return (0);
 
   plugin_list = *user_data;
 
-  for (i = 0; plugin_list[i].plugin != NULL; i++)
+  for (size_t i = 0; plugin_list[i].plugin != NULL; i++)
     free (plugin_list[i].plugin);
   free (plugin_list);
 
@@ -744,9 +739,7 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */
   }
   else
   {
-    size_t i;
-
-    for (i = 0; plugin_list[i].plugin != NULL; i++)
+    for (size_t i = 0; plugin_list[i].plugin != NULL; i++)
     {
       status = plugin_write (plugin_list[i].plugin, ds, vl);
       if (status != 0)
@@ -773,12 +766,11 @@ static int fc_bit_write_invoke (const data_set_t *ds, /* {{{ */
 static int fc_init_once (void) /* {{{ */
 {
   static int done = 0;
-  target_proc_t tproc;
+  target_proc_t tproc = { 0 };
 
   if (done != 0)
     return (0);
 
-  memset (&tproc, 0, sizeof (tproc));
   tproc.create  = fc_bit_jump_create;
   tproc.destroy = fc_bit_jump_destroy;
   tproc.invoke  = fc_bit_jump_invoke;
@@ -875,12 +867,10 @@ int fc_register_target (const char *name, target_proc_t proc) /* {{{ */
 
 fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */
 {
-  fc_chain_t *chain;
-
   if (chain_name == NULL)
     return (NULL);
 
-  for (chain = chain_list_head; chain != NULL; chain = chain->next)
+  for (fc_chain_t *chain = chain_list_head; chain != NULL; chain = chain->next)
     if (strcasecmp (chain_name, chain->name) == 0)
       return (chain);
 
@@ -890,7 +880,6 @@ fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */
 int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
     fc_chain_t *chain)
 {
-  fc_rule_t *rule;
   fc_target_t *target;
   int status = FC_TARGET_CONTINUE;
 
@@ -899,7 +888,7 @@ int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
   DEBUG ("fc_process_chain (chain = %s);", chain->name);
 
-  for (rule = chain->rules; rule != NULL; rule = rule->next)
+  for (fc_rule_t *rule = chain->rules; rule != NULL; rule = rule->next)
   {
     fc_match_t *match;
     status = FC_TARGET_CONTINUE;
index dbf4b83..2d280f8 100644 (file)
@@ -28,6 +28,7 @@
 #define FILTER_CHAIN_H 1
 
 #include "collectd.h"
+
 #include "plugin.h"
 
 #define FC_MATCH_NO_MATCH  0
index f4a340c..a11fccb 100644 (file)
  **/
 
 #include "collectd.h"
+
+#include "common.h"
 #include "plugin.h"
 #include "meta_data.h"
 
+#define MD_MAX_NONSTRING_CHARS 128
+
 /*
  * Data types
  */
@@ -332,8 +336,6 @@ meta_data_t *meta_data_clone (meta_data_t *orig) /* {{{ */
 
 int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig) /* {{{ */
 {
-  meta_entry_t *e;
-
   if (orig == NULL)
     return (0);
 
@@ -343,7 +345,7 @@ int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig) /* {{{ */
   }
 
   pthread_mutex_lock (&orig->lock);
-  for (e=orig->head; e != NULL; e = e->next)
+  for (meta_entry_t *e=orig->head; e != NULL; e = e->next)
   {
     md_entry_insert_clone((*dest), e);
   }
@@ -364,14 +366,12 @@ void meta_data_destroy (meta_data_t *md) /* {{{ */
 
 int meta_data_exists (meta_data_t *md, const char *key) /* {{{ */
 {
-  meta_entry_t *e;
-
   if ((md == NULL) || (key == NULL))
     return (-EINVAL);
 
   pthread_mutex_lock (&md->lock);
 
-  for (e = md->head; e != NULL; e = e->next)
+  for (meta_entry_t *e = md->head; e != NULL; e = e->next)
   {
     if (strcasecmp (key, e->key) == 0)
     {
@@ -386,14 +386,12 @@ int meta_data_exists (meta_data_t *md, const char *key) /* {{{ */
 
 int meta_data_type (meta_data_t *md, const char *key) /* {{{ */
 {
-  meta_entry_t *e;
-
   if ((md == NULL) || (key == NULL))
     return -EINVAL;
 
   pthread_mutex_lock (&md->lock);
 
-  for (e = md->head; e != NULL; e = e->next)
+  for (meta_entry_t *e = md->head; e != NULL; e = e->next)
   {
     if (strcasecmp (key, e->key) == 0)
     {
@@ -409,14 +407,13 @@ int meta_data_type (meta_data_t *md, const char *key) /* {{{ */
 int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */
 {
   int i = 0, count = 0;
-  meta_entry_t *e;
 
   if ((md == NULL) || (toc == NULL))
     return -EINVAL;
 
   pthread_mutex_lock (&md->lock);
 
-  for (e = md->head; e != NULL; e = e->next)
+  for (meta_entry_t *e = md->head; e != NULL; e = e->next)
     ++count;
 
   if (count == 0)
@@ -426,7 +423,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)
+  for (meta_entry_t *e = md->head; e != NULL; e = e->next)
     (*toc)[i++] = strdup(e->key);
 
   pthread_mutex_unlock (&md->lock);
@@ -735,4 +732,68 @@ int meta_data_get_boolean (meta_data_t *md, /* {{{ */
   return (0);
 } /* }}} int meta_data_get_boolean */
 
+int meta_data_as_string (meta_data_t *md, /* {{{ */
+    const char *key, char **value)
+{
+  meta_entry_t *e;
+  char *actual;
+  char buffer[MD_MAX_NONSTRING_CHARS];  /* For non-string types. */
+  char *temp;
+  int type;
+
+  if ((md == NULL) || (key == NULL) || (value == NULL))
+    return (-EINVAL);
+
+  pthread_mutex_lock (&md->lock);
+
+  e = md_entry_lookup (md, key);
+  if (e == NULL)
+  {
+    pthread_mutex_unlock (&md->lock);
+    return (-ENOENT);
+  }
+
+  type = e->type;
+
+  switch (type)
+  {
+    case MD_TYPE_STRING:
+      actual = e->value.mv_string;
+      break;
+    case MD_TYPE_SIGNED_INT:
+      ssnprintf (buffer, sizeof (buffer), "%"PRIi64, e->value.mv_signed_int);
+      actual = buffer;
+      break;
+    case MD_TYPE_UNSIGNED_INT:
+      ssnprintf (buffer, sizeof (buffer), "%"PRIu64, e->value.mv_unsigned_int);
+      actual = buffer;
+      break;
+    case MD_TYPE_DOUBLE:
+      ssnprintf (buffer, sizeof (buffer), GAUGE_FORMAT, e->value.mv_double);
+      actual = buffer;
+      break;
+    case MD_TYPE_BOOLEAN:
+      actual = e->value.mv_boolean ? "true" : "false";
+      break;
+    default:
+      pthread_mutex_unlock (&md->lock);
+      ERROR ("meta_data_as_string: unknown type %d for key `%s'", type, key);
+      return (-ENOENT);
+  }
+
+  pthread_mutex_unlock (&md->lock);
+
+  temp = md_strdup (actual);
+  if (temp == NULL)
+  {
+    pthread_mutex_unlock (&md->lock);
+    ERROR ("meta_data_as_string: md_strdup failed for key `%s'.", key);
+    return (-ENOMEM);
+  }
+
+  *value = temp;
+
+  return (0);
+} /* }}} int meta_data_as_string */
+
 /* vim: set sw=2 sts=2 et fdm=marker : */
index 9e448e5..f4a4f21 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "collectd.h"
 
+
 /*
  * Defines
  */
@@ -83,5 +84,10 @@ int meta_data_get_boolean (meta_data_t *md,
     const char *key,
     _Bool *value);
 
+/* Returns the value as a string, regardless of the type. */
+int meta_data_as_string (meta_data_t *md,
+    const char *key,
+    char **value);
+
 #endif /* META_DATA_H */
 /* vim: set sw=2 sts=2 et : */
index 48760d6..35cfe71 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "common.h" /* for STATIC_ARRAY_SIZE */
 #include "collectd.h"
+
 #include "testing.h"
 #include "meta_data.h"
 
index 9258b88..d4b962f 100644 (file)
@@ -26,6 +26,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "configfile.h"
@@ -150,34 +151,28 @@ static const char *plugin_get_dir (void)
 }
 
 static void plugin_update_internal_statistics (void) { /* {{{ */
-       derive_t copy_write_queue_length;
-       value_list_t vl = VALUE_LIST_INIT;
-       value_t values[2];
 
-       copy_write_queue_length = write_queue_length;
+       gauge_t copy_write_queue_length = (gauge_t) write_queue_length;
 
        /* Initialize `vl' */
-       vl.values = values;
-       vl.values_len = 2;
-       vl.time = 0;
+       value_list_t vl = VALUE_LIST_INIT;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "collectd", sizeof (vl.plugin));
 
-       vl.type_instance[0] = 0;
-       vl.values_len = 1;
-
        /* Write queue */
        sstrncpy (vl.plugin_instance, "write_queue",
                        sizeof (vl.plugin_instance));
 
        /* Write queue : queue length */
-       vl.values[0].gauge = (gauge_t) copy_write_queue_length;
+       vl.values = &(value_t) { .gauge = copy_write_queue_length };
+       vl.values_len = 1;
        sstrncpy (vl.type, "queue_length", sizeof (vl.type));
        vl.type_instance[0] = 0;
        plugin_dispatch_values (&vl);
 
        /* Write queue : Values dropped (queue length > low limit) */
-       vl.values[0].derive = (derive_t) stats_values_dropped;
+       vl.values = &(value_t) { .gauge = (gauge_t) stats_values_dropped };
+       vl.values_len = 1;
        sstrncpy (vl.type, "derive", sizeof (vl.type));
        sstrncpy (vl.type_instance, "dropped", sizeof (vl.type_instance));
        plugin_dispatch_values (&vl);
@@ -187,7 +182,8 @@ static void plugin_update_internal_statistics (void) { /* {{{ */
                        sizeof (vl.plugin_instance));
 
        /* Cache : Nb entry in cache tree */
-       vl.values[0].gauge = (gauge_t) uc_get_size();
+       vl.values = &(value_t) { .gauge = (gauge_t) uc_get_size() };
+       vl.values_len = 1;
        sstrncpy (vl.type, "cache_size", sizeof (vl.type));
        vl.type_instance[0] = 0;
        plugin_dispatch_values (&vl);
@@ -318,8 +314,8 @@ static void log_list_callbacks (llist_t **list, /* {{{ */
 {
        char *str;
        int len;
-       llentry_t *le;
        int i;
+       llentry_t *le;
        int n;
        char **keys;
 
@@ -654,8 +650,6 @@ static void *plugin_read_thread (void __attribute__((unused)) *args)
 
 static void start_read_threads (int num)
 {
-       int i;
-
        if (read_threads != NULL)
                return;
 
@@ -667,7 +661,7 @@ static void start_read_threads (int num)
        }
 
        read_threads_num = 0;
-       for (i = 0; i < num; i++)
+       for (int i = 0; i < num; i++)
        {
                if (pthread_create (read_threads + read_threads_num, NULL,
                                        plugin_read_thread, NULL) == 0)
@@ -684,8 +678,6 @@ static void start_read_threads (int num)
 
 static void stop_read_threads (void)
 {
-       int i;
-
        if (read_threads == NULL)
                return;
 
@@ -697,7 +689,7 @@ static void stop_read_threads (void)
        pthread_cond_broadcast (&read_cond);
        pthread_mutex_unlock (&read_lock);
 
-       for (i = 0; i < read_threads_num; i++)
+       for (int i = 0; i < read_threads_num; i++)
        {
                if (pthread_join (read_threads[i], NULL) != 0)
                {
@@ -869,8 +861,6 @@ static void *plugin_write_thread (void __attribute__((unused)) *args) /* {{{ */
 
 static void start_write_threads (size_t num) /* {{{ */
 {
-       size_t i;
-
        if (write_threads != NULL)
                return;
 
@@ -882,7 +872,7 @@ static void start_write_threads (size_t num) /* {{{ */
        }
 
        write_threads_num = 0;
-       for (i = 0; i < num; i++)
+       for (size_t i = 0; i < num; i++)
        {
                int status;
 
@@ -1459,7 +1449,6 @@ static void plugin_free_data_sets (void)
 int plugin_register_data_set (const data_set_t *ds)
 {
        data_set_t *ds_copy;
-       size_t i;
 
        if ((data_sets != NULL)
                        && (c_avl_get (data_sets, ds->type, NULL) == 0))
@@ -1487,7 +1476,7 @@ int plugin_register_data_set (const data_set_t *ds)
                return (-1);
        }
 
-       for (i = 0; i < ds->ds_num; i++)
+       for (size_t i = 0; i < ds->ds_num; i++)
                memcpy (ds_copy->ds + i, ds->ds + i, sizeof (data_source_t));
 
        return (c_avl_insert (data_sets, (void *) ds_copy->type, (void *) ds_copy));
@@ -1980,10 +1969,10 @@ int plugin_shutdown_all (void)
        llentry_t *le;
        int ret = 0;  // Assume success.
 
-       stop_read_threads ();
-
        destroy_all_callbacks (&list_init);
 
+       stop_read_threads ();
+
        pthread_mutex_lock (&read_lock);
        llist_destroy (read_list);
        read_list = NULL;
@@ -1991,6 +1980,10 @@ int plugin_shutdown_all (void)
 
        destroy_read_heap ();
 
+       /* blocks until all write threads have shut down. */
+       stop_write_threads ();
+
+       /* ask all plugins to write out the state they kept. */
        plugin_flush (/* plugin = */ NULL,
                        /* timeout = */ 0,
                        /* identifier = */ NULL);
@@ -2021,8 +2014,6 @@ int plugin_shutdown_all (void)
                plugin_set_ctx (old_ctx);
        }
 
-       stop_write_threads ();
-
        /* Write plugins which use the `user_data' pointer usually need the
         * same data available to the flush callback. If this is the case, set
         * the free_function to NULL when registering the flush callback and to
@@ -2405,7 +2396,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 *= sum ? (100.0 / sum) : 0;
+                               vl->values[0].gauge *= sum ? (100.0 / sum) : NAN;
                        break;
                case DS_TYPE_ABSOLUTE:
                        vl->values[0].absolute = va_arg (ap, absolute_t);
@@ -2685,14 +2676,12 @@ int plugin_notification_meta_add_boolean (notification_t *n,
 int plugin_notification_meta_copy (notification_t *dst,
     const notification_t *src)
 {
-  notification_meta_t *meta;
-
   assert (dst != NULL);
   assert (src != NULL);
   assert (dst != src);
   assert ((src->meta == NULL) || (src->meta != dst->meta));
 
-  for (meta = src->meta; meta != NULL; meta = meta->next)
+  for (notification_meta_t *meta = src->meta; meta != NULL; meta = meta->next)
   {
     if (meta->type == NM_TYPE_STRING)
       plugin_notification_meta_add_string (dst, meta->name,
index 75498c8..de42c06 100644 (file)
@@ -29,6 +29,7 @@
 #define PLUGIN_H
 
 #include "collectd.h"
+
 #include "configfile.h"
 #include "meta_data.h"
 #include "utils_time.h"
@@ -38,7 +39,7 @@
 #define PLUGIN_FLAGS_GLOBAL 0x0001
 
 #ifndef DATA_MAX_NAME_LEN
-# define DATA_MAX_NAME_LEN 64
+# define DATA_MAX_NAME_LEN 128
 #endif
 
 #define DS_TYPE_COUNTER  0
@@ -200,7 +201,6 @@ typedef void (*plugin_log_cb) (int severity, const char *message,
 typedef int (*plugin_shutdown_cb) (void);
 typedef int (*plugin_notification_cb) (const notification_t *,
                user_data_t *);
-
 /*
  * NAME
  *  plugin_set_dir
index de6fce3..34c222c 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 
 #include "plugin.h"
@@ -102,7 +103,6 @@ static void parse_line (char *buf)
   char  *fields[64];
   size_t fields_num;
   data_set_t *ds;
-  size_t i;
 
   fields_num = strsplit (buf, fields, 64);
   if (fields_num < 2)
@@ -126,7 +126,7 @@ static void parse_line (char *buf)
     return;
   }
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
     if (parse_ds (ds->ds + i, fields[i + 1], strlen (fields[i + 1])) != 0)
     {
       ERROR ("types_list: parse_line: Cannot parse data source #%zu "
index 1e0f271..43e94cf 100644 (file)
@@ -42,7 +42,7 @@ typedef struct c_avl_iterator_s c_avl_iterator_t;
  *
  * PARAMETERS
  *   `compare'  The function-pointer `compare' is used to compare two keys. It
- *              has to return less than zero if it's first argument is smaller
+ *              has to return less than zero if its first argument is smaller
  *              then the second argument, more than zero if the first argument
  *              is bigger than the second argument and zero if they are equal.
  *              If your keys are char-pointers, you can use the `strcmp'
@@ -131,7 +131,7 @@ int c_avl_get (c_avl_tree_t *t, const void *key, void **value);
  *   c_avl_pick
  *
  * DESCRIPTION
- *   Remove a (pseudo-)random element from the tree and return it's `key' and
+ *   Remove a (pseudo-)random element from the tree and return its `key' and
  *   `value'. Entries are not returned in any particular order. This function
  *   is intended for cache-flushes that don't care about the order but simply
  *   want to remove all elements, one at a time.
index 489d60f..150dd1b 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "common.h" /* STATIC_ARRAY_SIZE */
 #include "collectd.h"
+
 #include "testing.h"
 #include "utils_avltree.h"
 
@@ -70,13 +71,12 @@ DEF_TEST(success)
   };
 
   c_avl_tree_t *t;
-  size_t i;
 
   RESET_COUNTS ();
   CHECK_NOT_NULL (t = c_avl_create (compare_callback));
 
   /* insert */
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
   {
     char *key;
     char *value;
@@ -89,11 +89,11 @@ DEF_TEST(success)
   }
 
   /* Key already exists. */
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+  for (size_t 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++)
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
   {
     char *value_ret = NULL;
 
@@ -102,7 +102,7 @@ DEF_TEST(success)
   }
 
   /* remove half */
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
   {
     char *key = NULL;
     char *value = NULL;
@@ -121,7 +121,7 @@ DEF_TEST(success)
   }
 
   /* pick the other half */
-  for (i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
+  for (size_t i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
   {
     char *key = NULL;
     char *value = NULL;
index fa592f0..7c1fa41 100644 (file)
@@ -27,6 +27,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_avltree.h"
@@ -135,9 +136,7 @@ static void cache_free (cache_entry_t *ce)
 
 static void uc_check_range (const data_set_t *ds, cache_entry_t *ce)
 {
-  size_t i;
-
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     if (isnan (ce->values_gauge[i]))
       continue;
@@ -153,7 +152,6 @@ static int uc_insert (const data_set_t *ds, const value_list_t *vl,
 {
   char *key_copy;
   cache_entry_t *ce;
-  size_t i;
 
   /* `cache_lock' has been locked by `uc_update' */
 
@@ -174,7 +172,7 @@ static int uc_insert (const data_set_t *ds, const value_list_t *vl,
 
   sstrncpy (ce->name, key, sizeof (ce->name));
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     switch (ds->ds[i].type)
     {
@@ -253,7 +251,6 @@ int uc_check_timeout (void)
   c_avl_iterator_t *iter;
 
   int status;
-  int i;
 
   pthread_mutex_lock (&cache_lock);
 
@@ -325,7 +322,7 @@ int uc_check_timeout (void)
    * including plugin specific meta data, rates, history, …. This must be done
    * without holding the lock, otherwise we will run into a deadlock if a
    * plugin calls the cache interface. */
-  for (i = 0; i < keys_len; i++)
+  for (int i = 0; i < keys_len; i++)
   {
     value_list_t vl = VALUE_LIST_INIT;
 
@@ -350,7 +347,7 @@ int uc_check_timeout (void)
    * the timestamp again, so in theory it is possible we remove a value after
    * it is updated here. */
   pthread_mutex_lock (&cache_lock);
-  for (i = 0; i < keys_len; i++)
+  for (int i = 0; i < keys_len; i++)
   {
     key = NULL;
     ce = NULL;
@@ -382,7 +379,6 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   char name[6 * DATA_MAX_NAME_LEN];
   cache_entry_t *ce = NULL;
   int status;
-  size_t i;
 
   if (FORMAT_VL (name, sizeof (name), vl) != 0)
   {
@@ -414,7 +410,7 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
     return (-1);
   }
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     switch (ds->ds[i].type)
     {
@@ -463,7 +459,7 @@ int uc_update (const data_set_t *ds, const value_list_t *vl)
   if (ce->history != NULL)
   {
     assert (ce->history_index < ce->history_length);
-    for (i = 0; i < ce->values_num; i++)
+    for (size_t i = 0; i < ce->values_num; i++)
     {
       size_t hist_idx = (ce->values_num * ce->history_index) + i;
       ce->history[hist_idx] = ce->values_gauge[i];
@@ -643,9 +639,7 @@ int uc_get_names (char ***ret_names, cdtime_t **ret_times, size_t *ret_number)
 
   if (status != 0)
   {
-    size_t i;
-
-    for (i = 0; i < number; i++)
+    for (size_t i = 0; i < number; i++)
     {
       sfree (names[i]);
     }
@@ -720,7 +714,6 @@ int uc_get_history_by_name (const char *name,
     gauge_t *ret_history, size_t num_steps, size_t num_ds)
 {
   cache_entry_t *ce = NULL;
-  size_t i;
   int status = 0;
 
   pthread_mutex_lock (&cache_lock);
@@ -752,7 +745,7 @@ int uc_get_history_by_name (const char *name,
       return (-ENOMEM);
     }
 
-    for (i = ce->history_length * ce->values_num;
+    for (size_t i = ce->history_length * ce->values_num;
        i < (num_steps * ce->values_num);
        i++)
       tmp[i] = NAN;
@@ -762,7 +755,7 @@ int uc_get_history_by_name (const char *name,
   } /* if (ce->history_length < num_steps) */
 
   /* Copy the values to the output buffer. */
-  for (i = 0; i < num_steps; i++)
+  for (size_t i = 0; i < num_steps; i++)
   {
     size_t src_index;
     size_t dst_index;
@@ -947,8 +940,6 @@ int uc_iterator_get_time (uc_iter_t *iter, cdtime_t *ret_time)
 
 int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_num)
 {
-  size_t i;
-
   if ((iter == NULL) || (iter->entry == NULL)
       || (ret_values == NULL) || (ret_num == NULL))
     return (-1);
@@ -956,7 +947,7 @@ int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_n
   *ret_values = calloc (iter->entry->values_num, sizeof(*iter->entry->values_raw));
   if (*ret_values == NULL)
     return (-1);
-  for (i = 0; i < iter->entry->values_num; ++i)
+  for (size_t i = 0; i < iter->entry->values_num; ++i)
     *ret_values[i] = iter->entry->values_raw[i];
 
   *ret_num = iter->entry->values_num;
index 1cf6c3a..69909bb 100644 (file)
  **/
 
 #include "collectd.h"
+
 #include "utils_complain.h"
 #include "plugin.h"
 
 /* vcomplain returns 0 if it did not report, 1 else */
+__attribute__ ((format (printf, 3, 0)))
 static int vcomplain (int level, c_complain_t *c,
                const char *format, va_list ap)
 {
index 6d71c43..243554c 100644 (file)
@@ -39,7 +39,7 @@ typedef struct c_heap_s c_heap_t;
  *
  * PARAMETERS
  *   `compare'  The function-pointer `compare' is used to compare two keys. It
- *              has to return less than zero if it's first argument is smaller
+ *              has to return less than zero if its first argument is smaller
  *              then the second argument, more than zero if the first argument
  *              is bigger than the second argument and zero if they are equal.
  *              If your keys are char-pointers, you can use the `strcmp'
index 6ef8047..54a9613 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "collectd.h"
+
 #include "testing.h"
 #include "utils_heap.h"
 
@@ -44,14 +45,13 @@ static int compare (void const *v0, void const *v1)
 DEF_TEST(simple)
 {
   int values[] = { 9, 5, 6, 1, 3, 4, 0, 8, 2, 7 };
-  int i;
   c_heap_t *h;
 
   CHECK_NOT_NULL(h = c_heap_create (compare));
-  for (i = 0; i < 10; i++)
+  for (int i = 0; i < 10; i++)
     CHECK_ZERO(c_heap_insert (h, &values[i]));
 
-  for (i = 0; i < 5; i++)
+  for (int i = 0; i < 5; i++)
   {
     int *ret = NULL;
     CHECK_NOT_NULL(ret = c_heap_get_root(h));
@@ -64,7 +64,7 @@ DEF_TEST(simple)
   CHECK_ZERO(c_heap_insert (h, &values[4] /* = 3 */));
   CHECK_ZERO(c_heap_insert (h, &values[5] /* = 4 */));
 
-  for (i = 0; i < 10; i++)
+  for (int i = 0; i < 10; i++)
   {
     int *ret = NULL;
     CHECK_NOT_NULL(ret = c_heap_get_root(h));
index 311cb07..ff73ad7 100644 (file)
@@ -304,8 +304,6 @@ int ignorelist_add (ignorelist_t *il, const char *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);
@@ -314,7 +312,7 @@ int ignorelist_match (ignorelist_t *il, const char *entry)
                return (0);
 
        /* traverse list and check entries */
-       for (traverse = il->head; traverse != NULL; traverse = traverse->next)
+       for (ignorelist_item_t *traverse = il->head; traverse != NULL; traverse = traverse->next)
        {
 #if HAVE_REGEX_H
                if (traverse->rmatch != NULL)
index cf87b6b..914b6e2 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -169,7 +170,7 @@ static int default_callback (const char __attribute__((unused)) *str,
 
     if (data->ds_type & UTILS_MATCH_CF_DERIVE_INC)
     {
-      data->value.counter++;
+      data->value.derive++;
       data->values_num++;
       return (0);
     }
@@ -321,9 +322,8 @@ int match_apply (cu_match_t *obj, const char *str)
 {
   int status;
   regmatch_t re_match[32];
-  char *matches[32];
+  char *matches[32] = { 0 };
   size_t matches_num;
-  size_t i;
 
   if ((obj == NULL) || (str == NULL))
     return (-1);
@@ -347,7 +347,6 @@ int match_apply (cu_match_t *obj, const char *str)
   if (status != 0)
     return (0);
 
-  memset (matches, '\0', sizeof (matches));
   for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE (matches); matches_num++)
   {
     if ((re_match[matches_num].rm_so < 0)
@@ -376,7 +375,7 @@ int match_apply (cu_match_t *obj, const char *str)
     }
   }
 
-  for (i = 0; i < matches_num; i++)
+  for (size_t i = 0; i < matches_num; i++)
   {
     sfree (matches[i]);
   }
index fee0871..0488f91 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "utils_time.h"
 #include "utils_random.h"
 
index 9284f73..1bc28f7 100644 (file)
@@ -29,6 +29,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_subst.h"
 
index 953ccc4..c6caba2 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "common.h" /* for STATIC_ARRAY_SIZE */
 #include "collectd.h"
+
 #include "testing.h"
 #include "utils_subst.h"
 
@@ -75,9 +76,8 @@ DEF_TEST(subst)
     {"foo bar",  4,  3, "_",  NULL}, /* off1 > off2 */
     {"foo bar",  3,  4, NULL, NULL}, /* no replacement */
   };
-  size_t i;
 
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
     char buffer[16] = "!!!!!!!!!!!!!!!";
 
     if (cases[i].want == NULL) {
@@ -108,9 +108,8 @@ DEF_TEST(subst_string)
     {"foo bar",          "oo",      "oo",    "foo bar"},
     {"sixteen chars",    "chars",   "characters", "sixteen charact"},
   };
-  size_t i;
 
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
     char buffer[16];
 
     if (cases[i].want == NULL) {
index 0b0a8fb..0d8ed7c 100644 (file)
@@ -31,6 +31,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_tail.h"
 
@@ -45,10 +46,9 @@ static int cu_tail_reopen (cu_tail_t *obj)
 {
   int seek_end = 0;
   FILE *fh;
-  struct stat stat_buf;
+  struct stat stat_buf = { 0 };
   int status;
 
-  memset (&stat_buf, 0, sizeof (stat_buf));
   status = stat (obj->file, &stat_buf);
   if (status != 0)
   {
index 1aeb814..ffcaa90 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_match.h"
@@ -111,9 +112,8 @@ static int tail_callback (void *data, char *buf,
     int __attribute__((unused)) buflen)
 {
   cu_tail_match_t *obj = (cu_tail_match_t *) data;
-  size_t i;
 
-  for (i = 0; i < obj->matches_num; i++)
+  for (size_t i = 0; i < obj->matches_num; i++)
     match_apply (obj->matches[i].match, buf);
 
   return (0);
@@ -142,8 +142,6 @@ cu_tail_match_t *tail_match_create (const char *filename)
 
 void tail_match_destroy (cu_tail_match_t *obj)
 {
-  size_t i;
-
   if (obj == NULL)
     return;
 
@@ -153,7 +151,7 @@ void tail_match_destroy (cu_tail_match_t *obj)
     obj->tail = NULL;
   }
 
-  for (i = 0; i < obj->matches_num; i++)
+  for (size_t i = 0; i < obj->matches_num; i++)
   {
     cu_tail_match_match_t *match = obj->matches + i;
     if (match->match != NULL)
@@ -246,7 +244,6 @@ int tail_match_read (cu_tail_match_t *obj)
 {
   char buffer[4096];
   int status;
-  size_t i;
 
   status = cu_tail_read (obj->tail, buffer, sizeof (buffer), tail_callback,
       (void *) obj);
@@ -256,7 +253,7 @@ int tail_match_read (cu_tail_match_t *obj)
     return (status);
   }
 
-  for (i = 0; i < obj->matches_num; i++)
+  for (size_t i = 0; i < obj->matches_num; i++)
   {
     cu_tail_match_match_t *lt_match = obj->matches + i;
 
index cb1ea34..784e109 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_avltree.h"
 #include "utils_threshold.h"
index 56c250c..a3a9c33 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "utils_time.h"
 #include "plugin.h"
 #include "common.h"
@@ -53,10 +54,10 @@ cdtime_t cdtime (void) /* {{{ */
     char errbuf[1024];
     ERROR ("cdtime: clock_gettime failed: %s",
         sstrerror (errno, errbuf, sizeof (errbuf)));
-    return (0);
+    return 0;
   }
 
-  return (TIMESPEC_TO_CDTIME_T (&ts));
+  return TIMESPEC_TO_CDTIME_T (&ts);
 } /* }}} cdtime_t cdtime */
 # else /* !HAVE_CLOCK_GETTIME */
 /* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */
@@ -71,14 +72,64 @@ cdtime_t cdtime (void) /* {{{ */
     char errbuf[1024];
     ERROR ("cdtime: gettimeofday failed: %s",
         sstrerror (errno, errbuf, sizeof (errbuf)));
-    return (0);
+    return 0;
   }
 
-  return (TIMEVAL_TO_CDTIME_T (&tv));
+  return TIMEVAL_TO_CDTIME_T (&tv);
 } /* }}} cdtime_t cdtime */
 # endif
 #endif
 
+/**********************************************************************
+ Time retrieval functions
+***********************************************************************/
+
+static int get_utc_time (cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */
+{
+  struct timespec t_spec;
+  int status;
+
+  CDTIME_T_TO_TIMESPEC (t, &t_spec);
+  NORMALIZE_TIMESPEC (t_spec);
+
+  if (gmtime_r (&t_spec.tv_sec, t_tm) == NULL) {
+    char errbuf[1024];
+    status = errno;
+    ERROR ("get_utc_time: gmtime_r failed: %s",
+        sstrerror (status, errbuf, sizeof (errbuf)));
+    return status;
+  }
+
+  *nsec = t_spec.tv_nsec;
+  return 0;
+} /* }}} int get_utc_time */
+
+static int get_local_time (cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */
+{
+  struct timespec t_spec;
+  int status;
+
+  CDTIME_T_TO_TIMESPEC (t, &t_spec);
+  NORMALIZE_TIMESPEC (t_spec);
+
+  if (localtime_r (&t_spec.tv_sec, t_tm) == NULL) {
+    char errbuf[1024];
+    status = errno;
+    ERROR ("get_local_time: localtime_r failed: %s",
+        sstrerror (status, errbuf, sizeof (errbuf)));
+    return status;
+  }
+
+  *nsec = t_spec.tv_nsec;
+  return 0;
+} /* }}} int get_local_time */
+
+/**********************************************************************
+ Formatting functions
+***********************************************************************/
+
+static const char zulu_zone[] = "Z";
+
 /* 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. */
@@ -111,60 +162,90 @@ static int format_zone (char *buffer, size_t buffer_size, struct tm const *tm) /
   return 0;
 } /* }}} int format_zone */
 
-static int format_rfc3339 (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */
+int format_rfc3339 (char *buffer, size_t buffer_size, struct tm const *t_tm, long nsec, _Bool print_nano, char const *zone) /* {{{ */
+{
+  int len;
+  char *pos = buffer;
+  size_t size_left = buffer_size;
+
+  if ((len = strftime (pos, size_left, "%Y-%m-%dT%H:%M:%S", t_tm)) == 0)
+    return ENOMEM;
+  pos += len;
+  size_left -= len;
+
+  if (print_nano) {
+    if ((len = ssnprintf (pos, size_left, ".%09ld", nsec)) == 0)
+      return ENOMEM;
+    pos += len;
+    size_left -= len;
+  }
+
+  sstrncpy (pos, zone, size_left);
+  return 0;
+} /* }}} int format_rfc3339 */
+
+int format_rfc3339_utc (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;
+  long nsec = 0;
   int status;
 
-  CDTIME_T_TO_TIMESPEC (t, &t_spec);
-  NORMALIZE_TIMESPEC (t_spec);
+  if ((status = get_utc_time (t, &t_tm, &nsec)) != 0)
+    return status;  /* The error should have already be reported. */
 
-  if (localtime_r (&t_spec.tv_sec, &t_tm) == NULL) {
-    char errbuf[1024];
-    status = errno;
-    ERROR ("format_rfc3339: localtime_r failed: %s",
-        sstrerror (status, errbuf, sizeof (errbuf)));
-    return (status);
-  }
+  return format_rfc3339 (buffer, buffer_size, &t_tm, nsec, print_nano, zulu_zone);
+} /* }}} int format_rfc3339_utc */
 
-  len = strftime (base, sizeof (base), "%Y-%m-%dT%H:%M:%S", &t_tm);
-  if (len == 0)
-    return ENOMEM;
+int format_rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */
+{
+  struct tm t_tm;
+  long nsec = 0;
+  int status;
+  char zone[7];  /* +00:00 */
 
-  if (print_nano)
-    ssnprintf (nano, sizeof (nano), ".%09ld", (long) t_spec.tv_nsec);
-  else
-    sstrncpy (nano, "", sizeof (nano));
+  if ((status = get_local_time (t, &t_tm, &nsec)) != 0)
+    return status;  /* The error should have already be reported. */
 
-  status = format_zone (zone, sizeof (zone), &t_tm);
-  if (status != 0)
+  if ((status = format_zone (zone, sizeof (zone), &t_tm)) != 0)
     return status;
 
-  if (strjoin (buffer, buffer_size, fields, STATIC_ARRAY_SIZE (fields), "") < 0)
-    return ENOMEM;
-  return 0;
-} /* }}} int format_rfc3339 */
+  return format_rfc3339 (buffer, buffer_size, &t_tm, nsec, print_nano, zone);
+} /* }}} int format_rfc3339_local */
+
+/**********************************************************************
+ Public functions
+***********************************************************************/
 
 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 */
+  return format_rfc3339_utc (buffer, buffer_size, t, 0);
+} /* }}} int rfc3339 */
 
 int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
 {
   if (buffer_size < RFC3339NANO_SIZE)
     return ENOMEM;
 
-  return format_rfc3339 (buffer, buffer_size, t, 1);
-} /* }}} size_t cdtime_to_rfc3339nano */
+  return format_rfc3339_utc (buffer, buffer_size, t, 1);
+} /* }}} int rfc3339nano */
+
+int rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+  if (buffer_size < RFC3339_SIZE)
+    return ENOMEM;
+
+  return format_rfc3339_local (buffer, buffer_size, t, 0);
+} /* }}} int rfc3339 */
+
+int rfc3339nano_local (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+  if (buffer_size < RFC3339NANO_SIZE)
+    return ENOMEM;
+
+  return format_rfc3339_local (buffer, buffer_size, t, 1);
+} /* }}} int rfc3339nano */
 
 /* vim: set sw=2 sts=2 et fdm=marker : */
index 4d88dcc..7834723 100644 (file)
@@ -82,15 +82,24 @@ extern cdtime_t cdtime_mock;
 
 cdtime_t cdtime (void);
 
-#define RFC3339_SIZE     26
-#define RFC3339NANO_SIZE 36
+#define RFC3339_SIZE     26  /* 2006-01-02T15:04:05+00:00 */
+#define RFC3339NANO_SIZE 36  /* 2006-01-02T15:04:05.999999999+00:00 */
 
-/* rfc3339 formats a cdtime_t time in RFC 3339 format with second precision. */
+/* rfc3339 formats a cdtime_t time as UTC in RFC 3339 zulu format with second
+ * precision, e.g., "2006-01-02T15:04:05Z". */
 int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t);
 
-/* rfc3339nano formats a cdtime_t time in RFC 3339 format with nanosecond
- * precision. */
+/* rfc3339nano formats a cdtime_t as UTC time in RFC 3339 zulu format with
+ * nanosecond precision, e.g., "2006-01-02T15:04:05.999999999Z". */
 int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t);
 
+/* rfc3339 formats a cdtime_t time as local in RFC 3339 format with second
+ * precision, e.g., "2006-01-02T15:04:05+00:00". */
+int rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t);
+
+/* rfc3339nano formats a cdtime_t time as local in RFC 3339 format with
+ * nanosecond precision, e.g., "2006-01-02T15:04:05.999999999+00:00". */
+int rfc3339nano_local (char *buffer, size_t buffer_size, cdtime_t t);
+
 #endif /* UTILS_TIME_H */
 /* vim: set sw=2 sts=2 et : */
index 4d64991..9f04368 100644 (file)
@@ -27,6 +27,7 @@
 #define DBL_PRECISION 1e-3
 
 #include "collectd.h"
+
 #include "testing.h"
 #include "utils_time.h"
 
@@ -64,9 +65,8 @@ DEF_TEST(conversion)
     // 1546167986577716567 / 2^30 = 1439981150.0475896215...
     {1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150,  47590}, {1439981150,  47589622}},
   };
-  size_t i;
 
-  for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
+  for (size_t i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
     struct timeval tv;
     struct timespec ts;
 
@@ -107,9 +107,8 @@ DEF_TEST(ns_to_cdtime)
     // 1439981880053705608 * 2^30 / 10^9 = 1546168770415815077.4
     {1439981880053705608ULL, 1546168770415815077ULL},
   };
-  size_t i;
 
-  for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
+  for (size_t i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
     EXPECT_EQ_UINT64 (cases[i].want, NS_TO_CDTIME_T (cases[i].ns));
   }
 
index 273cce8..fefbf87 100644 (file)
--- a/src/dbi.c
+++ b/src/dbi.c
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_db_query.h"
 
 #include <dbi/dbi.h>
@@ -178,15 +178,13 @@ static int cdbi_result_get_field (dbi_result res, /* {{{ */
 
 static void cdbi_database_free (cdbi_database_t *db) /* {{{ */
 {
-  size_t i;
-
   if (db == NULL)
     return;
 
   sfree (db->name);
   sfree (db->driver);
 
-  for (i = 0; i < db->driver_options_num; i++)
+  for (size_t i = 0; i < db->driver_options_num; i++)
   {
     sfree (db->driver_options[i].key);
     if (!db->driver_options[i].is_numeric)
@@ -195,7 +193,7 @@ static void cdbi_database_free (cdbi_database_t *db) /* {{{ */
   sfree (db->driver_options);
 
   if (db->q_prep_areas)
-    for (i = 0; i < db->queries_num; ++i)
+    for (size_t i = 0; i < db->queries_num; ++i)
       udb_query_delete_preparation_area (db->q_prep_areas[i]);
   free (db->q_prep_areas);
 
@@ -284,7 +282,6 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
 {
   cdbi_database_t *db;
   int status;
-  int i;
 
   if ((ci->values_num != 1)
       || (ci->values[0].type != OCONFIG_TYPE_STRING))
@@ -309,7 +306,7 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
   }
 
   /* Fill the `cdbi_database_t' structure.. */
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -355,8 +352,6 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
 
   while ((status == 0) && (db->queries_num > 0))
   {
-    size_t j;
-
     db->q_prep_areas = calloc (db->queries_num, sizeof (*db->q_prep_areas));
     if (db->q_prep_areas == NULL)
     {
@@ -365,12 +360,12 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
       break;
     }
 
-    for (j = 0; j < db->queries_num; ++j)
+    for (size_t i = 0; i < db->queries_num; ++i)
     {
-      db->q_prep_areas[j]
-        = udb_query_allocate_preparation_area (db->queries[j]);
+      db->q_prep_areas[i]
+        = udb_query_allocate_preparation_area (db->queries[i]);
 
-      if (db->q_prep_areas[j] == NULL)
+      if (db->q_prep_areas[i] == NULL)
       {
         WARNING ("dbi plugin: udb_query_allocate_preparation_area failed");
         status = -1;
@@ -395,24 +390,19 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
     }
     else
     {
-      user_data_t ud;
-      char *name = NULL;
-
       databases = temp;
       databases[databases_num] = db;
       databases_num++;
 
-      memset (&ud, 0, sizeof (ud));
-      ud.data = (void *) db;
-      ud.free_func = NULL;
-      name = ssnprintf_alloc("dbi:%s", db->name);
-
+      char *name = ssnprintf_alloc("dbi:%s", db->name);
       plugin_register_complex_read (/* group = */ NULL,
           /* name = */ name ? name : db->name,
           /* callback = */ cdbi_read_database,
           /* interval = */ (db->interval > 0) ? db->interval : 0,
-          /* user_data = */ &ud);
-      free (name);
+          &(user_data_t) {
+            .data = db,
+         });
+      sfree (name);
     }
   }
 
@@ -427,9 +417,7 @@ static int cdbi_config_add_database (oconfig_item_t *ci) /* {{{ */
 
 static int cdbi_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if (strcasecmp ("Query", child->key) == 0)
@@ -459,14 +447,14 @@ static int cdbi_init (void) /* {{{ */
   if (queries_num == 0)
   {
     ERROR ("dbi plugin: No <Query> blocks have been found. Without them, "
-        "this plugin can't do anything useful, so we will returns an error.");
+        "this plugin can't do anything useful, so we will return an error.");
     return (-1);
   }
 
   if (databases_num == 0)
   {
     ERROR ("dbi plugin: No <Database> blocks have been found. Without them, "
-        "this plugin can't do anything useful, so we will returns an error.");
+        "this plugin can't do anything useful, so we will return an error.");
     return (-1);
   }
 
@@ -498,7 +486,6 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
   char **column_names;
   char **column_values;
   int status;
-  size_t i;
 
   /* Macro that cleans up dynamically allocated memory and returns the
    * specified status. */
@@ -558,7 +545,7 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
     ERROR ("dbi plugin: calloc failed.");
     BAIL_OUT (-1);
   }
-  for (i = 1; i < column_num; i++)
+  for (size_t i = 1; i < column_num; i++)
     column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;
 
   column_values = calloc (column_num, sizeof (*column_values));
@@ -574,12 +561,12 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
     ERROR ("dbi plugin: calloc failed.");
     BAIL_OUT (-1);
   }
-  for (i = 1; i < column_num; i++)
+  for (size_t i = 1; i < column_num; i++)
     column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;
   /* }}} */
 
   /* Copy the field names to `column_names' */
-  for (i = 0; i < column_num; i++) /* {{{ */
+  for (size_t i = 0; i < column_num; i++) /* {{{ */
   {
     const char *column_name;
 
@@ -619,7 +606,7 @@ static int cdbi_read_database_query (cdbi_database_t *db, /* {{{ */
   {
     status = 0;
     /* Copy the value of the columns to `column_values' */
-    for (i = 0; i < column_num; i++) /* {{{ */
+    for (size_t i = 0; i < column_num; i++) /* {{{ */
     {
       status = cdbi_result_get_field (res, (unsigned int) (i + 1),
           column_values[i], DATA_MAX_NAME_LEN);
@@ -675,7 +662,6 @@ static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */
 {
   dbi_driver driver;
   dbi_conn connection;
-  size_t i;
   int status;
 
   if (db->connection != NULL)
@@ -717,7 +703,7 @@ static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */
    * encountered, it will get a list of options understood by the driver and
    * report that as `INFO'. This way, users hopefully don't have too much
    * trouble finding out how to configure the plugin correctly.. */
-  for (i = 0; i < db->driver_options_num; i++)
+  for (size_t i = 0; i < db->driver_options_num; i++)
   {
     if (db->driver_options[i].is_numeric)
     {
@@ -750,11 +736,9 @@ static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */
 
     if (status != 0)
     {
-      char const *opt;
-
       INFO ("dbi plugin: This is a list of all options understood "
           "by the `%s' driver:", db->driver);
-      for (opt = dbi_conn_get_option_list (connection, NULL);
+      for (const char *opt = dbi_conn_get_option_list (connection, NULL);
           opt != NULL;
           opt = dbi_conn_get_option_list (connection, opt))
       {
@@ -799,7 +783,6 @@ static int cdbi_connect_database (cdbi_database_t *db) /* {{{ */
 static int cdbi_read_database (user_data_t *ud) /* {{{ */
 {
   cdbi_database_t *db = (cdbi_database_t *) ud->data;
-  size_t i;
   int success;
   int status;
 
@@ -814,7 +797,7 @@ static int cdbi_read_database (user_data_t *ud) /* {{{ */
   /* TODO: Complain if `db_version == 0' */
 
   success = 0;
-  for (i = 0; i < db->queries_num; i++)
+  for (size_t i = 0; i < db->queries_num; i++)
   {
     /* Check if we know the database's version and if so, if this query applies
      * to that version. */
@@ -839,9 +822,7 @@ static int cdbi_read_database (user_data_t *ud) /* {{{ */
 
 static int cdbi_shutdown (void) /* {{{ */
 {
-  size_t i;
-
-  for (i = 0; i < databases_num; i++)
+  for (size_t i = 0; i < databases_num; i++)
   {
     if (databases[i]->connection != NULL)
     {
index ff70172..632787b 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -22,9 +22,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_mount.h"
 #include "utils_ignorelist.h"
 
@@ -161,12 +161,9 @@ static void df_submit_one (char *plugin_instance,
                const char *type, const char *type_instance,
                gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "df", sizeof (vl.plugin));
@@ -190,7 +187,6 @@ static int df_read (void)
 #endif
        /* struct STATANYFS statbuf; */
        cu_mount_t *mnt_list;
-       cu_mount_t *mnt_ptr;
 
        mnt_list = NULL;
        if (cu_mount_getlist (&mnt_list) == NULL)
@@ -199,7 +195,7 @@ static int df_read (void)
                return (-1);
        }
 
-       for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next)
+       for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next)
        {
                unsigned long long blocksize;
                char disk_name[256];
@@ -230,7 +226,10 @@ static int df_read (void)
                        }
 
                        /* Duplicate found: leave non-NULL dup_ptr. */
-                       if (by_device && (strcmp (mnt_ptr->spec_device, dup_ptr->spec_device) == 0))
+                       if (by_device
+                            && (mnt_ptr->spec_device != NULL)
+                            && (dup_ptr->spec_device != NULL)
+                            && (strcmp (mnt_ptr->spec_device, dup_ptr->spec_device) == 0))
                                break;
                        else if (!by_device && (strcmp (mnt_ptr->dir, dup_ptr->dir) == 0))
                                break;
@@ -273,12 +272,12 @@ static int df_read (void)
                                sstrncpy (disk_name, "root", sizeof (disk_name));
                        else
                        {
-                               int i, len;
+                               int len;
 
                                sstrncpy (disk_name, mnt_ptr->dir + 1, sizeof (disk_name));
                                len = strlen (disk_name);
 
-                               for (i = 0; i < len; i++)
+                               for (int i = 0; i < len; i++)
                                        if (disk_name[i] == '/')
                                                disk_name[i] = '-';
                        }
index 9965bca..2c0d8b5 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_ignorelist.h"
@@ -127,7 +128,7 @@ static int numdisk = 0;
 /* #endif HAVE_LIBKSTAT */
 
 #elif defined(HAVE_LIBSTATGRAB)
-/* #endif HAVE_LIBKSTATGRAB */
+/* #endif HAVE_LIBSTATGRAB */
 
 #elif HAVE_PERFSTAT
 static perfstat_disk_t * stat_disk;
@@ -296,14 +297,14 @@ static void disk_submit (const char *plugin_instance,
                const char *type,
                derive_t read, derive_t write)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = read;
-       values[1].derive = write;
+       value_t values[] = {
+               { .derive = read },
+               { .derive = write },
+       };
 
        vl.values = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
        sstrncpy (vl.plugin_instance, plugin_instance,
@@ -316,14 +317,14 @@ static void disk_submit (const char *plugin_instance,
 #if KERNEL_FREEBSD || KERNEL_LINUX
 static void submit_io_time (char const *plugin_instance, derive_t io_time, derive_t weighted_time)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = io_time;
-       values[1].derive = weighted_time;
+       value_t values[] = {
+               { .derive = io_time },
+               { .derive = weighted_time },
+       };
 
        vl.values = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
        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));
@@ -336,12 +337,9 @@ static void submit_io_time (char const *plugin_instance, derive_t io_time, deriv
 #if KERNEL_LINUX
 static void submit_in_progress (char const *disk_name, gauge_t in_progress)
 {
-       value_t v;
        value_list_t vl = VALUE_LIST_INIT;
 
-       v.gauge = in_progress;
-
-       vl.values = &v;
+       vl.values = &(value_t) { .gauge = in_progress };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
@@ -351,7 +349,6 @@ static void submit_in_progress (char const *disk_name, gauge_t in_progress)
        plugin_dispatch_values (&vl);
 }
 
-
 static counter_t disk_calc_time_incr (counter_t delta_time, counter_t delta_ops)
 {
        double interval = CDTIME_T_TO_DOUBLE (plugin_get_interval ());
@@ -953,12 +950,11 @@ static int disk_read (void)
 #  error "kstat_io_t does not have the required members"
 # endif
        static kstat_io_t kio;
-       int i;
 
        if (kc == NULL)
                return (-1);
 
-       for (i = 0; i < numdisk; i++)
+       for (int i = 0; i < numdisk; i++)
        {
                if (kstat_read (kc, ksp[i], &kio) == -1)
                        continue;
@@ -996,13 +992,12 @@ static int disk_read (void)
 # else
        int disks;
 #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++) {
+       for (int counter = 0; counter < disks; counter++) {
                strncpy(name, ds->disk_name, sizeof(name));
                name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
 
@@ -1025,7 +1020,6 @@ static int disk_read (void)
        derive_t write_ops;
        perfstat_id_t firstpath;
        int rnumdisk;
-       int i;
 
        if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0)
        {
@@ -1051,7 +1045,7 @@ static int disk_read (void)
                return (-1);
        }
 
-       for (i = 0; i < rnumdisk; i++)
+       for (int i = 0; i < rnumdisk; i++)
        {
                if (ignorelist_match (ignorelist, stat_disk[i].name) != 0)
                        continue;
index 2c3a904..ae53710 100644 (file)
--- a/src/dns.c
+++ b/src/dns.c
 #define _BSD_SOURCE
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include "utils_dns.h"
 #include <poll.h>
 
 #include <pcap.h>
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 /*
  * Private data types
  */
@@ -210,7 +214,7 @@ static int dns_run_pcap_loop (void)
 {
        pcap_t *pcap_obj;
        char    pcap_error[PCAP_ERRBUF_SIZE];
-       struct  bpf_program fp;
+       struct  bpf_program fp = { 0 };
 
        int status;
 
@@ -237,7 +241,6 @@ static int dns_run_pcap_loop (void)
                return (PCAP_ERROR);
        }
 
-       memset (&fp, 0, sizeof (fp));
        status = pcap_compile (pcap_obj, &fp, "udp port 53", 1, 0);
        if (status < 0)
        {
@@ -347,18 +350,29 @@ static int dns_init (void)
 
        listen_thread_init = 1;
 
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_RAW)
+       if (check_capability (CAP_NET_RAW) != 0)
+       {
+               if (getuid () == 0)
+                       WARNING ("dns plugin: Running collectd as root, but the CAP_NET_RAW "
+                                       "capability is missing. The plugin's read function will probably "
+                                       "fail. Is your init system dropping capabilities?");
+               else
+                       WARNING ("dns plugin: collectd doesn't have the CAP_NET_RAW capability. "
+                                       "If you don't want to run collectd as root, try running \"setcap "
+                                       "cap_net_raw=ep\" on the collectd binary.");
+       }
+#endif
+
        return (0);
 } /* int dns_init */
 
 static void submit_derive (const char *type, const char *type_instance,
                derive_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .derive = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "dns", sizeof (vl.plugin));
@@ -370,14 +384,14 @@ static void submit_derive (const char *type, const char *type_instance,
 
 static void submit_octets (derive_t queries, derive_t responses)
 {
-       value_t values[2];
+       value_t values[] = {
+          { .derive = queries },
+          { .derive = responses },
+        };
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = queries;
-       values[1].derive = responses;
-
        vl.values = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "dns", sizeof (vl.plugin));
        sstrncpy (vl.type, "dns_octets", sizeof (vl.type));
@@ -390,7 +404,6 @@ static int dns_read (void)
        unsigned int keys[T_MAX];
        unsigned int values[T_MAX];
        int len;
-       int i;
 
        counter_list_t *ptr;
 
@@ -412,7 +425,7 @@ static int dns_read (void)
        }
        pthread_mutex_unlock (&qtype_mutex);
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                DEBUG ("dns plugin: qtype = %u; counter = %u;", keys[i], values[i]);
                submit_derive ("dns_qtype", qtype_str (keys[i]), values[i]);
@@ -428,7 +441,7 @@ static int dns_read (void)
        }
        pthread_mutex_unlock (&opcode_mutex);
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                DEBUG ("dns plugin: opcode = %u; counter = %u;", keys[i], values[i]);
                submit_derive ("dns_opcode", opcode_str (keys[i]), values[i]);
@@ -444,7 +457,7 @@ static int dns_read (void)
        }
        pthread_mutex_unlock (&rcode_mutex);
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                DEBUG ("dns plugin: rcode = %u; counter = %u;", keys[i], values[i]);
                submit_derive ("dns_rcode", rcode_str (keys[i]), values[i]);
index f029894..70f03ca 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -69,7 +70,6 @@ static int drbd_submit_fields (long int resource,
        char plugin_instance[DATA_MAX_NAME_LEN];
        value_t values[fields_num];
        value_list_t vl = VALUE_LIST_INIT;
-       size_t i;
 
        if (resource < 0)
        {
@@ -88,7 +88,7 @@ static int drbd_submit_fields (long int resource,
        ssnprintf (plugin_instance, sizeof (plugin_instance), "r%ld",
                        resource);
 
-       for (i = 0; i < drbd_names_num; i++)
+       for (size_t i = 0; i < drbd_names_num; i++)
        {
                char *data;
                /* skip non numeric wo */
@@ -107,7 +107,7 @@ static int drbd_submit_fields (long int resource,
                        sizeof (vl.plugin_instance));
        sstrncpy (vl.type, "drbd_resource", sizeof (vl.type));
 
-       for (i = 0; i < fields_num; i++)
+       for (size_t i = 0; i < fields_num; i++)
        {
                if (drbd_names[i] == NULL)
                        continue;
index db6dd41..97fbdfe 100644 (file)
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
-#include "configfile.h"
-
 #include <stddef.h>
 
 #include <sys/un.h>
@@ -464,8 +463,6 @@ static void *open_connection (void __attribute__((unused)) *arg)
        }
 
        { /* initialize collector threads */
-               int i   = 0;
-
                pthread_attr_t ptattr;
 
                conns.head = NULL;
@@ -479,7 +476,7 @@ static void *open_connection (void __attribute__((unused)) *arg)
                collectors =
                        smalloc (max_conns * sizeof (*collectors));
 
-               for (i = 0; i < max_conns; ++i) {
+               for (int i = 0; i < max_conns; ++i) {
                        collectors[i] = smalloc (sizeof (*collectors[i]));
                        collectors[i]->socket = NULL;
 
@@ -603,8 +600,6 @@ static void type_list_free (type_list_t *t)
 
 static int email_shutdown (void)
 {
-       int i = 0;
-
        if (connector != ((pthread_t) 0)) {
                pthread_kill (connector, SIGTERM);
                connector = (pthread_t) 0;
@@ -621,7 +616,7 @@ static int email_shutdown (void)
        available_collectors = 0;
 
        if (collectors != NULL) {
-               for (i = 0; i < max_conns; ++i) {
+               for (int i = 0; i < max_conns; ++i) {
                        if (collectors[i] == NULL)
                                continue;
 
@@ -658,12 +653,9 @@ static int email_shutdown (void)
 
 static void email_submit (const char *type, const char *type_instance, gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "email", sizeof (vl.plugin));
@@ -679,12 +671,9 @@ static void email_submit (const char *type, const char *type_instance, gauge_t v
  * after they have been copied to l2. */
 static void copy_type_list (type_list_t *l1, type_list_t *l2)
 {
-       type_t *ptr1;
-       type_t *ptr2;
-
        type_t *last = NULL;
 
-       for (ptr1 = l1->head, ptr2 = l2->head; NULL != ptr1;
+       for (type_t *ptr1 = l1->head, *ptr2 = l2->head; NULL != ptr1;
                        ptr1 = ptr1->next, last = ptr2, ptr2 = ptr2->next) {
                if (NULL == ptr2) {
                        ptr2 = smalloc (sizeof (*ptr2));
@@ -713,8 +702,6 @@ static void copy_type_list (type_list_t *l1, type_list_t *l2)
 
 static int email_read (void)
 {
-       type_t *ptr;
-
        double score_old;
        int score_count_old;
 
@@ -728,7 +715,7 @@ static int email_read (void)
 
        pthread_mutex_unlock (&count_mutex);
 
-       for (ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) {
+       for (type_t *ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) {
                email_submit ("email_count", ptr->name, ptr->value);
        }
 
@@ -739,7 +726,7 @@ static int email_read (void)
 
        pthread_mutex_unlock (&size_mutex);
 
-       for (ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) {
+       for (type_t *ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) {
                email_submit ("email_size", ptr->name, ptr->value);
        }
 
@@ -763,7 +750,7 @@ static int email_read (void)
 
        pthread_mutex_unlock (&check_mutex);
 
-       for (ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next)
+       for (type_t *ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next)
                email_submit ("spam_check", ptr->name, ptr->value);
 
        return (0);
index 03de9ef..b385c2a 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
 
 #define ENTROPY_FILE "/proc/sys/kernel/random/entropy_avail"
 
-static void entropy_submit (double entropy)
+static void entropy_submit (value_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = entropy;
-
-       vl.values = values;
+       vl.values = &value;
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "entropy", sizeof (vl.plugin));
@@ -52,26 +50,14 @@ static void entropy_submit (double entropy)
 
 static int entropy_read (void)
 {
-       double entropy;
-       FILE *fh;
-       char buffer[64];
-
-       fh = fopen (ENTROPY_FILE, "r");
-       if (fh == NULL)
-               return (-1);
-
-       if (fgets (buffer, sizeof (buffer), fh) == NULL)
+       value_t v;
+       if (parse_value_file (ENTROPY_FILE, &v, DS_TYPE_GAUGE) != 0)
        {
-               fclose (fh);
+               ERROR ("entropy plugin: Reading \""ENTROPY_FILE"\" failed.");
                return (-1);
        }
-       fclose (fh);
-
-       entropy = atof (buffer);
-       
-       if (entropy > 0.0)
-               entropy_submit (entropy);
 
+       entropy_submit (v);
        return (0);
 }
 
index 959737a..f0b8d9f 100644 (file)
@@ -23,9 +23,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_avltree.h"
 #include "utils_complain.h"
 
@@ -149,9 +149,7 @@ static int ethstat_add_map (const oconfig_item_t *ci) /* {{{ */
 
 static int ethstat_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -174,7 +172,6 @@ static void ethstat_submit_value (const char *device,
 {
   static c_complain_t complain_no_map = C_COMPLAIN_INIT_STATIC;
 
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
   value_map_t *map = NULL;
 
@@ -191,8 +188,7 @@ static void ethstat_submit_value (const char *device,
     return;
   }
 
-  values[0].derive = value;
-  vl.values = values;
+  vl.values = &(value_t) { .derive = value };
   vl.values_len = 1;
 
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -216,19 +212,13 @@ static void ethstat_submit_value (const char *device,
 static int ethstat_read_interface (char *device)
 {
   int fd;
-  struct ifreq req;
-  struct ethtool_drvinfo drvinfo;
   struct ethtool_gstrings *strings;
   struct ethtool_stats *stats;
   size_t n_stats;
   size_t strings_size;
   size_t stats_size;
-  size_t i;
   int status;
 
-  memset (&req, 0, sizeof (req));
-  sstrncpy(req.ifr_name, device, sizeof (req.ifr_name));
-
   fd = socket(AF_INET, SOCK_DGRAM, /* protocol = */ 0);
   if (fd < 0)
   {
@@ -238,9 +228,16 @@ static int ethstat_read_interface (char *device)
     return 1;
   }
 
-  memset (&drvinfo, 0, sizeof (drvinfo));
-  drvinfo.cmd = ETHTOOL_GDRVINFO;
-  req.ifr_data = (void *) &drvinfo;
+  struct ethtool_drvinfo drvinfo = {
+    .cmd = ETHTOOL_GDRVINFO
+  };
+
+  struct ifreq req = {
+    .ifr_data = (void *) &drvinfo
+  };
+
+  sstrncpy(req.ifr_name, device, sizeof (req.ifr_name));
+
   status = ioctl (fd, SIOCETHTOOL, &req);
   if (status < 0)
   {
@@ -309,7 +306,7 @@ static int ethstat_read_interface (char *device)
     return (-1);
   }
 
-  for (i = 0; i < n_stats; i++)
+  for (size_t i = 0; i < n_stats; i++)
   {
     char *stat_name;
 
@@ -333,9 +330,7 @@ static int ethstat_read_interface (char *device)
 
 static int ethstat_read(void)
 {
-  size_t i;
-
-  for (i = 0; i < interfaces_num; i++)
+  for (size_t i = 0; i < interfaces_num; i++)
     ethstat_read_interface (interfaces[i]);
 
   return 0;
index cdaf79a..dfd4b05 100644 (file)
@@ -27,6 +27,7 @@
 #define _BSD_SOURCE /* For setgroups */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
 #include <grp.h>
 #include <signal.h>
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #define PL_NORMAL        0x01
 #define PL_NOTIF_ACTION  0x02
 
@@ -245,9 +250,7 @@ static int exec_config_exec (oconfig_item_t *ci) /* {{{ */
 
 static int exec_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if ((strcasecmp ("Exec", child->key) == 0)
@@ -346,7 +349,6 @@ static void reset_signal_mask (void) /* {{{ */
 {
   sigset_t ss;
 
-  memset (&ss, 0, sizeof (ss));
   sigemptyset (&ss);
   sigprocmask (SIG_SETMASK, &ss, /* old mask = */ NULL);
 } /* }}} void reset_signal_mask */
@@ -471,11 +473,10 @@ static int fork_child (program_list_t *pl, int *fd_in, int *fd_out, int *fd_err)
   else if (pid == 0)
   {
     int fd_num;
-    int fd;
 
     /* Close all file descriptors but the pipe end we need. */
     fd_num = getdtablesize ();
-    for (fd = 0; fd < fd_num; fd++)
+    for (int fd = 0; fd < fd_num; fd++)
     {
       if ((fd == fd_pipe_in[0])
           || (fd == fd_pipe_out[1])
@@ -721,7 +722,6 @@ static void *exec_notification_one (void *arg) /* {{{ */
 {
   program_list_t *pl = ((program_list_and_notification_t *) arg)->pl;
   notification_t *n = &((program_list_and_notification_t *) arg)->n;
-  notification_meta_t *meta;
   int fd;
   FILE *fh;
   int pid;
@@ -769,7 +769,7 @@ static void *exec_notification_one (void *arg) /* {{{ */
   if (strlen (n->type_instance) > 0)
     fprintf (fh, "TypeInstance: %s\n", n->type_instance);
 
-  for (meta = n->meta; meta != NULL; meta = meta->next)
+  for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next)
   {
     if (meta->type == NM_TYPE_STRING)
       fprintf (fh, "%s: %s\n", meta->name, meta->nm_value.nm_string);
@@ -804,20 +804,34 @@ static void *exec_notification_one (void *arg) /* {{{ */
 
 static int exec_init (void) /* {{{ */
 {
-  struct sigaction sa;
+  struct sigaction sa = {
+    .sa_handler = sigchld_handler
+  };
 
-  memset (&sa, '\0', sizeof (sa));
-  sa.sa_handler = sigchld_handler;
   sigaction (SIGCHLD, &sa, NULL);
 
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SETUID) && defined(CAP_SETGID)
+  if ((check_capability (CAP_SETUID) != 0) ||
+      (check_capability (CAP_SETGID) != 0))
+  {
+    if (getuid () == 0)
+      WARNING ("exec plugin: Running collectd as root, but the CAP_SETUID "
+          "or CAP_SETGID capabilities are missing. The plugin's read function "
+          "will probably fail. Is your init system dropping capabilities?");
+    else
+      WARNING ("exec plugin: collectd doesn't have the CAP_SETUID or "
+          "CAP_SETGID capabilities. If you don't want to run collectd as root, "
+          "try running \"setcap 'cap_setuid=ep cap_setgid=ep'\" on the "
+          "collectd binary.");
+  }
+#endif
+
   return (0);
 } /* int exec_init }}} */
 
 static int exec_read (void) /* {{{ */
 {
-  program_list_t *pl;
-
-  for (pl = pl_head; pl != NULL; pl = pl->next)
+  for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next)
   {
     pthread_t t;
     pthread_attr_t attr;
@@ -848,10 +862,9 @@ static int exec_read (void) /* {{{ */
 static int exec_notification (const notification_t *n, /* {{{ */
     user_data_t __attribute__((unused)) *user_data)
 {
-  program_list_t *pl;
   program_list_and_notification_t *pln;
 
-  for (pl = pl_head; pl != NULL; pl = pl->next)
+  for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next)
   {
     pthread_t t;
     pthread_attr_t attr;
index 666dacc..a2f5aa8 100644 (file)
@@ -18,9 +18,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 
 static const char *config_keys[] = {
@@ -60,13 +60,9 @@ static int fhcount_config(const char *key, const char *value) {
 
 static void fhcount_submit(
     const char *type, const char *type_instance, gauge_t value) {
-
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
 
   // Compose the metric
@@ -79,7 +75,6 @@ static void fhcount_submit(
   plugin_dispatch_values(&vl);
 }
 
-
 static int fhcount_read(void) {
   int numfields = 0;
   int buffer_len = 60;
index c81fdc2..c1e53a2 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -60,13 +61,10 @@ static size_t directories_num = 0;
 
 static void fc_submit_dir (const fc_directory_conf_t *dir)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = (gauge_t) dir->files_num;
-
-  vl.values = values;
-  vl.values_len = STATIC_ARRAY_SIZE (values);
+  vl.values = &(value_t) { .gauge = (gauge_t) dir->files_num };
+  vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "filecount", sizeof (vl.plugin));
   sstrncpy (vl.plugin_instance, dir->instance, sizeof (vl.plugin_instance));
@@ -74,7 +72,7 @@ static void fc_submit_dir (const fc_directory_conf_t *dir)
 
   plugin_dispatch_values (&vl);
 
-  values[0].gauge = (gauge_t) dir->files_size;
+  vl.values = &(value_t) { .gauge = (gauge_t) dir->files_size };
   sstrncpy (vl.type, "bytes", sizeof (vl.type));
 
   plugin_dispatch_values (&vl);
@@ -334,7 +332,6 @@ static int fc_config_add_dir (oconfig_item_t *ci)
 {
   fc_directory_conf_t *dir;
   int status;
-  int i;
 
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
@@ -368,7 +365,7 @@ static int fc_config_add_dir (oconfig_item_t *ci)
   dir->size = 0;
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -428,9 +425,7 @@ static int fc_config_add_dir (oconfig_item_t *ci)
 
 static int fc_config (oconfig_item_t *ci)
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if (strcasecmp ("Directory", child->key) == 0)
@@ -557,9 +552,7 @@ static int fc_read_dir (fc_directory_conf_t *dir)
 
 static int fc_read (void)
 {
-  size_t i;
-
-  for (i = 0; i < directories_num; i++)
+  for (size_t i = 0; i < directories_num; i++)
     fc_read_dir (directories[i]);
 
   return (0);
index 68f5c79..33633d6 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include <stdio.h>  /* a header needed for FILE */
@@ -158,7 +159,6 @@ static void fscache_read_stats_file (FILE *fh)
         char *lineptr;
         char *fields[32];
         int fields_num;
-        int i;
 
         /* Find the colon and replace it with a null byte */
         lineptr = strchr (linebuffer, ':');
@@ -182,7 +182,7 @@ static void fscache_read_stats_file (FILE *fh)
         if (fields_num <= 0)
             continue;
 
-        for (i = 0; i < fields_num; i++)
+        for (int i = 0; i < fields_num; i++)
         {
             char *field_name;
             char *field_value_str;
index 728162e..13ec638 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 #include "utils_avltree.h"
 
 #if HAVE_NETDB_H
@@ -211,9 +211,7 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
     size_t *ret_sockets_num,
     const char *node, const char *service, int listen)
 {
-  struct addrinfo  ai_hints;
   struct addrinfo *ai_list;
-  struct addrinfo *ai_ptr;
   int              ai_return;
 
   socket_entry_t *sockets = NULL;
@@ -224,17 +222,12 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
   if (*ret_sockets != NULL)
     return (EINVAL);
 
-  memset (&ai_hints, 0, sizeof (ai_hints));
-  ai_hints.ai_flags    = 0;
-#ifdef AI_PASSIVE
-  ai_hints.ai_flags |= AI_PASSIVE;
-#endif
-#ifdef AI_ADDRCONFIG
-  ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-  ai_hints.ai_family   = AF_UNSPEC;
-  ai_hints.ai_socktype = SOCK_DGRAM;
-  ai_hints.ai_protocol = IPPROTO_UDP;
+  struct addrinfo ai_hints = {
+    .ai_family = AF_UNSPEC,
+    .ai_flags = AI_ADDRCONFIG | AI_PASSIVE,
+    .ai_protocol = IPPROTO_UDP,
+    .ai_socktype = SOCK_DGRAM
+  };
 
   ai_return = getaddrinfo (node, service, &ai_hints, &ai_list);
   if (ai_return != 0)
@@ -249,7 +242,7 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
     return (-1);
   }
 
-  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) /* {{{ */
+  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) /* {{{ */
   {
     socket_entry_t *tmp;
 
@@ -308,7 +301,6 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
     if (ai_ptr->ai_family == AF_INET)
     {
       struct sockaddr_in *addr;
-      struct ip_mreq mreq;
       int loop;
 
       addr = (struct sockaddr_in *) ai_ptr->ai_addr;
@@ -329,9 +321,10 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
                  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);
+      struct ip_mreq mreq = {
+        .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+        .imr_interface.s_addr = htonl (INADDR_ANY)
+      };
 
       status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
           (void *) &mreq, sizeof (mreq));
@@ -345,7 +338,6 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
     else if (ai_ptr->ai_family == AF_INET6)
     {
       struct sockaddr_in6 *addr;
-      struct ipv6_mreq mreq;
       int loop;
 
       addr = (struct sockaddr_in6 *) ai_ptr->ai_addr;
@@ -366,10 +358,12 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
                  sstrerror (errno, errbuf, sizeof (errbuf)));
       }
 
-      memset (&mreq, 0, sizeof (mreq));
+      struct ipv6_mreq mreq = {
+        .ipv6mr_interface = 0 /* any */
+      };
+
       memcpy (&mreq.ipv6mr_multiaddr,
           &addr->sin6_addr, sizeof (addr->sin6_addr));
-      mreq.ipv6mr_interface = 0; /* any */
       status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
           (void *) &mreq, sizeof (mreq));
       if (status != 0)
@@ -398,13 +392,10 @@ static int create_sockets (socket_entry_t **ret_sockets, /* {{{ */
 
 static int request_meta_data (const char *host, const char *name) /* {{{ */
 {
-  Ganglia_metadata_msg msg;
-  char buffer[BUFF_SIZE];
+  Ganglia_metadata_msg msg = { 0 };
+  char buffer[BUFF_SIZE] = { 0 };
   unsigned int buffer_size;
   XDR xdr;
-  size_t i;
-
-  memset (&msg, 0, sizeof (msg));
 
   msg.id = gmetadata_request;
   msg.Ganglia_metadata_msg_u.grequest.metric_id.host = strdup (host);
@@ -418,7 +409,6 @@ static int request_meta_data (const char *host, const char *name) /* {{{ */
     return (-1);
   }
 
-  memset (buffer, 0, sizeof (buffer));
   xdrmem_create (&xdr, buffer, sizeof (buffer), XDR_ENCODE);
 
   if (!xdr_Ganglia_metadata_msg (&xdr, &msg))
@@ -434,7 +424,7 @@ static int request_meta_data (const char *host, const char *name) /* {{{ */
       host, name);
 
   pthread_mutex_lock (&mc_send_sockets_lock);
-  for (i = 0; i < mc_send_sockets_num; i++)
+  for (size_t i = 0; i < mc_send_sockets_num; i++)
   {
     ssize_t status = sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
         /* flags = */ 0,
@@ -782,9 +772,8 @@ static int mc_handle_metric (void *buffer, size_t buffer_size) /* {{{ */
     case gmetric_float:
     case gmetric_double:
     {
-      Ganglia_value_msg msg;
+      Ganglia_value_msg msg = { 0 };
 
-      memset (&msg, 0, sizeof (msg));
       if (xdr_Ganglia_value_msg (&xdr, &msg))
         mc_handle_value_msg (&msg);
       break;
@@ -793,8 +782,7 @@ static int mc_handle_metric (void *buffer, size_t buffer_size) /* {{{ */
     case gmetadata_full:
     case gmetadata_request:
     {
-      Ganglia_metadata_msg msg;
-      memset (&msg, 0, sizeof (msg));
+      Ganglia_metadata_msg msg = { 0 };
       if (xdr_Ganglia_metadata_msg (&xdr, &msg))
         mc_handle_metadata_msg (&msg);
       break;
@@ -838,7 +826,6 @@ static void *mc_receive_thread (void *arg) /* {{{ */
 {
   socket_entry_t *mc_receive_socket_entries;
   int status;
-  size_t i;
 
   mc_receive_socket_entries = NULL;
   status = create_sockets (&mc_receive_socket_entries, &mc_receive_sockets_num,
@@ -856,7 +843,7 @@ static void *mc_receive_thread (void *arg) /* {{{ */
   if (mc_receive_sockets == NULL)
   {
     ERROR ("gmond plugin: calloc failed.");
-    for (i = 0; i < mc_receive_sockets_num; i++)
+    for (size_t i = 0; i < mc_receive_sockets_num; i++)
       close (mc_receive_socket_entries[i].fd);
     free (mc_receive_socket_entries);
     mc_receive_socket_entries = NULL;
@@ -864,7 +851,7 @@ static void *mc_receive_thread (void *arg) /* {{{ */
     return ((void *) -1);
   }
 
-  for (i = 0; i < mc_receive_sockets_num; i++)
+  for (size_t i = 0; i < mc_receive_sockets_num; i++)
   {
     mc_receive_sockets[i].fd = mc_receive_socket_entries[i].fd;
     mc_receive_sockets[i].events = POLLIN | POLLPRI;
@@ -884,7 +871,7 @@ static void *mc_receive_thread (void *arg) /* {{{ */
       break;
     }
 
-    for (i = 0; i < mc_receive_sockets_num; i++)
+    for (size_t i = 0; i < mc_receive_sockets_num; i++)
     {
       if (mc_receive_sockets[i].revents != 0)
         mc_handle_socket (mc_receive_sockets + i);
@@ -972,7 +959,6 @@ static int gmond_config_set_string (oconfig_item_t *ci, char **str) /* {{{ */
 static int gmond_config_add_metric (oconfig_item_t *ci) /* {{{ */
 {
   metric_map_t *map;
-  int i;
 
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
@@ -1004,7 +990,7 @@ static int gmond_config_add_metric (oconfig_item_t *ci) /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if (strcasecmp ("Type", child->key) == 0)
@@ -1081,9 +1067,7 @@ static int gmond_config_set_address (oconfig_item_t *ci, /* {{{ */
 
 static int gmond_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if (strcasecmp ("MCReceiveFrom", child->key) == 0)
@@ -1121,12 +1105,10 @@ static int gmond_init (void) /* {{{ */
 
 static int gmond_shutdown (void) /* {{{ */
 {
-  size_t i;
-
   mc_receive_thread_stop ();
 
   pthread_mutex_lock (&mc_send_sockets_lock);
-  for (i = 0; i < mc_send_sockets_num; i++)
+  for (size_t i = 0; i < mc_send_sockets_num; i++)
   {
     close (mc_send_sockets[i].fd);
     mc_send_sockets[i].fd = -1;
diff --git a/src/gps.c b/src/gps.c
new file mode 100644 (file)
index 0000000..d5b7176
--- /dev/null
+++ b/src/gps.c
@@ -0,0 +1,364 @@
+/**
+ * collectd - src/gps.c
+ * Copyright (C) 2015  Nicolas JOURDEN
+ *
+ * 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:
+ *   Nicolas JOURDEN <nicolas.jourden at laposte.net>
+ *   Florian octo Forster <octo at collectd.org>
+ *   Marc Fournier <marc.fournier at camptocamp.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_time.h"
+
+#define CGPS_TRUE                  1
+#define CGPS_FALSE                 0
+#define CGPS_DEFAULT_HOST          "localhost"
+#define CGPS_DEFAULT_PORT          "2947" /* DEFAULT_GPSD_PORT */
+#define CGPS_DEFAULT_TIMEOUT       MS_TO_CDTIME_T (15)
+#define CGPS_DEFAULT_PAUSE_CONNECT TIME_T_TO_CDTIME_T (5)
+#define CGPS_MAX_ERROR             100
+#define CGPS_CONFIG                "?WATCH={\"enable\":true,\"json\":true,\"nmea\":false}\r\n"
+
+#include <gps.h>
+#include <pthread.h>
+
+typedef struct {
+  char *host;
+  char *port;
+  cdtime_t timeout;
+  cdtime_t pause_connect;
+} cgps_config_t;
+
+typedef struct {
+  gauge_t sats_used;
+  gauge_t sats_visible;
+  gauge_t hdop;
+  gauge_t vdop;
+} cgps_data_t;
+
+static cgps_config_t cgps_config_data;
+
+static cgps_data_t cgps_data = {NAN, NAN, NAN, NAN};
+
+static pthread_t cgps_thread_id;
+static pthread_mutex_t  cgps_data_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t  cgps_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static int cgps_thread_shutdown = CGPS_FALSE;
+static int cgps_thread_running = CGPS_FALSE;
+
+/**
+ * Non blocking pause for the thread.
+ */
+static int cgps_thread_pause(cdtime_t pTime)
+{
+  cdtime_t now;
+  now = cdtime ();
+  struct timespec pause_th;
+  CDTIME_T_TO_TIMESPEC (MS_TO_CDTIME_T(10), &pause_th);
+  while (CGPS_TRUE)
+  {
+    if ( (cdtime () - now) > pTime )
+    {
+      break;
+    }
+
+    pthread_mutex_lock (&cgps_thread_lock);
+    if (cgps_thread_shutdown == CGPS_TRUE)
+    {
+      return CGPS_FALSE;
+    }
+    pthread_mutex_unlock (&cgps_thread_lock);
+    nanosleep (&pause_th, NULL);
+ }
+
+ return CGPS_TRUE;
+}
+
+/**
+ * Thread reading from gpsd.
+ */
+static void * cgps_thread (void * pData)
+{
+  struct gps_data_t gpsd_conn;
+  unsigned int err_count;
+  cgps_thread_running = CGPS_TRUE;
+
+  while (CGPS_TRUE)
+  {
+    pthread_mutex_lock (&cgps_thread_lock);
+    if (cgps_thread_shutdown == CGPS_TRUE)
+    {
+      goto quit;
+    }
+    pthread_mutex_unlock (&cgps_thread_lock);
+
+    err_count = 0;
+
+#if GPSD_API_MAJOR_VERSION > 4
+    int status = gps_open (cgps_config_data.host, cgps_config_data.port, &gpsd_conn);
+#else
+    int status = gps_open_r (cgps_config_data.host, cgps_config_data.port, &gpsd_conn);
+#endif
+    if (status < 0)
+    {
+      WARNING ("gps plugin: connecting to %s:%s failed: %s",
+               cgps_config_data.host, cgps_config_data.port, gps_errstr (status));
+
+      // Here we make a pause until a new tentative to connect, we check also if
+      // the thread does not need to stop.
+      if (cgps_thread_pause(cgps_config_data.pause_connect) == CGPS_FALSE)
+      {
+        goto quit;
+      }
+
+      continue;
+    }
+
+    gps_stream (&gpsd_conn, WATCH_ENABLE | WATCH_JSON | WATCH_NEWSTYLE, NULL);
+    gps_send (&gpsd_conn, CGPS_CONFIG);
+
+    while (CGPS_TRUE)
+    {
+      pthread_mutex_lock (&cgps_thread_lock);
+      if (cgps_thread_shutdown == CGPS_TRUE)
+      {
+        goto stop;
+      }
+      pthread_mutex_unlock (&cgps_thread_lock);
+
+#if GPSD_API_MAJOR_VERSION > 4
+      long timeout_us = CDTIME_T_TO_US (cgps_config_data.timeout);
+      if (!gps_waiting (&gpsd_conn, (int) timeout_us ))
+#else
+      if (!gps_waiting (&gpsd_conn))
+#endif
+      {
+        continue;
+      }
+
+      if (gps_read (&gpsd_conn) == -1)
+      {
+        WARNING ("gps plugin: incorrect data! (err_count: %d)", err_count);
+        err_count++;
+
+        if (err_count > CGPS_MAX_ERROR)
+        {
+          // Server is not responding ...
+          if (gps_send (&gpsd_conn, CGPS_CONFIG) == -1)
+          {
+            WARNING ("gps plugin: gpsd seems to be down, reconnecting");
+            gps_close (&gpsd_conn);
+            break;
+          }
+          // Server is responding ...
+          else
+          {
+            err_count = 0;
+          }
+        }
+
+        continue;
+      }
+
+      pthread_mutex_lock (&cgps_data_lock);
+
+      // Number of sats in view:
+      cgps_data.sats_used = (gauge_t) gpsd_conn.satellites_used;
+      cgps_data.sats_visible = (gauge_t) gpsd_conn.satellites_visible;
+
+      // dilution of precision:
+      cgps_data.vdop = NAN;
+      cgps_data.hdop = NAN;
+      if (cgps_data.sats_used > 0)
+      {
+        cgps_data.hdop = gpsd_conn.dop.hdop;
+        cgps_data.vdop = gpsd_conn.dop.vdop;
+      }
+
+      DEBUG ("gps plugin: %.0f sats used (of %.0f visible), hdop = %.3f, vdop = %.3f",
+             cgps_data.sats_used, cgps_data.sats_visible, cgps_data.hdop, cgps_data.vdop);
+
+      pthread_mutex_unlock (&cgps_data_lock);
+    }
+  }
+
+stop:
+  DEBUG ("gps plugin: thread closing gpsd connection ... ");
+  gps_stream (&gpsd_conn, WATCH_DISABLE, NULL);
+  gps_close (&gpsd_conn);
+quit:
+  DEBUG ("gps plugin: thread shutting down ... ");
+  cgps_thread_running = CGPS_FALSE;
+  pthread_mutex_unlock (&cgps_thread_lock);
+  pthread_exit (NULL);
+}
+
+
+/**
+ * Submit a piece of the data.
+ */
+static void cgps_submit (const char *type, gauge_t value, const char *type_instance)
+{
+  value_list_t vl = VALUE_LIST_INIT;
+
+  vl.values = &(value_t) { .gauge = value };
+  vl.values_len = 1;
+  sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+  sstrncpy (vl.plugin, "gps", sizeof (vl.plugin));
+  sstrncpy (vl.type, type, sizeof (vl.type));
+  sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
+
+  plugin_dispatch_values (&vl);
+}
+
+/**
+ * Read the data and submit by piece.
+ */
+static int cgps_read (void)
+{
+  cgps_data_t data_copy;
+
+  pthread_mutex_lock (&cgps_data_lock);
+  data_copy = cgps_data;
+  pthread_mutex_unlock (&cgps_data_lock);
+
+  cgps_submit ("dilution_of_precision", data_copy.hdop, "horizontal");
+  cgps_submit ("dilution_of_precision", data_copy.vdop, "vertical");
+  cgps_submit ("satellites", data_copy.sats_used, "used");
+  cgps_submit ("satellites", data_copy.sats_visible, "visible");
+
+  return (0);
+}
+
+/**
+ * Read configuration.
+ */
+static int cgps_config (oconfig_item_t *ci)
+{
+  int i;
+
+  for (i = 0; i < ci->children_num; i++)
+  {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp ("Host", child->key) == 0)
+      cf_util_get_string (child, &cgps_config_data.host);
+    else if (strcasecmp ("Port", child->key) == 0)
+      cf_util_get_service (child, &cgps_config_data.port);
+    else if (strcasecmp ("Timeout", child->key) == 0)
+      cf_util_get_cdtime (child, &cgps_config_data.timeout);
+    else if (strcasecmp ("PauseConnect", child->key) == 0)
+      cf_util_get_cdtime (child, &cgps_config_data.pause_connect);
+    else
+      WARNING ("gps plugin: Ignoring unknown config option \"%s\".", child->key);
+  }
+
+  // Controlling the value for timeout:
+  // If set too high it blocks the reading (> 5 s), too low it gets not reading (< 500 us).
+  // To avoid any issues we replace "out of range" value by the default value.
+  if (
+    cgps_config_data.timeout > TIME_T_TO_CDTIME_T(5)
+    ||
+    cgps_config_data.timeout < US_TO_CDTIME_T(500)
+  )
+  {
+    WARNING ("gps plugin: timeout set to %.6f sec. setting to default (%.6f).",
+      CDTIME_T_TO_DOUBLE(cgps_config_data.timeout),
+      CDTIME_T_TO_DOUBLE(CGPS_DEFAULT_TIMEOUT)
+    );
+    cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
+  }
+
+  return (0);
+}
+
+/**
+ * Init.
+ */
+static int cgps_init (void)
+{
+  int status;
+
+  if (cgps_thread_running == CGPS_TRUE)
+  {
+    DEBUG ("gps plugin: error gps thread already running ... ");
+    return 0;
+  }
+
+  DEBUG ("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., pause connect: %.3f sec.}",
+         cgps_config_data.host, cgps_config_data.port,
+         CDTIME_T_TO_DOUBLE (cgps_config_data.timeout),
+         CDTIME_T_TO_DOUBLE (cgps_config_data.pause_connect));
+
+  status = plugin_thread_create (&cgps_thread_id, NULL, cgps_thread, NULL);
+  if (status != 0)
+  {
+    ERROR ("gps plugin: pthread_create() failed.");
+    return (-1);
+  }
+
+  return (0);
+}
+
+/**
+ * Shutdown.
+ */
+static int cgps_shutdown (void)
+{
+  void * res;
+
+  pthread_mutex_lock (&cgps_thread_lock);
+  cgps_thread_shutdown = CGPS_TRUE;
+  pthread_mutex_unlock (&cgps_thread_lock);
+
+  pthread_join(cgps_thread_id, &res);
+  free(res);
+
+  // Clean mutex:
+  pthread_mutex_unlock(&cgps_thread_lock);
+  pthread_mutex_destroy(&cgps_thread_lock);
+  pthread_mutex_unlock(&cgps_data_lock);
+  pthread_mutex_destroy(&cgps_data_lock);
+
+  sfree (cgps_config_data.port);
+  sfree (cgps_config_data.host);
+
+  return (0);
+}
+
+/**
+ * Register the module.
+ */
+void module_register (void)
+{
+  cgps_config_data.host = sstrdup (CGPS_DEFAULT_HOST);
+  cgps_config_data.port = sstrdup (CGPS_DEFAULT_PORT);
+  cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
+  cgps_config_data.pause_connect = CGPS_DEFAULT_PAUSE_CONNECT;
+
+  plugin_register_complex_config ("gps", cgps_config);
+  plugin_register_init ("gps", cgps_init);
+  plugin_register_read ("gps", cgps_read);
+  plugin_register_shutdown ("gps", cgps_shutdown);
+}
index a1dac35..3b1891f 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <fstream>
 #include <iostream>
+#include <queue>
 #include <vector>
 
 #include "collectd.grpc.pb.h"
@@ -39,7 +40,6 @@ extern "C" {
 
 #include "collectd.h"
 #include "common.h"
-#include "configfile.h"
 #include "plugin.h"
 
 #include "daemon/utils_cache.h"
@@ -47,10 +47,10 @@ extern "C" {
 
 using collectd::Collectd;
 
-using collectd::DispatchValuesRequest;
-using collectd::DispatchValuesReply;
+using collectd::PutValuesRequest;
+using collectd::PutValuesResponse;
 using collectd::QueryValuesRequest;
-using collectd::QueryValuesReply;
+using collectd::QueryValuesResponse;
 
 using google::protobuf::util::TimeUtil;
 
@@ -172,7 +172,7 @@ static grpc::Status marshal_value_list(const value_list_t *vl, collectd::types::
        msg->set_allocated_interval(new google::protobuf::Duration(d));
 
        for (size_t i = 0; i < vl->values_len; ++i) {
-               auto v = msg->add_value();
+               auto v = msg->add_values();
                switch (ds->ds[i].type) {
                        case DS_TYPE_COUNTER:
                                v->set_counter(vl->values[i].counter);
@@ -190,6 +190,9 @@ static grpc::Status marshal_value_list(const value_list_t *vl, collectd::types::
                                return grpc::Status(grpc::StatusCode::INTERNAL,
                                                grpc::string("unknown value type"));
                }
+
+               auto name = msg->add_ds_names();
+               name->assign(ds->ds[i].name);
        }
 
        return grpc::Status::OK;
@@ -208,7 +211,7 @@ static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg,
        size_t values_len = 0;
 
        status = grpc::Status::OK;
-       for (auto v : msg.value()) {
+       for (auto v : msg.values()) {
                value_t *val = (value_t *)realloc(values, (values_len + 1) * sizeof(*values));
                if (!val) {
                        status = grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED,
@@ -254,159 +257,124 @@ static grpc::Status unmarshal_value_list(const collectd::types::ValueList &msg,
 } /* unmarshal_value_list() */
 
 /*
- * request call-backs and call objects
+ * Collectd service
  */
+class CollectdImpl : public collectd::Collectd::Service {
+public:
+       grpc::Status QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req, grpc::ServerWriter<QueryValuesResponse> *writer) override {
+               value_list_t match;
+               auto status = unmarshal_ident(req->identifier(), &match, false);
+               if (!status.ok()) {
+                       return status;
+               }
 
-static grpc::Status Process(grpc::ServerContext *ctx,
-               DispatchValuesRequest request, DispatchValuesReply *reply)
-{
-       value_list_t vl = VALUE_LIST_INIT;
-       auto status = unmarshal_value_list(request.values(), &vl);
-       if (!status.ok())
-               return status;
-
-       if (plugin_dispatch_values(&vl))
-               status = grpc::Status(grpc::StatusCode::INTERNAL,
-                               grpc::string("failed to enqueue values for writing"));
-       return status;
-} /* Process(): DispatchValues */
+               std::queue<value_list_t> value_lists;
+               status = this->queryValuesRead(&match, &value_lists);
+               if (status.ok()) {
+                       status = this->queryValuesWrite(ctx, writer, &value_lists);
+               }
 
-static grpc::Status Process(grpc::ServerContext *ctx,
-               QueryValuesRequest request, QueryValuesReply *reply)
-{
-       uc_iter_t *iter;
-       char *name = NULL;
+               while (!value_lists.empty()) {
+                       auto vl = value_lists.front();
+                       value_lists.pop();
+                       sfree(vl.values);
+               }
 
-       value_list_t matcher;
-       auto status = unmarshal_ident(request.identifier(), &matcher, false);
-       if (!status.ok())
                return status;
-
-       if ((iter = uc_get_iterator()) == NULL) {
-               return grpc::Status(grpc::StatusCode::INTERNAL,
-                               grpc::string("failed to query values: cannot create iterator"));
        }
 
-       while (uc_iterator_next(iter, &name) == 0) {
-               value_list_t res;
-               if (parse_identifier_vl(name, &res) != 0)
-                       return grpc::Status(grpc::StatusCode::INTERNAL,
-                                       grpc::string("failed to parse identifier"));
+       grpc::Status PutValues(grpc::ServerContext *ctx,
+                                                  grpc::ServerReader<PutValuesRequest> *reader,
+                                                  PutValuesResponse *res) override {
+               PutValuesRequest req;
 
-               if (!ident_matches(&res, &matcher))
-                       continue;
+               while (reader->Read(&req)) {
+                       value_list_t vl = VALUE_LIST_INIT;
+                       auto status = unmarshal_value_list(req.value_list(), &vl);
+                       if (!status.ok())
+                               return status;
 
-               if (uc_iterator_get_time(iter, &res.time) < 0)
-                       return grpc::Status(grpc::StatusCode::INTERNAL,
-                                       grpc::string("failed to retrieve value timestamp"));
-               if (uc_iterator_get_interval(iter, &res.interval) < 0)
-                       return grpc::Status(grpc::StatusCode::INTERNAL,
-                                       grpc::string("failed to retrieve value interval"));
-               if (uc_iterator_get_values(iter, &res.values, &res.values_len) < 0)
-                       return grpc::Status(grpc::StatusCode::INTERNAL,
-                                       grpc::string("failed to retrieve values"));
-
-               auto vl = reply->add_values();
-               status = marshal_value_list(&res, vl);
-               free(res.values);
-               if (!status.ok())
-                       return status;
-       }
-
-       uc_iterator_destroy(iter);
-
-       return grpc::Status::OK;
-} /* Process(): QueryValues */
-
-class Call
-{
-public:
-       Call(Collectd::AsyncService *service, grpc::ServerCompletionQueue *cq)
-               : service_(service), cq_(cq), status_(CREATE)
-       { }
-
-       virtual ~Call()
-       { }
-
-       void Handle()
-       {
-               if (status_ == CREATE) {
-                       Create();
-                       status_ = PROCESS;
-               }
-               else if (status_ == PROCESS) {
-                       Process();
-                       status_ = FINISH;
-               }
-               else {
-                       GPR_ASSERT(status_ == FINISH);
-                       Finish();
+                       if (plugin_dispatch_values(&vl))
+                               return grpc::Status(grpc::StatusCode::INTERNAL,
+                                                                       grpc::string("failed to enqueue values for writing"));
                }
-       } /* Handle() */
-
-protected:
-       virtual void Create() = 0;
-       virtual void Process() = 0;
-       virtual void Finish() = 0;
 
-       Collectd::AsyncService *service_;
-       grpc::ServerCompletionQueue *cq_;
-       grpc::ServerContext ctx_;
+               res->Clear();
+               return grpc::Status::OK;
+       }
 
 private:
-       enum CallStatus { CREATE, PROCESS, FINISH };
-       CallStatus status_;
-}; /* class Call */
+       grpc::Status queryValuesRead(value_list_t const *match, std::queue<value_list_t> *value_lists) {
+               uc_iter_t *iter;
+               if ((iter = uc_get_iterator()) == NULL) {
+                       return grpc::Status(grpc::StatusCode::INTERNAL,
+                                                               grpc::string("failed to query values: cannot create iterator"));
+               }
 
-template<typename RequestT, typename ReplyT>
-class RpcCall final : public Call
-{
-       typedef void (Collectd::AsyncService::*CreatorT)(grpc::ServerContext *,
-                       RequestT *, grpc::ServerAsyncResponseWriter<ReplyT> *,
-                       grpc::CompletionQueue *, grpc::ServerCompletionQueue *, void *);
+               grpc::Status status = grpc::Status::OK;
+               char *name = NULL;
+               while (uc_iterator_next(iter, &name) == 0) {
+                       value_list_t vl;
+                       if (parse_identifier_vl(name, &vl) != 0) {
+                               status = grpc::Status(grpc::StatusCode::INTERNAL,
+                                                                         grpc::string("failed to parse identifier"));
+                               break;
+                       }
 
-public:
-       RpcCall(Collectd::AsyncService *service,
-                       CreatorT creator, grpc::ServerCompletionQueue *cq)
-               : Call(service, cq), creator_(creator), responder_(&ctx_)
-       {
-               Handle();
-       } /* RpcCall() */
+                       if (!ident_matches(&vl, match))
+                               continue;
 
-       virtual ~RpcCall()
-       { }
+                       if (uc_iterator_get_time(iter, &vl.time) < 0) {
+                               status = grpc::Status(grpc::StatusCode::INTERNAL,
+                                                                         grpc::string("failed to retrieve value timestamp"));
+                               break;
+                       }
+                       if (uc_iterator_get_interval(iter, &vl.interval) < 0) {
+                               status = grpc::Status(grpc::StatusCode::INTERNAL,
+                                                                         grpc::string("failed to retrieve value interval"));
+                               break;
+                       }
+                       if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) {
+                               status = grpc::Status(grpc::StatusCode::INTERNAL,
+                                                                         grpc::string("failed to retrieve values"));
+                               break;
+                       }
 
-private:
-       void Create()
-       {
-               (service_->*creator_)(&ctx_, &request_, &responder_, cq_, cq_, this);
-       } /* Create() */
+                       value_lists->push(vl);
+               } // while (uc_iterator_next(iter, &name) == 0)
 
-       void Process()
-       {
-               // Add a new request object to the queue.
-               new RpcCall<RequestT, ReplyT>(service_, creator_, cq_);
-               grpc::Status status = ::Process(&ctx_, request_, &reply_);
-               responder_.Finish(reply_, status, this);
-       } /* Process() */
+               uc_iterator_destroy(iter);
+               return status;
+       }
 
-       void Finish()
-       {
-               delete this;
-       } /* Finish() */
+       grpc::Status queryValuesWrite(grpc::ServerContext *ctx,
+                                          grpc::ServerWriter<QueryValuesResponse> *writer,
+                                          std::queue<value_list_t> *value_lists) {
+               while (!value_lists->empty()) {
+                       auto vl = value_lists->front();
+                       QueryValuesResponse res;
+                       res.Clear();
+
+                       auto status = marshal_value_list(&vl, res.mutable_value_list());
+                       if (!status.ok()) {
+                               return status;
+                       }
 
-       CreatorT creator_;
+                       if (!writer->Write(res)) {
+                               return grpc::Status::CANCELLED;
+                       }
 
-       RequestT request_;
-       ReplyT reply_;
+                       value_lists->pop();
+                       sfree(vl.values);
+               }
 
-       grpc::ServerAsyncResponseWriter<ReplyT> responder_;
-}; /* class RpcCall */
+               return grpc::Status::OK;
+       }
+};
 
 /*
  * gRPC server implementation
  */
-
 class CollectdServer final
 {
 public:
@@ -436,63 +404,75 @@ public:
                        }
                }
 
-               builder.RegisterService(&service_);
-               cq_ = builder.AddCompletionQueue();
+               builder.RegisterService(&collectd_service_);
+
                server_ = builder.BuildAndStart();
        } /* Start() */
 
        void Shutdown()
        {
                server_->Shutdown();
-               cq_->Shutdown();
        } /* Shutdown() */
 
-       void Mainloop()
-       {
-               // Register request types.
-               new RpcCall<DispatchValuesRequest, DispatchValuesReply>(&service_,
-                               &Collectd::AsyncService::RequestDispatchValues, cq_.get());
-               new RpcCall<QueryValuesRequest, QueryValuesReply>(&service_,
-                               &Collectd::AsyncService::RequestQueryValues, cq_.get());
-
-               while (true) {
-                       void *req = NULL;
-                       bool ok = false;
-
-                       if (!cq_->Next(&req, &ok))
-                               break; // Queue shut down.
-                       if (!ok) {
-                               ERROR("grpc: Failed to read from queue");
-                               break;
-                       }
-
-                       static_cast<Call *>(req)->Handle();
-               }
-       } /* Mainloop() */
-
 private:
-       Collectd::AsyncService service_;
+       CollectdImpl collectd_service_;
 
        std::unique_ptr<grpc::Server> server_;
-       std::unique_ptr<grpc::ServerCompletionQueue> cq_;
 }; /* class CollectdServer */
 
+class CollectdClient final
+{
+public:
+       CollectdClient(std::shared_ptr<grpc::ChannelInterface> channel) : stub_(Collectd::NewStub(channel)) {
+       }
+
+       int PutValues(value_list_t const *vl) {
+               grpc::ClientContext ctx;
+
+               PutValuesRequest req;
+               auto status = marshal_value_list(vl, req.mutable_value_list());
+               if (!status.ok()) {
+                       ERROR("grpc: Marshalling value_list_t failed.");
+                       return -1;
+               }
+
+               PutValuesResponse res;
+               auto stream = stub_->PutValues(&ctx, &res);
+               if (!stream->Write(req)) {
+                       NOTICE("grpc: Broken stream.");
+                       /* intentionally not returning. */
+               }
+
+               stream->WritesDone();
+               status = stream->Finish();
+               if (!status.ok()) {
+                       ERROR ("grpc: Error while closing stream.");
+                       return -1;
+               }
+
+               return 0;
+       } /* int PutValues */
+
+private:
+       std::unique_ptr<Collectd::Stub> stub_;
+};
+
 static CollectdServer *server = nullptr;
 
 /*
  * collectd plugin interface
  */
-
 extern "C" {
-       static pthread_t *workers;
-       static size_t workers_num = 5;
+       static void c_grpc_destroy_write_callback (void *ptr) {
+               delete (CollectdClient *) ptr;
+       }
 
-       static void *worker_thread(void *arg)
-       {
-               CollectdServer *s = (CollectdServer *)arg;
-               s->Mainloop();
-               return NULL;
-       } /* worker_thread() */
+       static int c_grpc_write(__attribute__((unused)) data_set_t const *ds,
+                       value_list_t const *vl,
+                       user_data_t *ud) {
+               CollectdClient *c = (CollectdClient *) ud->data;
+               return c->PutValues(vl);
+       }
 
        static int c_grpc_config_listen(oconfig_item_t *ci)
        {
@@ -523,7 +503,7 @@ extern "C" {
                                        return -1;
                                }
                        }
-                       else if (!strcasecmp("SSLRootCerts", child->key)) {
+                       else if (!strcasecmp("SSLCACertificateFile", child->key)) {
                                char *certs = NULL;
                                if (cf_util_get_string(child, &certs)) {
                                        ERROR("grpc: Option `%s` expects a string value",
@@ -532,7 +512,7 @@ extern "C" {
                                }
                                ssl_opts->pem_root_certs = read_file(certs);
                        }
-                       else if (!strcasecmp("SSLServerKey", child->key)) {
+                       else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
                                char *key = NULL;
                                if (cf_util_get_string(child, &key)) {
                                        ERROR("grpc: Option `%s` expects a string value",
@@ -541,7 +521,7 @@ extern "C" {
                                }
                                pkcp.private_key = read_file(key);
                        }
-                       else if (!strcasecmp("SSLServerCert", child->key)) {
+                       else if (!strcasecmp("SSLCertificateFile", child->key)) {
                                char *cert = NULL;
                                if (cf_util_get_string(child, &cert)) {
                                        ERROR("grpc: Option `%s` expects a string value",
@@ -566,6 +546,78 @@ extern "C" {
                return 0;
        } /* c_grpc_config_listen() */
 
+       static int c_grpc_config_server(oconfig_item_t *ci)
+       {
+               if ((ci->values_num != 2)
+                               || (ci->values[0].type != OCONFIG_TYPE_STRING)
+                               || (ci->values[1].type != OCONFIG_TYPE_STRING)) {
+                       ERROR("grpc: The `%s` config option needs exactly "
+                                       "two string argument (address and port).", ci->key);
+                       return -1;
+               }
+
+               grpc::SslCredentialsOptions ssl_opts;
+               bool use_ssl = false;
+
+               for (int i = 0; i < ci->children_num; i++) {
+                       oconfig_item_t *child = ci->children + i;
+
+                       if (!strcasecmp("EnableSSL", child->key)) {
+                               if (cf_util_get_boolean(child, &use_ssl)) {
+                                       return -1;
+                               }
+                       }
+                       else if (!strcasecmp("SSLCACertificateFile", child->key)) {
+                               char *certs = NULL;
+                               if (cf_util_get_string(child, &certs)) {
+                                       return -1;
+                               }
+                               ssl_opts.pem_root_certs = read_file(certs);
+                       }
+                       else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
+                               char *key = NULL;
+                               if (cf_util_get_string(child, &key)) {
+                                       return -1;
+                               }
+                               ssl_opts.pem_private_key = read_file(key);
+                       }
+                       else if (!strcasecmp("SSLCertificateFile", child->key)) {
+                               char *cert = NULL;
+                               if (cf_util_get_string(child, &cert)) {
+                                       return -1;
+                               }
+                               ssl_opts.pem_cert_chain = read_file(cert);
+                       }
+                       else {
+                               WARNING("grpc: Option `%s` not allowed in <%s> block.",
+                                               child->key, ci->key);
+                       }
+               }
+
+               auto node    = grpc::string(ci->values[0].value.string);
+               auto service = grpc::string(ci->values[1].value.string);
+               auto addr    = node + ":" + service;
+
+               CollectdClient *client;
+               if (use_ssl) {
+                       auto channel_creds = grpc::SslCredentials(ssl_opts);
+                       auto channel = grpc::CreateChannel(addr, channel_creds);
+                       client = new CollectdClient(channel);
+               } else {
+                       auto channel = grpc::CreateChannel(addr, grpc::InsecureChannelCredentials());
+                       client = new CollectdClient(channel);
+               }
+
+               auto callback_name = grpc::string("grpc/") + addr;
+               user_data_t ud = {
+                       .data = client,
+                       .free_func = c_grpc_destroy_write_callback,
+               };
+
+               plugin_register_write (callback_name.c_str(), c_grpc_write, &ud);
+               return 0;
+       } /* c_grpc_config_server() */
+
        static int c_grpc_config(oconfig_item_t *ci)
        {
                int i;
@@ -577,12 +629,11 @@ extern "C" {
                                if (c_grpc_config_listen(child))
                                        return -1;
                        }
-                       else if (!strcasecmp("WorkerThreads", child->key)) {
-                               int n;
-                               if (cf_util_get_int(child, &n))
+                       else if (!strcasecmp("Server", child->key)) {
+                               if (c_grpc_config_server(child))
                                        return -1;
-                               workers_num = (size_t)n;
                        }
+
                        else {
                                WARNING("grpc: Option `%s` not allowed here.", child->key);
                        }
@@ -594,47 +645,22 @@ extern "C" {
        static int c_grpc_init(void)
        {
                server = new CollectdServer();
-               size_t i;
-
-               if (! server) {
+               if (!server) {
                        ERROR("grpc: Failed to create server");
                        return -1;
                }
 
-               workers = (pthread_t *)calloc(workers_num, sizeof(*workers));
-               if (! workers) {
-                       delete server;
-                       server = nullptr;
-
-                       ERROR("grpc: Failed to allocate worker threads");
-                       return -1;
-               }
-
                server->Start();
-               for (i = 0; i < workers_num; i++) {
-                       plugin_thread_create(&workers[i], /* attr = */ NULL,
-                                       worker_thread, server);
-               }
-               INFO("grpc: Started %zu workers", workers_num);
                return 0;
        } /* c_grpc_init() */
 
        static int c_grpc_shutdown(void)
        {
-               size_t i;
-
                if (!server)
-                       return -1;
+                       return 0;
 
                server->Shutdown();
 
-               INFO("grpc: Waiting for %zu workers to terminate", workers_num);
-               for (i = 0; i < workers_num; i++)
-                       pthread_join(workers[i], NULL);
-               free(workers);
-               workers = NULL;
-               workers_num = 0;
-
                delete server;
                server = nullptr;
 
index 3de18fd..31960b5 100644 (file)
@@ -30,9 +30,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 # include <netdb.h>
 # include <netinet/in.h>
@@ -88,19 +88,9 @@ static int hddtemp_query_daemon (char *buffer, int buffer_size)
        const char *host;
        const char *port;
 
-       struct addrinfo  ai_hints;
-       struct addrinfo *ai_list, *ai_ptr;
+       struct addrinfo *ai_list;
        int              ai_return;
 
-       memset (&ai_hints, '\0', sizeof (ai_hints));
-       ai_hints.ai_flags    = 0;
-#ifdef AI_ADDRCONFIG
-       ai_hints.ai_flags   |= AI_ADDRCONFIG;
-#endif
-       ai_hints.ai_family   = PF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_STREAM;
-       ai_hints.ai_protocol = IPPROTO_TCP;
-
        host = hddtemp_host;
        if (host == NULL)
                host = HDDTEMP_DEF_HOST;
@@ -109,6 +99,13 @@ static int hddtemp_query_daemon (char *buffer, int buffer_size)
        if (strlen (port) == 0)
                port = HDDTEMP_DEF_PORT;
 
+       struct addrinfo ai_hints = {
+               .ai_flags = AI_ADDRCONFIG,
+               .ai_family = AF_UNSPEC,
+               .ai_protocol = IPPROTO_TCP,
+               .ai_socktype = SOCK_STREAM
+       };
+
        if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0)
        {
                char errbuf[1024];
@@ -121,7 +118,7 @@ static int hddtemp_query_daemon (char *buffer, int buffer_size)
        }
 
        fd = -1;
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                /* create our socket descriptor */
                fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
@@ -229,12 +226,9 @@ static int hddtemp_config (const char *key, const char *value)
 
 static void hddtemp_submit (char *type_instance, double value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "hddtemp", sizeof (vl.plugin));
@@ -252,7 +246,6 @@ static int hddtemp_read (void)
        char *saveptr;
        int num_fields;
        int num_disks;
-       int i;
 
        /* get data from daemon */
        if (hddtemp_query_daemon (buf, sizeof (buf)) < 0)
@@ -273,7 +266,7 @@ static int hddtemp_read (void)
 
        num_disks = num_fields / 4;
 
-       for (i = 0; i < num_disks; i++)
+       for (int i = 0; i < num_disks; i++)
        {
                char *name;
                double temperature;
diff --git a/src/hugepages.c b/src/hugepages.c
new file mode 100644 (file)
index 0000000..f62df83
--- /dev/null
@@ -0,0 +1,278 @@
+/*-
+ * collectd - src/hugepages.c
+ * MIT License
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * 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:
+ *   Jaroslav Safka <jaroslavx.safka@intel.com>
+ *   Kim-Marie Jones <kim-marie.jones@intel.com>
+ *   Florian Forster <octo at collectd.org>
+ */
+
+#include "collectd.h"
+
+#include "common.h" /* auxiliary functions */
+#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
+
+static const char g_plugin_name[] = "hugepages";
+
+static _Bool g_flag_rpt_numa = 1;
+static _Bool g_flag_rpt_mm = 1;
+
+static _Bool g_values_pages = 1;
+static _Bool g_values_bytes = 0;
+static _Bool g_values_percent = 0;
+
+#define HP_HAVE_NR 0x01
+#define HP_HAVE_SURPLUS 0x02
+#define HP_HAVE_FREE 0x04
+#define HP_HAVE_ALL 0x07
+
+struct entry_info {
+  char *d_name;
+  const char *node;
+  size_t page_size_kb;
+
+  gauge_t nr;
+  gauge_t surplus;
+  gauge_t free;
+  uint8_t flags;
+};
+
+static int hp_config(oconfig_item_t *ci) {
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+    if (strcasecmp("ReportPerNodeHP", child->key) == 0)
+      cf_util_get_boolean(child, &g_flag_rpt_numa);
+    else if (strcasecmp("ReportRootHP", child->key) == 0)
+      cf_util_get_boolean(child, &g_flag_rpt_mm);
+    else if (strcasecmp("ValuesPages", child->key) == 0)
+      cf_util_get_boolean(child, &g_values_pages);
+    else if (strcasecmp("ValuesBytes", child->key) == 0)
+      cf_util_get_boolean(child, &g_values_bytes);
+    else if (strcasecmp("ValuesPercentage", child->key) == 0)
+      cf_util_get_boolean(child, &g_values_percent);
+    else
+      ERROR("%s: Invalid configuration option: \"%s\".", g_plugin_name,
+            child->key);
+  }
+
+  return (0);
+}
+
+static void submit_hp(const struct entry_info *info) {
+  value_list_t vl = VALUE_LIST_INIT;
+
+  vl.values = &(value_t) { .gauge = NAN };
+  vl.values_len = 1;
+
+  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+  sstrncpy(vl.plugin, g_plugin_name, sizeof(vl.plugin));
+  if (info->node) {
+    ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%zuKb",
+              info->node, info->page_size_kb);
+  } else {
+    ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%zuKb",
+              info->page_size_kb);
+  }
+
+  /* ensure all metrics have the same timestamp */
+  vl.time = cdtime();
+
+  gauge_t free = info->free;
+  gauge_t used = (info->nr + info->surplus) - info->free;
+
+  if (g_values_pages) {
+    sstrncpy(vl.type, "vmpage_number", sizeof(vl.type));
+    plugin_dispatch_multivalue(&vl, /* store_percentage = */ 0, DS_TYPE_GAUGE,
+                               "free", free, "used", used, NULL);
+  }
+  if (g_values_bytes) {
+    gauge_t page_size = (gauge_t)(1024 * info->page_size_kb);
+    sstrncpy(vl.type, "memory", sizeof(vl.type));
+    plugin_dispatch_multivalue(&vl, /* store_percentage = */ 0, DS_TYPE_GAUGE,
+                               "free", free * page_size, "used",
+                               used * page_size, NULL);
+  }
+  if (g_values_percent) {
+    sstrncpy(vl.type, "percent", sizeof(vl.type));
+    plugin_dispatch_multivalue(&vl, /* store_percentage = */ 1, DS_TYPE_GAUGE,
+                               "free", free, "used", used, NULL);
+  }
+}
+
+static int read_hugepage_entry(const char *path, const char *entry,
+                               void *e_info) {
+  char path2[PATH_MAX];
+  struct entry_info *info = e_info;
+  double value;
+
+  ssnprintf(path2, sizeof(path2), "%s/%s", path, entry);
+
+  FILE *fh = fopen(path2, "rt");
+  if (fh == NULL) {
+    ERROR("%s: cannot open %s", g_plugin_name, path2);
+    return -1;
+  }
+
+  if (fscanf(fh, "%lf", &value) != 1) {
+    ERROR("%s: cannot parse file %s", g_plugin_name, path2);
+    fclose(fh);
+    return -1;
+  }
+  fclose(fh);
+
+  if (strcmp(entry, "nr_hugepages") == 0) {
+    info->nr = value;
+    info->flags |= HP_HAVE_NR;
+  } else if (strcmp(entry, "surplus_hugepages") == 0) {
+    info->surplus = value;
+    info->flags |= HP_HAVE_SURPLUS;
+  } else if (strcmp(entry, "free_hugepages") == 0) {
+    info->free = value;
+    info->flags |= HP_HAVE_FREE;
+  }
+
+  if (info->flags != HP_HAVE_ALL) {
+    return 0;
+  }
+
+  submit_hp(info);
+
+  /* Reset flags so subsequent calls don't submit again. */
+  info->flags = 0;
+  return 0;
+}
+
+static int read_syshugepages(const char *path, const char *node) {
+  static const char hugepages_dir[] = "hugepages-";
+  DIR *dir;
+  struct dirent *result;
+  char path2[PATH_MAX];
+
+  dir = opendir(path);
+  if (dir == NULL) {
+    ERROR("%s: cannot open directory %s", g_plugin_name, path);
+    return -1;
+  }
+
+  /* read "hugepages-XXXXXkB" entries */
+  while ((result = readdir(dir)) != NULL) {
+    if (strncmp(result->d_name, hugepages_dir, sizeof(hugepages_dir) - 1)) {
+      /* not node dir */
+      errno = 0;
+      continue;
+    }
+
+    long page_size = strtol(result->d_name + strlen(hugepages_dir),
+                            /* endptr = */ NULL, /* base = */ 10);
+    if (errno != 0) {
+      char errbuf[1024];
+      ERROR("%s: failed to determine page size from directory name \"%s\": %s",
+            g_plugin_name, result->d_name,
+            sstrerror(errno, errbuf, sizeof(errbuf)));
+      continue;
+    }
+
+    /* /sys/devices/system/node/node?/hugepages/ */
+    ssnprintf(path2, sizeof(path2), "%s/%s", path, result->d_name);
+
+    walk_directory(path2, read_hugepage_entry,
+                   &(struct entry_info){
+                       .d_name = result->d_name,
+                       .node = node,
+                       .page_size_kb = (size_t)page_size,
+                   },
+                   /* hidden = */ 0);
+    errno = 0;
+  }
+
+  /* Check if NULL return from readdir() was an error */
+  if (errno != 0) {
+    ERROR("%s: readdir failed", g_plugin_name);
+    closedir(dir);
+    return -1;
+  }
+
+  closedir(dir);
+  return 0;
+}
+
+static int read_nodes(void) {
+  static const char sys_node[] = "/sys/devices/system/node";
+  static const char node_string[] = "node";
+  static const char sys_node_hugepages[] =
+      "/sys/devices/system/node/%s/hugepages";
+  DIR *dir;
+  struct dirent *result;
+  char path[PATH_MAX];
+
+  dir = opendir(sys_node);
+  if (dir == NULL) {
+    ERROR("%s: cannot open directory %s", g_plugin_name, sys_node);
+    return -1;
+  }
+
+  while ((result = readdir(dir)) != NULL) {
+    if (strncmp(result->d_name, node_string, sizeof(node_string) - 1)) {
+      /* not node dir */
+      errno = 0;
+      continue;
+    }
+
+    ssnprintf(path, sizeof(path), sys_node_hugepages, result->d_name);
+    read_syshugepages(path, result->d_name);
+    errno = 0;
+  }
+
+  /* Check if NULL return from readdir() was an error */
+  if (errno != 0) {
+    ERROR("%s: readdir failed", g_plugin_name);
+    closedir(dir);
+    return -1;
+  }
+
+  closedir(dir);
+  return 0;
+}
+
+static int huge_read(void) {
+  static const char sys_mm_hugepages[] = "/sys/kernel/mm/hugepages";
+
+  if (g_flag_rpt_mm) {
+    if (read_syshugepages(sys_mm_hugepages, "mm") != 0) {
+      return -1;
+    }
+  }
+  if (g_flag_rpt_numa) {
+    if (read_nodes() != 0) {
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+void module_register(void) {
+  plugin_register_complex_config(g_plugin_name, hp_config);
+  plugin_register_read(g_plugin_name, huge_read);
+}
index bc2121b..849de95 100644 (file)
@@ -23,9 +23,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_ignorelist.h"
 
 #if HAVE_SYS_TYPES_H
@@ -84,12 +84,14 @@ static const char *config_keys[] =
 {
        "Interface",
        "IgnoreSelected",
-       NULL
+       "ReportInactive",
 };
-static int config_keys_num = 2;
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
 
 static ignorelist_t *ignorelist = NULL;
 
+static _Bool report_inactive = 1;
+
 #ifdef HAVE_LIBKSTAT
 #define MAX_NUMIF 256
 extern kstat_ctl_t *kc;
@@ -114,6 +116,8 @@ static int interface_config (const char *key, const char *value)
                        invert = 0;
                ignorelist_set_invert (ignorelist, invert);
        }
+       else if (strcasecmp (key, "ReportInactive") == 0)
+               report_inactive = IS_TRUE (value);
        else if (strcasecmp (key, "UniqueName") == 0)
        {
                #ifdef HAVE_LIBKSTAT
@@ -164,17 +168,17 @@ static void if_submit (const char *dev, const char *type,
                derive_t rx,
                derive_t tx)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
+       value_t values[] = {
+               { .derive = rx },
+               { .derive = tx },
+       };
 
        if (ignorelist_match (ignorelist, dev) != 0)
                return;
 
-       values[0].derive = rx;
-       values[1].derive = tx;
-
        vl.values = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "interface", sizeof (vl.plugin));
        sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
@@ -187,7 +191,6 @@ static int interface_read (void)
 {
 #if HAVE_GETIFADDRS
        struct ifaddrs *if_list;
-       struct ifaddrs *if_ptr;
 
 /* Darwin/Mac OS X and possible other *BSDs */
 #if HAVE_STRUCT_IF_DATA
@@ -217,11 +220,14 @@ static int interface_read (void)
        if (getifaddrs (&if_list) != 0)
                return (-1);
 
-       for (if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next)
+       for (struct ifaddrs *if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next)
        {
                if (if_ptr->ifa_addr != NULL && if_ptr->ifa_addr->sa_family == AF_LINK) {
                        if_data = (struct IFA_DATA *) if_ptr->ifa_data;
 
+                       if (!report_inactive && if_data->IFA_RX_PACKT == 0 && if_data->IFA_TX_PACKT == 0)
+                               continue;
+
                        if_submit (if_ptr->ifa_name, "if_octets",
                                if_data->IFA_RX_BYTES,
                                if_data->IFA_TX_BYTES);
@@ -274,14 +280,17 @@ static int interface_read (void)
                if (numfields < 11)
                        continue;
 
-               incoming = atoll (fields[0]);
-               outgoing = atoll (fields[8]);
-               if_submit (device, "if_octets", incoming, outgoing);
-
                incoming = atoll (fields[1]);
                outgoing = atoll (fields[9]);
+               if (!report_inactive && incoming == 0 && outgoing == 0)
+                       continue;
+
                if_submit (device, "if_packets", incoming, outgoing);
 
+               incoming = atoll (fields[0]);
+               outgoing = atoll (fields[8]);
+               if_submit (device, "if_octets", incoming, outgoing);
+
                incoming = atoll (fields[2]);
                outgoing = atoll (fields[10]);
                if_submit (device, "if_errors", incoming, outgoing);
@@ -295,7 +304,6 @@ static int interface_read (void)
 /* #endif KERNEL_LINUX */
 
 #elif HAVE_LIBKSTAT
-       int i;
        derive_t rx;
        derive_t tx;
        char iname[DATA_MAX_NAME_LEN];
@@ -303,7 +311,7 @@ static int interface_read (void)
        if (kc == NULL)
                return (-1);
 
-       for (i = 0; i < numif; i++)
+       for (int i = 0; i < numif; i++)
        {
                if (kstat_read (kc, ksp[i], NULL) == -1)
                        continue;
@@ -314,26 +322,28 @@ static int interface_read (void)
                        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");
+               rx = get_kstat_value (ksp[i], "ipackets64");
+               tx = get_kstat_value (ksp[i], "opackets64");
                /* or fallback to 32bit */
                if (rx == -1LL)
-                       rx = get_kstat_value (ksp[i], "rbytes");
+                       rx = get_kstat_value (ksp[i], "ipackets");
                if (tx == -1LL)
-                       tx = get_kstat_value (ksp[i], "obytes");
+                       tx = get_kstat_value (ksp[i], "opackets");
+               if (!report_inactive && rx == 0 && tx == 0)
+                       continue;
                if ((rx != -1LL) || (tx != -1LL))
-                       if_submit (iname, "if_octets", rx, tx);
+                       if_submit (iname, "if_packets", rx, tx);
 
                /* try to get 64bit counters */
-               rx = get_kstat_value (ksp[i], "ipackets64");
-               tx = get_kstat_value (ksp[i], "opackets64");
+               rx = get_kstat_value (ksp[i], "rbytes64");
+               tx = get_kstat_value (ksp[i], "obytes64");
                /* or fallback to 32bit */
                if (rx == -1LL)
-                       rx = get_kstat_value (ksp[i], "ipackets");
+                       rx = get_kstat_value (ksp[i], "rbytes");
                if (tx == -1LL)
-                       tx = get_kstat_value (ksp[i], "opackets");
+                       tx = get_kstat_value (ksp[i], "obytes");
                if ((rx != -1LL) || (tx != -1LL))
-                       if_submit (iname, "if_packets", rx, tx);
+                       if_submit (iname, "if_octets", rx, tx);
 
                /* no 64bit error counters yet */
                rx = get_kstat_value (ksp[i], "ierrors");
@@ -345,17 +355,20 @@ static int interface_read (void)
 
 #elif defined(HAVE_LIBSTATGRAB)
        sg_network_io_stats *ios;
-       int i, num;
+       int num;
 
        ios = sg_get_network_io_stats (&num);
 
-       for (i = 0; i < num; i++)
+       for (int i = 0; i < num; i++) {
+               if (!report_inactive && ios[i].rx == 0 && ios[i].tx == 0)
+                       continue;
                if_submit (ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx);
+       }
 /* #endif HAVE_LIBSTATGRAB */
 
 #elif defined(HAVE_PERFSTAT)
        perfstat_id_t id;
-       int i, ifs;
+       int ifs;
 
        if ((nif =  perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)) < 0)
        {
@@ -381,8 +394,11 @@ static int interface_read (void)
                return (-1);
        }
 
-       for (i = 0; i < ifs; i++)
+       for (int i = 0; i < ifs; i++)
        {
+               if (!report_inactive && ifstat[i].ipackets == 0 && ifstat[i].opackets == 0)
+                       continue;
+
                if_submit (ifstat[i].name, "if_octets", ifstat[i].ibytes, ifstat[i].obytes);
                if_submit (ifstat[i].name, "if_packets", ifstat[i].ipackets ,ifstat[i].opackets);
                if_submit (ifstat[i].name, "if_errors", ifstat[i].ierrors, ifstat[i].oerrors );
@@ -401,3 +417,4 @@ void module_register (void)
 #endif
        plugin_register_read ("interface", interface_read);
 } /* void module_register */
+
index 00b3a5f..d6d2bbd 100644 (file)
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -27,9 +27,9 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #if KERNEL_LINUX
   /* _GNU_SOURCE is needed for struct shm_info.used_ids on musl libc */
@@ -97,12 +97,9 @@ static void ipc_submit_g (const char *plugin_instance,
                           const char *type_instance,
                           gauge_t value) /* {{{ */
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "ipc", sizeof (vl.plugin));
@@ -236,14 +233,14 @@ static int ipc_read_sem (void) /* {{{ */
   ipcinfo_sem_t *ipcinfo_sem;
   unsigned short sem_nsems=0;
   unsigned short sems=0;
-  int i,n;
+  int n;
 
   ipcinfo_sem = (ipcinfo_sem_t *)ipc_get_info(0,
     GET_IPCINFO_SEM_ALL, IPCINFO_SEM_VERSION, sizeof(ipcinfo_sem_t), &n);
   if (ipcinfo_sem == NULL)
     return -1;
 
-  for (i=0; i<n; i++) {
+  for (int i=0; i<n; i++) {
     sem_nsems += ipcinfo_sem[i].sem_nsems;
     sems++;
   }
@@ -261,14 +258,14 @@ static int ipc_read_shm (void) /* {{{ */
   ipcinfo_shm_t *pshm;
   unsigned int shm_segments=0;
   size64_t shm_bytes=0;
-  int i,n;
+  int n;
 
   ipcinfo_shm = (ipcinfo_shm_t *)ipc_get_info(0,
     GET_IPCINFO_SHM_ALL, IPCINFO_SHM_VERSION, sizeof(ipcinfo_shm_t), &n);
   if (ipcinfo_shm == NULL)
     return -1;
 
-  for (i=0, pshm=ipcinfo_shm; i<n; i++, pshm++) {
+  for (int i=0, pshm=ipcinfo_shm; i<n; i++, pshm++) {
     shm_segments++;
     shm_bytes += pshm->shm_segsz;
   }
@@ -287,14 +284,14 @@ static int ipc_read_msg (void) /* {{{ */
   uint32_t msg_used_space=0;
   uint32_t msg_alloc_queues=0;
   msgqnum32_t msg_qnum=0;
-  int i,n;
+  int n;
 
   ipcinfo_msg = (ipcinfo_msg_t *)ipc_get_info(0,
     GET_IPCINFO_MSG_ALL, IPCINFO_MSG_VERSION, sizeof(ipcinfo_msg_t), &n);
   if (ipcinfo_msg == NULL)
     return -1;
 
-  for (i=0; i<n; i++) {
+  for (int i=0; i<n; i++) {
     msg_alloc_queues++;
     msg_used_space += ipcinfo_msg[i].msg_cbytes;
     msg_qnum += ipcinfo_msg[i].msg_qnum;
index c3aa558..a42b787 100644 (file)
@@ -24,6 +24,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_ignorelist.h"
@@ -80,9 +81,7 @@ static int c_ipmi_nofiy_notpresent = 0;
  */
 static void c_ipmi_error (const char *func, int status)
 {
-  char errbuf[4096];
-
-  memset (errbuf, 0, sizeof (errbuf));
+  char errbuf[4096] = { 0 };
 
   if (IPMI_IS_OS_ERR (status))
   {
@@ -116,7 +115,6 @@ static void sensor_read_handler (ipmi_sensor_t *sensor,
     ipmi_states_t __attribute__((unused)) *states,
     void *user_data)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
   c_ipmi_sensor_list_t *list_item = (c_ipmi_sensor_list_t *)user_data;
@@ -215,9 +213,7 @@ static void sensor_read_handler (ipmi_sensor_t *sensor,
     return;
   }
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
 
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -234,7 +230,7 @@ static int sensor_list_add (ipmi_sensor_t *sensor)
   c_ipmi_sensor_list_t *list_item;
   c_ipmi_sensor_list_t *list_prev;
 
-  char buffer[DATA_MAX_NAME_LEN];
+  char buffer[DATA_MAX_NAME_LEN] = { 0 };
   const char *entity_id_string;
   char sensor_name[DATA_MAX_NAME_LEN];
   char *sensor_name_ptr;
@@ -244,7 +240,6 @@ static int sensor_list_add (ipmi_sensor_t *sensor)
 
   sensor_id = ipmi_sensor_convert_to_id (sensor);
 
-  memset (buffer, 0, sizeof (buffer));
   ipmi_sensor_get_name (sensor, buffer, sizeof (buffer));
   buffer[sizeof (buffer) - 1] = 0;
 
@@ -434,11 +429,9 @@ static int sensor_list_remove (ipmi_sensor_t *sensor)
 
 static int sensor_list_read_all (void)
 {
-  c_ipmi_sensor_list_t *list_item;
-
   pthread_mutex_lock (&sensor_list_lock);
 
-  for (list_item = sensor_list;
+  for (c_ipmi_sensor_list_t *list_item = sensor_list;
       list_item != NULL;
       list_item = list_item->next)
   {
@@ -550,7 +543,6 @@ static void domain_connection_change_handler (ipmi_domain_t *domain,
 static int thread_init (os_handler_t **ret_os_handler)
 {
   os_handler_t *os_handler;
-  ipmi_open_option_t open_option[1];
   ipmi_con_t *smi_connection = NULL;
   ipmi_domain_id_t domain_id;
   int status;
@@ -574,9 +566,12 @@ static int thread_init (os_handler_t **ret_os_handler)
     return (-1);
   }
 
-  memset (open_option, 0, sizeof (open_option));
-  open_option[0].option = IPMI_OPEN_OPTION_ALL;
-  open_option[0].ival = 1;
+  ipmi_open_option_t open_option[1] = {
+    [0] = {
+      .option = IPMI_OPEN_OPTION_ALL,
+      { .ival = 1 }
+    }
+  };
 
   status = ipmi_open_domain ("mydomain", &smi_connection, /* num_con = */ 1,
       domain_connection_change_handler, /* user data = */ NULL,
index 0103725..35975e6 100644 (file)
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <libiptc/libiptc.h>
 #include <libiptc/libip6tc.h>
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 /*
  * iptc_handle_t was available before libiptc was officially available as a
  * shared library. Note, that when the shared lib was introduced, the API and
@@ -111,7 +115,8 @@ static int iptables_config (const char *key, const char *value)
     else
         return (1);
 
-    ip_chain_t temp, *final, **list;
+    ip_chain_t  temp = { 0 };
+    ip_chain_t *final, **list;
     char *table;
     int   table_len;
     char *chain;
@@ -121,8 +126,6 @@ static int iptables_config (const char *key, const char *value)
     char *fields[4];
     int   fields_num;
 
-    memset (&temp, 0, sizeof (temp));
-
     value_copy = strdup (value);
     if (value_copy == NULL)
     {
@@ -239,7 +242,6 @@ static int submit6_match (const struct ip6t_entry_match *match,
                           int rule_num)
 {
     int status;
-    value_t values[1];
     value_list_t vl = VALUE_LIST_INIT;
 
     /* Select the rules to collect */
@@ -257,8 +259,6 @@ static int submit6_match (const struct ip6t_entry_match *match,
             return (0);
     }
 
-    vl.values = values;
-    vl.values_len = 1;
     sstrncpy (vl.host, hostname_g, sizeof (vl.host));
     sstrncpy (vl.plugin, "ip6tables", sizeof (vl.plugin));
 
@@ -282,16 +282,16 @@ static int submit6_match (const struct ip6t_entry_match *match,
     }
 
     sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
-    values[0].derive = (derive_t) entry->counters.bcnt;
+    vl.values = &(value_t) { .derive = (derive_t) entry->counters.bcnt };
+    vl.values_len = 1;
     plugin_dispatch_values (&vl);
 
     sstrncpy (vl.type, "ipt_packets", sizeof (vl.type));
-    values[0].derive = (derive_t) entry->counters.pcnt;
+    vl.values = &(value_t) { .derive = (derive_t) entry->counters.pcnt };
     plugin_dispatch_values (&vl);
 
     return (0);
-} /* int submit_match */
-
+} /* int submit6_match */
 
 /* This needs to return `int' for IPT_MATCH_ITERATE to work. */
 static int submit_match (const struct ipt_entry_match *match,
@@ -300,7 +300,6 @@ static int submit_match (const struct ipt_entry_match *match,
                          int rule_num)
 {
     int status;
-    value_t values[1];
     value_list_t vl = VALUE_LIST_INIT;
 
     /* Select the rules to collect */
@@ -318,8 +317,6 @@ static int submit_match (const struct ipt_entry_match *match,
             return (0);
     }
 
-    vl.values = values;
-    vl.values_len = 1;
     sstrncpy (vl.host, hostname_g, sizeof (vl.host));
     sstrncpy (vl.plugin, "iptables", sizeof (vl.plugin));
 
@@ -343,11 +340,12 @@ static int submit_match (const struct ipt_entry_match *match,
     }
 
     sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
-    values[0].derive = (derive_t) entry->counters.bcnt;
+    vl.values = &(value_t) { .derive = (derive_t) entry->counters.bcnt };
+    vl.values_len = 1;
     plugin_dispatch_values (&vl);
 
     sstrncpy (vl.type, "ipt_packets", sizeof (vl.type));
-    values[0].derive = (derive_t) entry->counters.pcnt;
+    vl.values = &(value_t) { .derive = (derive_t) entry->counters.pcnt };
     plugin_dispatch_values (&vl);
 
     return (0);
@@ -420,12 +418,11 @@ static void submit_chain (iptc_handle_t *handle, ip_chain_t *chain)
 
 static int iptables_read (void)
 {
-    int i;
     int num_failures = 0;
     ip_chain_t *chain;
 
     /* Init the iptc handle structure and query the correct table */
-    for (i = 0; i < chain_num; i++)
+    for (int i = 0; i < chain_num; i++)
     {
         chain = chain_list[i];
 
@@ -489,9 +486,7 @@ static int iptables_read (void)
 
 static int iptables_shutdown (void)
 {
-    int i;
-
-    for (i = 0; i < chain_num; i++)
+    for (int i = 0; i < chain_num; i++)
     {
         if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT))
             sfree (chain_list[i]->rule.comment);
@@ -502,10 +497,30 @@ static int iptables_shutdown (void)
     return (0);
 } /* int iptables_shutdown */
 
+static int iptables_init (void)
+{
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_ADMIN)
+    if (check_capability (CAP_NET_ADMIN) != 0)
+    {
+        if (getuid () == 0)
+            WARNING ("iptables plugin: Running collectd as root, but the "
+                  "CAP_NET_ADMIN capability is missing. The plugin's read "
+                  "function will probably fail. Is your init system dropping "
+                  "capabilities?");
+        else
+            WARNING ("iptables plugin: collectd doesn't have the CAP_NET_ADMIN "
+                  "capability. If you don't want to run collectd as root, try "
+                  "running \"setcap cap_net_admin=ep\" on the collectd binary.");
+    }
+#endif
+    return (0);
+} /* int iptables_init */
+
 void module_register (void)
 {
     plugin_register_config ("iptables", iptables_config,
                              config_keys, config_keys_num);
+    plugin_register_init ("iptables", iptables_init);
     plugin_register_read ("iptables", iptables_read);
     plugin_register_shutdown ("iptables", iptables_shutdown);
 } /* void module_register */
index 760aa3c..d2ceb50 100644 (file)
@@ -31,6 +31,7 @@
  */
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 
@@ -227,12 +228,9 @@ static int get_ti (struct ip_vs_dest_entry *de, char *ti, size_t size)
 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;
 
-       values[0].derive = value;
-
-       vl.values     = values;
+       vl.values     = &(value_t) { .derive = value };
        vl.values_len = 1;
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -249,14 +247,14 @@ static void cipvs_submit_connections (const char *pi, const 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];
+       value_t values[] = {
+               { .derive = rx },
+               { .derive = tx },
+       };
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = rx;
-       values[1].derive = tx;
-
        vl.values     = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "ipvs", sizeof (vl.plugin));
@@ -291,8 +289,6 @@ static void cipvs_submit_service (struct ip_vs_service_entry *se)
 
        char pi[DATA_MAX_NAME_LEN];
 
-       size_t i;
-
        if (0 != get_pi (se, pi, sizeof (pi)))
        {
                free (dests);
@@ -303,7 +299,7 @@ static void cipvs_submit_service (struct ip_vs_service_entry *se)
        cipvs_submit_if (pi, "if_packets", NULL, stats.inpkts, stats.outpkts);
        cipvs_submit_if (pi, "if_octets", NULL, stats.inbytes, stats.outbytes);
 
-       for (i = 0; i < dests->num_dests; ++i)
+       for (size_t i = 0; i < dests->num_dests; ++i)
                cipvs_submit_dest (pi, &dests->entrytable[i]);
 
        free (dests);
@@ -313,7 +309,6 @@ static void cipvs_submit_service (struct ip_vs_service_entry *se)
 static int cipvs_read (void)
 {
        struct ip_vs_get_services *services = NULL;
-       size_t i;
 
        if (sockfd < 0)
                return (-1);
@@ -321,7 +316,7 @@ static int cipvs_read (void)
        if (NULL == (services = ipvs_get_services ()))
                return -1;
 
-       for (i = 0; i < services->num_services; ++i)
+       for (size_t i = 0; i < services->num_services; ++i)
                cipvs_submit_service (&services->entrytable[i]);
 
        free (services);
index 93f3f53..cb444a4 100644 (file)
--- a/src/irq.c
+++ b/src/irq.c
@@ -22,9 +22,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_ignorelist.h"
 
 #if !KERNEL_LINUX
@@ -72,15 +72,12 @@ static int irq_config (const char *key, const char *value)
 
 static void irq_submit (const char *irq_name, derive_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
        if (ignorelist_match (ignorelist, irq_name) != 0)
                return;
 
-       values[0].derive = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .derive = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "irq", sizeof (vl.plugin));
index 01dc1b8..cd173c5 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "filter_chain.h"
@@ -506,7 +507,6 @@ static jobject ctoj_oconfig_item (JNIEnv *jvm_env, /* {{{ */
   jmethodID m_addchild;
   jobject o_key;
   jobject o_ocitem;
-  int i;
 
   c_ocitem = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/OConfigItem");
   if (c_ocitem == NULL)
@@ -571,7 +571,7 @@ static jobject ctoj_oconfig_item (JNIEnv *jvm_env, /* {{{ */
   (*jvm_env)->DeleteLocalRef (jvm_env, o_key);
 
   /* Call OConfigItem.addValue for each value */
-  for (i = 0; i < ci->values_num; i++) /* {{{ */
+  for (int i = 0; i < ci->values_num; i++) /* {{{ */
   {
     jobject o_value;
 
@@ -589,7 +589,7 @@ static jobject ctoj_oconfig_item (JNIEnv *jvm_env, /* {{{ */
   } /* }}} for (i = 0; i < ci->values_num; i++) */
 
   /* Call OConfigItem.addChild for each child */
-  for (i = 0; i < ci->children_num; i++) /* {{{ */
+  for (int i = 0; i < ci->children_num; i++) /* {{{ */
   {
     jobject o_child;
 
@@ -617,7 +617,6 @@ static jobject ctoj_data_set (JNIEnv *jvm_env, const data_set_t *ds) /* {{{ */
   jmethodID m_add;
   jobject o_type;
   jobject o_dataset;
-  size_t i;
 
   /* Look up the org/collectd/api/DataSet class */
   c_dataset = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/DataSet");
@@ -667,7 +666,7 @@ static jobject ctoj_data_set (JNIEnv *jvm_env, const data_set_t *ds) /* {{{ */
   /* Decrease reference counter on the java.lang.String object. */
   (*jvm_env)->DeleteLocalRef (jvm_env, o_type);
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     jobject o_datasource;
 
@@ -762,7 +761,6 @@ static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */
   jmethodID m_valuelist_constructor;
   jobject o_valuelist;
   int status;
-  size_t i;
 
   /* First, create a new ValueList instance..
    * Look up the class.. */
@@ -845,7 +843,7 @@ static jobject ctoj_value_list (JNIEnv *jvm_env, /* {{{ */
     return (NULL);
   }
 
-  for (i = 0; i < vl->values_len; i++)
+  for (size_t i = 0; i < vl->values_len; i++)
   {
     status = ctoj_value_list_add_value (jvm_env, vl->values[i], ds->ds[i].type,
         c_valuelist, o_valuelist);
@@ -1116,7 +1114,6 @@ static int jtoc_values_array (JNIEnv *jvm_env, /* {{{ */
 
   value_t *values;
   int values_num;
-  int i;
 
   values_num = ds->ds_num;
 
@@ -1176,7 +1173,7 @@ static int jtoc_values_array (JNIEnv *jvm_env, /* {{{ */
     BAIL_OUT (-1);
   }
 
-  for (i = 0; i < values_num; i++)
+  for (int i = 0; i < values_num; i++)
   {
     jobject o_number;
     int status;
@@ -1363,12 +1360,9 @@ static jint JNICALL cjni_api_dispatch_values (JNIEnv *jvm_env, /* {{{ */
 static jint JNICALL cjni_api_dispatch_notification (JNIEnv *jvm_env, /* {{{ */
     jobject this, jobject o_notification)
 {
-  notification_t n;
+  notification_t n = { 0 };
   int status;
 
-  memset (&n, 0, sizeof (n));
-  n.meta = NULL;
-
   status = jtoc_notification (jvm_env, &n, o_notification);
   if (status != 0)
   {
@@ -1423,7 +1417,6 @@ static jint JNICALL cjni_api_register_init (JNIEnv *jvm_env, /* {{{ */
 static jint JNICALL cjni_api_register_read (JNIEnv *jvm_env, /* {{{ */
     jobject this, jobject o_name, jobject o_read)
 {
-  user_data_t ud;
   cjni_callback_info_t *cbi;
 
   cbi = cjni_callback_info_create (jvm_env, o_name, o_read, CB_TYPE_READ);
@@ -1432,12 +1425,11 @@ static jint JNICALL cjni_api_register_read (JNIEnv *jvm_env, /* {{{ */
 
   DEBUG ("java plugin: Registering new read callback: %s", cbi->name);
 
-  memset (&ud, 0, sizeof (ud));
-  ud.data = (void *) cbi;
-  ud.free_func = cjni_callback_info_destroy;
-
   plugin_register_complex_read (/* group = */ NULL, cbi->name, cjni_read,
-      /* interval = */ 0, &ud);
+      /* interval = */ 0, &(user_data_t) {
+        .data = cbi,
+        .free_func = cjni_callback_info_destroy,
+      });
 
   (*jvm_env)->DeleteLocalRef (jvm_env, o_read);
 
@@ -1447,7 +1439,6 @@ static jint JNICALL cjni_api_register_read (JNIEnv *jvm_env, /* {{{ */
 static jint JNICALL cjni_api_register_write (JNIEnv *jvm_env, /* {{{ */
     jobject this, jobject o_name, jobject o_write)
 {
-  user_data_t ud;
   cjni_callback_info_t *cbi;
 
   cbi = cjni_callback_info_create (jvm_env, o_name, o_write, CB_TYPE_WRITE);
@@ -1456,11 +1447,10 @@ static jint JNICALL cjni_api_register_write (JNIEnv *jvm_env, /* {{{ */
 
   DEBUG ("java plugin: Registering new write callback: %s", cbi->name);
 
-  memset (&ud, 0, sizeof (ud));
-  ud.data = (void *) cbi;
-  ud.free_func = cjni_callback_info_destroy;
-
-  plugin_register_write (cbi->name, cjni_write, &ud);
+  plugin_register_write (cbi->name, cjni_write, &(user_data_t) {
+        .data = cbi,
+        .free_func = cjni_callback_info_destroy,
+      });
 
   (*jvm_env)->DeleteLocalRef (jvm_env, o_write);
 
@@ -1470,7 +1460,6 @@ static jint JNICALL cjni_api_register_write (JNIEnv *jvm_env, /* {{{ */
 static jint JNICALL cjni_api_register_flush (JNIEnv *jvm_env, /* {{{ */
     jobject this, jobject o_name, jobject o_flush)
 {
-  user_data_t ud;
   cjni_callback_info_t *cbi;
 
   cbi = cjni_callback_info_create (jvm_env, o_name, o_flush, CB_TYPE_FLUSH);
@@ -1479,11 +1468,10 @@ static jint JNICALL cjni_api_register_flush (JNIEnv *jvm_env, /* {{{ */
 
   DEBUG ("java plugin: Registering new flush callback: %s", cbi->name);
 
-  memset (&ud, 0, sizeof (ud));
-  ud.data = (void *) cbi;
-  ud.free_func = cjni_callback_info_destroy;
-
-  plugin_register_flush (cbi->name, cjni_flush, &ud);
+  plugin_register_flush (cbi->name, cjni_flush, &(user_data_t) {
+        .data = cbi,
+        .free_func = cjni_callback_info_destroy,
+      });
 
   (*jvm_env)->DeleteLocalRef (jvm_env, o_flush);
 
@@ -1500,7 +1488,6 @@ static jint JNICALL cjni_api_register_shutdown (JNIEnv *jvm_env, /* {{{ */
 static jint JNICALL cjni_api_register_log (JNIEnv *jvm_env, /* {{{ */
     jobject this, jobject o_name, jobject o_log)
 {
-  user_data_t ud;
   cjni_callback_info_t *cbi;
 
   cbi = cjni_callback_info_create (jvm_env, o_name, o_log, CB_TYPE_LOG);
@@ -1509,11 +1496,10 @@ static jint JNICALL cjni_api_register_log (JNIEnv *jvm_env, /* {{{ */
 
   DEBUG ("java plugin: Registering new log callback: %s", cbi->name);
 
-  memset (&ud, 0, sizeof (ud));
-  ud.data = (void *) cbi;
-  ud.free_func = cjni_callback_info_destroy;
-
-  plugin_register_log (cbi->name, cjni_log, &ud);
+  plugin_register_log (cbi->name, cjni_log, &(user_data_t) {
+        .data = cbi,
+        .free_func = cjni_callback_info_destroy,
+      });
 
   (*jvm_env)->DeleteLocalRef (jvm_env, o_log);
 
@@ -1523,7 +1509,6 @@ static jint JNICALL cjni_api_register_log (JNIEnv *jvm_env, /* {{{ */
 static jint JNICALL cjni_api_register_notification (JNIEnv *jvm_env, /* {{{ */
     jobject this, jobject o_name, jobject o_notification)
 {
-  user_data_t ud;
   cjni_callback_info_t *cbi;
 
   cbi = cjni_callback_info_create (jvm_env, o_name, o_notification,
@@ -1533,11 +1518,10 @@ static jint JNICALL cjni_api_register_notification (JNIEnv *jvm_env, /* {{{ */
 
   DEBUG ("java plugin: Registering new notification callback: %s", cbi->name);
 
-  memset (&ud, 0, sizeof (ud));
-  ud.data = (void *) cbi;
-  ud.free_func = cjni_callback_info_destroy;
-
-  plugin_register_notification (cbi->name, cjni_notification, &ud);
+  plugin_register_notification (cbi->name, cjni_notification, &(user_data_t) {
+        .data = cbi,
+        .free_func = cjni_callback_info_destroy,
+      });
 
   (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
 
@@ -1567,9 +1551,8 @@ static jint JNICALL cjni_api_register_match_target (JNIEnv *jvm_env, /* {{{ */
 
   if (type == CB_TYPE_MATCH)
   {
-    match_proc_t m_proc;
+    match_proc_t m_proc = { 0 };
 
-    memset (&m_proc, 0, sizeof (m_proc));
     m_proc.create  = cjni_match_target_create;
     m_proc.destroy = cjni_match_target_destroy;
     m_proc.match   = (void *) cjni_match_target_invoke;
@@ -1578,9 +1561,8 @@ static jint JNICALL cjni_api_register_match_target (JNIEnv *jvm_env, /* {{{ */
   }
   else if (type == CB_TYPE_TARGET)
   {
-    target_proc_t t_proc;
+    target_proc_t t_proc = { 0 };
 
-    memset (&t_proc, 0, sizeof (t_proc));
     t_proc.create  = cjni_match_target_create;
     t_proc.destroy = cjni_match_target_destroy;
     t_proc.invoke  = cjni_match_target_invoke;
@@ -1985,11 +1967,10 @@ static int cjni_init_native (JNIEnv *jvm_env) /* {{{ */
 static int cjni_create_jvm (void) /* {{{ */
 {
   JNIEnv *jvm_env;
-  JavaVMInitArgs vm_args;
+  JavaVMInitArgs vm_args = { 0 };
   JavaVMOption vm_options[jvm_argc];
 
   int status;
-  size_t i;
 
   if (jvm != NULL)
     return (0);
@@ -2004,12 +1985,11 @@ static int cjni_create_jvm (void) /* {{{ */
 
   jvm_env = NULL;
 
-  memset (&vm_args, 0, sizeof (vm_args));
   vm_args.version = JNI_VERSION_1_2;
   vm_args.options = vm_options;
   vm_args.nOptions = (jint) jvm_argc;
 
-  for (i = 0; i < jvm_argc; i++)
+  for (size_t i = 0; i < jvm_argc; i++)
   {
     DEBUG ("java plugin: cjni_create_jvm: jvm_argv[%zu] = %s",
         i, jvm_argv[i]);
@@ -2085,11 +2065,10 @@ static JNIEnv *cjni_thread_attach (void) /* {{{ */
   else
   {
     int status;
-    JavaVMAttachArgs args;
+    JavaVMAttachArgs args = { 0 };
 
     assert (cjni_env->jvm_env == NULL);
 
-    memset (&args, 0, sizeof (args));
     args.version = JNI_VERSION_1_2;
 
     status = (*jvm)->AttachCurrentThread (jvm, (void *) &jvm_env, (void *) &args);
@@ -2227,8 +2206,7 @@ static int cjni_config_load_plugin (oconfig_item_t *ci) /* {{{ */
   { /* Replace all dots ('.') with slashes ('/'). Dots are usually used
        thorough the Java community, but (Sun's) `FindClass' and friends need
        slashes. */
-    size_t i;
-    for (i = 0; class->name[i] != 0; i++)
+    for (size_t i = 0; class->name[i] != 0; i++)
       if (class->name[i] == '.')
         class->name[i] = '/';
   }
@@ -2286,7 +2264,6 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */
   cjni_callback_info_t *cbi;
   jobject o_ocitem;
   const char *name;
-  size_t i;
 
   jclass class;
   jmethodID method;
@@ -2301,7 +2278,7 @@ static int cjni_config_plugin_block (oconfig_item_t *ci) /* {{{ */
   name = ci->values[0].value.string;
 
   cbi = NULL;
-  for (i = 0; i < java_callbacks_num; i++)
+  for (size_t i = 0; i < java_callbacks_num; i++)
   {
     if (java_callbacks[i].type != CB_TYPE_CONFIG)
       continue;
@@ -2353,12 +2330,11 @@ static int cjni_config_perform (oconfig_item_t *ci) /* {{{ */
   int success;
   int errors;
   int status;
-  int i;
 
   success = 0;
   errors = 0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -2721,7 +2697,6 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */
   jobject o_ci;
   jobject o_tmp;
   int type;
-  size_t i;
 
   cbi_ret = NULL;
   o_ci = NULL;
@@ -2766,7 +2741,7 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */
 
   /* Lets see if we have a matching factory here.. */
   cbi_factory = NULL;
-  for (i = 0; i < java_callbacks_num; i++)
+  for (size_t i = 0; i < java_callbacks_num; i++)
   {
     if (java_callbacks[i].type != type)
       continue;
@@ -2920,9 +2895,8 @@ static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */
    * `value_list_t'. */
   if (cbi->type == CB_TYPE_TARGET)
   {
-    value_list_t new_vl;
+    value_list_t new_vl = { 0 };
 
-    memset (&new_vl, 0, sizeof (new_vl));
     status = jtoc_value_list (jvm_env, &new_vl, o_vl);
     if (status != 0)
     {
@@ -2949,9 +2923,8 @@ static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */
 static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */
 {
   int status;
-  size_t i;
 
-  for (i = 0; i < java_callbacks_num; i++)
+  for (size_t i = 0; i < java_callbacks_num; i++)
   {
     if (java_callbacks[i].type != CB_TYPE_INIT)
       continue;
@@ -2976,9 +2949,8 @@ static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */
 static int cjni_shutdown_plugins (JNIEnv *jvm_env) /* {{{ */
 {
   int status;
-  size_t i;
 
-  for (i = 0; i < java_callbacks_num; i++)
+  for (size_t i = 0; i < java_callbacks_num; i++)
   {
     if (java_callbacks[i].type != CB_TYPE_SHUTDOWN)
       continue;
@@ -3001,15 +2973,13 @@ static int cjni_shutdown_plugins (JNIEnv *jvm_env) /* {{{ */
 static int cjni_shutdown (void) /* {{{ */
 {
   JNIEnv *jvm_env;
-  JavaVMAttachArgs args;
+  JavaVMAttachArgs args = { 0 };
   int status;
-  size_t i;
 
   if (jvm == NULL)
     return (0);
 
   jvm_env = NULL;
-  memset (&args, 0, sizeof (args));
   args.version = JNI_VERSION_1_2;
 
   status = (*jvm)->AttachCurrentThread (jvm, (void *) &jvm_env, &args);
@@ -3024,7 +2994,7 @@ static int cjni_shutdown (void) /* {{{ */
   cjni_shutdown_plugins (jvm_env);
 
   /* Release all the global references to callback functions */
-  for (i = 0; i < java_callbacks_num; i++)
+  for (size_t i = 0; i < java_callbacks_num; i++)
   {
     if (java_callbacks[i].object != NULL)
     {
@@ -3037,7 +3007,7 @@ static int cjni_shutdown (void) /* {{{ */
   sfree (java_callbacks);
 
   /* Release all the global references to directly loaded classes. */
-  for (i = 0; i < java_classes_list_len; i++)
+  for (size_t i = 0; i < java_classes_list_len; i++)
   {
     if (java_classes_list[i].object != NULL)
     {
@@ -3058,7 +3028,7 @@ static int cjni_shutdown (void) /* {{{ */
   pthread_key_delete (jvm_env_key);
 
   /* Free the JVM argument list */
-  for (i = 0; i < jvm_argc; i++)
+  for (size_t i = 0; i < jvm_argc; i++)
     sfree (jvm_argv[i]);
   jvm_argc = 0;
   sfree (jvm_argv);
index 77fd576..4dbee1e 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdarg.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
   (c)->errbuf[sizeof ((c)->errbuf) - 1] = 0; \
 } while (0)
 
-#if COLLECT_DEBUG
-# define LCC_DEBUG(...) printf (__VA_ARGS__)
-#else
-# define LCC_DEBUG(...) /**/
-#endif
-
 /*
  * Types
  */
@@ -118,6 +113,23 @@ typedef struct lcc_response_s lcc_response_t;
 /*
  * Private functions
  */
+__attribute__ ((format (printf, 1, 0)))
+static int lcc_tracef(char const *format, ...)
+{
+  va_list ap;
+  int status;
+
+  char const *trace = getenv (LCC_TRACE_ENV);
+  if (!trace || (strcmp ("", trace) == 0) || (strcmp ("0", trace) == 0))
+    return 0;
+
+  va_start (ap, format);
+  status = vprintf (format, ap);
+  va_end (ap);
+
+  return status;
+}
+
 /* Even though Posix requires "strerror_r" to return an "int",
  * some systems (e.g. the GNU libc) return a "char *" _and_
  * ignore the second argument ... -tokkee */
@@ -235,12 +247,10 @@ static void lcc_chomp (char *str) /* {{{ */
 
 static void lcc_response_free (lcc_response_t *res) /* {{{ */
 {
-  size_t i;
-
   if (res == NULL)
     return;
 
-  for (i = 0; i < res->lines_num; i++)
+  for (size_t i = 0; i < res->lines_num; i++)
     free (res->lines[i]);
   free (res->lines);
   res->lines = NULL;
@@ -250,7 +260,7 @@ static int lcc_send (lcc_connection_t *c, const char *command) /* {{{ */
 {
   int status;
 
-  LCC_DEBUG ("send:    --> %s\n", command);
+  lcc_tracef ("send:    --> %s\n", command);
 
   status = fprintf (c->fh, "%s\r\n", command);
   if (status < 0)
@@ -266,13 +276,11 @@ static int lcc_send (lcc_connection_t *c, const char *command) /* {{{ */
 static int lcc_receive (lcc_connection_t *c, /* {{{ */
     lcc_response_t *ret_res)
 {
-  lcc_response_t res;
+  lcc_response_t res = { 0 };
   char *ptr;
   char buffer[4096];
   size_t i;
 
-  memset (&res, 0, sizeof (res));
-
   /* Read the first line, containing the status and a message */
   ptr = fgets (buffer, sizeof (buffer), c->fh);
   if (ptr == NULL)
@@ -281,7 +289,7 @@ static int lcc_receive (lcc_connection_t *c, /* {{{ */
     return (-1);
   }
   lcc_chomp (buffer);
-  LCC_DEBUG ("receive: <-- %s\n", buffer);
+  lcc_tracef ("receive: <-- %s\n", buffer);
 
   /* Convert the leading status to an integer and make `ptr' to point to the
    * beginning of the message. */
@@ -329,7 +337,7 @@ static int lcc_receive (lcc_connection_t *c, /* {{{ */
       break;
     }
     lcc_chomp (buffer);
-    LCC_DEBUG ("receive: <-- %s\n", buffer);
+    lcc_tracef ("receive: <-- %s\n", buffer);
 
     res.lines[i] = strdup (buffer);
     if (res.lines[i] == NULL)
@@ -358,7 +366,7 @@ static int lcc_receive (lcc_connection_t *c, /* {{{ */
 static int lcc_sendreceive (lcc_connection_t *c, /* {{{ */
     const char *command, lcc_response_t *ret_res)
 {
-  lcc_response_t res;
+  lcc_response_t res = { 0 };
   int status;
 
   if (c->fh == NULL)
@@ -371,7 +379,6 @@ static int lcc_sendreceive (lcc_connection_t *c, /* {{{ */
   if (status != 0)
     return (status);
 
-  memset (&res, 0, sizeof (res));
   status = lcc_receive (c, &res);
   if (status == 0)
     memcpy (ret_res, &res, sizeof (*ret_res));
@@ -381,7 +388,7 @@ static int lcc_sendreceive (lcc_connection_t *c, /* {{{ */
 
 static int lcc_open_unixsocket (lcc_connection_t *c, const char *path) /* {{{ */
 {
-  struct sockaddr_un sa;
+  struct sockaddr_un sa = { 0 };
   int fd;
   int status;
 
@@ -398,7 +405,6 @@ static int lcc_open_unixsocket (lcc_connection_t *c, const char *path) /* {{{ */
     return (-1);
   }
 
-  memset (&sa, 0, sizeof (sa));
   sa.sun_family = AF_UNIX;
   strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1);
 
@@ -424,9 +430,7 @@ static int lcc_open_unixsocket (lcc_connection_t *c, const char *path) /* {{{ */
 static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */
     const char *addr_orig)
 {
-  struct addrinfo ai_hints;
   struct addrinfo *ai_res;
-  struct addrinfo *ai_ptr;
   char addr_copy[NI_MAXHOST];
   char *addr;
   char *port;
@@ -441,14 +445,6 @@ static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */
   addr_copy[sizeof(addr_copy) - 1] = '\0';
   addr = addr_copy;
 
-  memset (&ai_hints, 0, sizeof (ai_hints));
-  ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
-  ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-  ai_hints.ai_family = AF_UNSPEC;
-  ai_hints.ai_socktype = SOCK_STREAM;
-
   port = NULL;
   if (*addr == '[') /* IPv6+port format */
   {
@@ -484,7 +480,12 @@ static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */
     }
   }
 
-  ai_res = NULL;
+  struct addrinfo ai_hints = {
+    .ai_family = AF_UNSPEC,
+    .ai_flags = AI_ADDRCONFIG,
+    .ai_socktype = SOCK_STREAM
+  };
+
   status = getaddrinfo (addr,
                         port == NULL ? LCC_DEFAULT_PORT : port,
                         &ai_hints, &ai_res);
@@ -494,7 +495,7 @@ static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */
     return (-1);
   }
 
-  for (ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+  for (struct addrinfo *ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
     fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
     if (fd < 0)
@@ -749,7 +750,6 @@ int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */
   char command[1024] = "";
   lcc_response_t res;
   int status;
-  size_t i;
 
   if ((c == NULL) || (vl == NULL) || (vl->values_len < 1)
       || (vl->values == NULL) || (vl->values_types == NULL))
@@ -774,7 +774,7 @@ int lcc_putval (lcc_connection_t *c, const lcc_value_list_t *vl) /* {{{ */
   else
     SSTRCAT (command, " N");
 
-  for (i = 0; i < vl->values_len; i++)
+  for (size_t i = 0; i < vl->values_len; i++)
   {
     if (vl->values_types[i] == LCC_TYPE_COUNTER)
       SSTRCATF (command, ":%"PRIu64, vl->values[i].counter);
@@ -866,7 +866,6 @@ int lcc_listval (lcc_connection_t *c, /* {{{ */
     lcc_identifier_t **ret_ident, size_t *ret_ident_num)
 {
   lcc_response_t res;
-  size_t i;
   int status;
 
   lcc_identifier_t *ident;
@@ -901,7 +900,7 @@ int lcc_listval (lcc_connection_t *c, /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < res.lines_num; i++)
+  for (size_t i = 0; i < res.lines_num; i++)
   {
     char *time_str;
     char *ident_str;
index ac26b84..47462a6 100644 (file)
 
 #include "lcc_features.h"
 
+/* COLLECTD_TRACE is the environment variable used to control trace output. When
+ * set to something non-zero, all lines sent to / received from the daemon are
+ * printed to STDOUT. */
+#ifndef LCC_TRACE_ENV
+# define LCC_TRACE_ENV "COLLECTD_TRACE"
+#endif
+
 /*
  * Includes (for data types)
  */
index 4564fbb..16293ca 100644 (file)
@@ -119,9 +119,7 @@ static void int_server_destroy (lcc_server_t *srv) /* {{{ */
 
 static int server_open_socket (lcc_server_t *srv) /* {{{ */
 {
-  struct addrinfo ai_hints = { 0 };
-  struct addrinfo *ai_list = NULL;
-  struct addrinfo *ai_ptr;
+  struct addrinfo *ai_list;
   int status;
 
   if (srv == NULL)
@@ -130,18 +128,18 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */
   if (srv->fd >= 0)
     server_close_socket (srv);
 
-#ifdef AI_ADDRCONFIG
-  ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-  ai_hints.ai_family   = AF_UNSPEC;
-  ai_hints.ai_socktype = SOCK_DGRAM;
+  struct addrinfo ai_hints = {
+    .ai_family = AF_UNSPEC,
+    .ai_flags = AI_ADDRCONFIG,
+    .ai_socktype = SOCK_DGRAM
+  };
 
   status = getaddrinfo (srv->node, srv->service, &ai_hints, &ai_list);
   if (status != 0)
     return (status);
   assert (ai_list != NULL);
 
-  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
     srv->fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
     if (srv->fd < 0)
@@ -204,7 +202,7 @@ static int server_open_socket (lcc_server_t *srv) /* {{{ */
 
 static int server_send_buffer (lcc_server_t *srv) /* {{{ */
 {
-  char buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT];
+  char buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT] = { 0 };
   size_t buffer_size;
   int status;
 
@@ -215,7 +213,6 @@ static int server_send_buffer (lcc_server_t *srv) /* {{{ */
       return (status);
   }
 
-  memset (buffer, 0, sizeof (buffer));
   buffer_size = sizeof (buffer);
 
   status = lcc_network_buffer_finalize (srv->buffer);
@@ -413,18 +410,16 @@ int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ *
        * index is preferred here, because of its similarity
        * to the way IPv6 handles this. Unfortunately, it
        * appears not to be portable. */
-      struct ip_mreqn mreq;
-
-      memset (&mreq, 0, sizeof (mreq));
-      mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
-      mreq.imr_address.s_addr = ntohl (INADDR_ANY);
-      mreq.imr_ifindex = (int) if_index;
+      struct ip_mreqn mreq = {
+        .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+        .imr_address.s_addr = ntohl (INADDR_ANY),
+        .imr_ifindex = (int) if_index
+      };
 #else
-      struct ip_mreq mreq;
-
-      memset (&mreq, 0, sizeof (mreq));
-      mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
-      mreq.imr_interface.s_addr = ntohl (INADDR_ANY);
+      struct ip_mreq mreq = {
+        .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+        .imr_interface.s_addr = ntohl (INADDR_ANY)
+      };
 #endif
 
       status = setsockopt (srv->fd, IPPROTO_IP, IP_MULTICAST_IF,
@@ -474,12 +469,10 @@ int lcc_server_set_security_level (lcc_server_t *srv, /* {{{ */
 int lcc_network_values_send (lcc_network_t *net, /* {{{ */
     const lcc_value_list_t *vl)
 {
-  lcc_server_t *srv;
-
   if ((net == NULL) || (vl == NULL))
     return (EINVAL);
 
-  for (srv = net->servers; srv != NULL; srv = srv->next)
+  for (lcc_server_t *srv = net->servers; srv != NULL; srv = srv->next)
     server_value_add (srv, vl);
 
   return (0);
index 49f5576..2c6277c 100644 (file)
@@ -274,7 +274,6 @@ static int nb_add_values (char **ret_buffer, /* {{{ */
   value_t       pkg_values[vl->values_len];
 
   size_t offset;
-  size_t i;
 
   packet_len = sizeof (pkg_type) + sizeof (pkg_length)
     + sizeof (pkg_num_values)
@@ -288,7 +287,7 @@ static int nb_add_values (char **ret_buffer, /* {{{ */
   pkg_length = htons ((uint16_t) packet_len);
   pkg_num_values = htons ((uint16_t) vl->values_len);
 
-  for (i = 0; i < vl->values_len; i++)
+  for (size_t i = 0; i < vl->values_len; i++)
   {
     pkg_values_types[i] = (uint8_t) vl->values_types[i];
     switch (vl->values_types[i])
@@ -761,7 +760,8 @@ int lcc_network_buffer_initialize (lcc_network_buffer_t *nb) /* {{{ */
     uint16_t pkg_type = htons (TYPE_ENCR_AES256);
     uint16_t pkg_length = 0; /* Filled in in finalize. */
     uint16_t pkg_user_len = htons ((uint16_t) username_length);
-    char hash[20];
+    /* Filled in in finalize. */
+    char hash[20] = { 0 };
 
     nb->encr_header_len = username_length;
     nb->encr_header_len += PART_ENCRYPTION_AES256_SIZE;
@@ -769,9 +769,6 @@ int lcc_network_buffer_initialize (lcc_network_buffer_t *nb) /* {{{ */
     gcry_randomize ((void *) &nb->encr_iv, sizeof (nb->encr_iv),
         GCRY_STRONG_RANDOM);
 
-    /* Filled in in finalize. */
-    memset (hash, 0, sizeof (hash));
-
     ADD_STATIC (nb, pkg_type);
     ADD_STATIC (nb, pkg_length);
     ADD_STATIC (nb, pkg_user_len);
index cfe9c5a..d6f0744 100644 (file)
@@ -43,7 +43,7 @@ static void yyset_in  (FILE *fd)
   yyin = fd;
 } /* void yyset_in */
 
-oconfig_item_t *oconfig_parse_fh (FILE *fh)
+static oconfig_item_t *oconfig_parse_fh (FILE *fh)
 {
   int status;
   oconfig_item_t *ret;
@@ -126,8 +126,6 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
 
   if (ci_orig->values_num > 0) /* {{{ */
   {
-    int i;
-
     ci_copy->values = (oconfig_value_t *) calloc ((size_t) ci_orig->values_num,
         sizeof (*ci_copy->values));
     if (ci_copy->values == NULL)
@@ -139,7 +137,7 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
     }
     ci_copy->values_num = ci_orig->values_num;
 
-    for (i = 0; i < ci_copy->values_num; i++)
+    for (int i = 0; i < ci_copy->values_num; i++)
     {
        ci_copy->values[i].type = ci_orig->values[i].type;
        if (ci_copy->values[i].type == OCONFIG_TYPE_STRING)
@@ -161,8 +159,6 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
 
   if (ci_orig->children_num > 0) /* {{{ */
   {
-    int i;
-
     ci_copy->children = (oconfig_item_t *) calloc ((size_t) ci_orig->children_num,
         sizeof (*ci_copy->children));
     if (ci_copy->children == NULL)
@@ -173,7 +169,7 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
     }
     ci_copy->children_num = ci_orig->children_num;
 
-    for (i = 0; i < ci_copy->children_num; i++)
+    for (int i = 0; i < ci_copy->children_num; i++)
     {
       oconfig_item_t *child;
 
@@ -194,15 +190,13 @@ oconfig_item_t *oconfig_clone (const oconfig_item_t *ci_orig)
 
 static void oconfig_free_all (oconfig_item_t *ci)
 {
-  int i;
-
   if (ci == NULL)
     return;
 
   if (ci->key != NULL)
     free (ci->key);
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
     if ((ci->values[i].type == OCONFIG_TYPE_STRING)
         && (NULL != ci->values[i].value.string))
       free (ci->values[i].value.string);
@@ -210,7 +204,7 @@ static void oconfig_free_all (oconfig_item_t *ci)
   if (ci->values != NULL)
     free (ci->values);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
     oconfig_free_all (ci->children + i);
 
   if (ci->children != NULL)
index 840137c..24045de 100644 (file)
@@ -64,7 +64,6 @@ struct oconfig_item_s
 /*
  * Functions
  */
-oconfig_item_t *oconfig_parse_fh (FILE *fh);
 oconfig_item_t *oconfig_parse_file (const char *file);
 
 oconfig_item_t *oconfig_clone (const oconfig_item_t *ci);
index 1eb7aec..4a550b3 100644 (file)
@@ -239,7 +239,6 @@ static char *unquote (const char *orig)
 {
        char *ret = strdup (orig);
        int len;
-       int i;
 
        if (ret == NULL)
                return (NULL);
@@ -253,7 +252,7 @@ static char *unquote (const char *orig)
        memmove (ret, ret + 1, len);
        ret[len] = '\0';
 
-       for (i = 0; i < len; i++)
+       for (int i = 0; i < len; i++)
        {
                if (ret[i] == '\\')
                {
index 7a831c2..4858003 100644 (file)
 #include "aux_types.h"
 #include "parser.h"
 
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-noreturn"
+#endif
+
+
 /* multiline string buffer */
 static char *ml_buffer = NULL;
 static int   ml_pos    = 0;
@@ -159,3 +165,6 @@ static void ml_append (char *string)
        return;
 } /* ml_append */
 
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
index 18b5f8e..a3f6bb1 100644 (file)
@@ -27,6 +27,7 @@
 #define _BSD_SOURCE
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -77,8 +78,6 @@ static int load_config (const char *key, const char *value)
 }
 static void load_submit (gauge_t snum, gauge_t mnum, gauge_t lnum)
 {
-       value_t values[3];
-       value_list_t vl = VALUE_LIST_INIT;
         int cores = 0;
         char errbuf[1024];
 
@@ -96,9 +95,12 @@ static void load_submit (gauge_t snum, gauge_t mnum, gauge_t lnum)
                lnum /= cores;
        }
 
-       values[0].gauge = snum;
-       values[1].gauge = mnum;
-       values[2].gauge = lnum;
+       value_list_t vl = VALUE_LIST_INIT;
+       value_t values[] = {
+               { .gauge = snum },
+               { .gauge = mnum },
+               { .gauge = lnum },
+       };
 
        vl.values = values;
        vl.values_len = STATIC_ARRAY_SIZE (values);
index 3cf636e..0886840 100644 (file)
@@ -27,6 +27,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
index 334226b..d18a536 100644 (file)
@@ -27,6 +27,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
index 4d53447..0e32c83 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -113,12 +114,9 @@ static int lpar_init (void)
 
 static void lpar_submit (const char *type_instance, double value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = (gauge_t)value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        if (report_by_serial)
        {
diff --git a/src/lua.c b/src/lua.c
new file mode 100644 (file)
index 0000000..d10b4ea
--- /dev/null
+++ b/src/lua.c
@@ -0,0 +1,589 @@
+/**
+ * collectd - src/lua.c
+ * Copyright (C) 2010       Julien Ammous
+ * Copyright (C) 2010       Florian Forster
+ * Copyright (C) 2016       Ruben Kerkhof
+ *
+ * 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:
+ *   Julien Ammous
+ *   Florian Forster <octo at collectd.org>
+ *   Ruben Kerkhof <ruben at rubenkerkhof.com>
+ **/
+
+/* <lua5.1/luaconf.h> defines a macro using "sprintf". Although not used here,
+ * GCC will complain about the macro definition. */
+#define DONT_POISON_SPRINTF_YET
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+/* Include the Lua API header files. */
+#include "utils_lua.h"
+#include <lauxlib.h>
+#include <lua.h>
+#include <lualib.h>
+
+#include <pthread.h>
+
+#if COLLECT_DEBUG && __GNUC__
+#undef sprintf
+#pragma GCC poison sprintf
+#endif
+
+typedef struct lua_script_s {
+  char *script_path;
+  lua_State *lua_state;
+  struct lua_script_s *next;
+} lua_script_t;
+
+typedef struct {
+  lua_State *lua_state;
+  const char *lua_function_name;
+  pthread_mutex_t lock;
+  int callback_id;
+} clua_callback_data_t;
+
+static char base_path[PATH_MAX];
+static lua_script_t *scripts;
+
+static int clua_store_callback(lua_State *L, int idx) /* {{{ */
+{
+  /* Copy the function pointer */
+  lua_pushvalue(L, idx);
+
+  return luaL_ref(L, LUA_REGISTRYINDEX);
+} /* }}} int clua_store_callback */
+
+static int clua_load_callback(lua_State *L, int callback_ref) /* {{{ */
+{
+  lua_rawgeti(L, LUA_REGISTRYINDEX, callback_ref);
+
+  if (!lua_isfunction(L, -1)) {
+    lua_pop(L, 1);
+    return (-1);
+  }
+
+  return (0);
+} /* }}} int clua_load_callback */
+
+/* Store the threads in a global variable so they are not cleaned up by the
+ * garbage collector. */
+static int clua_store_thread(lua_State *L, int idx) /* {{{ */
+{
+  if (idx < 0)
+    idx += lua_gettop(L) + 1;
+
+  /* Copy the thread pointer */
+  lua_pushvalue(L, idx); /* +1 = 3 */
+  if (!lua_isthread(L, -1)) {
+    lua_pop(L, 3); /* -3 = 0 */
+    return (-1);
+  }
+
+  luaL_ref(L, LUA_REGISTRYINDEX);
+  lua_pop(L, 1); /* -1 = 0 */
+  return (0);
+} /* }}} int clua_store_thread */
+
+static int clua_read(user_data_t *ud) /* {{{ */
+{
+  clua_callback_data_t *cb = ud->data;
+
+  pthread_mutex_lock(&cb->lock);
+
+  lua_State *L = cb->lua_state;
+
+  int status = clua_load_callback(L, cb->callback_id);
+  if (status != 0) {
+    ERROR("Lua plugin: Unable to load callback \"%s\" (id %i).",
+          cb->lua_function_name, cb->callback_id);
+    pthread_mutex_unlock(&cb->lock);
+    return (-1);
+  }
+  /* +1 = 1 */
+
+  status = lua_pcall(L, 0, 1, 0);
+  if (status != 0) {
+    const char *errmsg = lua_tostring(L, -1);
+    if (errmsg == NULL)
+      ERROR("Lua plugin: Calling a read callback failed. "
+            "In addition, retrieving the error message failed.");
+    else
+      ERROR("Lua plugin: Calling a read callback failed: %s", errmsg);
+    lua_pop(L, 1);
+    pthread_mutex_unlock(&cb->lock);
+    return (-1);
+  }
+
+  if (!lua_isnumber(L, -1)) {
+    ERROR("Lua plugin: Read function \"%s\" (id %i) did not return a numeric "
+          "status.",
+          cb->lua_function_name, cb->callback_id);
+    status = -1;
+  } else {
+    status = (int)lua_tointeger(L, -1);
+  }
+
+  /* pop return value and function */
+  lua_pop(L, 1); /* -1 = 0 */
+
+  pthread_mutex_unlock(&cb->lock);
+  return (status);
+} /* }}} int clua_read */
+
+static int clua_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */
+                      user_data_t *ud) {
+  clua_callback_data_t *cb = ud->data;
+
+  pthread_mutex_lock(&cb->lock);
+
+  lua_State *L = cb->lua_state;
+
+  int status = clua_load_callback(L, cb->callback_id);
+  if (status != 0) {
+    ERROR("Lua plugin: Unable to load callback \"%s\" (id %i).",
+          cb->lua_function_name, cb->callback_id);
+    pthread_mutex_unlock(&cb->lock);
+    return (-1);
+  }
+  /* +1 = 1 */
+
+  status = luaC_pushvaluelist(L, ds, vl);
+  if (status != 0) {
+    lua_pop(L, 1); /* -1 = 0 */
+    pthread_mutex_unlock(&cb->lock);
+    ERROR("Lua plugin: luaC_pushvaluelist failed.");
+    return (-1);
+  }
+  /* +1 = 2 */
+
+  status = lua_pcall(L, 1, 1, 0); /* -2+1 = 1 */
+  if (status != 0) {
+    const char *errmsg = lua_tostring(L, -1);
+    if (errmsg == NULL)
+      ERROR("Lua plugin: Calling the write callback failed. "
+            "In addition, retrieving the error message failed.");
+    else
+      ERROR("Lua plugin: Calling the write callback failed:\n%s", errmsg);
+    lua_pop(L, 1); /* -1 = 0 */
+    pthread_mutex_unlock(&cb->lock);
+    return (-1);
+  }
+
+  if (!lua_isnumber(L, -1)) {
+    ERROR("Lua plugin: Write function \"%s\" (id %i) did not return a numeric "
+          "value.",
+          cb->lua_function_name, cb->callback_id);
+    status = -1;
+  } else {
+    status = (int)lua_tointeger(L, -1);
+  }
+
+  lua_pop(L, 1); /* -1 = 0 */
+  pthread_mutex_unlock(&cb->lock);
+  return (status);
+} /* }}} int clua_write */
+
+/*
+ * Exported functions
+ */
+
+static int lua_cb_log_debug(lua_State *L) /* {{{ */
+{
+  const char *msg = luaL_checkstring(L, 1);
+  plugin_log(LOG_DEBUG, "%s", msg);
+  return 0;
+} /* }}} int lua_cb_log_debug */
+
+static int lua_cb_log_error(lua_State *L) /* {{{ */
+{
+  const char *msg = luaL_checkstring(L, 1);
+  plugin_log(LOG_ERR, "%s", msg);
+  return 0;
+} /* }}} int lua_cb_log_error */
+
+static int lua_cb_log_info(lua_State *L) /* {{{ */
+{
+  const char *msg = luaL_checkstring(L, 1);
+  plugin_log(LOG_INFO, "%s", msg);
+  return 0;
+} /* }}} int lua_cb_log_info */
+
+static int lua_cb_log_notice(lua_State *L) /* {{{ */
+{
+  const char *msg = luaL_checkstring(L, 1);
+  plugin_log(LOG_NOTICE, "%s", msg);
+  return 0;
+} /* }}} int lua_cb_log_notice */
+
+static int lua_cb_log_warning(lua_State *L) /* {{{ */
+{
+  const char *msg = luaL_checkstring(L, 1);
+  plugin_log(LOG_WARNING, "%s", msg);
+  return 0;
+} /* }}} int lua_cb_log_warning */
+
+static int lua_cb_dispatch_values(lua_State *L) /* {{{ */
+{
+  int nargs = lua_gettop(L);
+
+  if (nargs != 1)
+    return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs);
+
+  luaL_checktype(L, 1, LUA_TTABLE);
+
+  value_list_t *vl = luaC_tovaluelist(L, -1);
+  if (vl == NULL)
+    return luaL_error(L, "%s", "luaC_tovaluelist failed");
+
+#if COLLECT_DEBUG
+  char identifier[6 * DATA_MAX_NAME_LEN];
+  FORMAT_VL(identifier, sizeof(identifier), vl);
+
+  DEBUG("Lua plugin: collectd.dispatch_values(): Received value list \"%s\", "
+        "time %.3f, interval %.3f.",
+        identifier, CDTIME_T_TO_DOUBLE(vl->time),
+        CDTIME_T_TO_DOUBLE(vl->interval));
+#endif
+
+  plugin_dispatch_values(vl);
+
+  sfree(vl->values);
+  sfree(vl);
+  return 0;
+} /* }}} lua_cb_dispatch_values */
+
+static int lua_cb_register_read(lua_State *L) /* {{{ */
+{
+  int nargs = lua_gettop(L);
+
+  if (nargs != 1)
+    return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs);
+
+  luaL_checktype(L, 1, LUA_TFUNCTION);
+
+  char function_name[DATA_MAX_NAME_LEN];
+  ssnprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
+
+  int callback_id = clua_store_callback(L, 1);
+  if (callback_id < 0)
+    return luaL_error(L, "%s", "Storing callback function failed");
+
+  lua_State *thread = lua_newthread(L);
+  if (thread == NULL)
+    return luaL_error(L, "%s", "lua_newthread failed");
+  clua_store_thread(L, -1);
+  lua_pop(L, 1);
+
+  clua_callback_data_t *cb = calloc(1, sizeof(*cb));
+  if (cb == NULL)
+    return luaL_error(L, "%s", "calloc failed");
+
+  cb->lua_state = thread;
+  cb->callback_id = callback_id;
+  cb->lua_function_name = strdup(function_name);
+  pthread_mutex_init(&cb->lock, NULL);
+
+  int status = plugin_register_complex_read(/* group = */ "lua",
+                                            /* name      = */ function_name,
+                                            /* callback  = */ clua_read,
+                                            /* interval  = */ 0,
+                                            &(user_data_t) {
+                                              .data = cb,
+                                            });
+
+  if (status != 0)
+    return luaL_error(L, "%s", "plugin_register_complex_read failed");
+  return 0;
+} /* }}} int lua_cb_register_read */
+
+static int lua_cb_register_write(lua_State *L) /* {{{ */
+{
+  int nargs = lua_gettop(L);
+
+  if (nargs != 1)
+    return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs);
+
+  luaL_checktype(L, 1, LUA_TFUNCTION);
+
+  char function_name[DATA_MAX_NAME_LEN] = "";
+  ssnprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
+
+  int callback_id = clua_store_callback(L, 1);
+  if (callback_id < 0)
+    return luaL_error(L, "%s", "Storing callback function failed");
+
+  lua_State *thread = lua_newthread(L);
+  if (thread == NULL)
+    return luaL_error(L, "%s", "lua_newthread failed");
+  clua_store_thread(L, -1);
+  lua_pop(L, 1);
+
+  clua_callback_data_t *cb = calloc(1, sizeof(*cb));
+  if (cb == NULL)
+    return luaL_error(L, "%s", "calloc failed");
+
+  cb->lua_state = thread;
+  cb->callback_id = callback_id;
+  cb->lua_function_name = strdup(function_name);
+  pthread_mutex_init(&cb->lock, NULL);
+
+  int status = plugin_register_write(/* name = */ function_name,
+                                    /* callback  = */ clua_write,
+                                    &(user_data_t) {
+                                      .data = cb,
+                                    });
+
+  if (status != 0)
+    return luaL_error(L, "%s", "plugin_register_write failed");
+  return 0;
+} /* }}} int lua_cb_register_write */
+
+static const luaL_Reg collectdlib[] = {
+    {"log_debug", lua_cb_log_debug},
+    {"log_error", lua_cb_log_error},
+    {"log_info", lua_cb_log_info},
+    {"log_notice", lua_cb_log_notice},
+    {"log_warning", lua_cb_log_warning},
+    {"dispatch_values", lua_cb_dispatch_values},
+    {"register_read", lua_cb_register_read},
+    {"register_write", lua_cb_register_write},
+    {NULL, NULL}
+};
+
+static int open_collectd(lua_State *L) /* {{{ */
+{
+#if LUA_VERSION_NUM < 502
+  luaL_register(L, "collectd", collectdlib);
+#else
+  luaL_newlib(L, collectdlib);
+#endif
+  return 1;
+} /* }}} */
+
+static void lua_script_free(lua_script_t *script) /* {{{ */
+{
+  if (script == NULL)
+    return;
+
+  lua_script_t *next = script->next;
+
+  if (script->lua_state != NULL) {
+    lua_close(script->lua_state);
+    script->lua_state = NULL;
+  }
+
+  sfree(script->script_path);
+  sfree(script);
+
+  lua_script_free(next);
+} /* }}} void lua_script_free */
+
+static int lua_script_init(lua_script_t *script) /* {{{ */
+{
+  memset(script, 0, sizeof(*script));
+
+  /* initialize the lua context */
+  script->lua_state = luaL_newstate();
+  if (script->lua_state == NULL) {
+    ERROR("Lua plugin: luaL_newstate() failed.");
+    return (-1);
+  }
+
+  /* Open up all the standard Lua libraries. */
+  luaL_openlibs(script->lua_state);
+
+  /* Load the 'collectd' library */
+#if LUA_VERSION_NUM < 502
+  lua_pushcfunction(script->lua_state, open_collectd);
+  lua_pushstring(script->lua_state, "collectd");
+  lua_call(script->lua_state, 1, 0);
+#else
+  luaL_requiref(script->lua_state, "collectd", open_collectd, 1);
+  lua_pop(script->lua_state, 1);
+#endif
+
+  /* Prepend BasePath to package.path */
+  if (base_path[0] != '\0') {
+    lua_getglobal(script->lua_state, "package");
+    lua_getfield(script->lua_state, -1, "path");
+
+    const char *cur_path = lua_tostring(script->lua_state, -1);
+    char *new_path = ssnprintf_alloc("%s/?.lua;%s", base_path, cur_path);
+
+    lua_pop(script->lua_state, 1);
+    lua_pushstring(script->lua_state, new_path);
+
+    free(new_path);
+
+    lua_setfield(script->lua_state, -2, "path");
+    lua_pop(script->lua_state, 1);
+  }
+
+  return (0);
+} /* }}} int lua_script_init */
+
+static int lua_script_load(const char *script_path) /* {{{ */
+{
+  lua_script_t *script = malloc(sizeof(*script));
+  if (script == NULL) {
+    ERROR("Lua plugin: malloc failed.");
+    return (-1);
+  }
+
+  int status = lua_script_init(script);
+  if (status != 0) {
+    lua_script_free(script);
+    return (status);
+  }
+
+  script->script_path = strdup(script_path);
+  if (script->script_path == NULL) {
+    ERROR("Lua plugin: strdup failed.");
+    lua_script_free(script);
+    return (-1);
+  }
+
+  status = luaL_loadfile(script->lua_state, script->script_path);
+  if (status != 0) {
+    ERROR("Lua plugin: luaL_loadfile failed: %s",
+          lua_tostring(script->lua_state, -1));
+    lua_pop(script->lua_state, 1);
+    lua_script_free(script);
+    return (-1);
+  }
+
+  status = lua_pcall(script->lua_state,
+                     /* nargs = */ 0,
+                     /* nresults = */ LUA_MULTRET,
+                     /* errfunc = */ 0);
+  if (status != 0) {
+    const char *errmsg = lua_tostring(script->lua_state, -1);
+
+    if (errmsg == NULL)
+      ERROR("Lua plugin: lua_pcall failed with status %i. "
+            "In addition, no error message could be retrieved from the stack.",
+            status);
+    else
+      ERROR("Lua plugin: Executing script \"%s\" failed:\n%s",
+            script->script_path, errmsg);
+
+    lua_script_free(script);
+    return (-1);
+  }
+
+  /* Append this script to the global list of scripts. */
+  if (scripts) {
+    lua_script_t *last = scripts;
+    while (last->next)
+      last = last->next;
+
+    last->next = script;
+  } else {
+    scripts = script;
+  }
+
+  return (0);
+} /* }}} int lua_script_load */
+
+static int lua_config_base_path(const oconfig_item_t *ci) /* {{{ */
+{
+  int status = cf_util_get_string_buffer(ci, base_path, sizeof(base_path));
+  if (status != 0)
+    return (status);
+
+  size_t len = strlen(base_path);
+  while ((len > 0) && (base_path[len - 1] == '/')) {
+    len--;
+    base_path[len] = '\0';
+  }
+
+  DEBUG("Lua plugin: base_path = \"%s\";", base_path);
+
+  return (0);
+} /* }}} int lua_config_base_path */
+
+static int lua_config_script(const oconfig_item_t *ci) /* {{{ */
+{
+  char rel_path[PATH_MAX];
+
+  int status = cf_util_get_string_buffer(ci, rel_path, sizeof(rel_path));
+  if (status != 0)
+    return (status);
+
+  char abs_path[PATH_MAX];
+
+  if (base_path[0] == '\0')
+    sstrncpy(abs_path, rel_path, sizeof(abs_path));
+  else
+    ssnprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path);
+
+  DEBUG("Lua plugin: abs_path = \"%s\";", abs_path);
+
+  status = lua_script_load(abs_path);
+  if (status != 0)
+    return (status);
+
+  INFO("Lua plugin: File \"%s\" loaded succesfully", abs_path);
+
+  return 0;
+} /* }}} int lua_config_script */
+
+/*
+ * <Plugin lua>
+ *   BasePath "/"
+ *   Script "script1.lua"
+ *   Script "script2.lua"
+ * </Plugin>
+ */
+static int lua_config(oconfig_item_t *ci) /* {{{ */
+{
+  int status = 0;
+  for (int i = 0; i < ci->children_num; i++) {
+    oconfig_item_t *child = ci->children + i;
+
+    if (strcasecmp("BasePath", child->key) == 0) {
+      status = lua_config_base_path(child);
+    } else if (strcasecmp("Script", child->key) == 0) {
+      status = lua_config_script(child);
+    } else {
+      ERROR("Lua plugin: Option `%s' is not allowed here.", child->key);
+      status = 1;
+    }
+  }
+
+  return status;
+} /* }}} int lua_config */
+
+static int lua_shutdown(void) /* {{{ */
+{
+  lua_script_free(scripts);
+
+  return (0);
+} /* }}} int lua_shutdown */
+
+void module_register(void) {
+  plugin_register_complex_config("lua", lua_config);
+  plugin_register_shutdown("lua", lua_shutdown);
+}
+
+/* vim: set sw=2 sts=2 et fdm=marker : */
index 9e24542..77cb6eb 100644 (file)
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -24,6 +24,7 @@
 #include <lvm2app.h>
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -54,12 +55,9 @@ static char const *get_lv_property_string(lv_t lv, char const *property)
 static void lvm_submit (char const *plugin_instance, char const *type_instance,
         uint64_t ivalue)
 {
-    value_t v;
     value_list_t vl = VALUE_LIST_INIT;
 
-    v.gauge = (gauge_t) ivalue;
-
-    vl.values = &v;
+    vl.values = &(value_t) { .gauge = (gauge_t) ivalue };
     vl.values_len = 1;
 
     sstrncpy(vl.host, hostname_g, sizeof (vl.host));
index 6eb12dd..42474bc 100644 (file)
@@ -89,9 +89,9 @@
 
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_ignorelist.h"
 
 #include <dirent.h>
@@ -394,8 +394,7 @@ static inline void watchlist_remove (uint32_t *wl, int item)
 
 static inline void watchlist_set (uint32_t *wl, uint32_t val)
 {
-       int i;
-       for (i = 0; i < WL_LEN; i++)
+       for (int i = 0; i < WL_LEN; i++)
                wl[i] = val;
 }
 
@@ -403,9 +402,8 @@ static inline void watchlist_set (uint32_t *wl, uint32_t val)
 static int watchitem_find (const char *name)
 {
        int max = STATIC_ARRAY_SIZE (specs);
-       int i;
 
-       for (i = 0; i < max; i++)
+       for (int i = 0; i < max; i++)
                if (strcasecmp (name, specs[i].name) == 0)
                        return i;
 
@@ -420,15 +418,14 @@ static int watchitem_find (const char *name)
 static int madwifi_real_init (void)
 {
        size_t max = STATIC_ARRAY_SIZE (specs);
-       size_t i;
 
-       for (i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
+       for (size_t i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
                bounds[i] = 0;
 
        watchlist_set(watch_items, 0);
        watchlist_set(misc_items, 0);
 
-       for (i = 0; i < max; i++)
+       for (size_t i = 0; i < max; i++)
        {
                bounds[specs[i].flags & SRC_MASK] = i;
 
@@ -439,7 +436,7 @@ static int madwifi_real_init (void)
                        misc_items[i / 32] |= FLAG (i);
        }
 
-       for (i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
+       for (size_t i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
                bounds[i]++;
 
        return (0);
@@ -541,7 +538,7 @@ static int madwifi_config (const char *key, const char *value)
 
 
 static void submit (const char *dev, const char *type, const char *ti1,
-                       const char *ti2, value_t *val, int len)
+                       const char *ti2, value_t *val, size_t len)
 {
        value_list_t vl = VALUE_LIST_INIT;
 
@@ -561,37 +558,34 @@ static void submit (const char *dev, const char *type, const char *ti1,
 }
 
 static void submit_derive (const char *dev, const char *type, const char *ti1,
-                               const char *ti2, derive_t val)
+                               const char *ti2, derive_t value)
 {
-       value_t item;
-       item.derive = val;
-       submit (dev, type, ti1, ti2, &item, 1);
+       submit (dev, type, ti1, ti2, &(value_t) { .derive = value }, 1);
 }
 
 static void submit_derive2 (const char *dev, const char *type, const char *ti1,
                                const char *ti2, derive_t val1, derive_t val2)
 {
-       value_t items[2];
-       items[0].derive = val1;
-       items[1].derive = val2;
-       submit (dev, type, ti1, ti2, items, 2);
+       value_t values[] = {
+          { .derive = val1 },
+          { .derive = val2 },
+        };
+
+       submit (dev, type, ti1, ti2, values, STATIC_ARRAY_SIZE (values));
 }
 
 static void submit_gauge (const char *dev, const char *type, const char *ti1,
-                               const char *ti2, gauge_t val)
+                               const char *ti2, gauge_t value)
 {
-       value_t item;
-       item.gauge = val;
-       submit (dev, type, ti1, ti2, &item, 1);
+       submit (dev, type, ti1, ti2, &(value_t) { .gauge = value }, 1);
 }
 
 static void submit_antx (const char *dev, const char *name,
                u_int32_t *vals, int vals_num)
 {
        char ti2[16];
-       int i;
 
-       for (i = 0; i < vals_num; i++)
+       for (int i = 0; i < vals_num; i++)
        {
                if (vals[i] == 0)
                        continue;
@@ -614,12 +608,11 @@ process_stat_struct (int which, const void *ptr, const char *dev, const char *ma
                         const char *type_name, const char *misc_name)
 {
        uint32_t misc = 0;
-       int i;
 
        assert (which >= 1);
        assert (((size_t) which) < STATIC_ARRAY_SIZE (bounds));
 
-       for (i = bounds[which - 1]; i < bounds[which]; i++)
+       for (int i = bounds[which - 1]; i < bounds[which]; i++)
        {
                uint32_t val = *(uint32_t *)(((char *) ptr) + specs[i].offset) ;
 
@@ -699,7 +692,6 @@ process_80211stats (int sk, const char *dev)
 static int
 process_station (int sk, const char *dev, struct ieee80211req_sta_info *si)
 {
-       struct iwreq iwr;
        static char mac[DATA_MAX_NAME_LEN];
        struct ieee80211req_sta_stats stats;
        const struct ieee80211_nodestats *ns = &stats.is_stats;
@@ -714,10 +706,12 @@ process_station (int sk, const char *dev, struct ieee80211req_sta_info *si)
        if (item_watched (STAT_NODE_RSSI))
                submit_gauge (dev, "node_rssi", mac, NULL, si->isi_rssi);
 
-       memset (&iwr, 0, sizeof (iwr));
+       struct iwreq iwr = {
+               .u.data.pointer = (void *) &stats,
+               .u.data.length = sizeof (stats)
+       };
        sstrncpy(iwr.ifr_name, dev, sizeof (iwr.ifr_name));
-       iwr.u.data.pointer = (void *) &stats;
-       iwr.u.data.length = sizeof (stats);
+
        memcpy(stats.is_u.macaddr, si->isi_macaddr, IEEE80211_ADDR_LEN);
        status = ioctl(sk, IEEE80211_IOCTL_STA_STATS, &iwr);
        if (status < 0)
@@ -750,17 +744,17 @@ process_station (int sk, const char *dev, struct ieee80211req_sta_info *si)
 static int
 process_stations (int sk, const char *dev)
 {
-       uint8_t buf[24*1024];
-       struct iwreq iwr;
+       uint8_t buf[24*1024] = { 0 };
        uint8_t *cp;
        int nodes;
        size_t len;
        int status;
 
-       memset (&iwr, 0, sizeof (iwr));
+       struct iwreq iwr = {
+               .u.data.pointer = (void *) buf,
+               .u.data.length = sizeof (buf)
+       };
        sstrncpy (iwr.ifr_name, dev, sizeof (iwr.ifr_name));
-       iwr.u.data.pointer = (void *) buf;
-       iwr.u.data.length = sizeof (buf);
 
        status = ioctl (sk, IEEE80211_IOCTL_STA_INFO, &iwr);
        if (status < 0)
index bff9448..80a29ac 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "filter_chain.h"
 
@@ -55,9 +56,8 @@ static int mec_match (__attribute__((unused)) const data_set_t *ds, /* {{{ */
 {
   int num_counters = 0;
   int num_empty = 0;
-  size_t i;
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     if ((ds->ds[i].type != DS_TYPE_DERIVE)
         && (ds->ds[i].type != DS_TYPE_COUNTER))
index 79f79fa..c4983c2 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "filter_chain.h"
 
@@ -98,7 +99,6 @@ static int mh_config_match (const oconfig_item_t *ci, /* {{{ */
 static int mh_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   mh_match_t *m;
-  int i;
 
   m = calloc (1, sizeof (*m));
   if (m == NULL)
@@ -107,7 +107,7 @@ static int mh_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
     return (-ENOMEM);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -149,8 +149,6 @@ static int mh_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */
 {
   mh_match_t *m;
   uint32_t hash_val;
-  const char *host_ptr;
-  size_t i;
 
   if ((user_data == NULL) || (*user_data == NULL))
     return (-1);
@@ -159,14 +157,14 @@ static int mh_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */
 
   hash_val = 0;
 
-  for (host_ptr = vl->host; *host_ptr != 0; host_ptr++)
+  for (const char *host_ptr = vl->host; *host_ptr != 0; host_ptr++)
   {
     /* 2184401929 is some appropriately sized prime number. */
     hash_val = (hash_val * UINT32_C (2184401929)) + ((uint32_t) *host_ptr);
   }
   DEBUG ("hashed match: host = %s; hash_val = %"PRIu32";", vl->host, hash_val);
 
-  for (i = 0; i < m->matches_num; i++)
+  for (size_t i = 0; i < m->matches_num; i++)
     if ((hash_val % m->matches[i].total) == m->matches[i].match)
       return (FC_MATCH_MATCHES);
 
@@ -175,9 +173,8 @@ static int mh_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */
 
 void module_register (void)
 {
-  match_proc_t mproc;
+  match_proc_t mproc = { 0 };
 
-  memset (&mproc, 0, sizeof (mproc));
   mproc.create  = mh_create;
   mproc.destroy = mh_destroy;
   mproc.match   = mh_match;
index bbc35cd..dd8319e 100644 (file)
  */
 
 #include "collectd.h"
+
+#include "common.h"
 #include "filter_chain.h"
+#include "meta_data.h"
+#include "utils_llist.h"
 
 #include <sys/types.h>
 #include <regex.h>
@@ -63,6 +67,7 @@ struct mr_match_s
        mr_regex_t *plugin_instance;
        mr_regex_t *type;
        mr_regex_t *type_instance;
+       llist_t *meta;  /* Maps each meta key into mr_regex_t* */
        _Bool invert;
 };
 
@@ -76,7 +81,7 @@ static void mr_free_regex (mr_regex_t *r) /* {{{ */
 
        regfree (&r->re);
        memset (&r->re, 0, sizeof (r->re));
-       free (r->re_str);
+       sfree (r->re_str);
 
        if (r->next != NULL)
                mr_free_regex (r->next);
@@ -92,19 +97,23 @@ static void mr_free_match (mr_match_t *m) /* {{{ */
        mr_free_regex (m->plugin_instance);
        mr_free_regex (m->type);
        mr_free_regex (m->type_instance);
+       for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next)
+       {
+               sfree (e->key);
+               mr_free_regex ((mr_regex_t *) e->value);
+       }
+       llist_destroy (m->meta);
 
-       free (m);
+       sfree (m);
 } /* }}} void mr_free_match */
 
 static int mr_match_regexen (mr_regex_t *re_head, /* {{{ */
                const char *string)
 {
-       mr_regex_t *re;
-
        if (re_head == NULL)
                return (FC_MATCH_MATCHES);
 
-       for (re = re_head; re != NULL; re = re->next)
+       for (mr_regex_t *re = re_head; re != NULL; re = re->next)
        {
                int status;
 
@@ -128,31 +137,25 @@ static int mr_match_regexen (mr_regex_t *re_head, /* {{{ */
        return (FC_MATCH_MATCHES);
 } /* }}} int mr_match_regexen */
 
-static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
-               oconfig_item_t *ci)
+static int mr_add_regex (mr_regex_t **re_head, const char *re_str, /* {{{ */
+               const char *option)
 {
        mr_regex_t *re;
        int status;
 
-       if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
-       {
-               log_warn ("`%s' needs exactly one string argument.", ci->key);
-               return (-1);
-       }
-
        re = calloc (1, sizeof (*re));
        if (re == NULL)
        {
-               log_err ("mr_config_add_regex: calloc failed.");
+               log_err ("mr_add_regex: calloc failed.");
                return (-1);
        }
        re->next = NULL;
 
-       re->re_str = strdup (ci->values[0].value.string);
+       re->re_str = strdup (re_str);
        if (re->re_str == NULL)
        {
-               free (re);
-               log_err ("mr_config_add_regex: strdup failed.");
+               sfree (re);
+               log_err ("mr_add_regex: strdup failed.");
                return (-1);
        }
 
@@ -163,9 +166,9 @@ static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
                regerror (status, &re->re, errmsg, sizeof (errmsg));
                errmsg[sizeof (errmsg) - 1] = 0;
                log_err ("Compiling regex `%s' for `%s' failed: %s.",
-                               re->re_str, ci->key, errmsg);
-               free (re->re_str);
-               free (re);
+                               re->re_str, option, errmsg);
+               sfree (re->re_str);
+               sfree (re);
                return (-1);
        }
 
@@ -185,13 +188,82 @@ static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
        }
 
        return (0);
+} /* }}} int mr_add_regex */
+
+static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
+               oconfig_item_t *ci)
+{
+       if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
+       {
+               log_warn ("`%s' needs exactly one string argument.", ci->key);
+               return (-1);
+       }
+
+       return mr_add_regex (re_head, ci->values[0].value.string, ci->key);
 } /* }}} int mr_config_add_regex */
 
+static int mr_config_add_meta_regex (llist_t **meta, /* {{{ */
+               oconfig_item_t *ci)
+{
+       char *meta_key;
+       llentry_t *entry;
+       mr_regex_t *re_head;
+       int status;
+       char buffer[1024];
+
+       if ((ci->values_num != 2)
+               || (ci->values[0].type != OCONFIG_TYPE_STRING)
+               || (ci->values[1].type != OCONFIG_TYPE_STRING))
+       {
+               log_warn ("`%s' needs exactly two string arguments.", ci->key);
+               return (-1);
+       }
+
+       if (*meta == NULL)
+       {
+               *meta = llist_create();
+               if (*meta == NULL)
+               {
+                       log_err ("mr_config_add_meta_regex: llist_create failed.");
+                       return (-1);
+               }
+       }
+
+       meta_key = ci->values[0].value.string;
+       entry = llist_search (*meta, meta_key);
+       if (entry == NULL)
+       {
+               meta_key = strdup (meta_key);
+               if (meta_key == NULL)
+               {
+                       log_err ("mr_config_add_meta_regex: strdup failed.");
+                       return (-1);
+               }
+               entry = llentry_create (meta_key, NULL);
+               if (entry == NULL)
+               {
+                       log_err ("mr_config_add_meta_regex: llentry_create failed.");
+                       sfree (meta_key);
+                       return (-1);
+               }
+               /* meta_key and entry will now be freed by mr_free_match(). */
+               llist_append (*meta, entry);
+       }
+
+       ssnprintf (buffer, sizeof (buffer), "%s `%s'", ci->key, meta_key);
+       /* Can't pass &entry->value into mr_add_regex, so copy in/out. */
+       re_head = entry->value;
+       status = mr_add_regex (&re_head, ci->values[1].value.string, buffer);
+       if (status == 0) {
+               entry->value = re_head;
+       }
+       return status;
+} /* }}} int mr_config_add_meta_regex */
+
 static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
        mr_match_t *m;
        int status;
-       int i;
 
        m = calloc (1, sizeof (*m));
        if (m == NULL)
@@ -203,7 +275,7 @@ static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
        m->invert = 0;
 
        status = 0;
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -218,6 +290,8 @@ static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
                        status = mr_config_add_regex (&m->type, child);
                else if (strcasecmp ("TypeInstance", child->key) == 0)
                        status = mr_config_add_regex (&m->type_instance, child);
+               else if (strcasecmp ("MetaData", child->key) == 0)
+                       status = mr_config_add_meta_regex (&m->meta, child);
                else if (strcasecmp ("Invert", child->key) == 0)
                        status = cf_util_get_boolean(child, &m->invert);
                else
@@ -238,7 +312,8 @@ static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
                                && (m->plugin == NULL)
                                && (m->plugin_instance == NULL)
                                && (m->type == NULL)
-                               && (m->type_instance == NULL))
+                               && (m->type_instance == NULL)
+                               && (m->meta == NULL))
                {
                        log_err ("No (valid) regular expressions have been configured. "
                                        "This match will be ignored.");
@@ -297,15 +372,33 @@ static int mr_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */
        if (mr_match_regexen (m->type_instance,
                                vl->type_instance) == FC_MATCH_NO_MATCH)
                return (nomatch_value);
+       if (vl->meta != NULL)
+       {
+               for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next)
+               {
+                       mr_regex_t *meta_re = (mr_regex_t *) e->value;
+                       char *value;
+                       int status = meta_data_get_string (vl->meta, e->key, &value);
+                       if (status == (-ENOENT))  /* key is not present */
+                               return (nomatch_value);
+                       if (status != 0)  /* some other problem */
+                               continue;  /* error will have already been printed. */
+                       if (mr_match_regexen (meta_re, value) == FC_MATCH_NO_MATCH)
+                       {
+                               sfree (value);
+                               return (nomatch_value);
+                       }
+                       sfree (value);
+               }
+       }
 
        return (match_value);
 } /* }}} int mr_match */
 
 void module_register (void)
 {
-       match_proc_t mproc;
+       match_proc_t mproc = { 0 };
 
-       memset (&mproc, 0, sizeof (mproc));
        mproc.create  = mr_create;
        mproc.destroy = mr_destroy;
        mproc.match   = mr_match;
index 750817b..00fdd0c 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "filter_chain.h"
 
@@ -49,7 +50,6 @@ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   mt_match_t *m;
   int status;
-  int i;
 
   m = calloc (1, sizeof (*m));
   if (m == NULL)
@@ -62,7 +62,7 @@ static int mt_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   m->past = 0;
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -144,9 +144,8 @@ static int mt_match (const data_set_t __attribute__((unused)) *ds, /* {{{ */
 
 void module_register (void)
 {
-  match_proc_t mproc;
+  match_proc_t mproc = { 0 };
 
-  memset (&mproc, 0, sizeof (mproc));
   mproc.create  = mt_create;
   mproc.destroy = mt_destroy;
   mproc.match   = mt_match;
index 599f1cf..54ddba2 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_cache.h"
 #include "filter_chain.h"
@@ -58,14 +59,12 @@ struct mv_match_s
  */
 static void mv_free_match (mv_match_t *m) /* {{{ */
 {
-  size_t i;
-
   if (m == NULL)
     return;
 
   if (m->data_sources != NULL)
   {
-    for (i = 0; i < m->data_sources_num; ++i)
+    for (size_t i = 0; i < m->data_sources_num; ++i)
       free(m->data_sources[i]);
     free(m->data_sources);
   }
@@ -103,7 +102,6 @@ static int mv_config_add_data_source (mv_match_t *m, /* {{{ */
 {
   size_t new_data_sources_num;
   char **temp;
-  int i;
 
   /* Check number of arbuments. */
   if (ci->values_num < 1)
@@ -114,7 +112,7 @@ static int mv_config_add_data_source (mv_match_t *m, /* {{{ */
   }
 
   /* Check type of arguments */
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     if (ci->values[i].type == OCONFIG_TYPE_STRING)
       continue;
@@ -139,14 +137,12 @@ static int mv_config_add_data_source (mv_match_t *m, /* {{{ */
   m->data_sources = temp;
 
   /* Copy the strings, allocating memory as needed. */
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
-    size_t j;
-
     /* If we get here, there better be memory for us to write to. */
     assert (m->data_sources_num < new_data_sources_num);
 
-    j = m->data_sources_num;
+    size_t j = m->data_sources_num;
     m->data_sources[j] = sstrdup (ci->values[i].value.string);
     if (m->data_sources[j] == NULL)
     {
@@ -198,7 +194,6 @@ static int mv_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   mv_match_t *m;
   int status;
-  int i;
 
   m = calloc (1, sizeof (*m));
   if (m == NULL)
@@ -215,7 +210,7 @@ static int mv_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   m->data_sources_num = 0;
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -276,7 +271,6 @@ static int mv_match (const data_set_t *ds, const value_list_t *vl, /* {{{ */
   mv_match_t *m;
   gauge_t *values;
   int status;
-  size_t i;
 
   if ((user_data == NULL) || (*user_data == NULL))
     return (-1);
@@ -293,7 +287,7 @@ static int mv_match (const data_set_t *ds, const value_list_t *vl, /* {{{ */
 
   status = FC_MATCH_NO_MATCH;
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     int value_matches = 0;
 
@@ -349,9 +343,8 @@ static int mv_match (const data_set_t *ds, const value_list_t *vl, /* {{{ */
 
 void module_register (void)
 {
-  match_proc_t mproc;
+  match_proc_t mproc = { 0 };
 
-  memset (&mproc, 0, sizeof (mproc));
   mproc.create  = mv_create;
   mproc.destroy = mv_destroy;
   mproc.match   = mv_match;
index 2d6d77e..b72be89 100644 (file)
@@ -24,9 +24,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <netdb.h>
 #include <netinet/in.h>
@@ -84,19 +84,9 @@ static int mbmon_query_daemon (char *buffer, int buffer_size)
        const char *host;
        const char *port;
 
-       struct addrinfo  ai_hints;
-       struct addrinfo *ai_list, *ai_ptr;
+       struct addrinfo *ai_list;
        int              ai_return;
 
-       memset (&ai_hints, '\0', sizeof (ai_hints));
-       ai_hints.ai_flags    = 0;
-#ifdef AI_ADDRCONFIG
-       ai_hints.ai_flags   |= AI_ADDRCONFIG;
-#endif
-       ai_hints.ai_family   = PF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_STREAM;
-       ai_hints.ai_protocol = IPPROTO_TCP;
-
        host = mbmon_host;
        if (host == NULL)
                host = MBMON_DEF_HOST;
@@ -105,6 +95,13 @@ static int mbmon_query_daemon (char *buffer, int buffer_size)
        if (port == NULL)
                port = MBMON_DEF_PORT;
 
+       struct addrinfo ai_hints = {
+               .ai_family = AF_UNSPEC,
+               .ai_flags = AI_ADDRCONFIG,
+               .ai_protocol = IPPROTO_TCP,
+               .ai_socktype = SOCK_STREAM
+       };
+
        if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0)
        {
                char errbuf[1024];
@@ -117,7 +114,7 @@ static int mbmon_query_daemon (char *buffer, int buffer_size)
        }
 
        fd = -1;
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                /* create our socket descriptor */
                if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0)
@@ -221,12 +218,9 @@ static int mbmon_config (const char *key, const char *value)
 static void mbmon_submit (const char *type, const char *type_instance,
                double value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "mbmon", sizeof (vl.plugin));
@@ -239,9 +233,7 @@ static void mbmon_submit (const char *type, const char *type_instance,
 /* Trim trailing whitespace from a string. */
 static void trim_spaces (char *s)
 {
-       size_t l;
-
-       for (l = strlen (s) - 1; (l > 0) && isspace ((int) s[l]); l--)
+       for (size_t l = strlen (s) - 1; (l > 0) && isspace ((int) s[l]); l--)
                s[l] = '\0';
 }
 
index 3725f9a..db85c46 100644 (file)
--- a/src/md.c
+++ b/src/md.c
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_ignorelist.h"
 #include <linux/major.h>
 #include <linux/raid/md_u.h>
 
+#ifdef HAVE_SYS_SYSMACROS_H
+#include <sys/sysmacros.h>
+#endif
+
 #define PROC_DISKSTATS "/proc/diskstats"
 #define DEV_DIR "/dev"
 
@@ -67,12 +72,9 @@ static int md_config (const char *key, const char *value)
 static void md_submit (const int minor, const char *type_instance,
     gauge_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "md", sizeof (vl.plugin));
index d7e6c28..97e75c0 100644 (file)
@@ -22,9 +22,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_match.h"
 
 #include <libmemcached/memcached.h>
@@ -199,7 +199,6 @@ static int cmc_config_add_match (web_page_t *page, /* {{{ */
 {
   web_match_t *match;
   int status;
-  int i;
 
   if (ci->values_num != 0)
   {
@@ -214,7 +213,7 @@ static int cmc_config_add_match (web_page_t *page, /* {{{ */
   }
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -296,7 +295,6 @@ static int cmc_config_add_page (oconfig_item_t *ci) /* {{{ */
 {
   web_page_t *page;
   int status;
-  int i;
 
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
@@ -323,7 +321,7 @@ static int cmc_config_add_page (oconfig_item_t *ci) /* {{{ */
 
   /* Process all children */
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -400,12 +398,11 @@ static int cmc_config (oconfig_item_t *ci) /* {{{ */
   int success;
   int errors;
   int status;
-  int i;
 
   success = 0;
   errors = 0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -444,14 +441,11 @@ static int cmc_init (void) /* {{{ */
 } /* }}} int cmc_init */
 
 static void cmc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */
-    const cu_match_value_t *mv)
+    value_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0] = mv->value;
-
-  vl.values = values;
+  vl.values = &value;
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "memcachec", sizeof (vl.plugin));
@@ -464,7 +458,6 @@ static void cmc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */
 
 static int cmc_read_page (web_page_t *wp) /* {{{ */
 {
-  web_match_t *wm;
   memcached_return rc;
   size_t string_length;
   uint32_t flags;
@@ -482,7 +475,7 @@ static int cmc_read_page (web_page_t *wp) /* {{{ */
     return (-1);
   }
 
-  for (wm = wp->matches; wm != NULL; wm = wm->next)
+  for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next)
   {
     cu_match_value_t *mv;
 
@@ -500,7 +493,7 @@ static int cmc_read_page (web_page_t *wp) /* {{{ */
       continue;
     }
 
-    cmc_submit (wp, wm, mv);
+    cmc_submit (wp, wm, mv->value);
     match_value_reset (mv);
   } /* for (wm = wp->matches; wm != NULL; wm = wm->next) */
 
@@ -511,9 +504,7 @@ static int cmc_read_page (web_page_t *wp) /* {{{ */
 
 static int cmc_read (void) /* {{{ */
 {
-  web_page_t *wp;
-
-  for (wp = pages_g; wp != NULL; wp = wp->next)
+  for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next)
     cmc_read_page (wp);
 
   return (0);
index 54e3a19..77cadeb 100644 (file)
@@ -29,9 +29,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <netdb.h>
 #include <sys/un.h>
@@ -67,10 +67,9 @@ static void memcached_free (void *arg)
 
 static int memcached_connect_unix (memcached_t *st)
 {
-  struct sockaddr_un serv_addr;
+  struct sockaddr_un serv_addr = { 0 };
   int fd;
 
-  memset (&serv_addr, 0, sizeof (serv_addr));
   serv_addr.sun_family = AF_UNIX;
   sstrncpy (serv_addr.sun_path, st->socket,
       sizeof (serv_addr.sun_path));
@@ -102,24 +101,19 @@ static int memcached_connect_inet (memcached_t *st)
   const char *host;
   const char *port;
 
-  struct addrinfo  ai_hints;
-  struct addrinfo *ai_list, *ai_ptr;
+  struct addrinfo *ai_list;
   int status;
   int fd = -1;
 
-  memset (&ai_hints, 0, sizeof (ai_hints));
-  ai_hints.ai_flags    = 0;
-#ifdef AI_ADDRCONFIG
-  ai_hints.ai_flags   |= AI_ADDRCONFIG;
-#endif
-  ai_hints.ai_family   = AF_UNSPEC;
-  ai_hints.ai_socktype = SOCK_STREAM;
-  ai_hints.ai_protocol = 0;
-
   host = (st->host != NULL) ? st->host : MEMCACHED_DEF_HOST;
   port = (st->port != NULL) ? st->port : MEMCACHED_DEF_PORT;
 
-  ai_list = NULL;
+  struct addrinfo ai_hints = {
+    .ai_family = AF_UNSPEC,
+    .ai_flags = AI_ADDRCONFIG,
+    .ai_socktype = SOCK_STREAM
+  };
+
   status = getaddrinfo (host, port, &ai_hints, &ai_list);
   if (status != 0)
   {
@@ -133,7 +127,7 @@ static int memcached_connect_inet (memcached_t *st)
     return (-1);
   }
 
-  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
     /* create our socket descriptor */
     fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
@@ -245,33 +239,33 @@ static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t
 
 static void memcached_init_vl (value_list_t *vl, memcached_t const *st)
 {
+  char const *host = st->host;
+
+  /* Set vl->host to hostname_g, if:
+   * - Legacy mode is used.
+   * - "Socket" option is given (doc: "Host option is ignored").
+   * - "Host" option is not provided.
+   * - "Host" option is set to "localhost" or "127.0.0.1". */
+  if ((strcmp (st->name, "__legacy__") == 0)
+      || (st->socket != NULL)
+      || (st->host == NULL)
+      || (strcmp ("127.0.0.1", st->host) == 0)
+      || (strcmp ("localhost", st->host) == 0))
+    host = hostname_g;
+
   sstrncpy (vl->plugin, "memcached", sizeof (vl->plugin));
-  if (strcmp (st->name, "__legacy__") == 0) /* legacy mode */
-  {
-    sstrncpy (vl->host, hostname_g, sizeof (vl->host));
-  }
-  else
-  {
-    if (st->socket != NULL)
-      sstrncpy (vl->host, hostname_g, sizeof (vl->host));
-    else
-      sstrncpy (vl->host,
-          (st->host != NULL) ? st->host : MEMCACHED_DEF_HOST,
-          sizeof (vl->host));
+  sstrncpy (vl->host, host, sizeof (vl->host));
+  if (strcmp (st->name, "__legacy__") != 0)
     sstrncpy (vl->plugin_instance, st->name, sizeof (vl->plugin_instance));
-  }
 }
 
 static void submit_derive (const char *type, const char *type_inst,
     derive_t value, memcached_t *st)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
-  memcached_init_vl (&vl, st);
-
-  values[0].derive = value;
 
-  vl.values = values;
+  memcached_init_vl (&vl, st);
+  vl.values = &(value_t) { .derive = value };
   vl.values_len = 1;
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
@@ -283,15 +277,15 @@ static void submit_derive (const char *type, const char *type_inst,
 static void submit_derive2 (const char *type, const char *type_inst,
     derive_t value0, derive_t value1, memcached_t *st)
 {
-  value_t values[2];
   value_list_t vl = VALUE_LIST_INIT;
-  memcached_init_vl (&vl, st);
-
-  values[0].derive = value0;
-  values[1].derive = value1;
+  value_t values[] = {
+    { .derive = value0 },
+    { .derive = value1 },
+  };
 
+  memcached_init_vl (&vl, st);
   vl.values = values;
-  vl.values_len = 2;
+  vl.values_len = STATIC_ARRAY_SIZE (values);
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
     sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
@@ -302,13 +296,10 @@ static void submit_derive2 (const char *type, const char *type_inst,
 static void submit_gauge (const char *type, const char *type_inst,
     gauge_t value, memcached_t *st)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
-  memcached_init_vl (&vl, st);
-
-  values[0].gauge = value;
 
-  vl.values = values;
+  memcached_init_vl (&vl, st);
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
@@ -320,15 +311,15 @@ static void submit_gauge (const char *type, const char *type_inst,
 static void submit_gauge2 (const char *type, const char *type_inst,
     gauge_t value0, gauge_t value1, memcached_t *st)
 {
-  value_t values[2];
   value_list_t vl = VALUE_LIST_INIT;
-  memcached_init_vl (&vl, st);
-
-  values[0].gauge = value0;
-  values[1].gauge = value1;
+  value_t values[] = {
+    { .gauge = value0 },
+    { .gauge = value1 },
+  };
 
+  memcached_init_vl (&vl, st);
   vl.values = values;
-  vl.values_len = 2;
+  vl.values_len = STATIC_ARRAY_SIZE (values);
   sstrncpy (vl.type, type, sizeof (vl.type));
   if (type_inst != NULL)
     sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
@@ -551,14 +542,9 @@ static int memcached_read (user_data_t *user_data)
 
 static int memcached_add_read_callback (memcached_t *st)
 {
-  user_data_t ud;
   char callback_name[3*DATA_MAX_NAME_LEN];
   int status;
 
-  memset (&ud, 0, sizeof (ud));
-  ud.data = st;
-  ud.free_func = memcached_free;
-
   assert (st->name != NULL);
   ssnprintf (callback_name, sizeof (callback_name), "memcached/%s", st->name);
 
@@ -566,7 +552,11 @@ static int memcached_add_read_callback (memcached_t *st)
       /* name      = */ callback_name,
       /* callback  = */ memcached_read,
       /* interval  = */ 0,
-      /* user_data = */ &ud);
+      &(user_data_t) {
+        .data = st,
+        .free_func = memcached_free,
+      });
+
   return (status);
 } /* int memcached_add_read_callback */
 
@@ -581,7 +571,6 @@ static int memcached_add_read_callback (memcached_t *st)
 static int config_add_instance(oconfig_item_t *ci)
 {
   memcached_t *st;
-  int i;
   int status = 0;
 
   /* Disable automatic generation of default instance in the init callback. */
@@ -610,7 +599,7 @@ static int config_add_instance(oconfig_item_t *ci)
   }
   assert (st->name != NULL);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -647,9 +636,8 @@ static int memcached_config (oconfig_item_t *ci)
 {
   int status = 0;
   _Bool have_instance_block = 0;
-  int i;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
index 3d8a867..16b8e09 100644 (file)
@@ -24,6 +24,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -98,9 +99,7 @@ static _Bool values_percentage = 0;
 
 static int memory_config (oconfig_item_t *ci) /* {{{ */
 {
-       int i;
-
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
                if (strcasecmp ("ValuesAbsolute", child->key) == 0)
@@ -250,9 +249,7 @@ static int memory_read_internal (value_list_t *vl)
        };
        double sysctl_vals[8];
 
-       int    i;
-
-       for (i = 0; sysctl_keys[i] != NULL; i++)
+       for (int i = 0; sysctl_keys[i] != NULL; i++)
        {
                int value;
                size_t value_len = sizeof (value);
@@ -270,7 +267,7 @@ static int memory_read_internal (value_list_t *vl)
        } /* for (sysctl_keys) */
 
        /* multiply all all page counts with the pagesize */
-       for (i = 1; sysctl_keys[i] != NULL; i++)
+       for (int i = 1; sysctl_keys[i] != NULL; i++)
                if (!isnan (sysctl_vals[i]))
                        sysctl_vals[i] *= sysctl_vals[0];
 
@@ -456,13 +453,12 @@ static int memory_read_internal (value_list_t *vl)
 
 #elif HAVE_SYSCTL
        int mib[] = {CTL_VM, VM_METER};
-       struct vmtotal vmtotal;
+       struct vmtotal vmtotal = { 0 };
        gauge_t mem_active;
        gauge_t mem_inactive;
        gauge_t mem_free;
        size_t size;
 
-       memset (&vmtotal, 0, sizeof (vmtotal));
        size = sizeof (vmtotal);
 
        if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) {
@@ -495,9 +491,8 @@ static int memory_read_internal (value_list_t *vl)
 /* #endif HAVE_LIBSTATGRAB */
 
 #elif HAVE_PERFSTAT
-       perfstat_memory_total_t pmemory;
+       perfstat_memory_total_t pmemory = { 0 };
 
-       memset (&pmemory, 0, sizeof (pmemory));
        if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0)
        {
                char errbuf[1024];
index 570da51..5ec382b 100644 (file)
--- a/src/mic.c
+++ b/src/mic.c
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "utils_ignorelist.h"
@@ -149,17 +150,15 @@ static int mic_config (const char *key, const char *value) {
        return (0);
 }
 
-static void mic_submit_memory_use(int micnumber, const char *type_instance, U32 val)
+static void mic_submit_memory_use(int micnumber, const char *type_instance, U32 value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
        /* MicAccessAPI reports KB's of memory, adjust for this */
-       DEBUG("mic plugin: Memory Value Report; %u %lf",val,((gauge_t)val)*1024.0);
-       values[0].gauge = ((gauge_t)val)*1024.0;
+       DEBUG("mic plugin: Memory Value Report; %u %lf",value,((gauge_t)value)*1024.0);
 
-       vl.values=values;
-       vl.values_len=1;
+       vl.values = &(value_t) { .gauge = ((gauge_t)value) * 1024.0 };
+       vl.values_len = 1;
 
        strncpy (vl.host, hostname_g, sizeof (vl.host));
        strncpy (vl.plugin, "mic", sizeof (vl.plugin));
@@ -189,15 +188,12 @@ static int mic_read_memory(int mic)
        return (0);
 }
 
-static void mic_submit_temp(int micnumber, const char *type, gauge_t val)
+static void mic_submit_temp(int micnumber, const char *type, gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = val;
-
-       vl.values=values;
-       vl.values_len=1;
+       vl.values = &(value_t) { .gauge = value };
+       vl.values_len = 1;
 
        strncpy (vl.host, hostname_g, sizeof (vl.host));
        strncpy (vl.plugin, "mic", sizeof (vl.plugin));
@@ -213,9 +209,8 @@ static void mic_submit_temp(int micnumber, const char *type, gauge_t val)
 static int mic_read_temps(int mic)
 {
        size_t num_therms = STATIC_ARRAY_SIZE(therm_ids);
-       size_t j;
 
-       for (j = 0; j < num_therms; j++) {
+       for (size_t j = 0; j < num_therms; j++) {
                U32 status;
                U32 temp_buffer;
                U32 buffer_size = (U32)sizeof(temp_buffer);
@@ -237,15 +232,12 @@ static int mic_read_temps(int mic)
 }
 
 static void mic_submit_cpu(int micnumber, const char *type_instance,
-               int core, derive_t val)
+               int core, derive_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = val;
-
-       vl.values=values;
-       vl.values_len=1;
+       vl.values = &(value_t) { .derive = value };
+       vl.values_len = 1;
 
        strncpy (vl.host, hostname_g, sizeof (vl.host));
        strncpy (vl.plugin, "mic", sizeof (vl.plugin));
@@ -286,8 +278,7 @@ static int mic_read_cpu(int mic)
        }
 
        if (show_cpu_cores) {
-               int j;
-               for (j = 0; j < core_util.core; j++) {
+               for (int j = 0; j < core_util.core; j++) {
                        mic_submit_cpu(mic, "user", j, core_jiffs[j].user);
                        mic_submit_cpu(mic, "sys", j, core_jiffs[j].sys);
                        mic_submit_cpu(mic, "nice", j, core_jiffs[j].nice);
@@ -297,15 +288,12 @@ static int mic_read_cpu(int mic)
        return (0);
 }
 
-static void mic_submit_power(int micnumber, const char *type, const char *type_instance, gauge_t val)
+static void mic_submit_power(int micnumber, const char *type, const char *type_instance, gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = val;
-
-       vl.values=values;
-       vl.values_len=1;
+       vl.values = &(value_t) { .gauge = value };
+       vl.values_len = 1;
 
        strncpy (vl.host, hostname_g, sizeof (vl.host));
        strncpy (vl.plugin, "mic", sizeof (vl.plugin));
@@ -356,17 +344,16 @@ static int mic_read_power(int mic)
 
 static int mic_read (void)
 {
-       int i;
        U32 ret;
        int error;
 
-       error=0;
-       for (i=0;i<num_mics;i++) {
+       error = 0;
+       for (int i = 0;i<num_mics;i++) {
                ret = MicInitAdapter(&mic_handle,&mics[i]);
                if (ret != MIC_ACCESS_API_SUCCESS) {
                        ERROR("mic plugin: Problem initializing MicAdapter: %s",
                                        MicGetErrorString(ret));
-                       error=1;
+                       error = 1;
                }
 
                if (error == 0 && show_memory)
@@ -385,12 +372,12 @@ static int mic_read (void)
                if (ret != MIC_ACCESS_API_SUCCESS) {
                        ERROR("mic plugin: Problem closing MicAdapter: %s",
                                        MicGetErrorString(ret));
-                       error=2;
+                       error = 2;
                        break;
                }
        }
        if (num_mics==0)
-               error=3;
+               error = 3;
        return error;
 }
 
index 11b9bf1..a7d1b58 100644 (file)
@@ -21,9 +21,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <netdb.h>
 
@@ -161,12 +161,10 @@ static mb_data_t *data_definitions = NULL;
 static mb_data_t *data_get_by_name (mb_data_t *src, /* {{{ */
     const char *name)
 {
-  mb_data_t *ptr;
-
   if (name == NULL)
     return (NULL);
 
-  for (ptr = src; ptr != NULL; ptr = ptr->next)
+  for (mb_data_t *ptr = src; ptr != NULL; ptr = ptr->next)
     if (strcasecmp (ptr->name, name) == 0)
       return (ptr);
 
@@ -427,7 +425,7 @@ static int mb_init_connection (mb_host_t *host) /* {{{ */
 static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
     mb_data_t *data)
 {
-  uint16_t values[2];
+  uint16_t values[2] = { 0 };
   int values_num;
   const data_set_t *ds;
   int status = 0;
@@ -459,7 +457,6 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
         "is not UINT32.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type));
   }
 
-  memset (values, 0, sizeof (values));
   if ((data->register_type == REG_TYPE_INT32)
       || (data->register_type == REG_TYPE_UINT32)
       || (data->register_type == REG_TYPE_FLOAT))
@@ -473,11 +470,11 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
   }
   else if (host->conntype == MBCONN_TCP)
   {
-    struct sockaddr sockaddr;
-    socklen_t saddrlen = sizeof (sockaddr);
-
+    /* getpeername() is used only to determine if the socket is connected, not
+     * because we're really interested in the peer's IP address. */
     status = getpeername (modbus_get_socket (host->connection),
-        &sockaddr, &saddrlen);
+        (struct sockaddr *) &(struct sockaddr_storage) { 0 },
+        &(socklen_t) { sizeof (struct sockaddr_storage) });
     if (status != 0)
       status = errno;
   }
@@ -622,7 +619,6 @@ static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
 
 static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */
 {
-  mb_data_t *data;
   int success;
   int status;
 
@@ -630,7 +626,7 @@ static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */
     return (EINVAL);
 
   success = 0;
-  for (data = slave->collect; data != NULL; data = data->next)
+  for (mb_data_t *data = slave->collect; data != NULL; data = data->next)
   {
     status = mb_read_data (host, slave, data);
     if (status == 0)
@@ -646,7 +642,6 @@ static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */
 static int mb_read (user_data_t *user_data) /* {{{ */
 {
   mb_host_t *host;
-  size_t i;
   int success;
   int status;
 
@@ -656,7 +651,7 @@ static int mb_read (user_data_t *user_data) /* {{{ */
   host = user_data->data;
 
   success = 0;
-  for (i = 0; i < host->slaves_num; i++)
+  for (size_t i = 0; i < host->slaves_num; i++)
   {
     status = mb_read_slave (host, host->slaves + i);
     if (status == 0)
@@ -695,12 +690,10 @@ static void data_free_all (mb_data_t *data) /* {{{ */
 
 static void slaves_free_all (mb_slave_t *slaves, size_t slaves_num) /* {{{ */
 {
-  size_t i;
-
   if (slaves == NULL)
     return;
 
-  for (i = 0; i < slaves_num; i++)
+  for (size_t i = 0; i < slaves_num; i++)
     data_free_all (slaves[i].collect);
   sfree (slaves);
 } /* }}} void slaves_free_all */
@@ -720,11 +713,9 @@ static void host_free (void *void_host) /* {{{ */
 
 static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */
 {
-  mb_data_t data;
+  mb_data_t data = { 0 };
   int status;
-  int i;
 
-  memset (&data, 0, sizeof (data));
   data.name = NULL;
   data.register_type = REG_TYPE_UINT16;
   data.next = NULL;
@@ -733,7 +724,7 @@ static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */
   if (status != 0)
     return (status);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -819,24 +810,17 @@ static int mb_config_set_host_address (mb_host_t *host, /* {{{ */
     const char *address)
 {
   struct addrinfo *ai_list;
-  struct addrinfo *ai_ptr;
-  struct addrinfo  ai_hints;
   int status;
 
   if ((host == NULL) || (address == NULL))
     return (EINVAL);
 
-  memset (&ai_hints, 0, sizeof (ai_hints));
-#if AI_ADDRCONFIG
-  ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-  /* XXX: libmodbus can only handle IPv4 addresses. */
-  ai_hints.ai_family = AF_INET;
-  ai_hints.ai_addr = NULL;
-  ai_hints.ai_canonname = NULL;
-  ai_hints.ai_next = NULL;
+  struct addrinfo  ai_hints = {
+    /* XXX: libmodbus can only handle IPv4 addresses. */
+    .ai_family = AF_INET,
+    .ai_flags = AI_ADDRCONFIG
+  };
 
-  ai_list = NULL;
   status = getaddrinfo (address, /* service = */ NULL,
       &ai_hints, &ai_list);
   if (status != 0)
@@ -849,7 +833,7 @@ static int mb_config_set_host_address (mb_host_t *host, /* {{{ */
     return (status);
   }
 
-  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
     status = getnameinfo (ai_ptr->ai_addr, ai_ptr->ai_addrlen,
         host->node, sizeof (host->node),
@@ -876,7 +860,6 @@ static int mb_config_add_slave (mb_host_t *host, oconfig_item_t *ci) /* {{{ */
 {
   mb_slave_t *slave;
   int status;
-  int i;
 
   if ((host == NULL) || (ci == NULL))
     return (EINVAL);
@@ -893,7 +876,7 @@ static int mb_config_add_slave (mb_host_t *host, oconfig_item_t *ci) /* {{{ */
   if (status != 0)
     return (status);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -936,7 +919,6 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */
 {
   mb_host_t *host;
   int status;
-  int i;
 
   host = calloc (1, sizeof (*host));
   if (host == NULL)
@@ -955,7 +937,7 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */
     return (EINVAL);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     status = 0;
@@ -1021,18 +1003,17 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */
 
   if (status == 0)
   {
-    user_data_t ud;
     char name[1024];
 
-    ud.data = host;
-    ud.free_func = host_free;
-
     ssnprintf (name, sizeof (name), "modbus-%s", host->host);
 
     plugin_register_complex_read (/* group = */ NULL, name,
         /* callback = */ mb_read,
         /* interval = */ host->interval,
-        &ud);
+        &(user_data_t) {
+          .data = host,
+          .free_func = host_free,
+        });
   }
   else
   {
@@ -1044,12 +1025,10 @@ static int mb_config_add_host (oconfig_item_t *ci) /* {{{ */
 
 static int mb_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
   if (ci == NULL)
     return (EINVAL);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
index 7516db4..c08fd29 100644 (file)
@@ -31,6 +31,7 @@
 
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_complain.h"
@@ -144,11 +145,9 @@ static void mqtt_free (mqtt_client_conf_t *conf)
 
 static char *strip_prefix (char *topic)
 {
-    size_t num;
-    size_t i;
+    size_t num = 0;
 
-    num = 0;
-    for (i = 0; topic[i] != 0; i++)
+    for (size_t i = 0; topic[i] != 0; i++)
         if (topic[i] == '/')
             num++;
 
@@ -549,9 +548,7 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
 {
     mqtt_client_conf_t *conf;
     char cb_name[1024];
-    user_data_t user_data;
     int status;
-    int i;
 
     conf = calloc (1, sizeof (*conf));
     if (conf == NULL)
@@ -585,7 +582,7 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
 
     C_COMPLAIN_INIT (&conf->complaint_cantpublish);
 
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
         if (strcasecmp ("Host", child->key) == 0)
@@ -634,10 +631,9 @@ static int mqtt_config_publisher (oconfig_item_t *ci)
     }
 
     ssnprintf (cb_name, sizeof (cb_name), "mqtt/%s", conf->name);
-    memset (&user_data, 0, sizeof (user_data));
-    user_data.data = conf;
-
-    plugin_register_write (cb_name, mqtt_write, &user_data);
+    plugin_register_write (cb_name, mqtt_write, &(user_data_t) {
+                .data = conf,
+            });
     return (0);
 } /* mqtt_config_publisher */
 
@@ -656,7 +652,6 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
     mqtt_client_conf_t **tmp;
     mqtt_client_conf_t *conf;
     int status;
-    int i;
 
     conf = calloc (1, sizeof (*conf));
     if (conf == NULL)
@@ -690,7 +685,7 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
 
     C_COMPLAIN_INIT (&conf->complaint_cantpublish);
 
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
         if (strcasecmp ("Host", child->key) == 0)
@@ -752,9 +747,7 @@ static int mqtt_config_subscriber (oconfig_item_t *ci)
  */
 static int mqtt_config (oconfig_item_t *ci)
 {
-    int i;
-
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
@@ -771,11 +764,9 @@ static int mqtt_config (oconfig_item_t *ci)
 
 static int mqtt_init (void)
 {
-    size_t i;
-
     mosquitto_lib_init ();
 
-    for (i = 0; i < subscribers_num; i++)
+    for (size_t i = 0; i < subscribers_num; i++)
     {
         int status;
 
index 6953750..2ffcc8f 100644 (file)
@@ -23,6 +23,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -148,20 +149,18 @@ static int multimeter_read_value(double *value)
 
 static int multimeter_init (void)
 {
-       int i;
        char device[] = "/dev/ttyS ";
 
-       for (i = 0; i < 10; i++)
+       for (int i = 0; i < 10; i++)
        {
                device[strlen(device)-1] = i + '0';
 
                if ((fd = open(device, O_RDWR | O_NOCTTY)) != -1)
                {
-                       struct termios tios;
+                       struct termios tios = { 0 };
                        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;
@@ -194,12 +193,9 @@ static int multimeter_init (void)
 
 static void multimeter_submit (double value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "multimeter", sizeof (vl.plugin));
index 8ab775f..a64b0e5 100644 (file)
@@ -28,9 +28,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #ifdef HAVE_MYSQL_H
 #include <mysql.h>
@@ -46,6 +46,14 @@ struct mysql_database_s /* {{{ */
        char *user;
        char *pass;
        char *database;
+
+       /* mysql_ssl_set params */
+       char *key;
+       char *cert;
+       char *ca;
+       char *capath;
+       char *cipher;
+
        char *socket;
        int   port;
        int   timeout;
@@ -53,6 +61,7 @@ struct mysql_database_s /* {{{ */
        _Bool master_stats;
        _Bool slave_stats;
        _Bool innodb_stats;
+       _Bool wsrep_stats;
 
        _Bool slave_notif;
        _Bool slave_io_running;
@@ -86,6 +95,11 @@ static void mysql_database_free (void *arg) /* {{{ */
        sfree (db->socket);
        sfree (db->instance);
        sfree (db->database);
+       sfree (db->key);
+       sfree (db->cert);
+       sfree (db->ca);
+       sfree (db->capath);
+       sfree (db->cipher);
        sfree (db);
 } /* }}} void mysql_database_free */
 
@@ -103,7 +117,6 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
 {
        mysql_database_t *db;
        int status = 0;
-       int i;
 
        if ((ci->values_num != 1)
            || (ci->values[0].type != OCONFIG_TYPE_STRING))
@@ -126,6 +139,12 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
        db->user     = NULL;
        db->pass     = NULL;
        db->database = NULL;
+       db->key      = NULL;
+       db->cert     = NULL;
+       db->ca       = NULL;
+       db->capath   = NULL;
+       db->cipher   = NULL;
+
        db->socket   = NULL;
        db->con      = NULL;
        db->timeout  = 0;
@@ -143,7 +162,7 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
        assert (db->instance != NULL);
 
        /* Fill the `mysql_database_t' structure.. */
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -168,6 +187,16 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
                        status = cf_util_get_string (child, &db->socket);
                else if (strcasecmp ("Database", child->key) == 0)
                        status = cf_util_get_string (child, &db->database);
+               else if (strcasecmp ("SSLKey", child->key) == 0)
+                       status = cf_util_get_string (child, &db->key);
+               else if (strcasecmp ("SSLCert", child->key) == 0)
+                       status = cf_util_get_string (child, &db->cert);
+               else if (strcasecmp ("SSLCA", child->key) == 0)
+                       status = cf_util_get_string (child, &db->ca);
+               else if (strcasecmp ("SSLCAPath", child->key) == 0)
+                       status = cf_util_get_string (child, &db->capath);
+               else if (strcasecmp ("SSLCipher", child->key) == 0)
+                       status = cf_util_get_string (child, &db->cipher);
                else if (strcasecmp ("ConnectTimeout", child->key) == 0)
                        status = cf_util_get_int (child, &db->timeout);
                else if (strcasecmp ("MasterStats", child->key) == 0)
@@ -178,6 +207,8 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
                        status = cf_util_get_boolean (child, &db->slave_notif);
                else if (strcasecmp ("InnodbStats", child->key) == 0)
                        status = cf_util_get_boolean (child, &db->innodb_stats);
+               else if (strcasecmp ("WsrepStats", child->key) == 0)
+                       status = cf_util_get_boolean (child, &db->wsrep_stats);
                else
                {
                        WARNING ("mysql plugin: Option `%s' not allowed here.", child->key);
@@ -191,16 +222,11 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
        /* If all went well, register this database for reading */
        if (status == 0)
        {
-               user_data_t ud;
                char cb_name[DATA_MAX_NAME_LEN];
 
                DEBUG ("mysql plugin: Registering new read callback: %s",
                                (db->database != NULL) ? db->database : "<default>");
 
-               memset (&ud, 0, sizeof (ud));
-               ud.data = (void *) db;
-               ud.free_func = mysql_database_free;
-
                if (db->instance != NULL)
                        ssnprintf (cb_name, sizeof (cb_name), "mysql-%s",
                                        db->instance);
@@ -208,8 +234,10 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
                        sstrncpy (cb_name, "mysql", sizeof (cb_name));
 
                plugin_register_complex_read (/* group = */ NULL, cb_name,
-                                             mysql_read,
-                                             /* interval = */ 0, &ud);
+                               mysql_read, /* interval = */ 0, &(user_data_t) {
+                                       .data = db,
+                                       .free_func = mysql_database_free,
+                               });
        }
        else
        {
@@ -222,13 +250,11 @@ static int mysql_config_database (oconfig_item_t *ci) /* {{{ */
 
 static int mysql_config (oconfig_item_t *ci) /* {{{ */
 {
-       int i;
-
        if (ci == NULL)
                return (EINVAL);
 
        /* Fill the `mysql_database_t' structure.. */
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -246,6 +272,8 @@ static int mysql_config (oconfig_item_t *ci) /* {{{ */
 
 static MYSQL *getconnection (mysql_database_t *db)
 {
+       const char *cipher;
+
        if (db->is_connected)
        {
                int status;
@@ -273,6 +301,8 @@ static MYSQL *getconnection (mysql_database_t *db)
        /* Configure TCP connect timeout (default: 0) */
        db->con->options.connect_timeout = db->timeout;
 
+       mysql_ssl_set (db->con, db->key, db->cert, db->ca, db->capath, db->cipher);
+
        if (mysql_real_connect (db->con, db->host, db->user, db->pass,
                                db->database, db->port, db->socket, 0) == NULL)
        {
@@ -284,10 +314,14 @@ static MYSQL *getconnection (mysql_database_t *db)
                return (NULL);
        }
 
+       cipher = mysql_get_ssl_cipher (db->con);
+
        INFO ("mysql plugin: Successfully connected to database %s "
-                       "at server %s (server version: %s, protocol version: %d)",
+                       "at server %s with cipher %s "
+                       "(server version: %s, protocol version: %d) ",
                        (db->database != NULL) ? db->database : "<none>",
                        mysql_get_host_info (db->con),
+                       (cipher != NULL) ?  cipher : "<none>",
                        mysql_get_server_info (db->con),
                        mysql_get_proto_info (db->con));
 
@@ -331,39 +365,24 @@ static void submit (const char *type, const char *type_instance,
        plugin_dispatch_values (&vl);
 } /* submit */
 
-static void counter_submit (const char *type, const char *type_instance,
-               derive_t value, mysql_database_t *db)
-{
-       value_t values[1];
-
-       values[0].derive = value;
-       submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db);
-} /* void counter_submit */
-
 static void gauge_submit (const char *type, const char *type_instance,
                gauge_t value, mysql_database_t *db)
 {
-       value_t values[1];
-
-       values[0].gauge = value;
-       submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db);
+       submit (type, type_instance, &(value_t) { .gauge = value }, 1, db);
 } /* void gauge_submit */
 
 static void derive_submit (const char *type, const char *type_instance,
                derive_t value, mysql_database_t *db)
 {
-       value_t values[1];
-
-       values[0].derive = value;
-       submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db);
+       submit (type, type_instance, &(value_t) { .derive = value }, 1, db);
 } /* void derive_submit */
 
 static void traffic_submit (derive_t rx, derive_t tx, mysql_database_t *db)
 {
-       value_t values[2];
-
-       values[0].derive = rx;
-       values[1].derive = tx;
+       value_t values[] = {
+               { .derive = rx },
+               { .derive = tx },
+       };
 
        submit ("mysql_octets", NULL, values, STATIC_ARRAY_SIZE (values), db);
 } /* void traffic_submit */
@@ -428,7 +447,7 @@ static int mysql_read_master_stats (mysql_database_t *db, MYSQL *con)
        }
 
        position = atoll (row[1]);
-       counter_submit ("mysql_log_position", "master-bin", position, db);
+       derive_submit ("mysql_log_position", "master-bin", position, db);
 
        row = mysql_fetch_row (res);
        if (row != NULL)
@@ -486,10 +505,10 @@ static int mysql_read_slave_stats (mysql_database_t *db, MYSQL *con)
                double gauge;
 
                counter = atoll (row[READ_MASTER_LOG_POS_IDX]);
-               counter_submit ("mysql_log_position", "slave-read", counter, db);
+               derive_submit ("mysql_log_position", "slave-read", counter, db);
 
                counter = atoll (row[EXEC_MASTER_LOG_POS_IDX]);
-               counter_submit ("mysql_log_position", "slave-exec", counter, db);
+               derive_submit ("mysql_log_position", "slave-exec", counter, db);
 
                if (row[SECONDS_BEHIND_MASTER_IDX] != NULL)
                {
@@ -580,40 +599,12 @@ static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con)
                { "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 },
@@ -628,9 +619,6 @@ static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con)
                { "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 },
@@ -670,7 +658,7 @@ static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con)
 
                switch (metrics[i].ds_type) {
                        case DS_TYPE_COUNTER:
-                               counter_submit(metrics[i].type, key, (counter_t)val, db);
+                               derive_submit(metrics[i].type, key, (counter_t)val, db);
                                break;
                        case DS_TYPE_GAUGE:
                                gauge_submit(metrics[i].type, key, (gauge_t)val, db);
@@ -685,6 +673,93 @@ static int mysql_read_innodb_stats (mysql_database_t *db, MYSQL *con)
        return (0);
 }
 
+static int mysql_read_wsrep_stats (mysql_database_t *db, MYSQL *con)
+{
+       MYSQL_RES *res;
+       MYSQL_ROW  row;
+
+       const char *query;
+       struct {
+               const char *key;
+               const char *type;
+               int ds_type;
+       } metrics[] = {
+
+               { "wsrep_apply_oooe",                "operations",   DS_TYPE_DERIVE },
+               { "wsrep_apply_oool",                "operations",   DS_TYPE_DERIVE },
+               { "wsrep_causal_reads",              "operations",   DS_TYPE_DERIVE },
+               { "wsrep_commit_oooe",               "operations",   DS_TYPE_DERIVE },
+               { "wsrep_commit_oool",               "operations",   DS_TYPE_DERIVE },
+               { "wsrep_flow_control_recv",         "operations",   DS_TYPE_DERIVE },
+               { "wsrep_flow_control_sent",         "operations",   DS_TYPE_DERIVE },
+               { "wsrep_flow_control_paused",       "operations",   DS_TYPE_DERIVE },
+               { "wsrep_local_bf_aborts",           "operations",   DS_TYPE_DERIVE },
+               { "wsrep_local_cert_failures",       "operations",   DS_TYPE_DERIVE },
+               { "wsrep_local_commits",             "operations",   DS_TYPE_DERIVE },
+               { "wsrep_local_replays",             "operations",   DS_TYPE_DERIVE },
+               { "wsrep_received",                  "operations",   DS_TYPE_DERIVE },
+               { "wsrep_replicated",                "operations",   DS_TYPE_DERIVE },
+
+               { "wsrep_received_bytes",            "total_bytes",  DS_TYPE_DERIVE },
+               { "wsrep_replicated_bytes",          "total_bytes",  DS_TYPE_DERIVE },
+
+               { "wsrep_apply_window",              "gauge",        DS_TYPE_GAUGE },
+               { "wsrep_commit_window",             "gauge",        DS_TYPE_GAUGE },
+
+               { "wsrep_cluster_size",              "gauge",        DS_TYPE_GAUGE },
+               { "wsrep_cert_deps_distance",        "gauge",        DS_TYPE_GAUGE },
+
+               { "wsrep_local_recv_queue",          "queue_length", DS_TYPE_GAUGE },
+               { "wsrep_local_send_queue",          "queue_length", DS_TYPE_GAUGE },
+
+               { NULL,                              NULL,           0}
+
+       };
+
+       query = "SHOW GLOBAL STATUS LIKE 'wsrep_%'";
+
+       res = exec_query (con, query);
+       if (res == NULL)
+               return (-1);
+
+       row = mysql_fetch_row (res);
+       if (row == NULL)
+       {
+               ERROR ("mysql plugin: Failed to get wsrep statistics: "
+                       "`%s' did not return any rows.", query);
+               mysql_free_result (res);
+               return (-1);
+       }
+
+       while ((row = mysql_fetch_row (res)))
+       {
+               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_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);
+} /* mysql_read_wsrep_stats */
+
 static int mysql_read (user_data_t *ud)
 {
        mysql_database_t *db;
@@ -746,7 +821,7 @@ static int mysql_read (user_data_t *ud)
 
                        /* Ignore `prepared statements' */
                        if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0)
-                               counter_submit ("mysql_commands",
+                               derive_submit ("mysql_commands",
                                                key + strlen ("Com_"),
                                                val, db);
                }
@@ -756,7 +831,7 @@ static int mysql_read (user_data_t *ud)
                        if (val == 0ULL)
                                continue;
 
-                       counter_submit ("mysql_handler",
+                       derive_submit ("mysql_handler",
                                        key + strlen ("Handler_"),
                                        val, db);
                }
@@ -797,7 +872,7 @@ static int mysql_read (user_data_t *ud)
                else if (strncmp (key, "Table_locks_",
                                        strlen ("Table_locks_")) == 0)
                {
-                       counter_submit ("mysql_locks",
+                       derive_submit ("mysql_locks",
                                        key + strlen ("Table_locks_"),
                                        val, db);
                }
@@ -809,7 +884,7 @@ static int mysql_read (user_data_t *ud)
                        else if (strcmp (key, "Innodb_buffer_pool_pages_dirty") == 0)
                                gauge_submit ("mysql_bpool_pages", "dirty", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_pages_flushed") == 0)
-                               counter_submit ("mysql_bpool_counters", "pages_flushed", val, db);
+                               derive_submit ("mysql_bpool_counters", "pages_flushed", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_pages_free") == 0)
                                gauge_submit ("mysql_bpool_pages", "free", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_pages_misc") == 0)
@@ -817,17 +892,19 @@ static int mysql_read (user_data_t *ud)
                        else if (strcmp (key, "Innodb_buffer_pool_pages_total") == 0)
                                gauge_submit ("mysql_bpool_pages", "total", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_read_ahead_rnd") == 0)
-                               counter_submit ("mysql_bpool_counters", "read_ahead_rnd", val, db);
+                               derive_submit ("mysql_bpool_counters", "read_ahead_rnd", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_read_ahead") == 0)
-                               counter_submit ("mysql_bpool_counters", "read_ahead", val, db);
+                               derive_submit ("mysql_bpool_counters", "read_ahead", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_read_ahead_evicted") == 0)
-                               counter_submit ("mysql_bpool_counters", "read_ahead_evicted", val, db);
+                               derive_submit ("mysql_bpool_counters", "read_ahead_evicted", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_read_requests") == 0)
-                               counter_submit ("mysql_bpool_counters", "read_requests", val, db);
+                               derive_submit ("mysql_bpool_counters", "read_requests", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_reads") == 0)
-                               counter_submit ("mysql_bpool_counters", "reads", val, db);
+                               derive_submit ("mysql_bpool_counters", "reads", val, db);
+                       else if (strcmp (key, "Innodb_buffer_pool_wait_free") == 0)
+                               derive_submit ("mysql_bpool_counters", "wait_free", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_write_requests") == 0)
-                               counter_submit ("mysql_bpool_counters", "write_requests", val, db);
+                               derive_submit ("mysql_bpool_counters", "write_requests", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_bytes_data") == 0)
                                gauge_submit ("mysql_bpool_bytes", "data", val, db);
                        else if (strcmp (key, "Innodb_buffer_pool_bytes_dirty") == 0)
@@ -835,78 +912,80 @@ static int mysql_read (user_data_t *ud)
 
                        /* data */
                        if (strcmp (key, "Innodb_data_fsyncs") == 0)
-                               counter_submit ("mysql_innodb_data", "fsyncs", val, db);
+                               derive_submit ("mysql_innodb_data", "fsyncs", val, db);
                        else if (strcmp (key, "Innodb_data_read") == 0)
-                               counter_submit ("mysql_innodb_data", "read", val, db);
+                               derive_submit ("mysql_innodb_data", "read", val, db);
                        else if (strcmp (key, "Innodb_data_reads") == 0)
-                               counter_submit ("mysql_innodb_data", "reads", val, db);
+                               derive_submit ("mysql_innodb_data", "reads", val, db);
                        else if (strcmp (key, "Innodb_data_writes") == 0)
-                               counter_submit ("mysql_innodb_data", "writes", val, db);
+                               derive_submit ("mysql_innodb_data", "writes", val, db);
                        else if (strcmp (key, "Innodb_data_written") == 0)
-                               counter_submit ("mysql_innodb_data", "written", val, db);
+                               derive_submit ("mysql_innodb_data", "written", val, db);
 
                        /* double write */
                        else if (strcmp (key, "Innodb_dblwr_writes") == 0)
-                               counter_submit ("mysql_innodb_dblwr", "writes", val, db);
+                               derive_submit ("mysql_innodb_dblwr", "writes", val, db);
                        else if (strcmp (key, "Innodb_dblwr_pages_written") == 0)
-                               counter_submit ("mysql_innodb_dblwr", "written", val, db);
+                               derive_submit ("mysql_innodb_dblwr", "written", val, db);
+                       else if (strcmp (key, "Innodb_dblwr_page_size") == 0)
+                               gauge_submit ("mysql_innodb_dblwr", "page_size", val, db);
 
                        /* log */
                        else if (strcmp (key, "Innodb_log_waits") == 0)
-                               counter_submit ("mysql_innodb_log", "waits", val, db);
+                               derive_submit ("mysql_innodb_log", "waits", val, db);
                        else if (strcmp (key, "Innodb_log_write_requests") == 0)
-                               counter_submit ("mysql_innodb_log", "write_requests", val, db);
+                               derive_submit ("mysql_innodb_log", "write_requests", val, db);
                        else if (strcmp (key, "Innodb_log_writes") == 0)
-                               counter_submit ("mysql_innodb_log", "writes", val, db);
+                               derive_submit ("mysql_innodb_log", "writes", val, db);
                        else if (strcmp (key, "Innodb_os_log_fsyncs") == 0)
-                               counter_submit ("mysql_innodb_log", "fsyncs", val, db);
+                               derive_submit ("mysql_innodb_log", "fsyncs", val, db);
                        else if (strcmp (key, "Innodb_os_log_written") == 0)
-                               counter_submit ("mysql_innodb_log", "written", val, db);
+                               derive_submit ("mysql_innodb_log", "written", val, db);
 
                        /* pages */
                        else if (strcmp (key, "Innodb_pages_created") == 0)
-                               counter_submit ("mysql_innodb_pages", "created", val, db);
+                               derive_submit ("mysql_innodb_pages", "created", val, db);
                        else if (strcmp (key, "Innodb_pages_read") == 0)
-                               counter_submit ("mysql_innodb_pages", "read", val, db);
+                               derive_submit ("mysql_innodb_pages", "read", val, db);
                        else if (strcmp (key, "Innodb_pages_written") == 0)
-                               counter_submit ("mysql_innodb_pages", "written", val, db);
+                               derive_submit ("mysql_innodb_pages", "written", val, db);
 
                        /* row lock */
                        else if (strcmp (key, "Innodb_row_lock_time") == 0)
-                               counter_submit ("mysql_innodb_row_lock", "time", val, db);
+                               derive_submit ("mysql_innodb_row_lock", "time", val, db);
                        else if (strcmp (key, "Innodb_row_lock_waits") == 0)
-                               counter_submit ("mysql_innodb_row_lock", "waits", val, db);
+                               derive_submit ("mysql_innodb_row_lock", "waits", val, db);
 
                        /* rows */
                        else if (strcmp (key, "Innodb_rows_deleted") == 0)
-                               counter_submit ("mysql_innodb_rows", "deleted", val, db);
+                               derive_submit ("mysql_innodb_rows", "deleted", val, db);
                        else if (strcmp (key, "Innodb_rows_inserted") == 0)
-                               counter_submit ("mysql_innodb_rows", "inserted", val, db);
+                               derive_submit ("mysql_innodb_rows", "inserted", val, db);
                        else if (strcmp (key, "Innodb_rows_read") == 0)
-                               counter_submit ("mysql_innodb_rows", "read", val, db);
+                               derive_submit ("mysql_innodb_rows", "read", val, db);
                        else if (strcmp (key, "Innodb_rows_updated") == 0)
-                               counter_submit ("mysql_innodb_rows", "updated", val, db);
+                               derive_submit ("mysql_innodb_rows", "updated", val, db);
                }
                else if (strncmp (key, "Select_", strlen ("Select_")) == 0)
                {
-                       counter_submit ("mysql_select", key + strlen ("Select_"),
+                       derive_submit ("mysql_select", key + strlen ("Select_"),
                                        val, db);
                }
                else if (strncmp (key, "Sort_", strlen ("Sort_")) == 0)
                {
                        if (strcmp (key, "Sort_merge_passes") == 0)
-                               counter_submit ("mysql_sort_merge_passes", NULL, val, db);
+                               derive_submit ("mysql_sort_merge_passes", NULL, val, db);
                        else if (strcmp (key, "Sort_rows") == 0)
-                               counter_submit ("mysql_sort_rows", NULL, val, db);
+                               derive_submit ("mysql_sort_rows", NULL, val, db);
                        else if (strcmp (key, "Sort_range") == 0)
-                               counter_submit ("mysql_sort", "range", val, db);
+                               derive_submit ("mysql_sort", "range", val, db);
                        else if (strcmp (key, "Sort_scan") == 0)
-                               counter_submit ("mysql_sort", "scan", val, db);
+                               derive_submit ("mysql_sort", "scan", val, db);
 
                }
-               else if (strncmp (key, "Slow_queries", strlen ("Slow_queries")) == 0) 
+               else if (strncmp (key, "Slow_queries", strlen ("Slow_queries")) == 0)
                {
-                       counter_submit ("mysql_slow_queries", NULL , val, db);
+                       derive_submit ("mysql_slow_queries", NULL , val, db);
                }
        }
        mysql_free_result (res); res = NULL;
@@ -953,6 +1032,9 @@ static int mysql_read (user_data_t *ud)
        if ((db->slave_stats) || (db->slave_notif))
                mysql_read_slave_stats (db, con);
 
+       if (db->wsrep_stats)
+               mysql_read_wsrep_stats (db, con);
+
        return (0);
 } /* int mysql_read */
 
index e00c252..e83a475 100644 (file)
@@ -27,6 +27,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_ignorelist.h"
 
@@ -616,7 +617,7 @@ static data_volume_perf_t *get_volume_perf (cfg_volume_perf_t *cvp, /* {{{ */
 static int submit_values (const char *host, /* {{{ */
                const char *plugin_inst,
                const char *type, const char *type_inst,
-               value_t *values, int values_len,
+               value_t *values, size_t values_len,
                cdtime_t timestamp, cdtime_t interval)
 {
        value_list_t vl = VALUE_LIST_INIT;
@@ -648,50 +649,42 @@ static int submit_two_derive (const char *host, const char *plugin_inst, /* {{{
                const char *type, const char *type_inst, derive_t val0, derive_t val1,
                cdtime_t timestamp, cdtime_t interval)
 {
-       value_t values[2];
-
-       values[0].derive = val0;
-       values[1].derive = val1;
+       value_t values[] = {
+               { .derive = val0 },
+               { .derive = val1 },
+       };
 
        return (submit_values (host, plugin_inst, type, type_inst,
-                               values, 2, timestamp, interval));
+                               values, STATIC_ARRAY_SIZE (values), timestamp, interval));
 } /* }}} int submit_two_derive */
 
 static int submit_derive (const char *host, const char *plugin_inst, /* {{{ */
                const char *type, const char *type_inst, derive_t counter,
                cdtime_t timestamp, cdtime_t interval)
 {
-       value_t v;
-
-       v.derive = counter;
-
        return (submit_values (host, plugin_inst, type, type_inst,
-                               &v, 1, timestamp, interval));
+                               &(value_t) { .derive = counter }, 1, timestamp, interval));
 } /* }}} int submit_derive */
 
 static int submit_two_gauge (const char *host, const char *plugin_inst, /* {{{ */
                const char *type, const char *type_inst, gauge_t val0, gauge_t val1,
                cdtime_t timestamp, cdtime_t interval)
 {
-       value_t values[2];
-
-       values[0].gauge = val0;
-       values[1].gauge = val1;
+       value_t values[] = {
+               { .gauge = val0 },
+               { .gauge = val1 },
+       };
 
        return (submit_values (host, plugin_inst, type, type_inst,
-                               values, 2, timestamp, interval));
+                               values, STATIC_ARRAY_SIZE (values), timestamp, interval));
 } /* }}} int submit_two_gauge */
 
 static int submit_double (const char *host, const char *plugin_inst, /* {{{ */
                const char *type, const char *type_inst, double d,
                cdtime_t timestamp, cdtime_t interval)
 {
-       value_t v;
-
-       v.gauge = (gauge_t) d;
-
        return (submit_values (host, plugin_inst, type, type_inst,
-                               &v, 1, timestamp, interval));
+                               &(value_t) { .gauge = counter }, 1, timestamp, interval));
 } /* }}} int submit_uint64 */
 
 /* Calculate hit ratio from old and new counters and submit the resulting
@@ -706,7 +699,7 @@ static int submit_cache_ratio (const char *host, /* {{{ */
                cdtime_t timestamp,
                cdtime_t interval)
 {
-       value_t v;
+       value_t v = { .gauge = NAN };
 
        if ((new_hits >= old_hits) && (new_misses >= old_misses)) {
                uint64_t hits;
@@ -716,8 +709,6 @@ static int submit_cache_ratio (const char *host, /* {{{ */
                misses = new_misses - old_misses;
 
                v.gauge = 100.0 * ((gauge_t) hits) / ((gauge_t) (hits + misses));
-       } else {
-               v.gauge = NAN;
        }
 
        return (submit_values (host, plugin_inst, "cache_ratio", type_inst,
@@ -889,15 +880,12 @@ static cdtime_t cna_child_get_cdtime (na_elem_t *data) /* {{{ */
 static int cna_handle_wafl_data (const char *hostname, cfg_wafl_t *cfg_wafl, /* {{{ */
                na_elem_t *data, cdtime_t interval)
 {
-       cfg_wafl_t perf_data;
+       cfg_wafl_t perf_data = { 0 };
        const char *plugin_inst;
 
        na_elem_t *instances;
-       na_elem_t *counter;
        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");
@@ -920,7 +908,7 @@ static int cna_handle_wafl_data (const char *hostname, cfg_wafl_t *cfg_wafl, /*
 
        /* Iterate over all counters */
        counter_iter = na_child_iterator (na_elem_child (instances, "counters"));
-       for (counter = na_iterator_next (&counter_iter);
+       for (na_elem_t *counter = na_iterator_next (&counter_iter);
                        counter != NULL;
                        counter = na_iterator_next (&counter_iter))
        {
@@ -1056,7 +1044,6 @@ static int cna_handle_disk_data (const char *hostname, /* {{{ */
 {
        cdtime_t timestamp;
        na_elem_t *instances;
-       na_elem_t *instance;
        na_elem_iter_t instance_iter;
        disk_t *worst_disk = NULL;
 
@@ -1076,17 +1063,15 @@ static int cna_handle_disk_data (const char *hostname, /* {{{ */
 
        /* Iterate over all children */
        instance_iter = na_child_iterator (instances);
-       for (instance = na_iterator_next (&instance_iter);
+       for (na_elem_t *instance = na_iterator_next (&instance_iter);
                        instance != NULL;
                        instance = na_iterator_next(&instance_iter))
        {
                disk_t *old_data;
-               disk_t  new_data;
+               disk_t  new_data = { 0 };
 
                na_elem_iter_t counter_iterator;
-               na_elem_t *counter;
 
-               memset (&new_data, 0, sizeof (new_data));
                new_data.timestamp = timestamp;
                new_data.disk_busy_percent = NAN;
 
@@ -1096,7 +1081,7 @@ static int cna_handle_disk_data (const char *hostname, /* {{{ */
 
                /* Look for the "disk_busy" and "base_for_disk_busy" counters */
                counter_iterator = na_child_iterator(na_elem_child(instance, "counters"));
-               for (counter = na_iterator_next(&counter_iterator);
+               for (na_elem_t *counter = na_iterator_next(&counter_iterator);
                                counter != NULL;
                                counter = na_iterator_next(&counter_iterator))
                {
@@ -1253,7 +1238,6 @@ static int cna_handle_volume_perf_data (const char *hostname, /* {{{ */
        cdtime_t timestamp;
        na_elem_t *elem_instances;
        na_elem_iter_t iter_instances;
-       na_elem_t *elem_instance;
 
        timestamp = cna_child_get_cdtime (data);
 
@@ -1267,20 +1251,18 @@ static int cna_handle_volume_perf_data (const char *hostname, /* {{{ */
        }
 
        iter_instances = na_child_iterator (elem_instances);
-       for (elem_instance = na_iterator_next(&iter_instances);
+       for (na_elem_t *elem_instance = na_iterator_next(&iter_instances);
                        elem_instance != NULL;
                        elem_instance = na_iterator_next(&iter_instances))
        {
                const char *name;
 
-               data_volume_perf_t perf_data;
+               data_volume_perf_t perf_data = { 0 };
                data_volume_perf_t *v;
 
                na_elem_t *elem_counters;
                na_elem_iter_t iter_counters;
-               na_elem_t *elem_counter;
 
-               memset (&perf_data, 0, sizeof (perf_data));
                perf_data.timestamp = timestamp;
 
                name = na_child_get_string (elem_instance, "name");
@@ -1297,7 +1279,7 @@ static int cna_handle_volume_perf_data (const char *hostname, /* {{{ */
                        continue;
 
                iter_counters = na_child_iterator (elem_counters);
-               for (elem_counter = na_iterator_next(&iter_counters);
+               for (na_elem_t *elem_counter = na_iterator_next(&iter_counters);
                                elem_counter != NULL;
                                elem_counter = na_iterator_next(&iter_counters))
                {
@@ -1422,9 +1404,7 @@ static int cna_query_volume_perf (host_config_t *host) /* {{{ */
 static int cna_submit_volume_usage_data (const char *hostname, /* {{{ */
                cfg_volume_usage_t *cfg_volume, int interval)
 {
-       data_volume_usage_t *v;
-
-       for (v = cfg_volume->volumes; v != NULL; v = v->next)
+       for (data_volume_usage_t *v = cfg_volume->volumes; v != NULL; v = v->next)
        {
                char plugin_instance[DATA_MAX_NAME_LEN];
 
@@ -1519,9 +1499,8 @@ static int cna_submit_volume_usage_data (const char *hostname, /* {{{ */
 static int cna_change_volume_status (const char *hostname, /* {{{ */
                data_volume_usage_t *v)
 {
-       notification_t n;
+       notification_t n = { 0 };
 
-       memset (&n, 0, sizeof (n));
        n.time = cdtime ();
        sstrncpy (n.host, hostname, sizeof (n.host));
        sstrncpy (n.plugin, "netapp", sizeof (n.plugin));
@@ -1546,7 +1525,7 @@ static void cna_handle_volume_snap_usage(const host_config_t *host, /* {{{ */
                data_volume_usage_t *v)
 {
        uint64_t snap_used = 0, value;
-       na_elem_t *data, *elem_snap, *elem_snapshots;
+       na_elem_t *data, *elem_snapshots;
        na_elem_iter_t iter_snap;
 
        data = na_server_invoke_elem(host->srv, v->snap_query);
@@ -1578,7 +1557,7 @@ static void cna_handle_volume_snap_usage(const host_config_t *host, /* {{{ */
        }
 
        iter_snap = na_child_iterator (elem_snapshots);
-       for (elem_snap = na_iterator_next (&iter_snap);
+       for (na_elem_t *elem_snap = na_iterator_next (&iter_snap);
                        elem_snap != NULL;
                        elem_snap = na_iterator_next (&iter_snap))
        {
@@ -1693,7 +1672,6 @@ static void cna_handle_volume_sis_saved (const host_config_t *host, /* {{{ */
 static int cna_handle_volume_usage_data (const host_config_t *host, /* {{{ */
                cfg_volume_usage_t *cfg_volume, na_elem_t *data)
 {
-       na_elem_t *elem_volume;
        na_elem_t *elem_volumes;
        na_elem_iter_t iter_volume;
 
@@ -1707,7 +1685,7 @@ static int cna_handle_volume_usage_data (const host_config_t *host, /* {{{ */
        }
 
        iter_volume = na_child_iterator (elem_volumes);
-       for (elem_volume = na_iterator_next (&iter_volume);
+       for (na_elem_t *elem_volume = na_iterator_next (&iter_volume);
                        elem_volume != NULL;
                        elem_volume = na_iterator_next (&iter_volume))
        {
@@ -1831,7 +1809,6 @@ static int cna_query_volume_usage (host_config_t *host) /* {{{ */
 static int cna_handle_quota_data (const host_config_t *host, /* {{{ */
                cfg_quota_t *cfg_quota, na_elem_t *data)
 {
-       na_elem_t *elem_quota;
        na_elem_t *elem_quotas;
        na_elem_iter_t iter_quota;
 
@@ -1845,7 +1822,7 @@ static int cna_handle_quota_data (const host_config_t *host, /* {{{ */
        }
 
        iter_quota = na_child_iterator (elem_quotas);
-       for (elem_quota = na_iterator_next (&iter_quota);
+       for (na_elem_t *elem_quota = na_iterator_next (&iter_quota);
                        elem_quota != NULL;
                        elem_quota = na_iterator_next (&iter_quota))
        {
@@ -1957,7 +1934,6 @@ static int cna_query_quota (host_config_t *host) /* {{{ */
 static int cna_handle_snapvault_data (const char *hostname, /* {{{ */
                cfg_snapvault_t *cfg_snapvault, na_elem_t *data, cdtime_t interval)
 {
-       na_elem_t *status;
        na_elem_iter_t status_iter;
 
        status = na_elem_child (data, "status-list");
@@ -1967,7 +1943,7 @@ static int cna_handle_snapvault_data (const char *hostname, /* {{{ */
        }
 
        status_iter = na_child_iterator (status);
-       for (status = na_iterator_next (&status_iter);
+       for (na_elem_t *status = na_iterator_next (&status_iter);
                        status != NULL;
                        status = na_iterator_next (&status_iter))
        {
@@ -2017,7 +1993,6 @@ static int cna_handle_snapvault_iter (host_config_t *host, /* {{{ */
        const char *tag;
 
        uint32_t records_count;
-       uint32_t i;
 
        records_count = na_child_get_uint32 (data, "records", UINT32_MAX);
        if (records_count == UINT32_MAX)
@@ -2029,7 +2004,7 @@ static int cna_handle_snapvault_iter (host_config_t *host, /* {{{ */
 
        DEBUG ("netapp plugin: Iterating %u SV records (tag = %s)", records_count, tag);
 
-       for (i = 0; i < records_count; ++i) {
+       for (uint32_t i = 0; i < records_count; ++i) {
                na_elem_t *elem;
 
                elem = na_server_invoke (host->srv,
@@ -2118,7 +2093,6 @@ static int cna_handle_system_data (const char *hostname, /* {{{ */
                cfg_system_t *cfg_system, na_elem_t *data, int interval)
 {
        na_elem_t *instances;
-       na_elem_t *counter;
        na_elem_iter_t counter_iter;
 
        derive_t disk_read = 0, disk_written = 0;
@@ -2150,7 +2124,7 @@ static int cna_handle_system_data (const char *hostname, /* {{{ */
        }
 
        counter_iter = na_child_iterator (na_elem_child (instances, "counters"));
-       for (counter = na_iterator_next (&counter_iter);
+       for (na_elem_t *counter = na_iterator_next (&counter_iter);
                        counter != NULL;
                        counter = na_iterator_next (&counter_iter))
        {
@@ -2395,7 +2369,6 @@ static int cna_config_volume_performance (host_config_t *host, /* {{{ */
                const oconfig_item_t *ci)
 {
        cfg_volume_perf_t *cfg_volume_perf;
-       int i;
 
        if ((host == NULL) || (ci == NULL))
                return (EINVAL);
@@ -2438,7 +2411,7 @@ static int cna_config_volume_performance (host_config_t *host, /* {{{ */
        }
        cfg_volume_perf = host->cfg_volume_perf;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
 
                /* if (!item || !item->key || !*item->key) continue; */
@@ -2522,7 +2495,6 @@ static void cna_config_volume_usage_default (cfg_volume_usage_t *cvu, /* {{{ */
 static int cna_config_quota (host_config_t *host, oconfig_item_t *ci) /* {{{ */
 {
        cfg_quota_t *cfg_quota;
-       int i;
 
        if ((host == NULL) || (ci == NULL))
                return (EINVAL);
@@ -2538,7 +2510,7 @@ static int cna_config_quota (host_config_t *host, oconfig_item_t *ci) /* {{{ */
        }
        cfg_quota = host->cfg_quota;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
 
                if (strcasecmp (item->key, "Interval") == 0)
@@ -2554,7 +2526,6 @@ static int cna_config_quota (host_config_t *host, oconfig_item_t *ci) /* {{{ */
 /* Corresponds to a <Disks /> block */
 static int cna_config_disk(host_config_t *host, oconfig_item_t *ci) { /* {{{ */
        cfg_disk_t *cfg_disk;
-       int i;
 
        if ((host == NULL) || (ci == NULL))
                return (EINVAL);
@@ -2574,7 +2545,7 @@ static int cna_config_disk(host_config_t *host, oconfig_item_t *ci) { /* {{{ */
        }
        cfg_disk = host->cfg_disk;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
 
                /* if (!item || !item->key || !*item->key) continue; */
@@ -2599,7 +2570,6 @@ static int cna_config_disk(host_config_t *host, oconfig_item_t *ci) { /* {{{ */
 static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */
 {
        cfg_wafl_t *cfg_wafl;
-       int i;
 
        if ((host == NULL) || (ci == NULL))
                return (EINVAL);
@@ -2617,7 +2587,7 @@ static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */
        }
        cfg_wafl = host->cfg_wafl;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
 
                if (strcasecmp(item->key, "Interval") == 0)
@@ -2667,7 +2637,6 @@ static int cna_config_volume_usage(host_config_t *host, /* {{{ */
                const oconfig_item_t *ci)
 {
        cfg_volume_usage_t *cfg_volume_usage;
-       int i;
 
        if ((host == NULL) || (ci == NULL))
                return (EINVAL);
@@ -2701,7 +2670,7 @@ static int cna_config_volume_usage(host_config_t *host, /* {{{ */
        }
        cfg_volume_usage = host->cfg_volume_usage;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
 
                /* if (!item || !item->key || !*item->key) continue; */
@@ -2728,7 +2697,6 @@ static int cna_config_snapvault (host_config_t *host, /* {{{ */
                const oconfig_item_t *ci)
 {
        cfg_snapvault_t *cfg_snapvault;
-       int i;
 
        if ((host == NULL) || (ci == NULL))
                return EINVAL;
@@ -2745,7 +2713,7 @@ static int cna_config_snapvault (host_config_t *host, /* {{{ */
 
        cfg_snapvault = host->cfg_snapvault;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
 
                if (strcasecmp (item->key, "Interval") == 0)
@@ -2763,7 +2731,6 @@ static int cna_config_system (host_config_t *host, /* {{{ */
                oconfig_item_t *ci)
 {
        cfg_system_t *cfg_system;
-       int i;
 
        if ((host == NULL) || (ci == NULL))
                return (EINVAL);
@@ -2782,7 +2749,7 @@ static int cna_config_system (host_config_t *host, /* {{{ */
        }
        cfg_system = host->cfg_system;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *item = ci->children + i;
 
                if (strcasecmp(item->key, "Interval") == 0) {
@@ -2895,7 +2862,6 @@ static int cna_read (user_data_t *ud);
 static int cna_register_host (host_config_t *host) /* {{{ */
 {
        char cb_name[256];
-       user_data_t ud;
 
        if (host->vfiler)
                ssnprintf (cb_name, sizeof (cb_name), "netapp-%s-%s",
@@ -2903,14 +2869,13 @@ static int cna_register_host (host_config_t *host) /* {{{ */
        else
                ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name);
 
-       memset (&ud, 0, sizeof (ud));
-       ud.data = host;
-       ud.free_func = (void (*) (void *)) free_host_config;
-
        plugin_register_complex_read (/* group = */ NULL, cb_name,
                        /* callback  = */ cna_read,
                        /* interval  = */ host->interval,
-                       /* user data = */ &ud);
+                       &(user_data_t) {
+                               .data = host,
+                               .free_func = (void *) free_host_config,
+                       });
 
        return (0);
 } /* }}} int cna_register_host */
@@ -2921,7 +2886,6 @@ static int cna_config_host (host_config_t *host, /* {{{ */
        oconfig_item_t *item;
        _Bool is_vfiler = 0;
        int status;
-       int i;
 
        if (! strcasecmp (ci->key, "VFiler"))
                is_vfiler = 1;
@@ -2935,7 +2899,7 @@ static int cna_config_host (host_config_t *host, /* {{{ */
        if (status != 0)
                return (1);
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                item = ci->children + i;
 
                status = 0;
@@ -3074,9 +3038,8 @@ static int cna_init_host (host_config_t *host) /* {{{ */
 
 static int cna_init (void) /* {{{ */
 {
-       char err[256];
+       char err[256] = { 0 };
 
-       memset (err, 0, sizeof (err));
        if (!na_startup(err, sizeof(err))) {
                err[sizeof (err) - 1] = 0;
                ERROR("netapp plugin: Error initializing netapp API: %s", err);
@@ -3145,10 +3108,9 @@ static int cna_read (user_data_t *ud) { /* {{{ */
 } /* }}} int cna_read */
 
 static int cna_config (oconfig_item_t *ci) { /* {{{ */
-       int i;
        oconfig_item_t *item;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                item = ci->children + i;
 
                if (strcasecmp(item->key, "Host") == 0)
index 5c3a9f0..786056d 100644 (file)
@@ -26,6 +26,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 
@@ -156,14 +157,12 @@ static int add_ignorelist (const char *dev, const char *type,
 static int check_ignorelist (const char *dev,
     const char *type, const char *type_instance)
 {
-  ir_ignorelist_t *i;
-
   assert ((dev != NULL) && (type != NULL));
 
   if (ir_ignorelist_head == NULL)
     return (ir_ignorelist_invert ? 0 : 1);
 
-  for (i = ir_ignorelist_head; i != NULL; i = i->next)
+  for (ir_ignorelist_t *i = ir_ignorelist_head; i != NULL; i = i->next)
   {
     /* i->device == NULL  =>  match all devices */
     if ((i->device != NULL)
@@ -195,12 +194,9 @@ static int check_ignorelist (const char *dev,
 static void submit_one (const char *dev, const char *type,
     const char *type_instance, derive_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].derive = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .derive = value };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin));
@@ -217,14 +213,14 @@ static void submit_two (const char *dev, const char *type,
     const char *type_instance,
     derive_t rx, derive_t tx)
 {
-  value_t values[2];
   value_list_t vl = VALUE_LIST_INIT;
-
-  values[0].derive = rx;
-  values[1].derive = tx;
+  value_t values[] = {
+    { .derive = rx },
+    { .derive = tx },
+  };
 
   vl.values = values;
-  vl.values_len = 2;
+  vl.values_len = STATIC_ARRAY_SIZE (values);
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin));
   sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
@@ -724,8 +720,6 @@ static int ir_read (void)
   int ret;
   unsigned int seq, portid;
 
-  size_t ifindex;
-
   static const int type_id[] = { RTM_GETQDISC, RTM_GETTCLASS, RTM_GETTFILTER };
   static const char *type_name[] = { "qdisc", "class", "filter" };
 
@@ -760,15 +754,14 @@ static int ir_read (void)
 
   /* `link_filter_cb' will update `iflist' which is used here to iterate
    * over all interfaces. */
-  for (ifindex = 1; ifindex < iflist_len; ifindex++)
+  for (size_t ifindex = 1; ifindex < iflist_len; ifindex++)
   {
     struct tcmsg *tm;
-    size_t type_index;
 
     if (iflist[ifindex] == NULL)
       continue;
 
-    for (type_index = 0; type_index < STATIC_ARRAY_SIZE (type_id); type_index++)
+    for (size_t type_index = 0; type_index < STATIC_ARRAY_SIZE (type_id); type_index++)
     {
       if (check_ignorelist (iflist[ifindex], type_name[type_index], NULL))
       {
index 4393d08..9a0f429 100644 (file)
@@ -26,9 +26,9 @@
 #define _BSD_SOURCE /* For struct ip_mreq */
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 #include "utils_fbhash.h"
 #include "utils_cache.h"
 #include "utils_complain.h"
@@ -369,9 +369,7 @@ static _Bool check_send_okay (const value_list_t *vl) /* {{{ */
 
 static _Bool check_notify_received (const notification_t *n) /* {{{ */
 {
-  notification_meta_t *ptr;
-
-  for (ptr = n->meta; ptr != NULL; ptr = ptr->next)
+  for (notification_meta_t *ptr = n->meta; ptr != NULL; ptr = ptr->next)
     if ((strcmp ("network:received", ptr->name) == 0)
         && (ptr->type == NM_TYPE_BOOLEAN))
       return ((_Bool) ptr->nm_value.nm_boolean);
@@ -491,7 +489,7 @@ static int network_dispatch_notification (notification_t *n) /* {{{ */
 } /* }}} int network_dispatch_notification */
 
 #if HAVE_LIBGCRYPT
-static void network_init_gcrypt (void) /* {{{ */
+static int network_init_gcrypt (void) /* {{{ */
 {
   gcry_error_t err;
 
@@ -499,7 +497,7 @@ static void network_init_gcrypt (void) /* {{{ */
    * Because you can't know in a library whether another library has
    * already initialized the library */
   if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
-    return;
+    return (0);
 
  /* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
   * To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS
@@ -513,7 +511,7 @@ static void network_init_gcrypt (void) /* {{{ */
   if (err)
   {
     ERROR ("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s", gcry_strerror (err));
-    abort ();
+    return (-1);
   }
 # endif
 
@@ -523,11 +521,12 @@ static void network_init_gcrypt (void) /* {{{ */
   if (err)
   {
     ERROR ("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s", gcry_strerror (err));
-    abort ();
+    return (-1);
   }
 
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
-} /* }}} void network_init_gcrypt */
+  return (0);
+} /* }}} int network_init_gcrypt */
 
 static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
     const void *iv, size_t iv_size, const char *username)
@@ -618,7 +617,6 @@ static int write_part_values (char **ret_buffer, size_t *ret_buffer_len,
        value_t      *pkg_values;
 
        size_t offset;
-       int i;
 
        num_values = vl->values_len;
        packet_len = sizeof (part_header_t) + sizeof (uint16_t)
@@ -648,7 +646,7 @@ static int write_part_values (char **ret_buffer, size_t *ret_buffer_len,
 
        pkg_num_values = htons ((uint16_t) vl->values_len);
 
-       for (i = 0; i < num_values; i++)
+       for (int i = 0; i < num_values; i++)
        {
                pkg_values_types[i] = (uint8_t) ds->ds[i].type;
                switch (ds->ds[i].type)
@@ -786,7 +784,6 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
 
        uint16_t tmp16;
        size_t exp_size;
-       size_t i;
 
        uint16_t pkg_length;
        uint16_t pkg_type;
@@ -852,7 +849,7 @@ static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
        memcpy (pkg_values, buffer, pkg_numval * sizeof (*pkg_values));
        buffer += pkg_numval * sizeof (*pkg_values);
 
-       for (i = 0; i < pkg_numval; i++)
+       for (size_t i = 0; i < pkg_numval; i++)
        {
                switch (pkg_types[i])
                {
@@ -1151,7 +1148,7 @@ static int parse_part_sign_sha256 (sockent_t *se, /* {{{ */
   if (memcmp (pss.hash, hash, sizeof (pss.hash)) != 0)
   {
     WARNING ("network plugin: Verifying HMAC-SHA-256 signature failed: "
-        "Hash mismatch.");
+        "Hash mismatch. Username: %s", pss.username);
   }
   else
   {
@@ -1227,7 +1224,7 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
   size_t buffer_offset;
   uint16_t username_len;
   part_encryption_aes256_t pea;
-  unsigned char hash[sizeof (pea.hash)];
+  unsigned char hash[sizeof (pea.hash)] = { 0 };
 
   gcry_cipher_hd_t cypher;
   gcry_error_t err;
@@ -1286,6 +1283,7 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
       pea.username);
   if (cypher == NULL)
   {
+    ERROR ("network plugin: Failed to get cypher. Username: %s", pea.username);
     sfree (pea.username);
     return (-1);
   }
@@ -1301,8 +1299,8 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
   if (err != 0)
   {
     sfree (pea.username);
-    ERROR ("network plugin: gcry_cipher_decrypt returned: %s",
-        gcry_strerror (err));
+    ERROR ("network plugin: gcry_cipher_decrypt returned: %s. Username: %s",
+        gcry_strerror (err), pea.username);
     return (-1);
   }
 
@@ -1314,13 +1312,12 @@ static int parse_part_encr_aes256 (sockent_t *se, /* {{{ */
   assert (buffer_offset == (part_size - payload_len));
 
   /* Check hash sum */
-  memset (hash, 0, sizeof (hash));
   gcry_md_hash_buffer (GCRY_MD_SHA1, hash,
       buffer + buffer_offset, payload_len);
   if (memcmp (hash, pea.hash, sizeof (hash)) != 0)
   {
+    ERROR ("network plugin: Checksum mismatch. Username: %s", pea.username);
     sfree (pea.username);
-    ERROR ("network plugin: Decryption failed: Checksum mismatch.");
     return (-1);
   }
 
@@ -1395,17 +1392,16 @@ static int parse_packet (sockent_t *se, /* {{{ */
        int status;
 
        value_list_t vl = VALUE_LIST_INIT;
-       notification_t n;
+       notification_t n = { 0 };
 
 #if HAVE_LIBGCRYPT
        int packet_was_signed = (flags & PP_SIGNED);
-        int packet_was_encrypted = (flags & PP_ENCRYPTED);
+       int packet_was_encrypted = (flags & PP_ENCRYPTED);
        int printed_ignore_warning = 0;
 #endif /* HAVE_LIBGCRYPT */
 
 
        memset (&vl, '\0', sizeof (vl));
-       memset (&n, '\0', sizeof (n));
        status = 0;
 
        while ((status == 0) && (0 < buffer_size)
@@ -1652,9 +1648,7 @@ static void free_sockent_client (struct sockent_client *sec) /* {{{ */
 
 static void free_sockent_server (struct sockent_server *ses) /* {{{ */
 {
-  size_t i;
-
-  for (i = 0; i < ses->fd_num; i++)
+  for (size_t i = 0; i < ses->fd_num; i++)
   {
     if (ses->fd[i] >= 0)
     {
@@ -1779,18 +1773,16 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai
                         * index is preferred here, because of its similarity
                         * to the way IPv6 handles this. Unfortunately, it
                         * appears not to be portable. */
-                       struct ip_mreqn mreq;
-
-                       memset (&mreq, 0, sizeof (mreq));
-                       mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
-                       mreq.imr_address.s_addr = ntohl (INADDR_ANY);
-                       mreq.imr_ifindex = se->interface;
+                       struct ip_mreqn mreq = {
+                               .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+                               .imr_address.s_addr = ntohl (INADDR_ANY),
+                               .imr_ifindex = se->interface
+                       };
 #else
-                       struct ip_mreq mreq;
-
-                       memset (&mreq, 0, sizeof (mreq));
-                       mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
-                       mreq.imr_interface.s_addr = ntohl (INADDR_ANY);
+                       struct ip_mreq mreq = {
+                               .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+                               .imr_interface.s_addr = ntohl (INADDR_ANY)
+                       };
 #endif
 
                        if (setsockopt (se->data.client.fd, IPPROTO_IP, IP_MULTICAST_IF,
@@ -2070,7 +2062,12 @@ static int sockent_init_crypto (sockent_t *se) /* {{{ */
        {
                if (se->data.client.security_level > SECURITY_LEVEL_NONE)
                {
-                       network_init_gcrypt ();
+                       if (network_init_gcrypt () < 0)
+                       {
+                               ERROR ("network plugin: Cannot configure client socket with "
+                                               "security: Failed to initialize crypto library.");
+                               return (-1);
+                       }
 
                        if ((se->data.client.username == NULL)
                                        || (se->data.client.password == NULL))
@@ -2088,28 +2085,28 @@ static int sockent_init_crypto (sockent_t *se) /* {{{ */
        }
        else /* (se->type == SOCKENT_TYPE_SERVER) */
        {
-               if (se->data.server.security_level > SECURITY_LEVEL_NONE)
+               if ((se->data.server.security_level > SECURITY_LEVEL_NONE)
+                               && (se->data.server.auth_file == NULL))
                {
-                       network_init_gcrypt ();
-
-                       if (se->data.server.auth_file == NULL)
-                       {
-                               ERROR ("network plugin: Server socket with "
-                                               "security requested, but no "
-                                               "password file is configured.");
-                               return (-1);
-                       }
+                       ERROR ("network plugin: Server socket with security requested, "
+                                       "but no \"AuthFile\" is configured.");
+                       return (-1);
                }
                if (se->data.server.auth_file != NULL)
                {
+                       if (network_init_gcrypt () < 0)
+                       {
+                               ERROR ("network plugin: Cannot configure server socket with security: "
+                                               "Failed to initialize crypto library.");
+                               return (-1);
+                       }
+
                        se->data.server.userdb = fbh_create (se->data.server.auth_file);
                        if (se->data.server.userdb == NULL)
                        {
-                               ERROR ("network plugin: Reading password file "
-                                               "`%s' failed.",
+                               ERROR ("network plugin: Reading password file \"%s\" failed.",
                                                se->data.server.auth_file);
-                               if (se->data.server.security_level > SECURITY_LEVEL_NONE)
-                                       return (-1);
+                               return (-1);
                        }
                }
        }
@@ -2143,8 +2140,7 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */
        static c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
 
        struct sockent_client *client;
-       struct addrinfo  ai_hints;
-       struct addrinfo *ai_list = NULL, *ai_ptr;
+       struct addrinfo *ai_list;
        int status;
        _Bool reconnect = 0;
        cdtime_t now;
@@ -2164,13 +2160,12 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */
        if (client->fd >= 0 && !reconnect) /* already connected and not stale*/
                return (0);
 
-       memset (&ai_hints, 0, sizeof (ai_hints));
-#ifdef AI_ADDRCONFIG
-       ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-       ai_hints.ai_family   = AF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_DGRAM;
-       ai_hints.ai_protocol = IPPROTO_UDP;
+       struct addrinfo ai_hints = {
+               .ai_family   = AF_UNSPEC,
+               .ai_flags    = AI_ADDRCONFIG,
+               .ai_protocol = IPPROTO_UDP,
+               .ai_socktype = SOCK_DGRAM
+       };
 
        status = getaddrinfo (se->node,
                        (se->service != NULL) ? se->service : NET_DEFAULT_PORT,
@@ -2191,7 +2186,7 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */
                                se->node);
        }
 
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                if (client->fd >= 0) /* when we reconnect */
                        sockent_client_disconnect(se);
@@ -2241,8 +2236,7 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */
 /* Open the file descriptors for a initialized sockent structure. */
 static int sockent_server_listen (sockent_t *se) /* {{{ */
 {
-       struct addrinfo  ai_hints;
-       struct addrinfo *ai_list, *ai_ptr;
+       struct addrinfo *ai_list;
        int              status;
 
         const char *node;
@@ -2263,17 +2257,12 @@ static int sockent_server_listen (sockent_t *se) /* {{{ */
         DEBUG ("network plugin: sockent_server_listen: node = %s; service = %s;",
             node, service);
 
-       memset (&ai_hints, 0, sizeof (ai_hints));
-       ai_hints.ai_flags  = 0;
-#ifdef AI_PASSIVE
-       ai_hints.ai_flags |= AI_PASSIVE;
-#endif
-#ifdef AI_ADDRCONFIG
-       ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-       ai_hints.ai_family   = AF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_DGRAM;
-       ai_hints.ai_protocol = IPPROTO_UDP;
+       struct addrinfo ai_hints = {
+               .ai_family   = AF_UNSPEC,
+               .ai_flags    = AI_ADDRCONFIG | AI_PASSIVE,
+               .ai_protocol = IPPROTO_UDP,
+               .ai_socktype = SOCK_DGRAM
+       };
 
        status = getaddrinfo (node, service, &ai_hints, &ai_list);
        if (status != 0)
@@ -2285,7 +2274,7 @@ static int sockent_server_listen (sockent_t *se) /* {{{ */
                return (-1);
        }
 
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                int *tmp;
 
@@ -2340,7 +2329,6 @@ static int sockent_add (sockent_t *se) /* {{{ */
        if (se->type == SOCKENT_TYPE_SERVER)
        {
                struct pollfd *tmp;
-               size_t i;
 
                tmp = realloc (listen_sockets_pollfd,
                                sizeof (*tmp) * (listen_sockets_num
@@ -2353,7 +2341,7 @@ static int sockent_add (sockent_t *se) /* {{{ */
                listen_sockets_pollfd = tmp;
                tmp = listen_sockets_pollfd + listen_sockets_num;
 
-               for (i = 0; i < se->data.server.fd_num; i++)
+               for (size_t i = 0; i < se->data.server.fd_num; i++)
                {
                        memset (tmp + i, 0, sizeof (*tmp));
                        tmp[i].fd = se->data.server.fd[i];
@@ -2452,7 +2440,6 @@ static int network_receive (void) /* {{{ */
        char buffer[network_config_packet_size];
        int  buffer_len;
 
-       size_t i;
        int status = 0;
 
        receive_list_entry_t *private_list_head;
@@ -2478,7 +2465,7 @@ static int network_receive (void) /* {{{ */
                        break;
                }
 
-               for (i = 0; (i < listen_sockets_num) && (status > 0); i++)
+               for (size_t i = 0; (i < listen_sockets_num) && (status > 0); i++)
                {
                        receive_list_entry_t *ent;
 
@@ -2639,7 +2626,6 @@ static void network_send_buffer_plain (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;
   char buffer[BUFF_SIG_SIZE + in_buffer_size];
   size_t buffer_offset;
   size_t username_len;
@@ -2681,9 +2667,10 @@ static void network_send_buffer_signed (sockent_t *se, /* {{{ */
       in_buffer, in_buffer_size);
 
   /* Initialize the `ps' structure. */
-  memset (&ps, 0, sizeof (ps));
-  ps.head.type = htons (TYPE_SIGN_SHA256);
-  ps.head.length = htons (PART_SIGNATURE_SHA256_SIZE + username_len);
+  part_signature_sha256_t ps = {
+    .head.type = htons (TYPE_SIGN_SHA256),
+    .head.length = htons (PART_SIGNATURE_SHA256_SIZE + username_len)
+  };
 
   /* Calculate the hash value. */
   gcry_md_write (hd, buffer + PART_SIGNATURE_SHA256_SIZE,
@@ -2716,7 +2703,6 @@ static void network_send_buffer_signed (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;
   char buffer[BUFF_SIG_SIZE + in_buffer_size];
   size_t buffer_size;
   size_t buffer_offset;
@@ -2726,10 +2712,10 @@ static void network_send_buffer_encrypted (sockent_t *se, /* {{{ */
   gcry_cipher_hd_t cypher;
 
   /* Initialize the header fields */
-  memset (&pea, 0, sizeof (pea));
-  pea.head.type = htons (TYPE_ENCR_AES256);
-
-  pea.username = se->data.client.username;
+  part_encryption_aes256_t pea = {
+    .head.type = htons (TYPE_ENCR_AES256),
+    .username = se->data.client.username
+  };
 
   username_len = strlen (pea.username);
   if ((PART_ENCRYPTION_AES256_SIZE + username_len) > BUFF_SIG_SIZE)
@@ -2797,11 +2783,9 @@ static void network_send_buffer_encrypted (sockent_t *se, /* {{{ */
 
 static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */
 {
-  sockent_t *se;
-
   DEBUG ("network plugin: network_send_buffer: buffer_len = %zu", buffer_len);
 
-  for (se = sending_sockets; se != NULL; se = se->next)
+  for (sockent_t *se = sending_sockets; se != NULL; se = se->next)
   {
 #if HAVE_LIBGCRYPT
     if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
@@ -2902,6 +2886,11 @@ static int network_write (const data_set_t *ds, const value_list_t *vl,
 {
        int status;
 
+       /* listen_loop is set to non-zero in the shutdown callback, which is
+        * guaranteed to be called *after* all the write threads have been shut
+        * down. */
+       assert (listen_loop == 0);
+
        if (!check_send_okay (vl))
        {
 #if COLLECT_DEBUG
@@ -3048,7 +3037,6 @@ static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
 {
   sockent_t *se;
   int status;
-  int i;
 
   if ((ci->values_num < 1) || (ci->values_num > 2)
       || (ci->values[0].type != OCONFIG_TYPE_STRING)
@@ -3070,7 +3058,7 @@ static int network_config_add_listen (const oconfig_item_t *ci) /* {{{ */
   if (ci->values_num >= 2)
     se->service = strdup (ci->values[1].value.string);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -3134,7 +3122,6 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
 {
   sockent_t *se;
   int status;
-  int i;
 
   if ((ci->values_num < 1) || (ci->values_num > 2)
       || (ci->values[0].type != OCONFIG_TYPE_STRING)
@@ -3156,7 +3143,7 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
   if (ci->values_num >= 2)
     se->service = strdup (ci->values[1].value.string);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -3218,17 +3205,15 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */
 
 static int network_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
   /* The options need to be applied first */
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if (strcasecmp ("TimeToLive", child->key) == 0)
       network_config_set_ttl (child);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -3331,8 +3316,6 @@ static int network_notification (const notification_t *n,
 
 static int network_shutdown (void)
 {
-       sockent_t *se;
-
        listen_loop++;
 
        /* Kill the listening thread */
@@ -3363,7 +3346,7 @@ static int network_shutdown (void)
 
        sfree (send_buffer);
 
-       for (se = sending_sockets; se != NULL; se = se->next)
+       for (sockent_t *se = sending_sockets; se != NULL; se = se->next)
                sockent_client_disconnect (se);
        sockent_destroy (sending_sockets);
 
@@ -3461,10 +3444,6 @@ static int network_init (void)
                return (0);
        have_init = 1;
 
-#if HAVE_LIBGCRYPT
-       network_init_gcrypt ();
-#endif
-
        if (network_config_stats)
                plugin_register_read ("network", network_stats_read);
 
index 0948bc7..c128c81 100644 (file)
--- a/src/nfs.c
+++ b/src/nfs.c
@@ -23,6 +23,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -345,8 +346,6 @@ static int nfs_init (void)
 #elif HAVE_LIBKSTAT
 static int nfs_init (void)
 {
-       kstat_t *ksp_chain = NULL;
-
        nfs2_ksp_client = NULL;
        nfs2_ksp_server = NULL;
        nfs3_ksp_client = NULL;
@@ -357,7 +356,7 @@ static int nfs_init (void)
        if (kc == NULL)
                return (-1);
 
-       for (ksp_chain = kc->kc_chain; ksp_chain != NULL;
+       for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL;
                        ksp_chain = ksp_chain->ks_next)
        {
                if (strncmp (ksp_chain->ks_module, "nfs", 3) != 0)
@@ -385,7 +384,6 @@ static void nfs_procedures_submit (const char *plugin_instance,
                value_t *values, size_t values_num)
 {
        value_list_t vl = VALUE_LIST_INIT;
-       size_t i;
 
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -394,7 +392,7 @@ static void nfs_procedures_submit (const char *plugin_instance,
                        sizeof (vl.plugin_instance));
        sstrncpy (vl.type, "nfs_procedure", sizeof (vl.type));
 
-       for (i = 0; i < values_num; i++)
+       for (size_t i = 0; i < values_num; i++)
        {
                vl.values = values + i;
                sstrncpy (vl.type_instance, type_instances[i],
@@ -409,12 +407,11 @@ static void nfs_submit_fields (int nfs_version, const char *instance,
 {
        char plugin_instance[DATA_MAX_NAME_LEN];
        value_t values[fields_num];
-       size_t i;
 
        ssnprintf (plugin_instance, sizeof (plugin_instance), "v%i%s",
                        nfs_version, instance);
 
-       for (i = 0; i < fields_num; i++)
+       for (size_t i = 0; i < fields_num; i++)
                (void) parse_value (fields[i], &values[i], DS_TYPE_DERIVE);
 
        nfs_procedures_submit (plugin_instance, proc_names, values,
@@ -608,7 +605,6 @@ static int nfs_read_kstat (kstat_t *ksp, int nfs_version, const char *inst,
 {
        char plugin_instance[DATA_MAX_NAME_LEN];
        value_t values[proc_names_num];
-       size_t i;
 
        if (ksp == NULL)
                return (EINVAL);
@@ -617,7 +613,7 @@ static int nfs_read_kstat (kstat_t *ksp, int nfs_version, const char *inst,
                        nfs_version, inst);
 
        kstat_read(kc, ksp, NULL);
-       for (i = 0; i < proc_names_num; i++)
+       for (size_t i = 0; i < proc_names_num; i++)
        {
                /* The name passed to kstat_data_lookup() doesn't have the
                 * "const" modifier, so we need to copy the name here. */
index 7587c1f..3850acc 100644 (file)
@@ -27,9 +27,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <curl/curl.h>
 
@@ -210,7 +210,7 @@ static void submit (const char *type, const char *inst, long long value)
     return;
 
   vl.values = values;
-  vl.values_len = 1;
+  vl.values_len = STATIC_ARRAY_SIZE (values);
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "nginx", sizeof (vl.plugin));
   sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
@@ -224,8 +224,6 @@ static void submit (const char *type, const char *inst, long long value)
 
 static int nginx_read (void)
 {
-  int i;
-
   char *ptr;
   char *lines[16];
   int   lines_num = 0;
@@ -263,7 +261,7 @@ static int nginx_read (void)
    *  16630948 16630948 31070465
    * Reading: 6 Writing: 179 Waiting: 106
    */
-  for (i = 0; i < lines_num; i++)
+  for (int i = 0; i < lines_num; i++)
   {
     fields_num = strsplit (lines[i], fields,
        (sizeof (fields) / sizeof (fields[0])));
index c2d9752..5cab119 100644 (file)
@@ -29,9 +29,9 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <glib.h>
 #include <libnotify/notify.h>
@@ -66,9 +66,7 @@ static int set_timeout (oconfig_item_t *ci, int *timeout)
 
 static int c_notify_config (oconfig_item_t *ci)
 {
-       int i = 0;
-
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (0 == strcasecmp (c->key, "OkayTimeout"))
index 0120a40..cefeb22 100644 (file)
@@ -23,6 +23,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -66,8 +67,7 @@ static char *email_subject = NULL;
 static int authinteract (auth_client_request_t request, char **result,
     int fields, void __attribute__((unused)) *arg)
 {
-  int i;
-  for (i = 0; i < fields; i++)
+  for (int i = 0; i < fields; i++)
   {
     if (request[i].flags & AUTH_USER)
       result[i] = smtp_user;
index 1f4182b..b08c411 100644 (file)
@@ -25,9 +25,9 @@
  */
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 
 #define NAGIOS_OK       0
 #define NAGIOS_WARNING  1
@@ -42,9 +42,7 @@ static char *nagios_command_file;
 
 static int nagios_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -63,7 +61,7 @@ static int nagios_print (char const *buffer) /* {{{ */
   char const *file = NAGIOS_COMMAND_FILE;
   int fd;
   int status;
-  struct flock lock;
+  struct flock lock = { 0 };
 
   if (nagios_command_file != NULL)
     file = nagios_command_file;
@@ -78,11 +76,8 @@ static int nagios_print (char const *buffer) /* {{{ */
     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)
index f8f4f04..ccdecd9 100644 (file)
@@ -28,9 +28,9 @@
 #define _BSD_SOURCE /* For NI_MAXHOST */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #if HAVE_STDINT_H
 # include <stdint.h>
@@ -313,12 +313,9 @@ static int ntpd_config (const char *key, const char *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;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "ntpd", sizeof (vl.plugin));
@@ -346,9 +343,7 @@ static int ntpd_connect (void)
        const char *host;
        const char *port;
 
-       struct addrinfo  ai_hints;
        struct addrinfo *ai_list;
-       struct addrinfo *ai_ptr;
        int              status;
 
        if (sock_descr >= 0)
@@ -364,14 +359,12 @@ static int ntpd_connect (void)
        if (strlen (port) == 0)
                port = NTPD_DEFAULT_PORT;
 
-       memset (&ai_hints, '\0', sizeof (ai_hints));
-       ai_hints.ai_flags    = 0;
-#ifdef AI_ADDRCONFIG
-       ai_hints.ai_flags   |= AI_ADDRCONFIG;
-#endif
-       ai_hints.ai_family   = PF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_DGRAM;
-       ai_hints.ai_protocol = IPPROTO_UDP;
+       struct addrinfo ai_hints = {
+               .ai_family   = AF_UNSPEC,
+               .ai_flags    = AI_ADDRCONFIG,
+               .ai_protocol = IPPROTO_UDP,
+               .ai_socktype = SOCK_DGRAM
+       };
 
        if ((status = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0)
        {
@@ -384,7 +377,7 @@ static int ntpd_connect (void)
                return (-1);
        }
 
-       for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                /* create our socket descriptor */
                if ((sock_descr = socket (ai_ptr->ai_family,
@@ -422,7 +415,6 @@ static int ntpd_receive_response (int *res_items, int *res_size,
        struct resp_pkt  res;
        int              status;
        int              done;
-       int              i;
 
        char            *items;
        size_t           items_num;
@@ -431,13 +423,13 @@ static int ntpd_receive_response (int *res_items, int *res_size,
        struct timeval   time_now;
        int              timeout;
 
-       int              pkt_item_num;        /* items in this packet */
-       int              pkt_item_len;        /* size of the items in this packet */
+       int              pkt_item_num;                /* items in this packet */
+       int              pkt_item_len;                /* size of the items in this packet */
        int              pkt_sequence;
-       char             pkt_recvd[MAXSEQ+1]; /* sequence numbers that have been received */
-       int              pkt_recvd_num;       /* number of packets that have been received */
-       int              pkt_lastseq;         /* the last sequence number */
-       ssize_t          pkt_padding;         /* Padding in this packet */
+       char             pkt_recvd[MAXSEQ+1] = { 0 }; /* sequence numbers that have been received */
+       int              pkt_recvd_num;               /* number of packets that have been received */
+       int              pkt_lastseq;                 /* the last sequence number */
+       ssize_t          pkt_padding;                 /* Padding in this packet */
 
        if ((sd = ntpd_connect ()) < 0)
                return (-1);
@@ -445,7 +437,6 @@ static int ntpd_receive_response (int *res_items, int *res_size,
        items = NULL;
        items_num = 0;
 
-       memset (pkt_recvd, '\0', sizeof (pkt_recvd));
        pkt_recvd_num = 0;
        pkt_lastseq   = -1;
 
@@ -677,7 +668,7 @@ static int ntpd_receive_response (int *res_items, int *res_size,
                items_num += pkt_item_num;
                *res_data = items;
 
-               for (i = 0; i < pkt_item_num; i++)
+               for (int i = 0; i < pkt_item_num; i++)
                {
                        /* dst: There are already `*res_items' items with
                         *      res_item_size bytes each in in `*res_data'. Set
@@ -714,7 +705,7 @@ static int ntpd_receive_response (int *res_items, int *res_size,
 static int ntpd_send_request (int req_code, int req_items, int req_size, char *req_data)
 {
        int             sd;
-       struct req_pkt  req;
+       struct req_pkt  req = { 0 };
        size_t          req_data_len;
        int             status;
 
@@ -724,7 +715,6 @@ static int ntpd_send_request (int req_code, int req_items, int req_size, char *r
        if ((sd = ntpd_connect ()) < 0)
                return (-1);
 
-       memset (&req, '\0', sizeof (req));
        req.rm_vn_mode = RM_VN_MODE(0, 0, 0);
        req.auth_seq   = AUTH_SEQ (0, 0);
        req.implementation = IMPL_XNTPD;
@@ -805,20 +795,17 @@ static uint32_t ntpd_get_refclock_id (struct info_peer_summary const *peer_info)
 static int ntpd_get_name_from_address (char *buffer, size_t buffer_size,
                struct info_peer_summary const *peer_info, _Bool do_reverse_lookup)
 {
-       struct sockaddr_storage sa;
+       struct sockaddr_storage sa = { 0 };
        socklen_t sa_len;
        int flags = 0;
        int status;
 
-       memset (&sa, 0, sizeof (sa));
-
        if (peer_info->v6_flag)
        {
-               struct sockaddr_in6 sa6;
+               struct sockaddr_in6 sa6 = { 0 };
 
                assert (sizeof (sa) >= sizeof (sa6));
 
-               memset (&sa6, 0, sizeof (sa6));
                sa6.sin6_family = AF_INET6;
                sa6.sin6_port = htons (123);
                memcpy (&sa6.sin6_addr, &peer_info->srcadr6,
@@ -829,11 +816,10 @@ static int ntpd_get_name_from_address (char *buffer, size_t buffer_size,
        }
        else
        {
-               struct sockaddr_in sa4;
+               struct sockaddr_in sa4 = { 0 };
 
                assert (sizeof (sa) >= sizeof (sa4));
 
-               memset (&sa4, 0, sizeof (sa4));
                sa4.sin_family = AF_INET;
                sa4.sin_port = htons (123);
                memcpy (&sa4.sin_addr, &peer_info->srcadr,
@@ -911,7 +897,6 @@ static int ntpd_read (void)
        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. */
@@ -979,7 +964,7 @@ static int ntpd_read (void)
                return (-1);
        }
 
-       for (i = 0; i < ps_num; i++)
+       for (int i = 0; i < ps_num; i++)
        {
                struct info_peer_summary *ptr;
                double offset;
index a87a17e..8f5bf48 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -130,11 +131,10 @@ static int numa_init (void) /* {{{ */
   while (42)
   {
     char path[PATH_MAX];
-    struct stat statbuf;
+    struct stat statbuf = { 0 };
     int status;
 
     ssnprintf (path, sizeof (path), NUMA_ROOT_DIR "/node%i", max_node + 1);
-    memset (&statbuf, 0, sizeof (statbuf));
 
     status = stat (path, &statbuf);
     if (status == 0)
index a033e2f..29074c4 100644 (file)
--- a/src/nut.c
+++ b/src/nut.c
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -119,13 +120,10 @@ static int nut_config (const char *key, const char *value)
 static void nut_submit (nut_ups_t *ups, const char *type,
     const char *type_instance, gauge_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
-  vl.values_len = STATIC_ARRAY_SIZE (values);
+  vl.values = &(value_t) { .gauge = value };
+  vl.values_len = 1;
   sstrncpy (vl.host,
       (strcasecmp (ups->hostname, "localhost") == 0)
       ? hostname_g
@@ -247,7 +245,6 @@ static int nut_read_one (nut_ups_t *ups)
 
 static int nut_read (void)
 {
-  nut_ups_t *ups;
   int success = 0;
 
   pthread_mutex_lock (&read_lock);
@@ -258,7 +255,7 @@ static int nut_read (void)
   if (success != 0)
     return (0);
 
-  for (ups = upslist_head; ups != NULL; ups = ups->next)
+  for (nut_ups_t *ups = upslist_head; ups != NULL; ups = ups->next)
     if (nut_read_one (ups) == 0)
       success++;
 
index 6d22d98..3bf7128 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -149,22 +150,18 @@ static size_t strtabsplit (char *string, char **fields, size_t size) /* {{{ */
 
 static FILE *olsrd_connect (void) /* {{{ */
 {
-  struct addrinfo  ai_hints;
-  struct addrinfo *ai_list, *ai_ptr;
+  struct addrinfo *ai_list;
   int              ai_return;
 
   FILE *fh;
 
-  memset (&ai_hints, 0, sizeof (ai_hints));
-  ai_hints.ai_flags    = 0;
-#ifdef AI_ADDRCONFIG
-  ai_hints.ai_flags   |= AI_ADDRCONFIG;
-#endif
-  ai_hints.ai_family   = PF_UNSPEC;
-  ai_hints.ai_socktype = SOCK_STREAM;
-  ai_hints.ai_protocol = IPPROTO_TCP;
+  struct addrinfo ai_hints = {
+    .ai_family   = AF_UNSPEC,
+    .ai_flags    = AI_ADDRCONFIG,
+    .ai_protocol = IPPROTO_TCP,
+    .ai_socktype = SOCK_STREAM
+  };
 
-  ai_list = NULL;
   ai_return = getaddrinfo (olsrd_get_node (), olsrd_get_service (),
       &ai_hints, &ai_list);
   if (ai_return != 0)
@@ -176,7 +173,7 @@ static FILE *olsrd_connect (void) /* {{{ */
   }
 
   fh = NULL;
-  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
     int fd;
     int status;
@@ -219,12 +216,9 @@ __attribute__ ((nonnull(2)))
 static void olsrd_submit (const char *plugin_instance, /* {{{ */
     const char *type, const char *type_instance, gauge_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
 
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -557,9 +551,8 @@ static int olsrd_cb_topology (int lineno, /* {{{ */
 
     if (config_want_topology == OLSRD_WANT_DETAIL)
     {
-      char type_instance[DATA_MAX_NAME_LEN];
+      char type_instance[DATA_MAX_NAME_LEN] = { 0 };
 
-      memset (type_instance, 0, sizeof (type_instance));
       ssnprintf (type_instance, sizeof (type_instance), "%s-%s-lq",
           fields[0], fields[1]);
       DEBUG ("olsrd plugin: type_instance = %s; lq = %g;", type_instance, lq);
@@ -581,9 +574,8 @@ static int olsrd_cb_topology (int lineno, /* {{{ */
     }
     else
     {
-      char type_instance[DATA_MAX_NAME_LEN];
+      char type_instance[DATA_MAX_NAME_LEN] = { 0 };
 
-      memset (type_instance, 0, sizeof (type_instance));
       ssnprintf (type_instance, sizeof (type_instance), "%s-%s-nlq",
           fields[0], fields[1]);
       DEBUG ("olsrd plugin: type_instance = %s; nlq = %g;", type_instance, nlq);
index 42bd1eb..0b4b6f5 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_ignorelist.h"
@@ -335,10 +336,8 @@ static int cow_load_config (const char *key, const char *value)
 static int cow_read_values (const char *path, const char *name,
     const ow_family_features_t *family_info)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
   int success = 0;
-  size_t i;
 
   if (sensor_list != NULL)
   {
@@ -347,18 +346,16 @@ static int cow_read_values (const char *path, const char *name,
       return 0;
   }
 
-  vl.values = values;
-  vl.values_len = 1;
-
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "onewire", sizeof (vl.plugin));
   sstrncpy (vl.plugin_instance, name, sizeof (vl.plugin_instance));
 
-  for (i = 0; i < family_info->features_num; i++)
+  for (size_t i = 0; i < family_info->features_num; i++)
   {
     char *buffer;
     size_t buffer_size;
     int status;
+    char errbuf[1024];
 
     char file[4096];
     char *endptr;
@@ -373,14 +370,14 @@ static int cow_read_values (const char *path, const char *name,
     status = OW_get (file, &buffer, &buffer_size);
     if (status < 0)
     {
-      ERROR ("onewire plugin: OW_get (%s/%s) failed. status = %#x;",
-          path, family_info->features[i].filename, status);
+      ERROR ("onewire plugin: OW_get (%s/%s) failed. error = %s;",
+          path, family_info->features[i].filename, sstrerror(errno, errbuf, sizeof (errbuf)));
       return (-1);
     }
     DEBUG ("Read onewire device %s as %s", file, buffer);
 
     endptr = NULL;
-    values[0].gauge = strtod (buffer, &endptr);
+    gauge_t g = strtod (buffer, &endptr);
     if (endptr == NULL)
     {
       ERROR ("onewire plugin: Buffer is not a number: %s", buffer);
@@ -391,6 +388,9 @@ static int cow_read_values (const char *path, const char *name,
     sstrncpy (vl.type_instance, family_info->features[i].type_instance,
         sizeof (vl.type_instance));
 
+    vl.values = &(value_t) { .gauge = g };
+    vl.values_len = 1;
+
     plugin_dispatch_values (&vl);
     success++;
 
@@ -430,6 +430,7 @@ static int cow_read_bus (const char *path)
   char *buffer;
   size_t buffer_size;
   int status;
+  char errbuf[1024];
 
   char *buffer_ptr;
   char *dummy;
@@ -439,8 +440,8 @@ static int cow_read_bus (const char *path)
   status = OW_get (path, &buffer, &buffer_size);
   if (status < 0)
   {
-    ERROR ("onewire plugin: OW_get (%s) failed. status = %#x;",
-        path, status);
+    ERROR ("onewire plugin: OW_get (%s) failed. error = %s;",
+        path, sstrerror(errno, errbuf, sizeof (errbuf)));
     return (-1);
   }
   DEBUG ("onewire plugin: OW_get (%s) returned: %s",
@@ -493,20 +494,17 @@ static int cow_read_bus (const char *path)
 
 static int cow_simple_read (void)
 {
-  value_t      values[1];
   value_list_t vl = VALUE_LIST_INIT;
   char        *buffer;
   size_t       buffer_size;
   int          status;
+  char         errbuf[1024];
   char        *endptr;
   direct_access_element_t *traverse;
 
   /* traverse list and check entries */
   for (traverse = direct_list; traverse != NULL; traverse = traverse->next)
   {
-      vl.values = values;
-      vl.values_len = 1;
-
       sstrncpy (vl.host, hostname_g, sizeof (vl.host));
       sstrncpy (vl.plugin, "onewire", sizeof (vl.plugin));
       sstrncpy (vl.plugin_instance, traverse->address, sizeof (vl.plugin_instance));
@@ -514,16 +512,15 @@ static int cow_simple_read (void)
       status = OW_get (traverse->path, &buffer, &buffer_size);
       if (status < 0)
       {
-          ERROR ("onewire plugin: OW_get (%s) failed. status = %#x;",
+          ERROR ("onewire plugin: OW_get (%s) failed. status = %s;",
                  traverse->path,
-                 status);
+                 sstrerror(errno, errbuf, sizeof (errbuf)));
           return (-1);
       }
       DEBUG ("onewire plugin: Read onewire device %s as %s", traverse->path, buffer);
 
-
       endptr = NULL;
-      values[0].gauge = strtod (buffer, &endptr);
+      gauge_t g = strtod (buffer, &endptr);
       if (endptr == NULL)
       {
           ERROR ("onewire plugin: Buffer is not a number: %s", buffer);
@@ -533,6 +530,9 @@ static int cow_simple_read (void)
       sstrncpy (vl.type, traverse->file, sizeof (vl.type));
       sstrncpy (vl.type_instance, "",   sizeof (""));
 
+      vl.values = &(value_t) { .gauge = g };
+      vl.values_len = 1;
+
       plugin_dispatch_values (&vl);
       free (buffer);
   } /* for (traverse) */
@@ -590,6 +590,7 @@ static int cow_shutdown (void)
 static int cow_init (void)
 {
   int status;
+  char errbuf[1024];
 
   if (device_g == NULL)
   {
@@ -601,7 +602,7 @@ static int cow_init (void)
   status = (int) OW_init (device_g);
   if (status != 0)
   {
-    ERROR ("onewire plugin: OW_init(%s) failed: %i.", device_g, status);
+    ERROR ("onewire plugin: OW_init(%s) failed: %s.", device_g, sstrerror(errno, errbuf, sizeof (errbuf)));
     return (1);
   }
 
index 151d25d..dd3226d 100644 (file)
@@ -27,9 +27,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #if defined(__APPLE__)
 #pragma clang diagnostic push
@@ -192,23 +192,19 @@ static void cldap_submit_value (const char *type, const char *type_instance, /*
 static void cldap_submit_derive (const char *type, const char *type_instance, /* {{{ */
                derive_t d, cldap_t *st)
 {
-       value_t v;
-       v.derive = d;
-       cldap_submit_value (type, type_instance, v, st);
+       cldap_submit_value (type, type_instance, (value_t) { .derive = d }, st);
 } /* }}} void cldap_submit_derive */
 
 static void cldap_submit_gauge (const char *type, const char *type_instance, /* {{{ */
                gauge_t g, cldap_t *st)
 {
-       value_t v;
-       v.gauge = g;
-       cldap_submit_value (type, type_instance, v, st);
+       cldap_submit_value (type, type_instance, (value_t) { .gauge = g }, st);
 } /* }}} void cldap_submit_gauge */
 
 static int cldap_read_host (user_data_t *ud) /* {{{ */
 {
        cldap_t *st;
-       LDAPMessage *e, *result;
+       LDAPMessage *result;
        char *dn;
        int rc;
        int status;
@@ -249,7 +245,7 @@ static int cldap_read_host (user_data_t *ud) /* {{{ */
                return (-1);
        }
 
-       for (e = ldap_first_entry (st->ld, result); e != NULL;
+       for (LDAPMessage *e = ldap_first_entry (st->ld, result); e != NULL;
                e = ldap_next_entry (st->ld, e))
        {
                if ((dn = ldap_get_dn (st->ld, e)) != NULL)
@@ -558,7 +554,6 @@ static int cldap_read_host (user_data_t *ud) /* {{{ */
 static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
 {
        cldap_t *st;
-       int i;
        int status;
 
        st = calloc (1, sizeof (*st));
@@ -580,7 +575,7 @@ static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
        st->verifyhost = 1;
        st->version = LDAP_VERSION3;
 
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -653,27 +648,24 @@ static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
                }
                else
                {
-                       user_data_t ud;
-                       char callback_name[3*DATA_MAX_NAME_LEN];
+                       char callback_name[3*DATA_MAX_NAME_LEN] = { 0 };
 
                        databases = temp;
                        databases[databases_num] = st;
                        databases_num++;
 
-                       memset (&ud, 0, sizeof (ud));
-                       ud.data = st;
-
-                       memset (callback_name, 0, sizeof (callback_name));
                        ssnprintf (callback_name, sizeof (callback_name),
                                        "openldap/%s/%s",
                                        (st->host != NULL) ? st->host : hostname_g,
-                                       (st->name != NULL) ? st->name : "default"),
+                                       (st->name != NULL) ? st->name : "default");
 
                        status = plugin_register_complex_read (/* group = */ NULL,
                                        /* name      = */ callback_name,
                                        /* callback  = */ cldap_read_host,
                                        /* interval  = */ 0,
-                                       /* user_data = */ &ud);
+                                       &(user_data_t) {
+                                               .data = st,
+                                       });
                }
        }
 
@@ -688,10 +680,9 @@ static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
 
 static int cldap_config (oconfig_item_t *ci) /* {{{ */
 {
-       int i;
        int status = 0;
 
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -721,9 +712,7 @@ static int cldap_init (void) /* {{{ */
 
 static int cldap_shutdown (void) /* {{{ */
 {
-       size_t i;
-
-       for (i = 0; i < databases_num; i++)
+       for (size_t i = 0; i < databases_num; i++)
                if (databases[i]->ld != NULL)
                        ldap_unbind_ext_s (databases[i]->ld, NULL, NULL);
        sfree (databases);
index 85760e9..81ffa89 100644 (file)
@@ -26,6 +26,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -98,13 +99,10 @@ static int openvpn_strsplit (char *string, char **fields, size_t size)
 static void numusers_submit (const char *pinst, const char *tinst,
                gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
-       vl.values_len = STATIC_ARRAY_SIZE (values);
+       vl.values = &(value_t) { .gauge = value };
+       vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "openvpn", sizeof (vl.plugin));
        sstrncpy (vl.type, "users", sizeof (vl.type));
@@ -121,11 +119,11 @@ static void numusers_submit (const char *pinst, const char *tinst,
 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;
-
-       values[0].derive = rx;
-       values[1].derive = tx;
+       value_t values[] = {
+    { .derive = rx },
+    { .derive = tx },
+  };
 
        /* NOTE ON THE NEW NAMING SCHEMA:
         *       using plugin_instance to identify each vpn config (and
@@ -151,11 +149,11 @@ static void iostats_submit (const char *pinst, const char *tinst,
 static void compression_submit (const char *pinst, const char *tinst,
                derive_t uncompressed, derive_t compressed)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = uncompressed;
-       values[1].derive = compressed;
+       value_t values[] = {
+    { .derive = uncompressed },
+    { .derive = compressed },
+  };
 
        vl.values = values;
        vl.values_len = STATIC_ARRAY_SIZE (values);
@@ -521,12 +519,12 @@ static int multi4_read (const char *name, FILE *fh)
 static int openvpn_read (void)
 {
        FILE *fh;
-       int  i, read;
+       int  read;
 
        read = 0;
 
        /* call the right read function for every status entry in the list */
-       for (i = 0; i < vpn_num; i++)
+       for (int i = 0; i < vpn_num; i++)
        {
                int vpn_read = 0;
 
@@ -650,7 +648,7 @@ static int openvpn_config (const char *key, const char *value)
        if (strcasecmp ("StatusFile", key) == 0)
        {
                char    *status_file, *status_name, *filename;
-               int     status_version, i;
+               int     status_version;
                vpn_status_t *temp;
 
                /* try to detect the status file format */
@@ -686,7 +684,7 @@ static int openvpn_config (const char *key, const char *value)
                }
 
                /* scan the list looking for a clone */
-               for (i = 0; i < vpn_num; i++)
+               for (int i = 0; i < vpn_num; i++)
                {
                        if (strcasecmp (vpn_list[i]->name, status_name) == 0)
                        {
@@ -777,9 +775,7 @@ static int openvpn_config (const char *key, const char *value)
 /* shutdown callback */
 static int openvpn_shutdown (void)
 {
-       int i;
-
-       for (i = 0; i < vpn_num; i++)
+       for (int i = 0; i < vpn_num; i++)
        {
                sfree (vpn_list[i]->file);
                sfree (vpn_list[i]);
index cb9b3db..c0f2fa4 100644 (file)
@@ -46,9 +46,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_db_query.h"
 
 #include <oci.h>
@@ -93,7 +93,6 @@ static void o_report_error (const char *where, /* {{{ */
   char buffer[2048];
   sb4 error_code;
   int status;
-  unsigned int record_number;
 
   if (db_name == NULL)
     db_name = "(none)";
@@ -102,7 +101,7 @@ static void o_report_error (const char *where, /* {{{ */
 
   /* An operation may cause / return multiple errors. Loop until we have
    * handled all errors available (with a fail-save limit of 16). */
-  for (record_number = 1; record_number <= 16; record_number++)
+  for (unsigned int record_number = 1; record_number <= 16; record_number++)
   {
     memset (buffer, 0, sizeof (buffer));
     error_code = -1;
@@ -144,8 +143,6 @@ static void o_report_error (const char *where, /* {{{ */
 
 static void o_database_free (o_database_t *db) /* {{{ */
 {
-  size_t i;
-
   if (db == NULL)
     return;
 
@@ -156,7 +153,7 @@ static void o_database_free (o_database_t *db) /* {{{ */
   sfree (db->queries);
 
   if (db->q_prep_areas != NULL)
-    for (i = 0; i < db->queries_num; ++i)
+    for (size_t i = 0; i < db->queries_num; ++i)
       udb_query_delete_preparation_area (db->q_prep_areas[i]);
   free (db->q_prep_areas);
 
@@ -188,7 +185,6 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
 {
   o_database_t *db;
   int status;
-  int i;
 
   if ((ci->values_num != 1)
       || (ci->values[0].type != OCONFIG_TYPE_STRING))
@@ -218,7 +214,7 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
   }
 
   /* Fill the `o_database_t' structure.. */
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -277,7 +273,7 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
       break;
     }
 
-    for (i = 0; i < db->queries_num; ++i)
+    for (int i = 0; i < db->queries_num; ++i)
     {
       db->q_prep_areas[i]
         = udb_query_allocate_preparation_area (db->queries[i]);
@@ -325,9 +321,7 @@ static int o_config_add_database (oconfig_item_t *ci) /* {{{ */
 
 static int o_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if (strcasecmp ("Query", child->key) == 0)
@@ -399,7 +393,6 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
   OCIDefine **oci_defines;
 
   int status;
-  size_t i;
 
   oci_statement = udb_query_get_user_data (q);
 
@@ -517,13 +510,13 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
   ALLOC_OR_FAIL (column_names, column_num * sizeof (char *));
   ALLOC_OR_FAIL (column_names[0], column_num * DATA_MAX_NAME_LEN
       * sizeof (char));
-  for (i = 1; i < column_num; i++)
+  for (size_t i = 1; i < column_num; i++)
     column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;
 
   ALLOC_OR_FAIL (column_values, column_num * sizeof (char *));
   ALLOC_OR_FAIL (column_values[0], column_num * DATA_MAX_NAME_LEN
       * sizeof (char));
-  for (i = 1; i < column_num; i++)
+  for (size_t i = 1; i < column_num; i++)
     column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;
 
   ALLOC_OR_FAIL (oci_defines, column_num * sizeof (OCIDefine *));
@@ -531,7 +524,7 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
 
   /* ``Define'' the returned data, i. e. bind the columns to the buffers
    * allocated above. */
-  for (i = 0; i < column_num; i++) /* {{{ */
+  for (size_t i = 0; i < column_num; i++) /* {{{ */
   {
     char *column_name;
     ub4 column_name_length;
@@ -642,7 +635,6 @@ static int o_read_database_query (o_database_t *db, /* {{{ */
 
 static int o_read_database (o_database_t *db) /* {{{ */
 {
-  size_t i;
   int status;
 
   if (db->oci_service_context != NULL)
@@ -717,7 +709,7 @@ static int o_read_database (o_database_t *db) /* {{{ */
   DEBUG ("oracle plugin: o_read_database: db->connect_id = %s; db->oci_service_context = %p;",
       db->connect_id, db->oci_service_context);
 
-  for (i = 0; i < db->queries_num; i++)
+  for (size_t i = 0; i < db->queries_num; i++)
     o_read_database_query (db, db->queries[i], db->q_prep_areas[i]);
 
   return (0);
index 7d78630..4a11d6c 100644 (file)
@@ -22,6 +22,7 @@
  *
  * Authors:
  *   Sebastian Harl <sh at tokkee.org>
+ *   Pavel Rochnyak <pavel2000 ngs.ru>
  **/
 
 /*
@@ -34,9 +35,8 @@
 
 #define DONT_POISON_SPRINTF_YET 1
 #include "collectd.h"
-#undef DONT_POISON_SPRINTF_YET
 
-#include "configfile.h"
+#undef DONT_POISON_SPRINTF_YET
 
 #if HAVE_STDBOOL_H
 # include <stdbool.h>
@@ -78,8 +78,9 @@
 #define PLUGIN_LOG      4
 #define PLUGIN_NOTIF    5
 #define PLUGIN_FLUSH    6
+#define PLUGIN_FLUSH_ALL 7  /* For collectd-5.6 only */
 
-#define PLUGIN_TYPES    7
+#define PLUGIN_TYPES    8
 
 #define PLUGIN_CONFIG   254
 #define PLUGIN_DATASET  255
 /* this is defined in DynaLoader.a */
 void boot_DynaLoader (PerlInterpreter *, CV *);
 
+static XS (Collectd_plugin_register_read);
+static XS (Collectd_plugin_register_write);
+static XS (Collectd_plugin_register_log);
+static XS (Collectd_plugin_register_notification);
+static XS (Collectd_plugin_register_flush);
+static XS (Collectd_plugin_unregister_read);
+static XS (Collectd_plugin_unregister_write);
+static XS (Collectd_plugin_unregister_log);
+static XS (Collectd_plugin_unregister_notification);
+static XS (Collectd_plugin_unregister_flush);
 static XS (Collectd_plugin_register_ds);
 static XS (Collectd_plugin_unregister_ds);
 static XS (Collectd_plugin_dispatch_values);
@@ -114,6 +125,14 @@ static XS (Collectd_plugin_log);
 static XS (Collectd__fc_register);
 static XS (Collectd_call_by_name);
 
+static int perl_read (user_data_t *ud);
+static int perl_write (const data_set_t *ds, const value_list_t *vl,
+               user_data_t *user_data);
+static void perl_log (int level, const char *msg, user_data_t *user_data);
+static int perl_notify (const notification_t *notif, user_data_t *user_data);
+static int perl_flush (cdtime_t timeout, const char *identifier,
+               user_data_t *user_data);
+
 /*
  * private data types
  */
@@ -166,6 +185,8 @@ extern char **environ;
  * private variables
  */
 
+static _Bool register_legacy_flush = 1;
+
 /* if perl_threads != NULL perl_threads->head must
  * point to the "base" thread */
 static c_ithread_list_t *perl_threads = NULL;
@@ -183,6 +204,18 @@ static struct {
        XS ((*f));
 } api[] =
 {
+       { "Collectd::plugin_register_read",       Collectd_plugin_register_read },
+       { "Collectd::plugin_register_write",      Collectd_plugin_register_write },
+       { "Collectd::plugin_register_log",        Collectd_plugin_register_log },
+       { "Collectd::plugin_register_notification",
+               Collectd_plugin_register_notification },
+       { "Collectd::plugin_register_flush",       Collectd_plugin_register_flush },
+       { "Collectd::plugin_unregister_read",     Collectd_plugin_unregister_read },
+       { "Collectd::plugin_unregister_write",    Collectd_plugin_unregister_write },
+       { "Collectd::plugin_unregister_log",      Collectd_plugin_unregister_log },
+       { "Collectd::plugin_unregister_notification",
+               Collectd_plugin_unregister_notification },
+       { "Collectd::plugin_unregister_flush",    Collectd_plugin_unregister_flush },
        { "Collectd::plugin_register_data_set",   Collectd_plugin_register_ds },
        { "Collectd::plugin_unregister_data_set", Collectd_plugin_unregister_ds },
        { "Collectd::plugin_dispatch_values",     Collectd_plugin_dispatch_values },
@@ -308,7 +341,6 @@ static int hv2data_source (pTHX_ HV *hash, data_source_t *ds)
 static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t array_len)
 {
        const data_set_t *ds;
-       size_t i;
 
        if ((NULL == name) || (NULL == array) || (NULL == value) || (array_len == 0))
                return 0;
@@ -328,7 +360,7 @@ static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t arra
                                name, array_len, ds->ds_num);
        }
 
-       for (i = 0; i < ds->ds_num; ++i) {
+       for (size_t i = 0; i < ds->ds_num; ++i) {
                SV **tmp = av_fetch (array, i, 0);
 
                if (NULL != tmp) {
@@ -427,7 +459,7 @@ static int hv2value_list (pTHX_ HV *hash, value_list_t *vl)
 
 static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds)
 {
-       int len, i;
+       int len;
 
        if ((NULL == array) || (NULL == name) || (NULL == ds))
                return -1;
@@ -442,7 +474,7 @@ static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds)
        ds->ds = smalloc ((len + 1) * sizeof (*ds->ds));
        ds->ds_num = len + 1;
 
-       for (i = 0; i <= len; ++i) {
+       for (int i = 0; i <= len; ++i) {
                SV **elem = av_fetch (array, i, 0);
 
                if (NULL == elem) {
@@ -486,9 +518,8 @@ static int av2notification_meta (pTHX_ AV *array, notification_meta_t **meta)
        notification_meta_t **m = meta;
 
        int len = av_len (array);
-       int i;
 
-       for (i = 0; i <= len; ++i) {
+       for (int i = 0; i <= len; ++i) {
                SV **tmp = av_fetch (array, i, 0);
                HV  *hash;
 
@@ -604,14 +635,12 @@ static int hv2notification (pTHX_ HV *hash, notification_t *n)
 
 static int data_set2av (pTHX_ data_set_t *ds, AV *array)
 {
-       size_t i;
-
        if ((NULL == ds) || (NULL == array))
                return -1;
 
        av_extend (array, ds->ds_num);
 
-       for (i = 0; i < ds->ds_num; ++i) {
+       for (size_t i = 0; i < ds->ds_num; ++i) {
                HV *source = newHV ();
 
                if (NULL == hv_store (source, "name", 4,
@@ -711,7 +740,6 @@ static int value_list2hv (pTHX_ value_list_t *vl, data_set_t *ds, HV *hash)
 static int notification_meta2av (pTHX_ notification_meta_t *meta, AV *array)
 {
        int meta_num = 0;
-       int i;
 
        while (meta) {
                ++meta_num;
@@ -720,7 +748,7 @@ static int notification_meta2av (pTHX_ notification_meta_t *meta, AV *array)
 
        av_extend (array, meta_num);
 
-       for (i = 0; NULL != meta; meta = meta->next, ++i) {
+       for (int i = 0; NULL != meta; meta = meta->next, ++i) {
                HV *m = newHV ();
                SV *value;
 
@@ -807,8 +835,6 @@ static int notification2hv (pTHX_ notification_t *n, HV *hash)
 
 static int oconfig_item2hv (pTHX_ oconfig_item_t *ci, HV *hash)
 {
-       int i;
-
        AV *values;
        AV *children;
 
@@ -825,7 +851,7 @@ static int oconfig_item2hv (pTHX_ oconfig_item_t *ci, HV *hash)
                return -1;
        }
 
-       for (i = 0; i < ci->values_num; ++i) {
+       for (int i = 0; i < ci->values_num; ++i) {
                SV *value;
 
                switch (ci->values[i].type) {
@@ -862,7 +888,7 @@ static int oconfig_item2hv (pTHX_ oconfig_item_t *ci, HV *hash)
                return -1;
        }
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                HV *child = newHV ();
 
                if (0 != oconfig_item2hv (aTHX_ ci->children + i, child)) {
@@ -983,15 +1009,13 @@ static int pplugin_write (pTHX_ const char *plugin, AV *data_set, HV *values)
  */
 static int pplugin_dispatch_notification (pTHX_ HV *notif)
 {
-       notification_t n;
+       notification_t n = { 0 };
 
        int ret;
 
        if (NULL == notif)
                return -1;
 
-       memset (&n, 0, sizeof (n));
-
        if (0 != hv2notification (aTHX_ notif, &n))
                return -1;
 
@@ -1020,7 +1044,7 @@ static int call_pv_locked (pTHX_ const char* sub_name)
                return 0;
        }
 
-       ret = call_pv (sub_name, G_SCALAR);
+       ret = call_pv (sub_name, G_SCALAR|G_EVAL);
 
        t->running = old_running;
        return ret;
@@ -1029,12 +1053,13 @@ static int call_pv_locked (pTHX_ const char* sub_name)
 /*
  * Call all working functions of the given type.
  */
-static int pplugin_call_all (pTHX_ int type, ...)
+static int pplugin_call (pTHX_ int type, ...)
 {
        int retvals = 0;
 
        va_list ap;
        int ret = 0;
+       char *subname;
 
        dSP;
 
@@ -1048,9 +1073,17 @@ static int pplugin_call_all (pTHX_ int type, ...)
 
        PUSHMARK (SP);
 
-       XPUSHs (sv_2mortal (newSViv ((IV)type)));
+       if (PLUGIN_READ == type) {
+               subname = va_arg(ap, char *);
+       }
+       else if (PLUGIN_WRITE == type) {
+               data_set_t   *ds;
+               value_list_t *vl;
+
+               AV *pds = newAV ();
+               HV *pvl = newHV ();
 
-       if (PLUGIN_WRITE == type) {
+               subname = va_arg(ap, char *);
                /*
                 * $_[0] = $plugin_type;
                 *
@@ -1076,12 +1109,6 @@ static int pplugin_call_all (pTHX_ int type, ...)
                 *   type_instance   => $type_instance
                 * };
                 */
-               data_set_t   *ds;
-               value_list_t *vl;
-
-               AV *pds = newAV ();
-               HV *pvl = newHV ();
-
                ds = va_arg (ap, data_set_t *);
                vl = va_arg (ap, value_list_t *);
 
@@ -1104,6 +1131,7 @@ static int pplugin_call_all (pTHX_ int type, ...)
                XPUSHs (sv_2mortal (newRV_noinc ((SV *)pvl)));
        }
        else if (PLUGIN_LOG == type) {
+               subname = va_arg(ap, char *);
                /*
                 * $_[0] = $level;
                 *
@@ -1113,6 +1141,10 @@ static int pplugin_call_all (pTHX_ int type, ...)
                XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
        }
        else if (PLUGIN_NOTIF == type) {
+               notification_t *n;
+               HV *notif = newHV ();
+
+               subname = va_arg(ap, char *);
                /*
                 * $_[0] =
                 * {
@@ -1126,9 +1158,6 @@ static int pplugin_call_all (pTHX_ int type, ...)
                 *   type_instance   => $type_instance
                 * };
                 */
-               notification_t *n;
-               HV *notif = newHV ();
-
                n = va_arg (ap, notification_t *);
 
                if (-1 == notification2hv (aTHX_ n, notif)) {
@@ -1142,23 +1171,53 @@ static int pplugin_call_all (pTHX_ int type, ...)
        }
        else if (PLUGIN_FLUSH == type) {
                cdtime_t timeout;
+               subname = va_arg(ap, char *);
+               /*
+                * $_[0] = $timeout;
+                * $_[1] = $identifier;
+                */
+               timeout = va_arg (ap, cdtime_t);
 
+               XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
+               XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
+       }
+       else if (PLUGIN_FLUSH_ALL == type) {
+               cdtime_t timeout;
+               subname = "Collectd::plugin_call_all";
                /*
                 * $_[0] = $timeout;
                 * $_[1] = $identifier;
                 */
                timeout = va_arg (ap, cdtime_t);
 
+               XPUSHs (sv_2mortal (newSViv ((IV)PLUGIN_FLUSH)));
                XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
                XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
        }
+       else if (PLUGIN_INIT == type) {
+               subname = "Collectd::plugin_call_all";
+               XPUSHs (sv_2mortal (newSViv ((IV)type)));
+       }
+       else if (PLUGIN_SHUTDOWN == type) {
+               subname = "Collectd::plugin_call_all";
+               XPUSHs (sv_2mortal (newSViv ((IV)type)));
+       }
+       else { /* Unknown type. Run 'plugin_call_all' and make compiler happy */
+               subname = "Collectd::plugin_call_all";
+               XPUSHs (sv_2mortal (newSViv ((IV)type)));
+       }
 
        PUTBACK;
 
-       retvals = call_pv_locked (aTHX_ "Collectd::plugin_call_all");
+       retvals = call_pv_locked (aTHX_ subname);
 
        SPAGAIN;
-       if (0 < retvals) {
+       if (SvTRUE(ERRSV)) {
+               if (PLUGIN_LOG != type)
+                       ERROR ("perl: %s error: %s", subname, SvPV_nolen(ERRSV));
+               ret = -1;
+       }
+       else if (0 < retvals) {
                SV *tmp = POPs;
                if (! SvTRUE (tmp))
                        ret = -1;
@@ -1170,7 +1229,7 @@ static int pplugin_call_all (pTHX_ int type, ...)
 
        va_end (ap);
        return ret;
-} /* static int pplugin_call_all (int, ...) */
+} /* static int pplugin_call (int, ...) */
 
 /*
  * collectd's Perl interpreter based thread implementation.
@@ -1186,6 +1245,10 @@ static void c_ithread_destroy (c_ithread_t *ithread)
        assert (NULL != perl_threads);
 
        PERL_SET_CONTEXT (aTHX);
+       /* Mark as running to avoid deadlock:
+          c_ithread_destroy -> log_debug -> perl_log()
+       */
+       ithread->running = 1;
        log_debug ("Shutting down Perl interpreter %p...", aTHX);
 
 #if COLLECT_DEBUG
@@ -1409,7 +1472,11 @@ static int fc_call (pTHX_ int type, int cb_type, pfc_user_data_t *data, ...)
        }
 
        SPAGAIN;
-       if (0 < retvals) {
+       if (SvTRUE(ERRSV)) {
+               ERROR ("perl: Collectd::fc_call error: %s", SvPV_nolen(ERRSV));
+               ret = -1;
+       }
+       else if (0 < retvals) {
                SV *tmp = POPs;
 
                /* the exec callbacks return a status, while
@@ -1578,6 +1645,173 @@ static target_proc_t ptarget = {
  * Exported Perl API.
  */
 
+static void _plugin_register_generic_userdata (pTHX, int type, const char *desc)
+{
+       int ret   = 0;
+       user_data_t userdata;
+       char *pluginname;
+
+       dXSARGS;
+
+       if (2 != items) {
+               log_err ("Usage: Collectd::plugin_register_%s(pluginname, subname)",
+                                       desc);
+               XSRETURN_EMPTY;
+       }
+
+       if (! SvOK (ST (0))) {
+               log_err ("Collectd::plugin_register_%s(pluginname, subname): "
+                        "Invalid pluginname", desc);
+               XSRETURN_EMPTY;
+       }
+       if (! SvOK (ST (1))) {
+               log_err ("Collectd::plugin_register_%s(pluginname, subname): "
+                        "Invalid subname", desc);
+               XSRETURN_EMPTY;
+       }
+
+       /* Use pluginname as-is to allow flush a single perl plugin */
+       pluginname = SvPV_nolen (ST (0));
+
+       log_debug ("Collectd::plugin_register_%s: "
+                       "plugin = \"%s\", sub = \"%s\"",
+                       desc, pluginname, SvPV_nolen (ST (1)));
+
+       memset(&userdata, 0, sizeof(userdata));
+       userdata.data = strdup(SvPV_nolen (ST (1)));
+       userdata.free_func = free;
+
+       if (PLUGIN_READ == type) {
+               ret = plugin_register_complex_read(
+                       "perl",                /* group */
+                       pluginname,
+                       perl_read,
+                       plugin_get_interval(), /* Default interval */
+                       &userdata);
+       }
+       else if (PLUGIN_WRITE == type) {
+               ret = plugin_register_write(pluginname, perl_write, &userdata);
+       }
+       else if (PLUGIN_LOG == type) {
+               ret = plugin_register_log(pluginname, perl_log, &userdata);
+       }
+       else if (PLUGIN_NOTIF == type) {
+               ret = plugin_register_notification(pluginname, perl_notify, &userdata);
+       }
+       else if (PLUGIN_FLUSH == type) {
+               if (1 == register_legacy_flush) { /* For collectd-5.7 only, #1731 */
+                       register_legacy_flush = 0;
+                       ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL);
+               }
+
+               if (0 == ret)
+                       ret = plugin_register_flush(pluginname, perl_flush, &userdata);
+       }
+       else {
+               ret = -1;
+       }
+
+       if (0 == ret)
+               XSRETURN_YES;
+       else {
+               free (userdata.data);
+               XSRETURN_EMPTY;
+       }
+} /* static void _plugin_register_generic_userdata ( ... ) */
+
+/*
+ * Collectd::plugin_register_TYPE (pluginname, subname).
+ *
+ * pluginname:
+ *   name of the perl plugin
+ *
+ * subname:
+ *   name of the plugin's subroutine that does the work
+ */
+
+static XS (Collectd_plugin_register_read) {
+       return _plugin_register_generic_userdata(aTHX, PLUGIN_READ, "read");
+}
+
+static XS (Collectd_plugin_register_write) {
+       return _plugin_register_generic_userdata(aTHX, PLUGIN_WRITE, "write");
+}
+
+static XS (Collectd_plugin_register_log) {
+       return _plugin_register_generic_userdata(aTHX, PLUGIN_LOG, "log");
+}
+
+static XS (Collectd_plugin_register_notification) {
+       return _plugin_register_generic_userdata(aTHX, PLUGIN_NOTIF, "notification");
+}
+
+static XS (Collectd_plugin_register_flush) {
+       return _plugin_register_generic_userdata(aTHX, PLUGIN_FLUSH, "flush");
+}
+
+typedef int perl_unregister_function_t(const char *name);
+
+static void _plugin_unregister_generic (pTHX,
+                               perl_unregister_function_t *unreg, const char *desc)
+{
+       dXSARGS;
+
+       if (1 != items) {
+               log_err ("Usage: Collectd::plugin_unregister_%s(pluginname)", desc);
+               XSRETURN_EMPTY;
+       }
+
+       if (! SvOK (ST (0))) {
+               log_err ("Collectd::plugin_unregister_%s(pluginname): "
+                        "Invalid pluginname", desc);
+               XSRETURN_EMPTY;
+       }
+
+       log_debug ("Collectd::plugin_unregister_%s: plugin = \"%s\"",
+                       desc, SvPV_nolen (ST (0)));
+
+       unreg(SvPV_nolen (ST (0)));
+
+       XSRETURN_EMPTY;
+
+       return;
+} /* static void _plugin_unregister_generic ( ... ) */
+
+/*
+ * Collectd::plugin_unregister_TYPE (pluginname).
+ *
+ * TYPE:
+ *   type of callback to be unregistered: read, write, log, notification, flush
+ *
+ * pluginname:
+ *   name of the perl plugin
+ */
+
+static XS (Collectd_plugin_unregister_read) {
+       return _plugin_unregister_generic(aTHX,
+                               plugin_unregister_read, "read");
+}
+
+static XS (Collectd_plugin_unregister_write) {
+       return _plugin_unregister_generic(aTHX,
+                               plugin_unregister_write, "write");
+}
+
+static XS (Collectd_plugin_unregister_log) {
+       return _plugin_unregister_generic(aTHX,
+                               plugin_unregister_log, "log");
+}
+
+static XS (Collectd_plugin_unregister_notification) {
+       return _plugin_unregister_generic(aTHX,
+                               plugin_unregister_notification, "notification");
+}
+
+static XS (Collectd_plugin_unregister_flush) {
+       return _plugin_unregister_generic(aTHX,
+                               plugin_unregister_flush, "flush");
+}
+
 /*
  * Collectd::plugin_register_data_set (type, dataset).
  *
@@ -1965,14 +2199,14 @@ static int perl_init (void)
        assert (aTHX == perl_threads->head->interp);
        pthread_mutex_lock (&perl_threads->mutex);
 
-       status = pplugin_call_all (aTHX_ PLUGIN_INIT);
+       status = pplugin_call (aTHX_ PLUGIN_INIT);
 
        pthread_mutex_unlock (&perl_threads->mutex);
 
        return status;
 } /* static int perl_init (void) */
 
-static int perl_read (void)
+static int perl_read (user_data_t *user_data)
 {
        dTHX;
 
@@ -1996,11 +2230,12 @@ static int perl_read (void)
 
        log_debug ("perl_read: c_ithread: interp = %p (active threads: %i)",
                        aTHX, perl_threads->number_of_threads);
-       return pplugin_call_all (aTHX_ PLUGIN_READ);
-} /* static int perl_read (void) */
+
+       return pplugin_call (aTHX_ PLUGIN_READ, user_data->data);
+} /* static int perl_read (user_data_t *user_data) */
 
 static int perl_write (const data_set_t *ds, const value_list_t *vl,
-               user_data_t __attribute__((unused)) *user_data)
+               user_data_t *user_data)
 {
        int status;
        dTHX;
@@ -2026,7 +2261,7 @@ static int perl_write (const data_set_t *ds, const value_list_t *vl,
 
        log_debug ("perl_write: c_ithread: interp = %p (active threads: %i)",
                        aTHX, perl_threads->number_of_threads);
-       status = pplugin_call_all (aTHX_ PLUGIN_WRITE, ds, vl);
+       status = pplugin_call (aTHX_ PLUGIN_WRITE, user_data->data, ds, vl);
 
        if (aTHX == perl_threads->head->interp)
                pthread_mutex_unlock (&perl_threads->mutex);
@@ -2035,7 +2270,7 @@ static int perl_write (const data_set_t *ds, const value_list_t *vl,
 } /* static int perl_write (const data_set_t *, const value_list_t *) */
 
 static void perl_log (int level, const char *msg,
-               user_data_t __attribute__((unused)) *user_data)
+               user_data_t *user_data)
 {
        dTHX;
 
@@ -2060,7 +2295,7 @@ static void perl_log (int level, const char *msg,
        if (aTHX == perl_threads->head->interp)
                pthread_mutex_lock (&perl_threads->mutex);
 
-       pplugin_call_all (aTHX_ PLUGIN_LOG, level, msg);
+       pplugin_call (aTHX_ PLUGIN_LOG, user_data->data, level, msg);
 
        if (aTHX == perl_threads->head->interp)
                pthread_mutex_unlock (&perl_threads->mutex);
@@ -2068,8 +2303,7 @@ static void perl_log (int level, const char *msg,
        return;
 } /* static void perl_log (int, const char *) */
 
-static int perl_notify (const notification_t *notif,
-               user_data_t __attribute__((unused)) *user_data)
+static int perl_notify (const notification_t *notif, user_data_t *user_data)
 {
        dTHX;
 
@@ -2085,11 +2319,11 @@ static int perl_notify (const notification_t *notif,
 
                aTHX = t->interp;
        }
-       return pplugin_call_all (aTHX_ PLUGIN_NOTIF, notif);
+       return pplugin_call (aTHX_ PLUGIN_NOTIF, user_data->data, notif);
 } /* static int perl_notify (const notification_t *) */
 
 static int perl_flush (cdtime_t timeout, const char *identifier,
-               user_data_t __attribute__((unused)) *user_data)
+               user_data_t *user_data)
 {
        dTHX;
 
@@ -2105,7 +2339,12 @@ static int perl_flush (cdtime_t timeout, const char *identifier,
 
                aTHX = t->interp;
        }
-       return pplugin_call_all (aTHX_ PLUGIN_FLUSH, timeout, identifier);
+
+       /* For collectd-5.6 only, #1731 */
+       if (user_data == NULL || user_data->data == NULL)
+               return pplugin_call (aTHX_ PLUGIN_FLUSH_ALL, timeout, identifier);
+
+       return pplugin_call (aTHX_ PLUGIN_FLUSH, user_data->data, timeout, identifier);
 } /* static int perl_flush (const int) */
 
 static int perl_shutdown (void)
@@ -2116,6 +2355,7 @@ static int perl_shutdown (void)
        dTHX;
 
        plugin_unregister_complex_config ("perl");
+       plugin_unregister_read_group ("perl");
 
        if (NULL == perl_threads)
                return 0;
@@ -2131,14 +2371,10 @@ static int perl_shutdown (void)
        log_debug ("perl_shutdown: c_ithread: interp = %p (active threads: %i)",
                        aTHX, perl_threads->number_of_threads);
 
-       plugin_unregister_log ("perl");
-       plugin_unregister_notification ("perl");
        plugin_unregister_init ("perl");
-       plugin_unregister_read ("perl");
-       plugin_unregister_write ("perl");
-       plugin_unregister_flush ("perl");
+       plugin_unregister_flush ("perl"); /* For collectd-5.6 only, #1731 */
 
-       ret = pplugin_call_all (aTHX_ PLUGIN_SHUTDOWN);
+       ret = pplugin_call (aTHX_ PLUGIN_SHUTDOWN);
 
        pthread_mutex_lock (&perl_threads->mutex);
        t = perl_threads->tail;
@@ -2240,21 +2476,19 @@ static void xs_init (pTHX)
        SV   *tmp   = NULL;
        char *file  = __FILE__;
 
-       int i = 0;
-
        dXSUB_SYS;
 
        /* enable usage of Perl modules using shared libraries */
        newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
 
        /* register API */
-       for (i = 0; NULL != api[i].f; ++i)
+       for (int i = 0; NULL != api[i].f; ++i)
                newXS (api[i].name, api[i].f, file);
 
        stash = gv_stashpv ("Collectd", 1);
 
        /* export "constants" */
-       for (i = 0; '\0' != constants[i].name[0]; ++i)
+       for (int i = 0; '\0' != constants[i].name[0]; ++i)
                newCONSTSUB (stash, constants[i].name, newSViv (constants[i].value));
 
        /* export global variables
@@ -2263,7 +2497,7 @@ static void xs_init (pTHX)
         * accessing any such variable (this is basically the same as using
         * tie() in Perl) */
        /* global strings */
-       for (i = 0; '\0' != g_strings[i].name[0]; ++i) {
+       for (int i = 0; '\0' != g_strings[i].name[0]; ++i) {
                tmp = get_sv (g_strings[i].name, 1);
                sv_magicext (tmp, NULL, PERL_MAGIC_ext, &g_pv_vtbl,
                                g_strings[i].var, 0);
@@ -2288,9 +2522,7 @@ static int init_pi (int argc, char **argv)
        log_info ("Initializing Perl interpreter...");
 #if COLLECT_DEBUG
        {
-               int i = 0;
-
-               for (i = 0; i < argc; ++i)
+               for (int i = 0; i < argc; ++i)
                        log_debug ("argv[%i] = \"%s\"", i, argv[i]);
        }
 #endif /* COLLECT_DEBUG */
@@ -2352,15 +2584,7 @@ static int init_pi (int argc, char **argv)
 
        perl_run (aTHX);
 
-       plugin_register_log ("perl", perl_log, /* user_data = */ NULL);
-       plugin_register_notification ("perl", perl_notify,
-                       /* user_data = */ NULL);
        plugin_register_init ("perl", perl_init);
-
-       plugin_register_read ("perl", perl_read);
-
-       plugin_register_write ("perl", perl_write, /* user_data = */ NULL);
-       plugin_register_flush ("perl", perl_flush, /* user_data = */ NULL);
        plugin_register_shutdown ("perl", perl_shutdown);
        return 0;
 } /* static int init_pi (const char **, const int) */
@@ -2559,11 +2783,10 @@ static int perl_config_plugin (pTHX_ oconfig_item_t *ci)
 static int perl_config (oconfig_item_t *ci)
 {
        int status = 0;
-       int i = 0;
 
        dTHXa (NULL);
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
                int current_status = 0;
 
@@ -2583,6 +2806,8 @@ static int perl_config (oconfig_item_t *ci)
                        current_status = perl_config_includedir (aTHX_ c);
                else if (0 == strcasecmp (c->key, "Plugin"))
                        current_status = perl_config_plugin (aTHX_ c);
+               else if (0 == strcasecmp (c->key, "RegisterLegacyFlush"))
+                       cf_util_get_boolean (c, &register_legacy_flush);
                else
                {
                        log_warn ("Ignoring unknown config key \"%s\".", c->key);
index 225d536..d7a5a15 100644 (file)
--- a/src/pf.c
+++ b/src/pf.c
@@ -20,6 +20,7 @@
  */
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 
@@ -82,7 +83,6 @@ static int pf_read (void)
        struct pf_status state;
        int fd;
        int status;
-       int i;
 
        fd = open (pf_device, O_RDONLY);
        if (fd < 0)
@@ -94,7 +94,6 @@ static int pf_read (void)
                return (-1);
        }
 
-       memset (&state, 0, sizeof (state));
        status = ioctl (fd, DIOCGETSTATUS, &state);
        if (status != 0)
        {
@@ -113,16 +112,16 @@ static int pf_read (void)
                return (-1);
        }
 
-       for (i = 0; i < PFRES_MAX; i++)
+       for (int i = 0; i < PFRES_MAX; i++)
                pf_submit ("pf_counters", pf_reasons[i], state.counters[i],
                                /* is gauge = */ 0);
-       for (i = 0; i < LCNT_MAX; i++)
+       for (int i = 0; i < LCNT_MAX; i++)
                pf_submit ("pf_limits", pf_lcounters[i], state.lcounters[i],
                                /* is gauge = */ 0);
-       for (i = 0; i < FCNT_MAX; i++)
+       for (int i = 0; i < FCNT_MAX; i++)
                pf_submit ("pf_state", pf_fcounters[i], state.fcounters[i],
                                /* is gauge = */ 0);
-       for (i = 0; i < SCNT_MAX; i++)
+       for (int i = 0; i < SCNT_MAX; i++)
                pf_submit ("pf_source", pf_scounters[i], state.scounters[i],
                                /* is gauge = */ 0);
 
index cfc0777..76b765b 100644 (file)
@@ -24,9 +24,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <netdb.h>
 #include <poll.h>
@@ -251,11 +251,9 @@ static void service_statnode_process (pinba_statnode_t *node, /* {{{ */
 
 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++)
+  for (unsigned int i = 0; i < stat_nodes_num; i++)
   {
     if ((stat_nodes[i].host != NULL)
         && (strcmp (request->hostname, stat_nodes[i].host) != 0))
@@ -351,25 +349,20 @@ static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */
 {
   pinba_socket_t *s;
   struct addrinfo *ai_list;
-  struct addrinfo *ai_ptr;
-  struct addrinfo  ai_hints;
   int status;
 
-  memset (&ai_hints, 0, sizeof (ai_hints));
-  ai_hints.ai_flags = AI_PASSIVE;
-  ai_hints.ai_family = AF_UNSPEC;
-  ai_hints.ai_socktype = SOCK_DGRAM;
-  ai_hints.ai_addr = NULL;
-  ai_hints.ai_canonname = NULL;
-  ai_hints.ai_next = NULL;
-
   if (node == NULL)
     node = PINBA_DEFAULT_NODE;
 
   if (service == NULL)
     service = PINBA_DEFAULT_SERVICE;
 
-  ai_list = NULL;
+  struct addrinfo  ai_hints = {
+    .ai_family = AF_UNSPEC,
+    .ai_flags = AI_PASSIVE,
+    .ai_socktype = SOCK_DGRAM
+  };
+
   status = getaddrinfo (node, service,
       &ai_hints, &ai_list);
   if (status != 0)
@@ -388,7 +381,7 @@ static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */
     return (NULL);
   }
 
-  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
     status = pb_add_socket (s, ai_ptr);
     if (status != 0)
@@ -409,12 +402,10 @@ static pinba_socket_t *pinba_socket_open (const char *node, /* {{{ */
 
 static void pinba_socket_free (pinba_socket_t *socket) /* {{{ */
 {
-  nfds_t i;
-
   if (!socket)
     return;
 
-  for (i = 0; i < socket->fd_num; i++)
+  for (nfds_t i = 0; i < socket->fd_num; i++)
   {
     if (socket->fd[i].fd < 0)
       continue;
@@ -505,7 +496,6 @@ static int receive_loop (void) /* {{{ */
   while (!collector_thread_do_shutdown)
   {
     int status;
-    nfds_t i;
 
     if (s->fd_num < 1)
       break;
@@ -528,7 +518,7 @@ static int receive_loop (void) /* {{{ */
       return (-1);
     }
 
-    for (i = 0; i < s->fd_num; i++)
+    for (nfds_t i = 0; i < s->fd_num; i++)
     {
       if (s->fd[i].revents & (POLLERR | POLLHUP | POLLNVAL))
       {
@@ -568,13 +558,12 @@ static int pinba_config_view (const oconfig_item_t *ci) /* {{{ */
   char *server = NULL;
   char *script = NULL;
   int status;
-  int i;
 
   status = cf_util_get_string (ci, &name);
   if (status != 0)
     return (status);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -607,13 +596,11 @@ 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);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -690,38 +677,36 @@ static int plugin_shutdown (void) /* {{{ */
 
 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));
   sstrncpy (vl.plugin, "pinba", sizeof (vl.plugin));
   sstrncpy (vl.plugin_instance, res->name, sizeof (vl.plugin_instance));
 
-  value.derive = res->req_count;
+  vl.values = &(value_t) { .derive = res->req_count };
   sstrncpy (vl.type, "total_requests", sizeof (vl.type));
   plugin_dispatch_values (&vl);
 
-  value.derive = float_counter_get (&res->req_time, /* factor = */ 1000);
+  vl.values = &(value_t) { .derive = float_counter_get (&res->req_time, /* factor = */ 1000) };
   sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type));
   plugin_dispatch_values (&vl);
 
-  value.derive = res->doc_size;
+  vl.values = &(value_t) { .derive = res->doc_size };
   sstrncpy (vl.type, "total_bytes", sizeof (vl.type));
   plugin_dispatch_values (&vl);
 
-  value.derive = float_counter_get (&res->ru_utime, /* factor = */ 100);
+  vl.values = &(value_t) { .derive = float_counter_get (&res->ru_utime, /* factor = */ 100) };
   sstrncpy (vl.type, "cpu", sizeof (vl.type));
   sstrncpy (vl.type_instance, "user", sizeof (vl.type_instance));
   plugin_dispatch_values (&vl);
 
-  value.derive = float_counter_get (&res->ru_stime, /* factor = */ 100);
+  vl.values = &(value_t) { .derive = float_counter_get (&res->ru_stime, /* factor = */ 100) };
   sstrncpy (vl.type, "cpu", sizeof (vl.type));
   sstrncpy (vl.type_instance, "system", sizeof (vl.type_instance));
   plugin_dispatch_values (&vl);
 
-  value.gauge = res->mem_peak;
+  vl.values = &(value_t) { .gauge = res->mem_peak };
   sstrncpy (vl.type, "memory", sizeof (vl.type));
   sstrncpy (vl.type_instance, "peak", sizeof (vl.type_instance));
   plugin_dispatch_values (&vl);
index 5fd5439..22e61c6 100644 (file)
@@ -1,3 +1,5 @@
+syntax = "proto2";
+
 package Pinba;
 option optimize_for = SPEED;
 
index e16ba07..39e9de5 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_complain.h"
 
 #include <netinet/in.h>
 # include <netdb.h> /* NI_MAXHOST */
 #endif
 
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
 #include <oping.h>
 
 #ifndef NI_MAXHOST
@@ -151,11 +155,10 @@ static void time_calc (struct timespec *ts_dest, /* {{{ */
 
 static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */
 {
-  pingobj_iter_t *iter;
   hostlist_t *hl;
   int status;
 
-  for (iter = ping_iterator_get (pingobj);
+  for (pingobj_iter_t *iter = ping_iterator_get (pingobj);
       iter != NULL;
       iter = ping_iterator_next (iter))
   { /* {{{ */
@@ -250,7 +253,6 @@ static void *ping_thread (void *arg) /* {{{ */
   struct timespec ts_wait;
   struct timespec ts_int;
 
-  hostlist_t *hl;
   int count;
 
   c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
@@ -286,7 +288,7 @@ static void *ping_thread (void *arg) /* {{{ */
 
   /* Add all the hosts to the ping object. */
   count = 0;
-  for (hl = hostlist_head; hl != NULL; hl = hl->next)
+  for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next)
   {
     int tmp_status;
     tmp_status = ping_host_add (pingobj, hl->host);
@@ -384,7 +386,7 @@ static int start_thread (void) /* {{{ */
   if (ping_thread_loop != 0)
   {
     pthread_mutex_unlock (&ping_lock);
-    return (-1);
+    return (0);
   }
 
   ping_thread_loop = 1;
@@ -449,10 +451,21 @@ static int ping_init (void) /* {{{ */
         "Will use a timeout of %gs.", ping_timeout);
   }
 
-  if (start_thread () != 0)
-    return (-1);
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_RAW)
+  if (check_capability (CAP_NET_RAW) != 0)
+  {
+    if (getuid () == 0)
+      WARNING ("ping plugin: Running collectd as root, but the CAP_NET_RAW "
+          "capability is missing. The plugin's read function will probably "
+          "fail. Is your init system dropping capabilities?");
+    else
+      WARNING ("ping plugin: collectd doesn't have the CAP_NET_RAW capability. "
+          "If you don't want to run collectd as root, try running \"setcap "
+          "cap_net_raw=ep\" on the collectd binary.");
+  }
+#endif
 
-  return (0);
+  return (start_thread ());
 } /* }}} int ping_init */
 
 static int config_set_string (const char *name, /* {{{ */
@@ -549,8 +562,6 @@ static int ping_config (const char *key, const char *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)
@@ -566,7 +577,7 @@ static int ping_config (const char *key, const char *value) /* {{{ */
        * 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++) /* {{{ */
+      for (size_t i = 0; i < size; i++) /* {{{ */
       {
         /* This restricts data pattern to be only composed of easily
          * printable characters, and not NUL character. */
@@ -604,12 +615,9 @@ static int ping_config (const char *key, const char *value) /* {{{ */
 static void submit (const char *host, const char *type, /* {{{ */
     gauge_t value)
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0].gauge = value;
-
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = value };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "ping", sizeof (vl.plugin));
@@ -622,15 +630,13 @@ static void submit (const char *host, const char *type, /* {{{ */
 
 static int ping_read (void) /* {{{ */
 {
-  hostlist_t *hl;
-
   if (ping_thread_error != 0)
   {
     ERROR ("ping plugin: The ping thread had a problem. Restarting it.");
 
     stop_thread ();
 
-    for (hl = hostlist_head; hl != NULL; hl = hl->next)
+    for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next)
     {
       hl->pkg_sent = 0;
       hl->pkg_recv = 0;
@@ -643,7 +649,7 @@ static int ping_read (void) /* {{{ */
     return (-1);
   } /* if (ping_thread_error != 0) */
 
-  for (hl = hostlist_head; hl != NULL; hl = hl->next) /* {{{ */
+  for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) /* {{{ */
   {
     uint32_t pkg_sent;
     uint32_t pkg_recv;
index 41ce95c..8b60949 100644 (file)
@@ -31,9 +31,9 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 
-#include "configfile.h"
 #include "plugin.h"
 
 #include "utils_cache.h"
@@ -276,8 +276,6 @@ static c_psql_database_t *c_psql_database_new (const char *name)
 
 static void c_psql_database_delete (void *data)
 {
-       size_t i;
-
        c_psql_database_t *db = data;
 
        --db->ref_cnt;
@@ -295,7 +293,7 @@ static void c_psql_database_delete (void *data)
        db->conn = NULL;
 
        if (db->q_prep_areas)
-               for (i = 0; i < db->queries_num; ++i)
+               for (size_t i = 0; i < db->queries_num; ++i)
                        udb_query_delete_preparation_area (db->q_prep_areas[i]);
        free (db->q_prep_areas);
 
@@ -427,14 +425,13 @@ static PGresult *c_psql_exec_query_params (c_psql_database_t *db,
 {
        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));
 
        assert (db->max_params_num >= data->params_num);
 
-       for (i = 0; i < data->params_num; ++i) {
+       for (int i = 0; i < data->params_num; ++i) {
                switch (data->params[i]) {
                        case C_PSQL_PARAM_HOST:
                                params[i] = C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host)
@@ -483,7 +480,6 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q,
 
        int rows_num;
        int status;
-       int row, col;
 
        /* The user data may hold parameter information, but may be NULL. */
        data = udb_query_get_user_data (q);
@@ -552,7 +548,7 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q,
                BAIL_OUT (-1);
        }
 
-       for (col = 0; col < column_num; ++col) {
+       for (int col = 0; col < column_num; ++col) {
                /* Pointers returned by `PQfname' are freed by `PQclear' via
                 * `BAIL_OUT'. */
                column_names[col] = PQfname (res, col);
@@ -577,7 +573,8 @@ static int c_psql_exec_query (c_psql_database_t *db, udb_query_t *q,
                BAIL_OUT (-1);
        }
 
-       for (row = 0; row < rows_num; ++row) {
+       for (int row = 0; row < rows_num; ++row) {
+        int col;
                for (col = 0; col < column_num; ++col) {
                        /* Pointers returned by `PQgetvalue' are freed by `PQclear' via
                         * `BAIL_OUT'. */
@@ -611,7 +608,6 @@ static int c_psql_read (user_data_t *ud)
        c_psql_database_t *db;
 
        int success = 0;
-       size_t i;
 
        if ((ud == NULL) || (ud->data == NULL)) {
                log_err ("c_psql_read: Invalid user data.");
@@ -631,7 +627,7 @@ static int c_psql_read (user_data_t *ud)
                return -1;
        }
 
-       for (i = 0; i < db->queries_num; ++i)
+       for (size_t i = 0; i < db->queries_num; ++i)
        {
                udb_query_preparation_area_t *prep_area;
                udb_query_t *q;
@@ -659,12 +655,11 @@ static char *values_name_to_sqlarray (const data_set_t *ds,
 {
        char  *str_ptr;
        size_t str_len;
-       size_t i;
 
        str_ptr = string;
        str_len = string_len;
 
-       for (i = 0; i < ds->ds_num; ++i) {
+       for (size_t i = 0; i < ds->ds_num; ++i) {
                int status = ssnprintf (str_ptr, str_len, ",'%s'", ds->ds[i].name);
 
                if (status < 1)
@@ -697,12 +692,11 @@ static char *values_type_to_sqlarray (const data_set_t *ds,
 {
        char  *str_ptr;
        size_t str_len;
-       size_t i;
 
        str_ptr = string;
        str_len = string_len;
 
-       for (i = 0; i < ds->ds_num; ++i) {
+       for (size_t i = 0; i < ds->ds_num; ++i) {
                int status;
 
                if (store_rates)
@@ -745,12 +739,11 @@ static char *values_to_sqlarray (const data_set_t *ds, const value_list_t *vl,
        size_t str_len;
 
        gauge_t *rates = NULL;
-       size_t i;
 
        str_ptr = string;
        str_len = string_len;
 
-       for (i = 0; i < vl->values_len; ++i) {
+       for (size_t i = 0; i < vl->values_len; ++i) {
                int status = 0;
 
                if ((ds->ds[i].type != DS_TYPE_GAUGE)
@@ -830,7 +823,6 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl,
        const char *params[9];
 
        int success = 0;
-       size_t i;
 
        if ((ud == NULL) || (ud->data == NULL)) {
                log_err ("c_psql_write: Invalid user data.");
@@ -841,7 +833,7 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl,
        assert (db->database != NULL);
        assert (db->writers != NULL);
 
-       if (rfc3339nano (time_str, sizeof (time_str), vl->time) != 0) {
+       if (rfc3339nano_local (time_str, sizeof (time_str), vl->time) != 0) {
                log_err ("c_psql_write: Failed to convert time to RFC 3339 format");
                return -1;
        }
@@ -879,7 +871,7 @@ static int c_psql_write (const data_set_t *ds, const value_list_t *vl,
                        && (db->next_commit == 0))
                c_psql_begin (db);
 
-       for (i = 0; i < db->writers_num; ++i) {
+       for (size_t i = 0; i < db->writers_num; ++i) {
                c_psql_writer_t *writer;
                PGresult *res;
 
@@ -967,14 +959,13 @@ static int c_psql_flush (cdtime_t timeout,
 {
        c_psql_database_t **dbs = databases;
        size_t dbs_num = databases_num;
-       size_t i;
 
        if ((ud != NULL) && (ud->data != NULL)) {
                dbs = (void *)&ud->data;
                dbs_num = 1;
        }
 
-       for (i = 0; i < dbs_num; ++i) {
+       for (size_t i = 0; i < dbs_num; ++i) {
                c_psql_database_t *db = dbs[i];
 
                /* don't commit if the timeout is larger than the regular commit
@@ -988,13 +979,11 @@ static int c_psql_flush (cdtime_t timeout,
 
 static int c_psql_shutdown (void)
 {
-       size_t i = 0;
-
        _Bool had_flush = 0;
 
        plugin_unregister_read_group ("postgresql");
 
-       for (i = 0; i < databases_num; ++i) {
+       for (size_t i = 0; i < databases_num; ++i) {
                c_psql_database_t *db = databases[i];
 
                if (db->writers_num > 0) {
@@ -1139,7 +1128,6 @@ static int c_psql_config_writer (oconfig_item_t *ci)
        c_psql_writer_t *tmp;
 
        int status = 0;
-       int i;
 
        if ((ci->values_num != 1)
                        || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
@@ -1162,7 +1150,7 @@ static int c_psql_config_writer (oconfig_item_t *ci)
        writer->statement = NULL;
        writer->store_rates = 1;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (strcasecmp ("Statement", c->key) == 0)
@@ -1188,25 +1176,19 @@ static int c_psql_config_database (oconfig_item_t *ci)
        c_psql_database_t *db;
 
        char cb_name[DATA_MAX_NAME_LEN];
-       user_data_t ud;
-
        static _Bool have_flush = 0;
 
-       int i;
-
        if ((1 != ci->values_num)
                        || (OCONFIG_TYPE_STRING != ci->values[0].type)) {
                log_err ("<Database> expects a single string argument.");
                return 1;
        }
 
-       memset (&ud, 0, sizeof (ud));
-
        db = c_psql_database_new (ci->values[0].value.string);
        if (db == NULL)
                return -1;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (0 == strcasecmp (c->key, "Host"))
@@ -1243,7 +1225,7 @@ static int c_psql_config_database (oconfig_item_t *ci)
 
        /* If no `Query' options were given, add the default queries.. */
        if ((db->queries_num == 0) && (db->writers_num == 0)){
-               for (i = 0; i < def_queries_num; i++)
+               for (int i = 0; i < def_queries_num; i++)
                        udb_query_pick_from_list_by_name (def_queries[i],
                                        queries, queries_num,
                                        &db->queries, &db->queries_num);
@@ -1260,7 +1242,7 @@ static int c_psql_config_database (oconfig_item_t *ci)
                }
        }
 
-       for (i = 0; (size_t)i < db->queries_num; ++i) {
+       for (int i = 0; (size_t)i < db->queries_num; ++i) {
                c_psql_user_data_t *data;
                data = udb_query_get_user_data (db->queries[i]);
                if ((data != NULL) && (data->params_num > db->max_params_num))
@@ -1276,11 +1258,13 @@ static int c_psql_config_database (oconfig_item_t *ci)
                }
        }
 
-       ud.data = db;
-       ud.free_func = c_psql_database_delete;
-
        ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->instance);
 
+       user_data_t ud = {
+               .data = db,
+               .free_func = c_psql_database_delete
+       };
+
        if (db->queries_num > 0) {
                ++db->ref_cnt;
                plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
@@ -1313,8 +1297,6 @@ static int c_psql_config (oconfig_item_t *ci)
 {
        static int have_def_config = 0;
 
-       int i;
-
        if (0 == have_def_config) {
                oconfig_item_t *c;
 
@@ -1331,7 +1313,7 @@ static int c_psql_config (oconfig_item_t *ci)
                                        "any queries - please check your installation.");
        }
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (0 == strcasecmp (c->key, "Query"))
index f72bd40..eb54180 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_llist.h"
 
 #include <sys/stat.h>
@@ -300,10 +300,10 @@ static char *local_sockpath = NULL;
 
 /* <https://doc.powerdns.com/md/recursor/stats/> */
 static void submit (const char *plugin_instance, /* {{{ */
-    const char *pdns_type, const char *value)
+    const char *pdns_type, const char *value_str)
 {
   value_list_t vl = VALUE_LIST_INIT;
-  value_t values[1];
+  value_t value;
 
   const char *type = NULL;
   const char *type_instance = NULL;
@@ -318,7 +318,7 @@ static void submit (const char *plugin_instance, /* {{{ */
   if (i >= lookup_table_length)
   {
     INFO ("powerdns plugin: submit: Not found in lookup table: %s = %s;",
-        pdns_type, value);
+        pdns_type, value_str);
     return;
   }
 
@@ -345,14 +345,14 @@ static void submit (const char *plugin_instance, /* {{{ */
     return;
   }
 
-  if (0 != parse_value (value, &values[0], ds->ds[0].type))
+  if (0 != parse_value (value_str, &value, ds->ds[0].type))
   {
     ERROR ("powerdns plugin: Cannot convert `%s' "
-        "to a number.", value);
+        "to a number.", value_str);
     return;
   }
 
-  vl.values = values;
+  vl.values = &value;
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "powerdns", sizeof (vl.plugin));
@@ -375,7 +375,7 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */
   char *buffer = NULL;
   size_t buffer_size = 0;
 
-  struct sockaddr_un sa_unix;
+  struct sockaddr_un sa_unix = { 0 };
 
   struct timeval stv_timeout;
   cdtime_t cdt_timeout;
@@ -387,7 +387,6 @@ static int powerdns_get_data_dgram (list_item_t *item, /* {{{ */
     return (-1);
   }
 
-  memset (&sa_unix, 0, sizeof (sa_unix));
   sa_unix.sun_family = AF_UNIX;
   sstrncpy (sa_unix.sun_path,
       (local_sockpath != NULL) ? local_sockpath : PDNS_LOCAL_SOCKPATH,
@@ -631,8 +630,6 @@ static int powerdns_read_server (list_item_t *item) /* {{{ */
   saveptr = NULL;
   while ((key = strtok_r (dummy, ",", &saveptr)) != NULL)
   {
-    int i;
-
     dummy = NULL;
 
     value = strchr (key, '=');
@@ -646,6 +643,7 @@ static int powerdns_read_server (list_item_t *item) /* {{{ */
       continue;
 
     /* Check if this item was requested. */
+    int i;
     for (i = 0; i < fields_num; i++)
       if (strcasecmp (key, fields[i]) == 0)
        break;
@@ -781,7 +779,6 @@ static int powerdns_read_recursor (list_item_t *item) /* {{{ */
 static int powerdns_config_add_collect (list_item_t *li, /* {{{ */
     oconfig_item_t *ci)
 {
-  int i;
   char **temp;
 
   if (ci->values_num < 1)
@@ -791,7 +788,7 @@ static int powerdns_config_add_collect (list_item_t *li, /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
     if (ci->values[i].type != OCONFIG_TYPE_STRING)
     {
       WARNING ("powerdns plugin: Only string arguments are allowed to "
@@ -808,7 +805,7 @@ static int powerdns_config_add_collect (list_item_t *li, /* {{{ */
   }
   li->fields = temp;
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     li->fields[li->fields_num] = strdup (ci->values[i].value.string);
     if (li->fields[li->fields_num] == NULL)
@@ -831,7 +828,6 @@ static int powerdns_config_add_server (oconfig_item_t *ci) /* {{{ */
 
   list_item_t *item;
   int status;
-  int i;
 
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
@@ -880,7 +876,7 @@ static int powerdns_config_add_server (oconfig_item_t *ci) /* {{{ */
   }
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -940,8 +936,6 @@ static int powerdns_config_add_server (oconfig_item_t *ci) /* {{{ */
 
 static int powerdns_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
   DEBUG ("powerdns plugin: powerdns_config (ci = %p);", (void *) ci);
 
   if (list == NULL)
@@ -955,7 +949,7 @@ static int powerdns_config (oconfig_item_t *ci) /* {{{ */
     }
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -988,9 +982,7 @@ static int powerdns_config (oconfig_item_t *ci) /* {{{ */
 
 static int powerdns_read (void)
 {
-  llentry_t *e;
-
-  for (e = llist_head (list); e != NULL; e = e->next)
+  for (llentry_t *e = llist_head (list); e != NULL; e = e->next)
   {
     list_item_t *item = e->value;
     item->func (item);
@@ -1001,12 +993,10 @@ static int powerdns_read (void)
 
 static int powerdns_shutdown (void)
 {
-  llentry_t *e;
-
   if (list == NULL)
     return (0);
 
-  for (e = llist_head (list); e != NULL; e = e->next)
+  for (llentry_t *e = llist_head (list); e != NULL; e = e->next)
   {
     list_item_t *item = (list_item_t *) e->value;
     e->value = NULL;
index f029a6c..f470c84 100644 (file)
@@ -35,9 +35,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 /* Include header files for the mach system, if they exist.. */
 #if HAVE_THREAD_INFO
@@ -390,13 +390,12 @@ static void ps_update_counter (_Bool init, derive_t *group_counter,
 /* 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)
 {
-       procstat_t *ps;
        procstat_entry_t *pse;
 
        if (entry->id == 0)
                return;
 
-       for (ps = list_head_g; ps != NULL; ps = ps->next)
+       for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next)
        {
                _Bool want_init;
 
@@ -482,11 +481,10 @@ static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t
 /* remove old entries from instances of processes in list_head_g */
 static void ps_list_reset (void)
 {
-       procstat_t *ps;
        procstat_entry_t *pse;
        procstat_entry_t *pse_prev;
 
-       for (ps = list_head_g; ps != NULL; ps = ps->next)
+       for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next)
        {
                ps->num_proc    = 0;
                ps->num_lwp     = 0;
@@ -538,15 +536,13 @@ static void ps_list_reset (void)
 /* put all pre-defined 'Process' names from config to list_head_g tree */
 static int ps_config (oconfig_item_t *ci)
 {
-       int i;
-
 #if KERNEL_LINUX
        const size_t max_procname_len = 15;
 #elif KERNEL_SOLARIS || KERNEL_FREEBSD
        const size_t max_procname_len = MAXCOMLEN -1;
 #endif
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (strcasecmp (c->key, "Process") == 0)
@@ -664,12 +660,9 @@ static int ps_init (void)
 /* submit global state (e.g.: qty of zombies, running, etc..) */
 static void ps_submit_state (const char *state, double value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "processes", sizeof (vl.plugin));
@@ -683,11 +676,10 @@ static void ps_submit_state (const char *state, double value)
 /* submit info about specific process (e.g.: memory taken, cpu usage, etc..) */
 static void ps_submit_proc_list (procstat_t *ps)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
+       value_t values[2];
 
        vl.values = values;
-       vl.values_len = 2;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "processes", sizeof (vl.plugin));
        sstrncpy (vl.plugin_instance, ps->name, sizeof (vl.plugin_instance));
@@ -788,12 +780,9 @@ static void ps_submit_proc_list (procstat_t *ps)
 #if KERNEL_LINUX || KERNEL_SOLARIS
 static void ps_submit_fork_rate (derive_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .derive = value };
        vl.values_len = 1;
        sstrncpy(vl.host, hostname_g, sizeof (vl.host));
        sstrncpy(vl.plugin, "processes", sizeof (vl.plugin));
@@ -1467,13 +1456,12 @@ static int ps_read_process(long pid, procstat_t *ps, char *state)
 static int read_fork_rate (void)
 {
        extern kstat_ctl_t *kc;
-       kstat_t *ksp_chain = NULL;
        derive_t result = 0;
 
        if (kc == NULL)
                return (-1);
 
-       for (ksp_chain = kc->kc_chain;
+       for (kstat_t *ksp_chain = kc->kc_chain;
                        ksp_chain != NULL;
                        ksp_chain = ksp_chain->ks_next)
        {
@@ -1539,17 +1527,14 @@ static int ps_read (void)
 #if HAVE_THREAD_INFO
        kern_return_t            status;
 
-       int                      pset;
        processor_set_t          port_pset_priv;
 
-       int                      task;
        task_array_t             task_list;
        mach_msg_type_number_t   task_list_len;
 
        int                      task_pid;
        char                     task_name[MAXCOMLEN + 1];
 
-       int                      thread;
        thread_act_array_t       thread_list;
        mach_msg_type_number_t   thread_list_len;
        thread_basic_info_data_t thread_data;
@@ -1574,7 +1559,7 @@ static int ps_read (void)
         * Tasks are assigned to sets of processors, so that's where you go to
         * get a list.
         */
-       for (pset = 0; pset < pset_list_len; pset++)
+       for (mach_msg_type_number_t pset = 0; pset < pset_list_len; pset++)
        {
                if ((status = host_processor_set_priv (port_host_self,
                                                pset_list[pset],
@@ -1595,7 +1580,7 @@ static int ps_read (void)
                        continue;
                }
 
-               for (task = 0; task < task_list_len; task++)
+               for (mach_msg_type_number_t task = 0; task < task_list_len; task++)
                {
                        ps = NULL;
                        if (mach_get_task_name (task_list[task],
@@ -1693,7 +1678,7 @@ static int ps_read (void)
                                continue; /* with next task_list */
                        }
 
-                       for (thread = 0; thread < thread_list_len; thread++)
+                       for (mach_msg_type_number_t thread = 0; thread < thread_list_len; thread++)
                        {
                                thread_data_len = THREAD_BASIC_INFO_COUNT;
                                status = thread_info (thread_list[thread],
@@ -1824,8 +1809,6 @@ static int ps_read (void)
        procstat_entry_t pse;
        char       state;
 
-       procstat_t *ps_ptr;
-
        running = sleeping = zombies = stopped = paging = blocked = 0;
        ps_list_reset ();
 
@@ -1906,7 +1889,7 @@ static int ps_read (void)
        ps_submit_state ("paging",   paging);
        ps_submit_state ("blocked",  blocked);
 
-       for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+       for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
                ps_submit_proc_list (ps_ptr);
 
        read_fork_rate();
@@ -1926,9 +1909,7 @@ static int ps_read (void)
        struct kinfo_proc *procs;          /* array of processes */
        struct kinfo_proc *proc_ptr = NULL;
        int count;                         /* returns number of processes */
-       int i;
 
-       procstat_t *ps_ptr;
        procstat_entry_t pse;
 
        ps_list_reset ();
@@ -1953,7 +1934,7 @@ static int ps_read (void)
        }
 
        /* Iterate through the processes in kinfo_proc */
-       for (i = 0; i < count; i++)
+       for (int i = 0; i < count; i++)
        {
                /* Create only one process list entry per _process_, i.e.
                 * filter out threads (duplicate PID entries). */
@@ -2056,7 +2037,7 @@ static int ps_read (void)
        ps_submit_state ("idle",     idle);
        ps_submit_state ("wait",     wait);
 
-       for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+       for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
                ps_submit_proc_list (ps_ptr);
 /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
 
@@ -2074,9 +2055,7 @@ static int ps_read (void)
        struct kinfo_proc *procs;          /* array of processes */
        struct kinfo_proc *proc_ptr = NULL;
        int count;                         /* returns number of processes */
-       int i;
 
-       procstat_t *ps_ptr;
        procstat_entry_t pse;
 
        ps_list_reset ();
@@ -2101,7 +2080,7 @@ static int ps_read (void)
        }
 
        /* Iterate through the processes in kinfo_proc */
-       for (i = 0; i < count; i++)
+       for (int i = 0; i < count; i++)
        {
                /* Create only one process list entry per _process_, i.e.
                 * filter out threads (duplicate PID entries). */
@@ -2193,7 +2172,7 @@ static int ps_read (void)
        ps_submit_state ("idle",     idle);
        ps_submit_state ("dead",     dead);
 
-       for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+       for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
                ps_submit_proc_list (ps_ptr);
 /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD */
 
@@ -2209,7 +2188,6 @@ static int ps_read (void)
        pid_t pindex = 0;
        int nprocs;
 
-       procstat_t *ps;
        procstat_entry_t pse;
 
        ps_list_reset ();
@@ -2217,9 +2195,7 @@ static int ps_read (void)
                                        /* fdsinfo = */ NULL, sizeof(struct fdsinfo64),
                                        &pindex, MAXPROCENTRY)) > 0)
        {
-               int i;
-
-               for (i = 0; i < nprocs; i++)
+               for (int i = 0; i < nprocs; i++)
                {
                        tid64_t thindex;
                        int nthreads;
@@ -2330,7 +2306,7 @@ static int ps_read (void)
        ps_submit_state ("paging",   paging);
        ps_submit_state ("blocked",  blocked);
 
-       for (ps = list_head_g; ps != NULL; ps = ps->next)
+       for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next)
                ps_submit_proc_list (ps);
 /* #endif HAVE_PROCINFO_H */
 
@@ -2354,7 +2330,6 @@ static int ps_read (void)
        DIR *proc;
 
        int status;
-       procstat_t *ps_ptr;
        char state;
 
        char cmdline[PRARGSZ];
@@ -2444,7 +2419,7 @@ static int ps_read (void)
        ps_submit_state ("system",   system);
        ps_submit_state ("orphan",   orphan);
 
-       for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+       for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
                ps_submit_proc_list (ps_ptr);
 
        read_fork_rate();
index 4d2b2ea..ae35c42 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_ignorelist.h"
@@ -54,11 +55,11 @@ static ignorelist_t *values_list = NULL;
 static void submit (const char *protocol_name,
     const char *str_key, const char *str_value)
 {
-  value_t values[1];
+  value_t value;
   value_list_t vl = VALUE_LIST_INIT;
   int status;
 
-  status = parse_value (str_value, values, DS_TYPE_DERIVE);
+  status = parse_value (str_value, &value, DS_TYPE_DERIVE);
   if (status != 0)
   {
     ERROR ("protocols plugin: Parsing string as integer failed: %s",
@@ -66,7 +67,7 @@ static void submit (const char *protocol_name,
     return;
   }
 
-  vl.values = values;
+  vl.values = &value;
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "protocols", sizeof (vl.plugin));
index 32b31cc..83748b4 100644 (file)
@@ -28,6 +28,7 @@
 #include <structmember.h>
 
 #include "collectd.h"
+
 #include "common.h"
 
 #include "cpython.h"
index 61d464d..5274262 100644 (file)
@@ -30,6 +30,7 @@
 #include <signal.h>
 
 #include "collectd.h"
+
 #include "common.h"
 
 #include "cpython.h"
@@ -196,7 +197,7 @@ static char reg_flush_doc[] = "register_flush(callback[, data][, name]) -> ident
                "The callback function will be called with two or three parameters:\n"
                "timeout: Indicates that only data older than 'timeout' seconds is to\n"
                "    be flushed.\n"
-               "id: Specifies which values are to be flushed.\n"
+               "id: Specifies which values are to be flushed. Might be None.\n"
                "data: The optional data parameter passed to the register function.\n"
                "    If the parameter was omitted it will be omitted here, too.";
 
@@ -218,7 +219,9 @@ static char reg_shutdown_doc[] = "register_shutdown(callback[, data][, name]) ->
                "    data if it was supplied.";
 
 
-static int do_interactive = 0;
+static pthread_t main_thread;
+static PyOS_sighandler_t python_sigint_handler;
+static _Bool do_interactive = 0;
 
 /* This is our global thread state. Python saves some stuff in thread-local
  * storage. So if we allow the interpreter to run in the background
@@ -233,12 +236,23 @@ static cpy_callback_t *cpy_config_callbacks;
 static cpy_callback_t *cpy_init_callbacks;
 static cpy_callback_t *cpy_shutdown_callbacks;
 
+/* Make sure to hold the GIL while modifying these. */
+static int cpy_shutdown_triggered = 0;
+static int cpy_num_callbacks = 0;
+
 static void cpy_destroy_user_data(void *data) {
        cpy_callback_t *c = data;
        free(c->name);
+       CPY_LOCK_THREADS
        Py_DECREF(c->callback);
        Py_XDECREF(c->data);
        free(c);
+       --cpy_num_callbacks;
+       if (!cpy_num_callbacks && cpy_shutdown_triggered) {
+               Py_Finalize();
+               return;
+       }
+       CPY_RELEASE_THREADS
 }
 
 /* You must hold the GIL to call this function!
@@ -270,7 +284,7 @@ static void cpy_build_name(char *buf, size_t size, PyObject *callback, const cha
 }
 
 void cpy_log_exception(const char *context) {
-       int l = 0, i;
+       int l = 0;
        const char *typename = NULL, *message = NULL;
        PyObject *type, *value, *traceback, *tn, *m, *list;
 
@@ -303,7 +317,7 @@ void cpy_log_exception(const char *context) {
        if (list)
                l = PyObject_Length(list);
 
-       for (i = 0; i < l; ++i) {
+       for (int i = 0; i < l; ++i) {
                PyObject *line;
                char const *msg;
                char *cpy;
@@ -352,7 +366,6 @@ static int cpy_read_callback(user_data_t *data) {
 }
 
 static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
-       size_t i;
        cpy_callback_t *c = data->data;
        PyObject *ret, *list, *temp, *dict = NULL;
        Values *v;
@@ -363,7 +376,7 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
                        cpy_log_exception("write callback");
                        CPY_RETURN_FROM_THREADS 0;
                }
-               for (i = 0; i < value_list->values_len; ++i) {
+               for (size_t i = 0; i < value_list->values_len; ++i) {
                        if (ds->ds[i].type == DS_TYPE_COUNTER) {
                                PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
                        } else if (ds->ds[i].type == DS_TYPE_GAUGE) {
@@ -387,12 +400,11 @@ 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 num;
                        char **table;
                        meta_data_t *meta = value_list->meta;
 
-                       num = meta_data_toc(meta, &table);
-                       for (i = 0; i < num; ++i) {
+                       int num = meta_data_toc(meta, &table);
+                       for (int i = 0; i < num; ++i) {
                                int type;
                                char *string;
                                int64_t si;
@@ -517,7 +529,12 @@ static void cpy_flush_callback(int timeout, const char *id, user_data_t *data) {
        PyObject *ret, *text;
 
        CPY_LOCK_THREADS
-       text = cpy_string_to_unicode_or_bytes(id);
+       if (id) {
+               text = cpy_string_to_unicode_or_bytes(id);
+       } else {
+               text = Py_None;
+               Py_INCREF(text);
+       }
        if (c->data == NULL)
                ret = PyObject_CallFunction(c->callback, "iN", timeout, text); /* New reference. */
        else
@@ -557,6 +574,7 @@ static PyObject *cpy_register_generic(cpy_callback_t **list_head, PyObject *args
        c->callback = callback;
        c->data = data;
        c->next = *list_head;
+       ++cpy_num_callbacks;
        *list_head = c;
        Py_XDECREF(mod);
        PyMem_Free(name);
@@ -571,7 +589,6 @@ static PyObject *float_or_none(float number) {
 }
 
 static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) {
-       size_t i;
        char *name;
        const data_set_t *ds;
        PyObject *list, *tuple;
@@ -584,7 +601,7 @@ static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) {
                return NULL;
        }
        list = PyList_New(ds->ds_num); /* New reference. */
-       for (i = 0; i < ds->ds_num; ++i) {
+       for (size_t i = 0; i < ds->ds_num; ++i) {
                tuple = PyTuple_New(4);
                PyTuple_SET_ITEM(tuple, 0, cpy_string_to_unicode_or_bytes(ds->ds[i].name));
                PyTuple_SET_ITEM(tuple, 1, cpy_string_to_unicode_or_bytes(DS_TYPE_TO_STRING(ds->ds[i].type)));
@@ -623,7 +640,6 @@ 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;
        char *name = NULL;
        PyObject *callback = NULL, *data = NULL;
        static char *kwlist[] = {"callback", "data", "name", NULL};
@@ -649,18 +665,18 @@ static PyObject *cpy_register_generic_userdata(void *reg, void *handler, PyObjec
        c->data = data;
        c->next = NULL;
 
-       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_t) {
+                               .data = c,
+                               .free_func = cpy_destroy_user_data,
+                       });
 
-       register_function(buf, handler, &user_data);
+       ++cpy_num_callbacks;
        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;
        double interval = 0;
        char *name = NULL;
        PyObject *callback = NULL, *data = NULL;
@@ -687,12 +703,13 @@ static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwd
        c->data = data;
        c->next = NULL;
 
-       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);
+                       cpy_read_callback, DOUBLE_TO_CDTIME_T (interval),
+                       &(user_data_t) {
+                               .data = c,
+                               .free_func = cpy_destroy_user_data,
+                       });
+       ++cpy_num_callbacks;
        return cpy_string_to_unicode_or_bytes(buf);
 }
 
@@ -798,8 +815,8 @@ static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, PyObject *ar
                PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
                return NULL;
        }
-       /* Yes, this is actually save. To call this function the caller has to
-        * hold the GIL. Well, save as long as there is only one GIL anyway ... */
+       /* Yes, this is actually safe. To call this function the caller has to
+        * hold the GIL. Well, safe as long as there is only one GIL anyway ... */
        if (prev == NULL)
                *list_head = tmp->next;
        else
@@ -808,6 +825,15 @@ static PyObject *cpy_unregister_generic(cpy_callback_t **list_head, PyObject *ar
        Py_RETURN_NONE;
 }
 
+static void cpy_unregister_list(cpy_callback_t **list_head) {
+       cpy_callback_t *cur, *next;
+       for (cur = *list_head; cur; cur = next) {
+               next = cur->next;
+               cpy_destroy_user_data(cur);
+       }
+       *list_head = NULL;
+}
+
 typedef int cpy_unregister_function_t(const char *name);
 
 static PyObject *cpy_unregister_generic_userdata(cpy_unregister_function_t *unreg, PyObject *arg, const char *desc) {
@@ -895,14 +921,21 @@ 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);
+       if (!state) {
+               printf("================================================================\n");
+               printf("collectd shutdown while running an interactive session. This will\n");
+               printf("probably leave your terminal in a mess.\n");
+               printf("Run the command \"reset\" to get it back into a usable state.\n");
+               printf("You can press Ctrl+D in the interactive session to\n");
+               printf("close collectd and avoid this problem in the future.\n");
+               printf("================================================================\n");
+       }
+
+       CPY_LOCK_THREADS
 
-       for (c = cpy_shutdown_callbacks; c; c = c->next) {
+       for (cpy_callback_t *c = cpy_shutdown_callbacks; c; c = c->next) {
                ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
                if (ret == NULL)
                        cpy_log_exception("shutdown callback");
@@ -910,17 +943,25 @@ static int cpy_shutdown(void) {
                        Py_DECREF(ret);
        }
        PyErr_Print();
-       Py_Finalize();
-       return 0;
-}
 
-static void cpy_int_handler(int sig) {
-       return;
+       Py_BEGIN_ALLOW_THREADS
+       cpy_unregister_list(&cpy_config_callbacks);
+       cpy_unregister_list(&cpy_init_callbacks);
+       cpy_unregister_list(&cpy_shutdown_callbacks);
+       cpy_shutdown_triggered = 1;
+       Py_END_ALLOW_THREADS
+
+       if (!cpy_num_callbacks) {
+               Py_Finalize();
+               return 0;
+       }
+
+       CPY_RELEASE_THREADS
+       return 0;
 }
 
-static void *cpy_interactive(void *data) {
-       sigset_t sigset;
-       struct sigaction sig_int_action, old;
+static void *cpy_interactive(void *pipefd) {
+       PyOS_sighandler_t cur_sig;
 
        /* Signal handler in a plugin? Bad stuff, but the best way to
         * handle it I guess. In an interactive session people will
@@ -930,83 +971,86 @@ static void *cpy_interactive(void *data) {
         * 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.
-        * 3. Unblock SIGINT in the interactive thread.
+        * 1. Restore Python's own signal handler
+        * 2. Tell Python we just forked so it will accept this thread
+        *    as the main one. No version of Python will ever handle
+        *    interrupts anywhere but in the main thread.
+        * 3. After the interactive loop is done, restore collectd's
+        *    SIGINT handler.
+        * 4. Raise SIGINT for a clean shutdown. The signal is sent to
+        *    the main thread to ensure it wakes up the main interval
+        *    sleep so that collectd shuts down immediately not in 10
+        *    seconds.
         *
         * This will make sure that SIGINT won't kill collectd but
-        * still interrupt syscalls like sleep and pause.
-        * It does not raise a KeyboardInterrupt exception because so
-        * far nobody managed to figure out how to do that. */
-       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);
-       PyEval_AcquireThread(state);
+        * still interrupt syscalls like sleep and pause. */
+
        if (PyImport_ImportModule("readline") == NULL) {
                /* This interactive session will suck. */
                cpy_log_exception("interactive session init");
        }
+       cur_sig = PyOS_setsig(SIGINT, python_sigint_handler);
+       PyOS_AfterFork();
+       PyEval_InitThreads();
+       close(*(int *) pipefd);
        PyRun_InteractiveLoop(stdin, "<stdin>");
+       PyOS_setsig(SIGINT, cur_sig);
        PyErr_Print();
-       PyEval_ReleaseThread(state);
+       state = PyEval_SaveThread();
        NOTICE("python: Interactive interpreter exited, stopping collectd ...");
-       /* Restore the original collectd SIGINT handler and raise SIGINT.
-        * The main thread still has SIGINT blocked and there's nothing we
-        * can do about that so this thread will handle it. But that's not
-        * important, except that it won't interrupt the main loop and so
-        * it might take a few seconds before collectd really shuts down. */
-       sigaction (SIGINT, &old, NULL);
-       raise(SIGINT);
-       pause();
+       pthread_kill(main_thread, SIGINT);
        return NULL;
 }
 
 static int cpy_init(void) {
-       cpy_callback_t *c;
        PyObject *ret;
+       int pipefd[2];
+       char buf;
        static pthread_t thread;
-       sigset_t sigset;
 
        if (!Py_IsInitialized()) {
                WARNING("python: Plugin loaded but not configured.");
                plugin_unregister_shutdown("python");
+               Py_Finalize();
                return 0;
        }
-       PyEval_InitThreads();
-       /* Now it's finally OK to use python threads. */
-       for (c = cpy_init_callbacks; c; c = c->next) {
+       main_thread = pthread_self();
+       if (do_interactive) {
+               if (pipe(pipefd)) {
+                       ERROR("python: Unable to create pipe.");
+                       return 1;
+               }
+               if (plugin_thread_create(&thread, NULL, cpy_interactive, pipefd + 1)) {
+                       ERROR("python: Error creating thread for interactive interpreter.");
+               }
+               if(read(pipefd[0], &buf, 1))
+                       ;
+               (void)close(pipefd[0]);
+       } else {
+               PyEval_InitThreads();
+               state = PyEval_SaveThread();
+       }
+       CPY_LOCK_THREADS
+       for (cpy_callback_t *c = cpy_init_callbacks; c; c = c->next) {
                ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
                if (ret == NULL)
                        cpy_log_exception("init callback");
                else
                        Py_DECREF(ret);
        }
-       sigemptyset(&sigset);
-       sigaddset(&sigset, SIGINT);
-       pthread_sigmask(SIG_BLOCK, &sigset, NULL);
-       state = PyEval_SaveThread();
-       if (do_interactive) {
-               if (plugin_thread_create(&thread, NULL, cpy_interactive, NULL)) {
-                       ERROR("python: Error creating thread for interactive interpreter.");
-               }
-       }
+       CPY_RELEASE_THREADS
 
        return 0;
 }
 
 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) {
+       for (int i = 0; i < ci->values_num; ++i) {
                if (ci->values[i].type == OCONFIG_TYPE_STRING) {
                        PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes(ci->values[i].value.string));
                } else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) {
@@ -1021,7 +1065,7 @@ static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
        if (item == NULL)
                return NULL;
        children = PyTuple_New(ci->children_num); /* New reference. */
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                PyTuple_SET_ITEM(children, i, cpy_oconfig_to_pyconfig(ci->children + i, item));
        }
        tmp = ((Config *) item)->children;
@@ -1045,6 +1089,7 @@ PyMODINIT_FUNC PyInit_collectd(void) {
 #endif
 
 static int cpy_init_python(void) {
+       PyOS_sighandler_t cur_sig;
        PyObject *sys;
        PyObject *module;
 
@@ -1056,7 +1101,10 @@ static int cpy_init_python(void) {
        char *argv = "";
 #endif
 
+       /* Chances are the current signal handler is already SIG_DFL, but let's make sure. */
+       cur_sig = PyOS_setsig(SIGINT, SIG_DFL);
        Py_Initialize();
+       python_sigint_handler = PyOS_setsig(SIGINT, cur_sig);
 
        PyType_Ready(&ConfigType);
        PyType_Ready(&PluginDataType);
@@ -1108,8 +1156,8 @@ static int cpy_init_python(void) {
 }
 
 static int cpy_config(oconfig_item_t *ci) {
-       int i;
        PyObject *tb;
+       int status = 0;
 
        /* Ok in theory we shouldn't do initialization at this point
         * but we have to. In order to give python scripts a chance
@@ -1120,27 +1168,40 @@ static int cpy_config(oconfig_item_t *ci) {
 
        if (!Py_IsInitialized() && cpy_init_python()) return 1;
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int 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)
+                       if (cf_util_get_boolean(item, &do_interactive) != 0) {
+                               status = 1;
                                continue;
-                       do_interactive = item->values[0].value.boolean;
+                       }
                } else if (strcasecmp(item->key, "Encoding") == 0) {
-                       if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_STRING)
+                       char *encoding = NULL;
+                       if (cf_util_get_string(item, &encoding) != 0) {
+                               status = 1;
                                continue;
+                       }
 #ifdef IS_PY3K
-                       NOTICE("python: \"Encoding\" was used in the config file but Python3 was used, which does not support changing encodings. Ignoring this.");
+                       ERROR("python: \"Encoding\" was used in the config file but Python3 was used, which does not support changing encodings");
+                       status = 1;
+                       sfree(encoding);
+                       continue;
 #else
                        /* Why is this even necessary? And undocumented? */
-                       if (PyUnicode_SetDefaultEncoding(item->values[0].value.string))
+                       if (PyUnicode_SetDefaultEncoding(encoding)) {
                                cpy_log_exception("setting default encoding");
+                               status = 1;
+                       }
 #endif
+                       sfree(encoding);
                } else if (strcasecmp(item->key, "LogTraces") == 0) {
-                       if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
+                       _Bool log_traces;
+                       if (cf_util_get_boolean(item, &log_traces) != 0) {
+                               status = 1;
                                continue;
-                       if (!item->values[0].value.boolean) {
+                       }
+                       if (!log_traces) {
                                Py_XDECREF(cpy_format_exception);
                                cpy_format_exception = NULL;
                                continue;
@@ -1150,30 +1211,37 @@ static int cpy_config(oconfig_item_t *ci) {
                        tb = PyImport_ImportModule("traceback"); /* New reference. */
                        if (tb == NULL) {
                                cpy_log_exception("python initialization");
+                               status = 1;
                                continue;
                        }
                        cpy_format_exception = PyObject_GetAttrString(tb, "format_exception"); /* New reference. */
                        Py_DECREF(tb);
-                       if (cpy_format_exception == NULL)
+                       if (cpy_format_exception == NULL) {
                                cpy_log_exception("python initialization");
+                               status = 1;
+                       }
                } 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) {
+                               status = 1;
                                continue;
+                       }
                        dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */
                        if (dir_object == NULL) {
                                ERROR("python plugin: Unable to convert \"%s\" to "
                                      "a python object.", dir);
                                free(dir);
                                cpy_log_exception("python initialization");
+                               status = 1;
                                continue;
                        }
                        if (PyList_Insert(sys_path, 0, dir_object) != 0) {
                                ERROR("python plugin: Unable to prepend \"%s\" to "
                                      "python module path.", dir);
                                cpy_log_exception("python initialization");
+                               status = 1;
                        }
                        Py_DECREF(dir_object);
                        free(dir);
@@ -1181,12 +1249,15 @@ static int cpy_config(oconfig_item_t *ci) {
                        char *module_name = NULL;
                        PyObject *module;
 
-                       if (cf_util_get_string(item, &module_name) != 0)
+                       if (cf_util_get_string(item, &module_name) != 0) {
+                               status = 1;
                                continue;
+                       }
                        module = PyImport_ImportModule(module_name); /* New reference. */
                        if (module == NULL) {
                                ERROR("python plugin: Error importing module \"%s\".", module_name);
                                cpy_log_exception("importing module");
+                               status = 1;
                        }
                        free(module_name);
                        Py_XDECREF(module);
@@ -1195,8 +1266,10 @@ static int cpy_config(oconfig_item_t *ci) {
                        cpy_callback_t *c;
                        PyObject *ret;
 
-                       if (cf_util_get_string(item, &name) != 0)
+                       if (cf_util_get_string(item, &name) != 0) {
+                               status = 1;
                                continue;
+                       }
                        for (c = cpy_config_callbacks; c; c = c->next) {
                                if (strcasecmp(c->name + 7, name) == 0)
                                        break;
@@ -1215,15 +1288,17 @@ static int cpy_config(oconfig_item_t *ci) {
                        else
                                ret = PyObject_CallFunction(c->callback, "NO",
                                        cpy_oconfig_to_pyconfig(item, NULL), c->data); /* New reference. */
-                       if (ret == NULL)
+                       if (ret == NULL) {
                                cpy_log_exception("loading module");
-                       else
+                               status = 1;
+                       } else
                                Py_DECREF(ret);
                } else {
-                       WARNING("python plugin: Ignoring unknown config key \"%s\".", item->key);
+                       ERROR("python plugin: Unknown config key \"%s\".", item->key);
+                       status = 1;
                }
        }
-       return 0;
+       return (status);
 }
 
 void module_register(void) {
index 0ba0436..a7cb792 100644 (file)
@@ -28,6 +28,7 @@
 #include <structmember.h>
 
 #include "collectd.h"
+
 #include "common.h"
 
 #include "cpython.h"
@@ -415,7 +416,7 @@ static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) {
 }
 
 static meta_data_t *cpy_build_meta(PyObject *meta) {
-       int i, s;
+       int s;
        meta_data_t *m = NULL;
        PyObject *l;
 
@@ -434,7 +435,7 @@ static meta_data_t *cpy_build_meta(PyObject *meta) {
        }
 
        m = meta_data_create();
-       for (i = 0; i < s; ++i) {
+       for (int i = 0; i < s; ++i) {
                const char *string, *keystring;
                PyObject *key, *value, *item, *tmp;
 
@@ -504,7 +505,7 @@ static meta_data_t *cpy_build_meta(PyObject *meta) {
 static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
        int ret;
        const data_set_t *ds;
-       size_t size, i;
+       size_t size;
        value_t *value;
        value_list_t value_list = VALUE_LIST_INIT;
        PyObject *values = self->values, *meta = self->meta;
@@ -548,22 +549,25 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
                return NULL;
        }
        value = calloc(size, sizeof(*value));
-       for (i = 0; i < size; ++i) {
+       for (size_t i = 0; i < size; ++i) {
                PyObject *item, *num;
                item = PySequence_Fast_GET_ITEM(values, (int) i); /* Borrowed reference. */
-               if (ds->ds->type == DS_TYPE_COUNTER) {
+               switch (ds->ds[i].type) {
+               case DS_TYPE_COUNTER:
                        num = PyNumber_Long(item); /* New reference. */
                        if (num != NULL) {
                                value[i].counter = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_GAUGE) {
+                       break;
+               case DS_TYPE_GAUGE:
                        num = PyNumber_Float(item); /* New reference. */
                        if (num != NULL) {
                                value[i].gauge = PyFloat_AsDouble(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_DERIVE) {
+                       break;
+               case DS_TYPE_DERIVE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -571,7 +575,8 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].derive = PyLong_AsLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+                       break;
+               case DS_TYPE_ABSOLUTE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -579,9 +584,10 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].absolute = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else {
+                       break;
+               default:
                        free(value);
-                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
                        return NULL;
                }
                if (PyErr_Occurred() != NULL) {
@@ -613,7 +619,7 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
 static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
        int ret;
        const data_set_t *ds;
-       size_t size, i;
+       size_t size;
        value_t *value;
        value_list_t value_list = VALUE_LIST_INIT;
        PyObject *values = self->values, *meta = self->meta;
@@ -652,22 +658,25 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
                return NULL;
        }
        value = calloc(size, sizeof(*value));
-       for (i = 0; i < size; ++i) {
+       for (size_t i = 0; i < size; ++i) {
                PyObject *item, *num;
                item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
-               if (ds->ds->type == DS_TYPE_COUNTER) {
+               switch (ds->ds[i].type) {
+               case DS_TYPE_COUNTER:
                        num = PyNumber_Long(item); /* New reference. */
                        if (num != NULL) {
                                value[i].counter = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_GAUGE) {
+                       break;
+               case DS_TYPE_GAUGE:
                        num = PyNumber_Float(item); /* New reference. */
                        if (num != NULL) {
                                value[i].gauge = PyFloat_AsDouble(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_DERIVE) {
+                       break;
+               case DS_TYPE_DERIVE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -675,7 +684,8 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].derive = PyLong_AsLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+                       break;
+               case DS_TYPE_ABSOLUTE:
                        /* This might overflow without raising an exception.
                         * Not much we can do about it */
                        num = PyNumber_Long(item); /* New reference. */
@@ -683,9 +693,10 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
                                value[i].absolute = PyLong_AsUnsignedLongLong(num);
                                Py_XDECREF(num);
                        }
-               } else {
+                       break;
+               default:
                        free(value);
-                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+                       PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
                        return NULL;
                }
                if (PyErr_Occurred() != NULL) {
index 2d0bd95..7f57571 100644 (file)
@@ -21,9 +21,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include <sys/time.h>
 #include <hiredis/hiredis.h>
@@ -125,7 +125,6 @@ static redis_query_t *redis_config_query (oconfig_item_t *ci) /* {{{ */
 {
     redis_query_t *rq;
     int status;
-    int i;
 
     rq = calloc(1, sizeof(*rq));
     if (rq == NULL) {
@@ -143,7 +142,7 @@ static redis_query_t *redis_config_query (oconfig_item_t *ci) /* {{{ */
     (void)sstrncpy(rq->instance, rq->query, sizeof(rq->instance));
     replace_special(rq->instance, sizeof(rq->instance));
 
-    for (i = 0; i < ci->children_num; i++) {
+    for (int i = 0; i < ci->children_num; i++) {
         oconfig_item_t *option = ci->children + i;
 
         if (strcasecmp("Type", option->key) == 0) {
@@ -165,23 +164,22 @@ static redis_query_t *redis_config_query (oconfig_item_t *ci) /* {{{ */
 
 static int redis_config_node (oconfig_item_t *ci) /* {{{ */
 {
-  redis_node_t rn;
   redis_query_t *rq;
-  int i;
   int status;
   int timeout;
 
-  memset (&rn, 0, sizeof (rn));
+  redis_node_t rn = {
+    .port = REDIS_DEF_PORT,
+    .timeout.tv_usec = REDIS_DEF_TIMEOUT
+  };
+
   sstrncpy (rn.host, REDIS_DEF_HOST, sizeof (rn.host));
-  rn.port = REDIS_DEF_PORT;
-  rn.timeout.tv_usec = REDIS_DEF_TIMEOUT;
-  rn.queries = NULL;
 
   status = cf_util_get_string_buffer (ci, rn.name, sizeof (rn.name));
   if (status != 0)
     return (status);
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -229,9 +227,7 @@ static int redis_config_node (oconfig_item_t *ci) /* {{{ */
 
 static int redis_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -256,12 +252,9 @@ static void redis_submit (char *plugin_instance,
     const char *type, const char *type_instance,
     value_t value) /* {{{ */
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  values[0] = value;
-
-  vl.values = values;
+  vl.values = &value;
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "redis", sizeof (vl.plugin));
@@ -379,10 +372,7 @@ static int redis_handle_query (redisContext *rh, redis_node_t *rn, redis_query_t
 
 static int redis_read (void) /* {{{ */
 {
-  redis_node_t *rn;
-  redis_query_t *rq;
-
-  for (rn = nodes_head; rn != NULL; rn = rn->next)
+  for (redis_node_t *rn = nodes_head; rn != NULL; rn = rn->next)
   {
     redisContext *rh;
     redisReply   *rr;
@@ -441,7 +431,7 @@ static int redis_read (void) /* {{{ */
     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)
+    for (redis_query_t *rq = rn->queries; rq != NULL; rq = rq->next)
         redis_handle_query(rh, rn, rq);
 
 redis_fail:
index 7ee3024..5e8a294 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -51,11 +52,11 @@ typedef struct cr_data_s cr_data_t;
 static void cr_submit_io (cr_data_t *rd, const char *type, /* {{{ */
     const char *type_instance, derive_t rx, derive_t tx)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = rx;
-       values[1].derive = tx;
+       value_t values[] = {
+         { .derive = rx },
+         { .derive = tx },
+       };
 
        vl.values = values;
        vl.values_len = STATIC_ARRAY_SIZE (values);
@@ -324,9 +325,7 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */
 {
   cr_data_t *router_data;
   char read_name[128];
-  user_data_t user_data;
   int status;
-  int i;
 
   router_data = calloc (1, sizeof (*router_data));
   if (router_data == NULL)
@@ -338,7 +337,7 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */
   router_data->password = NULL;
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -409,11 +408,12 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */
   }
 
   ssnprintf (read_name, sizeof (read_name), "routeros/%s", router_data->node);
-  user_data.data = router_data;
-  user_data.free_func = (void *) cr_free_data;
   if (status == 0)
     status = plugin_register_complex_read (/* group = */ NULL, read_name,
-       cr_read, /* interval = */ 0, &user_data);
+        cr_read, /* interval = */ 0, &(user_data_t) {
+          .data = router_data,
+          .free_func = (void *) cr_free_data,
+        });
 
   if (status != 0)
     cr_free_data (router_data);
@@ -423,9 +423,7 @@ static int cr_config_router (oconfig_item_t *ci) /* {{{ */
 
 static int cr_config (oconfig_item_t *ci)
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
index 3a6c985..07eac7b 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "utils_rrdcreate.h"
@@ -69,7 +70,6 @@ static int value_list_to_string (char *buffer, int buffer_len,
 {
   int offset;
   int status;
-  size_t i;
   time_t t;
 
   assert (0 == strcmp (ds->type, vl->type));
@@ -82,7 +82,7 @@ static int value_list_to_string (char *buffer, int buffer_len,
     return (-1);
   offset = status;
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     if ((ds->ds[i].type != DS_TYPE_COUNTER)
         && (ds->ds[i].type != DS_TYPE_GAUGE)
@@ -217,9 +217,7 @@ static int rc_config_add_timespan (int timespan)
 
 static int rc_config (oconfig_item_t *ci)
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t const *child = ci->children + i;
     const char *key = child->key;
@@ -293,10 +291,10 @@ static int rc_read (void)
 {
   int status;
   rrdc_stats_t *head;
-  rrdc_stats_t *ptr;
 
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
+  vl.values = &(value_t) { .gauge = NAN };
+  vl.values_len = 1;
 
   if (daemon_address == NULL)
     return (-1);
@@ -304,9 +302,6 @@ static int rc_read (void)
   if (!config_collect_stats)
     return (-1);
 
-  vl.values = values;
-  vl.values_len = 1;
-
   if ((strncmp ("unix:", daemon_address, strlen ("unix:")) == 0)
       || (daemon_address[0] == '/'))
     sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -330,12 +325,12 @@ static int rc_read (void)
     return (-1);
   }
 
-  for (ptr = head; ptr != NULL; ptr = ptr->next)
+  for (rrdc_stats_t *ptr = head; ptr != NULL; ptr = ptr->next)
   {
     if (ptr->type == RRDC_STATS_TYPE_GAUGE)
-      values[0].gauge = (gauge_t) ptr->value.gauge;
+      vl.values[0].gauge = (gauge_t) ptr->value.gauge;
     else if (ptr->type == RRDC_STATS_TYPE_COUNTER)
-      values[0].counter = (counter_t) ptr->value.counter;
+      vl.values[0].counter = (counter_t) ptr->value.counter;
     else
       continue;
 
index 348f287..094dd42 100644 (file)
@@ -24,6 +24,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "utils_avltree.h"
@@ -200,7 +201,6 @@ static int value_list_to_string_multiple (char *buffer, int buffer_len,
        int offset;
        int status;
        time_t tt;
-       size_t i;
 
        memset (buffer, '\0', buffer_len);
 
@@ -210,7 +210,7 @@ static int value_list_to_string_multiple (char *buffer, int buffer_len,
                return (-1);
        offset = status;
 
-       for (i = 0; i < ds->ds_num; i++)
+       for (size_t i = 0; i < ds->ds_num; i++)
        {
                if ((ds->ds[i].type != DS_TYPE_COUNTER)
                                && (ds->ds[i].type != DS_TYPE_GAUGE)
@@ -331,7 +331,6 @@ static void *rrd_queue_thread (void __attribute__((unused)) *data)
                char **values;
                int    values_num;
                int    status;
-               int    i;
 
                values = NULL;
                values_num = 0;
@@ -412,7 +411,7 @@ static void *rrd_queue_thread (void __attribute__((unused)) *data)
                pthread_mutex_unlock (&queue_lock);
 
                /* We now need the cache lock so the entry isn't updated while
-                * we make a copy of it's values */
+                * we make a copy of its values */
                pthread_mutex_lock (&cache_lock);
 
                status = c_avl_get (cache, queue_entry->filename,
@@ -458,7 +457,7 @@ static void *rrd_queue_thread (void __attribute__((unused)) *data)
                                values_num, (values_num == 1) ? "" : "s",
                                queue_entry->filename);
 
-               for (i = 0; i < values_num; i++)
+               for (int i = 0; i < values_num; i++)
                {
                        sfree (values[i]);
                }
@@ -556,7 +555,6 @@ static void rrd_cache_flush (cdtime_t timeout)
 
        char *key;
        c_avl_iterator_t *iter;
-       int i;
 
        DEBUG ("rrdtool plugin: Flushing cache, timeout = %.3f",
                        CDTIME_T_TO_DOUBLE (timeout));
@@ -604,7 +602,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++)
+       for (int i = 0; i < keys_num; i++)
        {
                if (c_avl_remove (cache, keys[i], (void *) &key, (void *) &rc) != 0)
                {
@@ -856,7 +854,6 @@ static int rrd_cache_destroy (void) /* {{{ */
   while (c_avl_pick (cache, &key, &value) == 0)
   {
     rrd_cache_t *rc;
-    int i;
 
     sfree (key);
     key = NULL;
@@ -867,7 +864,7 @@ static int rrd_cache_destroy (void) /* {{{ */
     if (rc->values_num > 0)
       non_empty++;
 
-    for (i = 0; i < rc->values_num; i++)
+    for (int i = 0; i < rc->values_num; i++)
       sfree (rc->values[i]);
     sfree (rc->values);
     sfree (rc);
index 63a1c8e..f13b3ea 100644 (file)
@@ -34,9 +34,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_ignorelist.h"
 
 #if defined(HAVE_SENSORS_SENSORS_H)
@@ -215,11 +215,9 @@ static int sensors_snprintf_chip_name (char *buf, size_t buf_size,
 
 static int sensors_feature_name_to_type (const char *name)
 {
-       int i;
-
        /* Yes, this is slow, but it's only ever done during initialization, so
         * it's a one time cost.. */
-       for (i = 0; i < known_features_num; i++)
+       for (int i = 0; i < known_features_num; i++)
                if (strcasecmp (known_features[i].label, name) == 0)
                        return (known_features[i].type);
 
@@ -275,7 +273,6 @@ static int sensors_config (const char *key, const char *value)
 
 static void sensors_free_features (void)
 {
-       featurelist_t *thisft;
        featurelist_t *nextft;
 
        if (first_feature == NULL)
@@ -283,7 +280,7 @@ static void sensors_free_features (void)
 
        sensors_cleanup ();
 
-       for (thisft = first_feature; thisft != NULL; thisft = nextft)
+       for (featurelist_t *thisft = first_feature; thisft != NULL; thisft = nextft)
        {
                nextft = thisft->next;
                sfree (thisft);
@@ -484,12 +481,11 @@ static int sensors_shutdown (void)
 
 static void sensors_submit (const char *plugin_instance,
                const char *type, const char *type_instance,
-               double val)
+               double value)
 {
        char match_key[1024];
        int status;
 
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
        status = ssnprintf (match_key, sizeof (match_key), "%s/%s-%s",
@@ -504,9 +500,7 @@ static void sensors_submit (const char *plugin_instance,
                        return;
        }
 
-       values[0].gauge = val;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -521,13 +515,11 @@ static void sensors_submit (const char *plugin_instance,
 
 static int sensors_read (void)
 {
-       featurelist_t *fl;
-
        if (sensors_load_conf () != 0)
                return (-1);
 
 #if SENSORS_API_VERSION < 0x400
-       for (fl = first_feature; fl != NULL; fl = fl->next)
+       for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next)
        {
                double value;
                int status;
@@ -555,7 +547,7 @@ static int sensors_read (void)
 /* #endif SENSORS_API_VERSION < 0x400 */
 
 #elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500)
-       for (fl = first_feature; fl != NULL; fl = fl->next)
+       for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next)
        {
                double value;
                int status;
index 0878d3c..4822320 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
 static void serial_submit (const char *type_instance,
                derive_t rx, derive_t tx)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = rx;
-       values[1].derive = tx;
+       value_t values[] = {
+               { .derive = rx },
+               { .derive = tx },
+       };
 
        vl.values = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "serial", sizeof (vl.plugin));
        sstrncpy (vl.type, "serial_octets", sizeof (vl.type));
@@ -73,7 +74,6 @@ static int serial_read (void)
 
                char *fields[16];
                int numfields;
-               int i;
 
                numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
                if (numfields < 6)
@@ -90,7 +90,7 @@ static int serial_read (void)
                        continue;
                fields[0][len - 1] = 0;
 
-               for (i = 1; i < numfields; i++)
+               for (int i = 1; i < numfields; i++)
                {
                        len = strlen (fields[i]);
                        if (len < 4)
index d8c65c0..5b85004 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -69,7 +70,6 @@ static int sigrok_log_callback(void*cb_data __attribute__((unused)),
 static int sigrok_config_device(oconfig_item_t *ci)
 {
        struct config_device *cfdev;
-       int i;
 
        if (!(cfdev = calloc(1, sizeof(*cfdev)))) {
                ERROR("sigrok plugin: calloc failed.");
@@ -82,7 +82,7 @@ static int sigrok_config_device(oconfig_item_t *ci)
        }
        cfdev->min_dispatch_interval = DEFAULT_MIN_DISPATCH_INTERVAL;
 
-       for (i = 0; i < ci->children_num; i++) {
+       for (int i = 0; i < ci->children_num; i++) {
                oconfig_item_t *item = ci->children + i;
                if (!strcasecmp(item->key, "driver"))
                        cf_util_get_string(item, &cfdev->driver);
@@ -104,9 +104,7 @@ static int sigrok_config_device(oconfig_item_t *ci)
 
 static int sigrok_config(oconfig_item_t *ci)
 {
-       int i;
-
-       for (i = 0; i < ci->children_num; i++) {
+       for (int i = 0; i < ci->children_num; i++) {
                oconfig_item_t *item = ci->children + i;
                if (strcasecmp("LogLevel", item->key) == 0) {
                        int status;
@@ -163,13 +161,11 @@ static void sigrok_feed_callback(const struct sr_dev_inst *sdi,
 {
        const struct sr_datafeed_analog *analog;
        struct config_device *cfdev;
-       GSList *l;
-       value_t value;
        value_list_t vl = VALUE_LIST_INIT;
 
        /* Find this device's configuration. */
        cfdev = NULL;
-       for (l = config_devices; l; l = l->next) {
+       for (GSList *l = config_devices; l; l = l->next) {
                cfdev = l->data;
                if (cfdev->sdi == sdi) {
                        /* Found it. */
@@ -202,8 +198,7 @@ static void sigrok_feed_callback(const struct sr_dev_inst *sdi,
 
        /* Ignore all but the first sample on the first probe. */
        analog = packet->payload;
-       value.gauge = analog->data[0];
-       vl.values = &value;
+       vl.values = &(value_t) { .gauge = analog->data[0] };
        vl.values_len = 1;
        sstrncpy(vl.host, hostname_g, sizeof(vl.host));
        sstrncpy(vl.plugin, "sigrok", sizeof(vl.plugin));
index 33b9751..52e78a1 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_ignorelist.h"
@@ -85,12 +86,9 @@ static int smart_config (const char *key, const char *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;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "smart", sizeof (vl.plugin));
@@ -105,17 +103,20 @@ static void smart_handle_disk_attribute(SkDisk *d, const SkSmartAttributeParsedD
                                         void* userdata)
 {
   const char *dev = userdata;
-  value_t values[4];
-  value_list_t vl = VALUE_LIST_INIT;
 
-  if (!a->current_value_valid || !a->worst_value_valid) return;
-  values[0].gauge = a->current_value;
-  values[1].gauge = a->worst_value;
-  values[2].gauge = a->threshold_valid?a->threshold:0;
-  values[3].gauge = a->pretty_value;
+  if (!a->current_value_valid || !a->worst_value_valid)
+    return;
+
+  value_list_t vl = VALUE_LIST_INIT;
+  value_t values[] = {
+    { .gauge = a->current_value },
+    { .gauge = a->worst_value },
+    { .gauge = a->threshold_valid ? a->threshold : 0 },
+    { .gauge = a->pretty_value },
+  };
 
   vl.values = values;
-  vl.values_len = 4;
+  vl.values_len = STATIC_ARRAY_SIZE (values);
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "smart", sizeof (vl.plugin));
   sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
index 6a5bb8b..d80ee92 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_complain.h"
@@ -164,9 +165,8 @@ static int csnmp_oid_to_string (char *buffer, size_t buffer_size,
 {
   char oid_str[MAX_OID_LEN][16];
   char *oid_str_ptr[MAX_OID_LEN];
-  size_t i;
 
-  for (i = 0; i < o->oid_len; i++)
+  for (size_t i = 0; i < o->oid_len; i++)
   {
     ssnprintf (oid_str[i], sizeof (oid_str[i]), "%lu", (unsigned long) o->oid[i]);
     oid_str_ptr[i] = oid_str[i];
@@ -291,15 +291,13 @@ static int csnmp_config_add_data_instance_prefix (data_definition_t *dd,
 
 static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *ci)
 {
-  int i;
-
   if (ci->values_num < 1)
   {
     WARNING ("snmp plugin: `Values' needs at least one argument.");
     return (-1);
   }
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
     if (ci->values[i].type != OCONFIG_TYPE_STRING)
     {
       WARNING ("snmp plugin: `Values' needs only string argument.");
@@ -313,7 +311,7 @@ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *
     return (-1);
   dd->values_len = (size_t) ci->values_num;
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     dd->values[i].oid_len = MAX_OID_LEN;
 
@@ -334,12 +332,10 @@ static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *
 
 static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t *ci)
 {
-  int i;
-
   if (ci->values_num < 1)
     return (0);
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     if (ci->values[i].type != OCONFIG_TYPE_STRING)
     {
@@ -351,7 +347,7 @@ static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t
   dd->ignores_len = 0;
   dd->ignores = NULL;
 
-  for (i = 0; i < ci->values_num; ++i)
+  for (int i = 0; i < ci->values_num; ++i)
   {
     if (strarray_add(&(dd->ignores), &(dd->ignores_len), ci->values[i].value.string) != 0)
     {
@@ -380,7 +376,6 @@ static int csnmp_config_add_data (oconfig_item_t *ci)
 {
   data_definition_t *dd;
   int status = 0;
-  int i;
 
   dd = calloc (1, sizeof (*dd));
   if (dd == NULL)
@@ -396,7 +391,7 @@ static int csnmp_config_add_data (oconfig_item_t *ci)
   dd->scale = 1.0;
   dd->shift = 0.0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -502,7 +497,6 @@ static int csnmp_config_add_host_collect (host_definition_t *host,
   data_definition_t *data;
   data_definition_t **data_list;
   int data_list_len;
-  int i;
 
   if (ci->values_num < 1)
   {
@@ -510,7 +504,7 @@ static int csnmp_config_add_host_collect (host_definition_t *host,
     return (-1);
   }
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
     if (ci->values[i].type != OCONFIG_TYPE_STRING)
     {
       WARNING ("snmp plugin: All arguments to `Collect' must be strings.");
@@ -524,7 +518,7 @@ static int csnmp_config_add_host_collect (host_definition_t *host,
     return (-1);
   host->data_list = data_list;
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     for (data = data_head; data != NULL; data = data->next)
       if (strcasecmp (ci->values[i].value.string, data->name) == 0)
@@ -637,11 +631,9 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
 {
   host_definition_t *hd;
   int status = 0;
-  int i;
 
   /* Registration stuff. */
   char cb_name[DATA_MAX_NAME_LEN];
-  user_data_t cb_data;
 
   hd = calloc (1, sizeof (*hd));
   if (hd == NULL)
@@ -659,7 +651,7 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
   hd->sess_handle = NULL;
   hd->interval = 0;
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
     status = 0;
@@ -772,12 +764,11 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
 
   ssnprintf (cb_name, sizeof (cb_name), "snmp-%s", hd->name);
 
-  memset (&cb_data, 0, sizeof (cb_data));
-  cb_data.data = hd;
-  cb_data.free_func = csnmp_host_definition_destroy;
-
   status = plugin_register_complex_read (/* group = */ NULL, cb_name,
-      csnmp_read_host, hd->interval, /* user_data = */ &cb_data);
+      csnmp_read_host, hd->interval, &(user_data_t) {
+        .data = hd,
+        .free_func = csnmp_host_definition_destroy,
+      });
   if (status != 0)
   {
     ERROR ("snmp plugin: Registering complex read function failed.");
@@ -790,11 +781,9 @@ static int csnmp_config_add_host (oconfig_item_t *ci)
 
 static int csnmp_config (oconfig_item_t *ci)
 {
-  int i;
-
   call_snmp_init_once ();
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
     if (strcasecmp ("Data", child->key) == 0)
@@ -942,9 +931,8 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type,
   }
   else
   {
-    char oid_buffer[1024];
+    char oid_buffer[1024] = { 0 };
 
-    memset (oid_buffer, 0, sizeof (oid_buffer));
     snprint_objid (oid_buffer, sizeof (oid_buffer) - 1,
         vl->name, vl->name_length);
 
@@ -1056,14 +1044,13 @@ static int csnmp_strvbcopy_hexstring (char *dst, /* {{{ */
 {
   char *buffer_ptr;
   size_t buffer_free;
-  size_t i;
 
   dst[0] = 0;
 
   buffer_ptr = dst;
   buffer_free = dst_size;
 
-  for (i = 0; i < vb->val_len; i++)
+  for (size_t i = 0; i < vb->val_len; i++)
   {
     int status;
 
@@ -1096,7 +1083,6 @@ static int csnmp_strvbcopy (char *dst, /* {{{ */
 {
   char *src;
   size_t num_chars;
-  size_t i;
 
   if (vb->type == ASN_OCTET_STR)
     src = (char *) vb->val.string;
@@ -1120,7 +1106,7 @@ static int csnmp_strvbcopy (char *dst, /* {{{ */
   if (num_chars > vb->val_len)
     num_chars = vb->val_len;
 
-  for (i = 0; i < num_chars; i++)
+  for (size_t i = 0; i < num_chars; i++)
   {
     /* Check for control characters. */
     if ((unsigned char)src[i] < 32)
@@ -1145,7 +1131,6 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head,
   struct variable_list *vb;
   oid_t vb_name;
   int status;
-  uint32_t i;
   uint32_t is_matched;
 
   /* Set vb on the last variable */
@@ -1180,7 +1165,7 @@ static int csnmp_instance_list_add (csnmp_list_instances_t **head,
 
     csnmp_strvbcopy (il->instance, vb, sizeof (il->instance));
     is_matched = 0;
-    for (i = 0; i < dd->ignores_len; i++)
+    for (uint32_t i = 0; i < dd->ignores_len; i++)
     {
       status = fnmatch(dd->ignores[i], il->instance, 0);
       if (status == 0)
@@ -1276,7 +1261,6 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
   vl.interval = host->interval;
 
   have_more = 1;
-  memset (&current_suffix, 0, sizeof (current_suffix));
   while (have_more)
   {
     _Bool suffix_skipped = 0;
@@ -1375,8 +1359,12 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat
     for (i = 0; i < data->values_len; i++)
       vl.values[i] = value_table_ptr[i]->value;
 
-    /* If we get here `vl.type_instance' and all `vl.values' have been set */
-    plugin_dispatch_values (&vl);
+    /* If we get here `vl.type_instance' and all `vl.values' have been set
+     * vl.type_instance can be empty, i.e. a blank port description on a
+     * switch if you're using IF-MIB::ifDescr as Instance.
+     */
+    if (vl.type_instance[0] != '\0')
+      plugin_dispatch_values (&vl);
 
     if (instance_list != NULL)
       instance_list_ptr = instance_list_ptr->next;
index a0c6e4f..82ae387 100644 (file)
@@ -25,9 +25,9 @@
  */
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 #include "utils_avltree.h"
 #include "utils_latency.h"
 
@@ -500,22 +500,18 @@ static int statsd_network_init (struct pollfd **ret_fds, /* {{{ */
   struct pollfd *fds = NULL;
   size_t fds_num = 0;
 
-  struct addrinfo ai_hints;
-  struct addrinfo *ai_list = NULL;
-  struct addrinfo *ai_ptr;
+  struct addrinfo *ai_list;
   int status;
 
   char const *node = (conf_node != NULL) ? conf_node : STATSD_DEFAULT_NODE;
   char const *service = (conf_service != NULL)
     ? conf_service : STATSD_DEFAULT_SERVICE;
 
-  memset (&ai_hints, 0, sizeof (ai_hints));
-  ai_hints.ai_flags = AI_PASSIVE;
-#ifdef AI_ADDRCONFIG
-  ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-  ai_hints.ai_family = AF_UNSPEC;
-  ai_hints.ai_socktype = SOCK_DGRAM;
+  struct addrinfo ai_hints = {
+    .ai_family = AF_UNSPEC,
+    .ai_flags = AI_PASSIVE | AI_ADDRCONFIG,
+    .ai_socktype = SOCK_DGRAM
+  };
 
   status = getaddrinfo (node, service, &ai_hints, &ai_list);
   if (status != 0)
@@ -525,7 +521,7 @@ static int statsd_network_init (struct pollfd **ret_fds, /* {{{ */
     return (status);
   }
 
-  for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+  for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
   {
     int fd;
     struct pollfd *tmp;
@@ -592,7 +588,6 @@ static void *statsd_network_thread (void *args) /* {{{ */
   struct pollfd *fds = NULL;
   size_t fds_num = 0;
   int status;
-  size_t i;
 
   status = statsd_network_init (&fds, &fds_num);
   if (status != 0)
@@ -616,7 +611,7 @@ static void *statsd_network_thread (void *args) /* {{{ */
       break;
     }
 
-    for (i = 0; i < fds_num; i++)
+    for (size_t i = 0; i < fds_num; i++)
     {
       if ((fds[i].revents & (POLLIN | POLLPRI)) == 0)
         continue;
@@ -627,7 +622,7 @@ static void *statsd_network_thread (void *args) /* {{{ */
   } /* while (!network_thread_shutdown) */
 
   /* Clean up */
-  for (i = 0; i < fds_num; i++)
+  for (size_t i = 0; i < fds_num; i++)
     close (fds[i].fd);
   sfree (fds);
 
@@ -667,9 +662,7 @@ static int statsd_config_timer_percentile (oconfig_item_t *ci) /* {{{ */
 
 static int statsd_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -759,10 +752,9 @@ static int statsd_metric_clear_set_unsafe (statsd_metric_t *metric) /* {{{ */
 /* Must hold metrics_lock when calling this function. */
 static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metric) /* {{{ */
 {
-  value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
 
-  vl.values = values;
+  vl.values = &(value_t) { .gauge = NAN };
   vl.values_len = 1;
   sstrncpy (vl.host, hostname_g, sizeof (vl.host));
   sstrncpy (vl.plugin, "statsd", sizeof (vl.plugin));
@@ -779,10 +771,9 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
   sstrncpy (vl.type_instance, name, sizeof (vl.type_instance));
 
   if (metric->type == STATSD_GAUGE)
-    values[0].gauge = (gauge_t) metric->value;
+    vl.values[0].gauge = (gauge_t) metric->value;
   else if (metric->type == STATSD_TIMER)
   {
-    size_t i;
     _Bool have_events = (metric->updates_num > 0);
 
     /* Make sure all timer metrics share the *same* timestamp. */
@@ -790,7 +781,7 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
 
     ssnprintf (vl.type_instance, sizeof (vl.type_instance),
         "%s-average", name);
-    values[0].gauge = have_events
+    vl.values[0].gauge = have_events
       ? CDTIME_T_TO_DOUBLE (latency_counter_get_average (metric->latency))
       : NAN;
     plugin_dispatch_values (&vl);
@@ -798,7 +789,7 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
     if (conf_timer_lower) {
       ssnprintf (vl.type_instance, sizeof (vl.type_instance),
           "%s-lower", name);
-      values[0].gauge = have_events
+      vl.values[0].gauge = have_events
         ? CDTIME_T_TO_DOUBLE (latency_counter_get_min (metric->latency))
         : NAN;
       plugin_dispatch_values (&vl);
@@ -807,7 +798,7 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
     if (conf_timer_upper) {
       ssnprintf (vl.type_instance, sizeof (vl.type_instance),
           "%s-upper", name);
-      values[0].gauge = have_events
+      vl.values[0].gauge = have_events
         ? CDTIME_T_TO_DOUBLE (latency_counter_get_max (metric->latency))
         : NAN;
       plugin_dispatch_values (&vl);
@@ -816,17 +807,17 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
     if (conf_timer_sum) {
       ssnprintf (vl.type_instance, sizeof (vl.type_instance),
           "%s-sum", name);
-      values[0].gauge = have_events
+      vl.values[0].gauge = have_events
         ? CDTIME_T_TO_DOUBLE (latency_counter_get_sum (metric->latency))
         : NAN;
       plugin_dispatch_values (&vl);
     }
 
-    for (i = 0; i < conf_timer_percentile_num; i++)
+    for (size_t i = 0; i < conf_timer_percentile_num; i++)
     {
       ssnprintf (vl.type_instance, sizeof (vl.type_instance),
           "%s-percentile-%.0f", name, conf_timer_percentile[i]);
-      values[0].gauge = have_events
+      vl.values[0].gauge = have_events
         ? CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (metric->latency, conf_timer_percentile[i]))
         : NAN;
       plugin_dispatch_values (&vl);
@@ -838,7 +829,7 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
       sstrncpy (vl.type, "gauge", sizeof (vl.type));
       ssnprintf (vl.type_instance, sizeof (vl.type_instance),
           "%s-count", name);
-      values[0].gauge = latency_counter_get_num (metric->latency);
+      vl.values[0].gauge = latency_counter_get_num (metric->latency);
       plugin_dispatch_values (&vl);
     }
 
@@ -848,9 +839,9 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
   else if (metric->type == STATSD_SET)
   {
     if (metric->set == NULL)
-      values[0].gauge = 0.0;
+      vl.values[0].gauge = 0.0;
     else
-      values[0].gauge = (gauge_t) c_avl_size (metric->set);
+      vl.values[0].gauge = (gauge_t) c_avl_size (metric->set);
   }
   else { /* STATSD_COUNTER */
     gauge_t delta = nearbyint (metric->value);
@@ -862,7 +853,7 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
     if (conf_counter_sum)
     {
       sstrncpy (vl.type, "count", sizeof (vl.type));
-      values[0].gauge = delta;
+      vl.values[0].gauge = delta;
       plugin_dispatch_values (&vl);
 
       /* restore vl.type */
@@ -874,7 +865,7 @@ static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metri
     metric->value   -= delta;
     metric->counter += (derive_t) delta;
 
-    values[0].derive = metric->counter;
+    vl.values[0].derive = metric->counter;
   }
 
   return (plugin_dispatch_values (&vl));
@@ -888,7 +879,6 @@ static int statsd_read (void) /* {{{ */
 
   char **to_be_deleted = NULL;
   size_t to_be_deleted_num = 0;
-  size_t i;
 
   pthread_mutex_lock (&metrics_lock);
 
@@ -923,7 +913,7 @@ static int statsd_read (void) /* {{{ */
   }
   c_avl_iterator_destroy (iter);
 
-  for (i = 0; i < to_be_deleted_num; i++)
+  for (size_t i = 0; i < to_be_deleted_num; i++)
   {
     int status;
 
index d714b5f..3cc9516 100644 (file)
@@ -35,6 +35,7 @@
 #endif
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -112,9 +113,7 @@ static _Bool values_percentage = 0;
 
 static int swap_config (oconfig_item_t *ci) /* {{{ */
 {
-       int i;
-
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
                if (strcasecmp ("ReportBytes", child->key) == 0)
@@ -195,11 +194,10 @@ static void swap_submit_usage (char const *plugin_instance, /* {{{ */
                gauge_t used, gauge_t free,
                char const *other_name, gauge_t other_value)
 {
-       value_t v[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       vl.values = v;
-       vl.values_len = STATIC_ARRAY_SIZE (v);
+       vl.values = &(value_t) { .gauge = NAN };
+       vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "swap", sizeof (vl.plugin));
        if (plugin_instance != NULL)
@@ -223,12 +221,9 @@ static void swap_submit_derive (char const *type_instance, /* {{{ */
                derive_t value)
 {
        value_list_t vl = VALUE_LIST_INIT;
-       value_t v[1];
 
-       v[0].derive = value;
-
-       vl.values = v;
-       vl.values_len = STATIC_ARRAY_SIZE (v);
+       vl.values = &(value_t) { .derive = value };
+       vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "swap", sizeof (vl.plugin));
        sstrncpy (vl.type, "swap_io", sizeof (vl.type));
@@ -509,7 +504,6 @@ static int swap_read (void) /* {{{ */
        char *s_paths;
         int swap_num;
         int status;
-        int i;
 
         gauge_t avail = 0;
         gauge_t total = 0;
@@ -542,7 +536,7 @@ static int swap_read (void) /* {{{ */
                sfree (s);
                return (-1);
        }
-        for (i = 0; i < swap_num; i++)
+        for (int i = 0; i < swap_num; i++)
                s->swt_ent[i].ste_path = s_paths + (i * PATH_MAX);
         s->swt_n = swap_num;
 
@@ -572,7 +566,7 @@ static int swap_read (void) /* {{{ */
                /* less elements returned than requested */
                swap_num = status;
 
-        for (i = 0; i < swap_num; i++)
+        for (int i = 0; i < swap_num; i++)
         {
                char path[PATH_MAX];
                gauge_t this_total;
@@ -625,7 +619,6 @@ static int swap_read (void) /* {{{ */
        struct swapent *swap_entries;
        int swap_num;
        int status;
-       int i;
 
        gauge_t used  = 0;
        gauge_t total = 0;
@@ -664,7 +657,7 @@ static int swap_read (void) /* {{{ */
 
        /* TODO: Report per-device stats. The path name is available from
         * swap_entries[i].se_path */
-       for (i = 0; i < swap_num; i++)
+       for (int i = 0; i < swap_num; i++)
        {
                if ((swap_entries[i].se_flags & SWF_ENABLE) == 0)
                        continue;
@@ -677,6 +670,7 @@ static int swap_read (void) /* {{{ */
        {
                ERROR ("swap plugin: Total swap space (%g) is less than used swap space (%g).",
                                total, used);
+               sfree (swap_entries);
                return (-1);
        }
 
@@ -761,14 +755,13 @@ static int swap_read (void) /* {{{ */
 #elif HAVE_PERFSTAT
 static int swap_read (void) /* {{{ */
 {
-       perfstat_memory_total_t pmemory;
+       perfstat_memory_total_t pmemory = { 0 };
        int status;
 
        gauge_t total;
        gauge_t free;
        gauge_t reserved;
 
-       memset (&pmemory, 0, sizeof (pmemory));
         status = perfstat_memory_total (NULL, &pmemory, sizeof(perfstat_memory_total_t), 1);
        if (status < 0)
        {
index 849f7d1..73e5e1f 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
index 38d5f03..81e9461 100644 (file)
@@ -29,9 +29,9 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 
-#include "configfile.h"
 #include "plugin.h"
 
 #define log_err(...) ERROR ("table plugin: " __VA_ARGS__)
@@ -105,13 +105,11 @@ static void tbl_setup (tbl_t *tbl, char *file)
 
 static void tbl_clear (tbl_t *tbl)
 {
-       size_t i;
-
        sfree (tbl->file);
        sfree (tbl->sep);
        sfree (tbl->instance);
 
-       for (i = 0; i < tbl->results_num; ++i)
+       for (size_t i = 0; i < tbl->results_num; ++i)
                tbl_result_clear (tbl->results + i);
        sfree (tbl->results);
        tbl->results_num = 0;
@@ -144,7 +142,6 @@ static int tbl_config_append_array_i (char *name, size_t **var, size_t *len,
 {
        size_t *tmp;
        size_t num;
-       size_t i;
 
        if (1 > ci->values_num) {
                log_err ("\"%s\" expects at least one argument.", name);
@@ -152,7 +149,7 @@ static int tbl_config_append_array_i (char *name, size_t **var, size_t *len,
        }
 
        num = (size_t) ci->values_num;
-       for (i = 0; i < num; ++i) {
+       for (size_t i = 0; i < num; ++i) {
                if (OCONFIG_TYPE_NUMBER != ci->values[i].type) {
                        log_err ("\"%s\" expects numerical arguments only.", name);
                        return 1;
@@ -168,7 +165,7 @@ static int tbl_config_append_array_i (char *name, size_t **var, size_t *len,
        }
        *var = tmp;
 
-       for (i = 0; i < num; ++i) {
+       for (size_t i = 0; i < num; ++i) {
                (*var)[*len] = (size_t) ci->values[i].value.number;
                (*len)++;
        }
@@ -181,7 +178,6 @@ static int tbl_config_result (tbl_t *tbl, oconfig_item_t *ci)
        tbl_result_t *res;
 
        int status = 0;
-       int i;
 
        if (0 != ci->values_num) {
                log_err ("<Result> does not expect any arguments.");
@@ -203,7 +199,7 @@ static int tbl_config_result (tbl_t *tbl, oconfig_item_t *ci)
        res = tbl->results + tbl->results_num - 1;
        tbl_result_setup (res);
 
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (0 == strcasecmp (c->key, "Type"))
@@ -246,7 +242,6 @@ static int tbl_config_table (oconfig_item_t *ci)
        tbl_t *tbl;
 
        int status = 0;
-       size_t i;
 
        if ((1 != ci->values_num)
                        || (OCONFIG_TYPE_STRING != ci->values[0].type)) {
@@ -268,7 +263,7 @@ static int tbl_config_table (oconfig_item_t *ci)
        tbl = tables + tables_num - 1;
        tbl_setup (tbl, ci->values[0].value.string);
 
-       for (i = 0; i < ((size_t) ci->children_num); ++i) {
+       for (size_t i = 0; i < ((size_t) ci->children_num); ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (0 == strcasecmp (c->key, "Separator"))
@@ -306,15 +301,14 @@ static int tbl_config_table (oconfig_item_t *ci)
                return status;
        }
 
-       for (i = 0; i < tbl->results_num; ++i) {
+       for (size_t i = 0; i < tbl->results_num; ++i) {
                tbl_result_t *res = tbl->results + i;
-               size_t j;
 
-               for (j = 0; j < res->instances_num; ++j)
+               for (size_t j = 0; j < res->instances_num; ++j)
                        if (res->instances[j] > tbl->max_colnum)
                                tbl->max_colnum = res->instances[j];
 
-               for (j = 0; j < res->values_num; ++j)
+               for (size_t j = 0; j < res->values_num; ++j)
                        if (res->values[j] > tbl->max_colnum)
                                tbl->max_colnum = res->values[j];
        }
@@ -323,9 +317,7 @@ static int tbl_config_table (oconfig_item_t *ci)
 
 static int tbl_config (oconfig_item_t *ci)
 {
-       int i;
-
-       for (i = 0; i < ci->children_num; ++i) {
+       for (int i = 0; i < ci->children_num; ++i) {
                oconfig_item_t *c = ci->children + i;
 
                if (0 == strcasecmp (c->key, "Table"))
@@ -342,9 +334,7 @@ static int tbl_config (oconfig_item_t *ci)
 
 static int tbl_prepare (tbl_t *tbl)
 {
-       size_t i;
-
-       for (i = 0; i < tbl->results_num; ++i) {
+       for (size_t i = 0; i < tbl->results_num; ++i) {
                tbl_result_t *res = tbl->results + i;
 
                res->ds = plugin_get_ds (res->type);
@@ -367,9 +357,7 @@ static int tbl_prepare (tbl_t *tbl)
 
 static int tbl_finish (tbl_t *tbl)
 {
-       size_t i;
-
-       for (i = 0; i < tbl->results_num; ++i)
+       for (size_t i = 0; i < tbl->results_num; ++i)
                tbl->results[i].ds = NULL;
        return 0;
 } /* tbl_finish */
@@ -380,12 +368,10 @@ static int tbl_result_dispatch (tbl_t *tbl, tbl_result_t *res,
        value_list_t vl = VALUE_LIST_INIT;
        value_t values[res->values_num];
 
-       size_t i;
-
        assert (NULL != res->ds);
        assert (res->values_num == res->ds->ds_num);
 
-       for (i = 0; i < res->values_num; ++i) {
+       for (size_t i = 0; i < res->values_num; ++i) {
                char *value;
 
                assert (res->values[i] < fields_num);
@@ -412,7 +398,7 @@ static int tbl_result_dispatch (tbl_t *tbl, tbl_result_t *res,
                char *instances[res->instances_num];
                char  instances_str[DATA_MAX_NAME_LEN];
 
-               for (i = 0; i < res->instances_num; ++i) {
+               for (size_t i = 0; i < res->instances_num; ++i) {
                        assert (res->instances[i] < fields_num);
                        instances[i] = fields[res->instances[i]];
                }
@@ -444,9 +430,8 @@ static int tbl_parse_line (tbl_t *tbl, char *line, size_t len)
        char *fields[tbl->max_colnum + 1];
        char *ptr, *saveptr;
 
-       size_t i;
+       size_t i = 0;
 
-       i = 0;
        ptr = line;
        saveptr = NULL;
        while (NULL != (fields[i] = strtok_r (ptr, tbl->sep, &saveptr))) {
@@ -518,12 +503,11 @@ static int tbl_read_table (tbl_t *tbl)
 static int tbl_read (void)
 {
        int status = -1;
-       size_t i;
 
        if (0 == tables_num)
                return 0;
 
-       for (i = 0; i < tables_num; ++i) {
+       for (size_t i = 0; i < tables_num; ++i) {
                tbl_t *tbl = tables + i;
 
                if (0 != tbl_prepare (tbl)) {
@@ -541,9 +525,7 @@ static int tbl_read (void)
 
 static int tbl_shutdown (void)
 {
-       size_t i;
-
-       for (i = 0; i < tables_num; ++i)
+       for (size_t i = 0; i < tables_num; ++i)
                tbl_clear (&tables[i]);
        sfree (tables);
        return 0;
index 5402f66..74fdf84 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_tail_match.h"
@@ -137,11 +138,8 @@ static int ctail_config_add_match_dstype (ctail_config_match_t *cm,
 static int ctail_config_add_match (cu_tail_match_t *tm,
     const char *plugin_instance, oconfig_item_t *ci, cdtime_t interval)
 {
-  ctail_config_match_t cm;
+  ctail_config_match_t cm = { 0 };
   int status;
-  int i;
-
-  memset (&cm, '\0', sizeof (cm));
 
   if (ci->values_num != 0)
   {
@@ -149,7 +147,7 @@ static int ctail_config_add_match (cu_tail_match_t *tm,
   }
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -224,7 +222,6 @@ static int ctail_config_add_file (oconfig_item_t *ci)
   cdtime_t interval = 0;
   char *plugin_instance = NULL;
   int num_matches = 0;
-  int i;
 
   if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
   {
@@ -240,7 +237,7 @@ static int ctail_config_add_file (oconfig_item_t *ci)
     return (-1);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
     int status = 0;
@@ -299,9 +296,7 @@ static int ctail_config_add_file (oconfig_item_t *ci)
 
 static int ctail_config (oconfig_item_t *ci)
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -333,8 +328,6 @@ static int ctail_read (user_data_t *ud)
 static int ctail_init (void)
 {
   char str[255];
-  user_data_t ud;
-  size_t i;
 
   if (tail_match_list_num == 0)
   {
@@ -342,13 +335,14 @@ static int ctail_init (void)
     return (-1);
   }
 
-  memset(&ud, '\0', sizeof(ud));
-
-  for (i = 0; i < tail_match_list_num; i++)
+  for (size_t i = 0; i < tail_match_list_num; i++)
   {
-    ud.data = (void *)tail_match_list[i];
     ssnprintf(str, sizeof(str), "tail-%zu", i);
-    plugin_register_complex_read (NULL, str, ctail_read, tail_match_list_intervals[i], &ud);
+
+    plugin_register_complex_read (NULL, str, ctail_read, tail_match_list_intervals[i],
+        &(user_data_t) {
+          .data = tail_match_list[i],
+        });
   }
 
   return (0);
@@ -356,9 +350,7 @@ static int ctail_init (void)
 
 static int ctail_shutdown (void)
 {
-  size_t i;
-
-  for (i = 0; i < tail_match_list_num; i++)
+  for (size_t i = 0; i < tail_match_list_num; i++)
   {
     tail_match_destroy (tail_match_list[i]);
     tail_match_list[i] = NULL;
index a768ef8..faeb56f 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
 #include "common.h" /* auxiliary functions */
 #include "utils_tail.h"
@@ -288,7 +289,6 @@ static int tcsv_config_get_index(oconfig_item_t *ci, ssize_t *ret_index) {
 static int tcsv_config_add_metric(oconfig_item_t *ci){
     metric_definition_t *md;
     int status;
-    int i;
 
     md = calloc(1, sizeof(*md));
     if (md == NULL)
@@ -306,7 +306,7 @@ static int tcsv_config_add_metric(oconfig_item_t *ci){
         return (-1);
     }
 
-    for (i = 0; i < ci->children_num; ++i){
+    for (int i = 0; i < ci->children_num; ++i){
         oconfig_item_t *option = ci->children + i;
 
         if (strcasecmp("Type", option->key) == 0)
@@ -376,7 +376,6 @@ static int tcsv_config_add_instance_collect(instance_definition_t *id, oconfig_i
     metric_definition_t *metric;
     metric_definition_t **metric_list;
     size_t metric_list_size;
-    int i;
 
     if (ci->values_num < 1) {
         WARNING("tail_csv plugin: The `Collect' config option needs at least one argument.");
@@ -389,7 +388,7 @@ static int tcsv_config_add_instance_collect(instance_definition_t *id, oconfig_i
         return (-1);
     id->metric_list = metric_list;
 
-    for (i = 0; i < ci->values_num; i++) {
+    for (int i = 0; i < ci->values_num; i++) {
         char *metric_name;
 
         if (ci->values[i].type != OCONFIG_TYPE_STRING) {
@@ -419,11 +418,9 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
 {
     instance_definition_t* id;
     int status = 0;
-    int i;
 
     /* Registration variables */
     char cb_name[DATA_MAX_NAME_LEN];
-    user_data_t cb_data;
 
     id = calloc(1, sizeof(*id));
     if (id == NULL)
@@ -443,7 +440,7 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
     /* Use default interval. */
     id->interval = plugin_get_interval();
 
-    for (i = 0; i < ci->children_num; ++i){
+    for (int i = 0; i < ci->children_num; ++i){
         oconfig_item_t *option = ci->children + i;
         status = 0;
 
@@ -484,11 +481,12 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
     }
 
     ssnprintf (cb_name, sizeof (cb_name), "tail_csv/%s", id->path);
-    memset(&cb_data, 0, sizeof(cb_data));
-    cb_data.data = id;
-    cb_data.free_func = tcsv_instance_definition_destroy;
-    status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval, &cb_data);
 
+    status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval,
+            &(user_data_t) {
+                .data = id,
+                .free_func = tcsv_instance_definition_destroy,
+            });
     if (status != 0){
         ERROR("tail_csv plugin: Registering complex read function failed.");
         tcsv_instance_definition_destroy(id);
@@ -500,8 +498,7 @@ static int tcsv_config_add_file(oconfig_item_t *ci)
 
 /* Parse blocks */
 static int tcsv_config(oconfig_item_t *ci){
-    int i;
-    for (i = 0; i < ci->children_num; ++i){
+    for (int i = 0; i < ci->children_num; ++i){
         oconfig_item_t *child = ci->children + i;
         if (strcasecmp("Metric", child->key) == 0)
             tcsv_config_add_metric(child);
index a8e7dc4..8ec9bf2 100644 (file)
@@ -21,6 +21,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -60,14 +61,14 @@ static void tape_submit (const char *plugin_instance,
                const char *type,
                derive_t read, derive_t write)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = read;
-       values[1].derive = write;
+       value_t values[] = {
+               { .derive = read },
+               { .derive = write },
+       };
 
        vl.values = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "tape", sizeof (vl.plugin));
        sstrncpy (vl.plugin_instance, plugin_instance,
@@ -98,7 +99,6 @@ static int tape_read (void)
 # error "kstat_io_t does not have the required members"
 #endif
        static kstat_io_t kio;
-       int i;
 
        if (kc == NULL)
                return (-1);
@@ -106,7 +106,7 @@ static int tape_read (void)
        if (numtape <= 0)
                return (-1);
 
-       for (i = 0; i < numtape; i++)
+       for (int i = 0; i < numtape; i++)
        {
                if (kstat_read (kc, ksp[i], &kio) == -1)
                        continue;
index 55b72ac..21c071e 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "filter_chain.h"
 #include "utils_cache.h"
@@ -124,7 +125,6 @@ static int tn_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   tn_data_t *data;
   int status;
-  int i;
 
   data = calloc (1, sizeof (*data));
   if (data == NULL)
@@ -137,7 +137,7 @@ static int tn_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   data->severity = 0;
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -192,14 +192,12 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
     notification_meta_t __attribute__((unused)) **meta, void **user_data)
 {
   tn_data_t *data;
-  notification_t n;
+  notification_t n = { 0 };
   char temp[NOTIF_MAX_MSG_LEN];
 
   gauge_t *rates;
   int rates_failed;
 
-  size_t i;
-
   if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
     return (-EINVAL);
 
@@ -211,7 +209,6 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
   }
 
   /* Initialize the structure. */
-  memset (&n, 0, sizeof (n));
   n.severity = data->severity;
   n.time = cdtime ();
   sstrncpy (n.message, data->message, sizeof (n.message));
@@ -235,7 +232,8 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
   rates_failed = 0;
   rates = NULL;
-  for (i = 0; i < ds->ds_num; i++)
+
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     char template[DATA_MAX_NAME_LEN];
     char value_str[DATA_MAX_NAME_LEN];
@@ -276,9 +274,8 @@ static int tn_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
 void module_register (void)
 {
-       target_proc_t tproc;
+       target_proc_t tproc = { 0 };
 
-       memset (&tproc, 0, sizeof (tproc));
        tproc.create  = tn_create;
        tproc.destroy = tn_destroy;
        tproc.invoke  = tn_invoke;
index 545fa35..dba3a8c 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "filter_chain.h"
 #include "utils_subst.h"
@@ -37,11 +38,22 @@ struct tr_action_s
 {
   regex_t re;
   char *replacement;
-  int may_be_empty;
+  _Bool may_be_empty;
 
   tr_action_t *next;
 };
 
+struct tr_meta_data_action_s;
+typedef struct tr_meta_data_action_s tr_meta_data_action_t;
+struct tr_meta_data_action_s
+{
+  char *key;
+  regex_t re;
+  char *replacement;
+
+  tr_meta_data_action_t *next;
+};
+
 struct tr_data_s
 {
   tr_action_t *host;
@@ -49,6 +61,7 @@ struct tr_data_s
   tr_action_t *plugin_instance;
   /* tr_action_t *type; */
   tr_action_t *type_instance;
+  tr_meta_data_action_t *meta;
 };
 typedef struct tr_data_s tr_data_t;
 
@@ -84,8 +97,23 @@ static void tr_action_destroy (tr_action_t *act) /* {{{ */
   sfree (act);
 } /* }}} void tr_action_destroy */
 
+static void tr_meta_data_action_destroy (tr_meta_data_action_t *act) /* {{{ */
+{
+  if (act == NULL)
+    return;
+
+  sfree (act->key);
+  regfree (&act->re);
+  sfree (act->replacement);
+
+  if (act->next != NULL)
+    tr_meta_data_action_destroy (act->next);
+
+  sfree (act);
+} /* }}} void tr_meta_data_action_destroy */
+
 static int tr_config_add_action (tr_action_t **dest, /* {{{ */
-    const oconfig_item_t *ci, int may_be_empty)
+    const oconfig_item_t *ci, _Bool may_be_empty)
 {
   tr_action_t *act;
   int status;
@@ -130,8 +158,7 @@ static int tr_config_add_action (tr_action_t **dest, /* {{{ */
   if (act->replacement == NULL)
   {
     ERROR ("tr_config_add_action: tr_strdup failed.");
-    regfree (&act->re);
-    sfree (act);
+    tr_action_destroy (act);
     return (-ENOMEM);
   }
 
@@ -152,23 +179,121 @@ static int tr_config_add_action (tr_action_t **dest, /* {{{ */
   return (0);
 } /* }}} int tr_config_add_action */
 
+static int tr_config_add_meta_action (tr_meta_data_action_t **dest, /* {{{ */
+    const oconfig_item_t *ci, _Bool should_delete)
+{
+  tr_meta_data_action_t *act;
+  int status;
+
+  if (dest == NULL)
+    return (-EINVAL);
+
+  if (should_delete)
+  {
+    if ((ci->values_num != 2)
+        || (ci->values[0].type != OCONFIG_TYPE_STRING)
+        || (ci->values[1].type != OCONFIG_TYPE_STRING))
+    {
+      ERROR ("Target `replace': The `%s' option requires exactly two string "
+          "arguments.", ci->key);
+      return (-1);
+    }
+  }
+  else
+  {
+    if ((ci->values_num != 3)
+        || (ci->values[0].type != OCONFIG_TYPE_STRING)
+        || (ci->values[1].type != OCONFIG_TYPE_STRING)
+        || (ci->values[2].type != OCONFIG_TYPE_STRING))
+    {
+      ERROR ("Target `replace': The `%s' option requires exactly three string "
+          "arguments.", ci->key);
+      return (-1);
+    }
+  }
+
+  if (strlen (ci->values[0].value.string) == 0)
+  {
+    ERROR ("Target `replace': The `%s' option does not accept empty string as "
+        "first argument.", ci->key);
+    return (-1);
+  }
+
+  act = calloc (1, sizeof (*act));
+  if (act == NULL)
+  {
+    ERROR ("tr_config_add_meta_action: calloc failed.");
+    return (-ENOMEM);
+  }
+
+  act->key = NULL;
+  act->replacement = NULL;
+
+  status = regcomp (&act->re, ci->values[1].value.string, REG_EXTENDED);
+  if (status != 0)
+  {
+    char errbuf[1024] = "";
+
+    /* regerror assures null termination. */
+    regerror (status, &act->re, errbuf, sizeof (errbuf));
+    ERROR ("Target `replace': Compiling the regular expression `%s' "
+        "failed: %s.",
+        ci->values[1].value.string, errbuf);
+    sfree (act->key);
+    sfree (act);
+    return (-EINVAL);
+  }
+
+  act->key = tr_strdup (ci->values[0].value.string);
+  if (act->key == NULL)
+  {
+    ERROR ("tr_config_add_meta_action: tr_strdup failed.");
+    tr_meta_data_action_destroy (act);
+    return (-ENOMEM);
+  }
+
+  if (!should_delete) {
+    act->replacement = tr_strdup (ci->values[2].value.string);
+    if (act->replacement == NULL)
+    {
+      ERROR ("tr_config_add_meta_action: tr_strdup failed.");
+      tr_meta_data_action_destroy (act);
+      return (-ENOMEM);
+    }
+  }
+
+  /* Insert action at end of list. */
+  if (*dest == NULL)
+    *dest = act;
+  else
+  {
+    tr_meta_data_action_t *prev;
+
+    prev = *dest;
+    while (prev->next != NULL)
+      prev = prev->next;
+
+    prev->next = act;
+  }
+
+  return (0);
+} /* }}} int tr_config_add_meta_action */
+
 static int tr_action_invoke (tr_action_t *act_head, /* {{{ */
-    char *buffer_in, size_t buffer_in_size, int may_be_empty)
+    char *buffer_in, size_t buffer_in_size, _Bool may_be_empty)
 {
-  tr_action_t *act;
   int status;
   char buffer[DATA_MAX_NAME_LEN];
-  regmatch_t matches[8];
+  regmatch_t matches[8] = { [0] = { 0 } };
 
   if (act_head == NULL)
     return (-EINVAL);
 
   sstrncpy (buffer, buffer_in, sizeof (buffer));
-  memset (matches, 0, sizeof (matches));
 
   DEBUG ("target_replace plugin: tr_action_invoke: <- buffer = %s;", buffer);
 
-  for (act = act_head; act != NULL; act = act->next)
+  for (tr_action_t *act = act_head; act != NULL; act = act->next)
   {
     char temp[DATA_MAX_NAME_LEN];
     char *subst_status;
@@ -216,6 +341,119 @@ static int tr_action_invoke (tr_action_t *act_head, /* {{{ */
   return (0);
 } /* }}} int tr_action_invoke */
 
+static int tr_meta_data_action_invoke ( /* {{{ */
+    tr_meta_data_action_t *act_head, meta_data_t **dest)
+{
+  int status;
+  regmatch_t matches[8] = { [0] = { 0 } };
+
+  if (act_head == NULL)
+    return (-EINVAL);
+
+  if ((*dest) == NULL)  /* nothing to do */
+    return (0);
+
+  for (tr_meta_data_action_t *act = act_head; act != NULL; act = act->next)
+  {
+    char temp[DATA_MAX_NAME_LEN];
+    char *subst_status;
+    int value_type;
+    int meta_data_status;
+    char *value;
+    meta_data_t *result;
+
+    value_type = meta_data_type (*dest, act->key);
+    if (value_type == 0)  /* not found */
+      continue;
+    if (value_type != MD_TYPE_STRING)
+    {
+      WARNING ("Target `replace': Attempting replace on metadata key `%s', "
+          "which isn't a string.",
+          act->key);
+      continue;
+    }
+
+    meta_data_status = meta_data_get_string (*dest, act->key, &value);
+    if (meta_data_status != 0)
+    {
+      ERROR ("Target `replace': Unable to retrieve metadata value for `%s'.",
+          act->key);
+      return (meta_data_status);
+    }
+
+    DEBUG ("target_replace plugin: tr_meta_data_action_invoke: `%s' "
+        "old value = `%s'", act->key, value);
+
+    status = regexec (&act->re, value,
+        STATIC_ARRAY_SIZE (matches), matches,
+        /* flags = */ 0);
+    if (status == REG_NOMATCH)
+    {
+      sfree (value);
+      continue;
+    }
+    else if (status != 0)
+    {
+      char errbuf[1024] = "";
+
+      regerror (status, &act->re, errbuf, sizeof (errbuf));
+      ERROR ("Target `replace': Executing a regular expression failed: %s.",
+          errbuf);
+      sfree (value);
+      continue;
+    }
+
+    if (act->replacement == NULL)
+    {
+      /* no replacement; delete the key */
+      DEBUG ("target_replace plugin: tr_meta_data_action_invoke: "
+          "deleting `%s'", act->key);
+      meta_data_delete (*dest, act->key);
+      sfree (value);
+      continue;
+    }
+
+    subst_status = subst (temp, sizeof (temp), value,
+        (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, act->replacement);
+    if (subst_status == NULL)
+    {
+      ERROR ("Target `replace': subst (value = %s, start = %zu, end = %zu, "
+          "replacement = %s) failed.",
+          value, (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo,
+          act->replacement);
+      sfree (value);
+      continue;
+    }
+
+    DEBUG ("target_replace plugin: tr_meta_data_action_invoke: `%s' "
+        "value `%s' -> `%s'", act->key, value, temp);
+
+    if ((result = meta_data_create()) == NULL)
+    {
+      ERROR ("Target `replace': failed to create metadata for `%s'.",
+          act->key);
+      sfree (value);
+      return (-ENOMEM);
+    }
+
+    meta_data_status = meta_data_add_string (result, act->key, temp);
+    if (meta_data_status != 0)
+    {
+      ERROR ("Target `replace': Unable to set metadata value for `%s'.",
+          act->key);
+      meta_data_destroy (result);
+      sfree (value);
+      return (meta_data_status);
+    }
+
+    meta_data_clone_merge (dest, result);
+    meta_data_destroy (result);
+    sfree (value);
+  } /* for (act = act_head; act != NULL; act = act->next) */
+
+  return (0);
+} /* }}} int tr_meta_data_action_invoke */
+
 static int tr_destroy (void **user_data) /* {{{ */
 {
   tr_data_t *data;
@@ -232,6 +470,7 @@ static int tr_destroy (void **user_data) /* {{{ */
   tr_action_destroy (data->plugin_instance);
   /* tr_action_destroy (data->type); */
   tr_action_destroy (data->type_instance);
+  tr_meta_data_action_destroy (data->meta);
   sfree (data);
 
   return (0);
@@ -241,7 +480,6 @@ static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   tr_data_t *data;
   int status;
-  int i;
 
   data = calloc (1, sizeof (*data));
   if (data == NULL)
@@ -255,9 +493,10 @@ static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   data->plugin_instance = NULL;
   /* data->type = NULL; */
   data->type_instance = NULL;
+  data->meta = NULL;
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -279,6 +518,12 @@ static int tr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
     else if (strcasecmp ("TypeInstance", child->key) == 0)
       status = tr_config_add_action (&data->type_instance, child,
           /* may be empty = */ 1);
+    else if (strcasecmp ("MetaData", child->key) == 0)
+      status = tr_config_add_meta_action (&data->meta, child,
+          /* should delete = */ 0);
+    else if (strcasecmp ("DeleteMetaData", child->key) == 0)
+      status = tr_config_add_meta_action (&data->meta, child,
+          /* should delete = */ 1);
     else
     {
       ERROR ("Target `replace': The `%s' configuration option is not understood "
@@ -297,7 +542,8 @@ static int tr_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 `replace': You need to set at least one of `Host', "
           "`Plugin', `PluginInstance' or `TypeInstance'.");
@@ -332,13 +578,18 @@ static int tr_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
     return (-EINVAL);
   }
 
+  if (data->meta != NULL)
+  {
+    tr_meta_data_action_invoke (data->meta, &(vl->meta));
+  }
+
 #define HANDLE_FIELD(f,e) \
   if (data->f != NULL) \
     tr_action_invoke (data->f, vl->f, sizeof (vl->f), e)
   HANDLE_FIELD (host, 0);
   HANDLE_FIELD (plugin, 0);
   HANDLE_FIELD (plugin_instance, 1);
-  /* HANDLE_FIELD (type); */
+  /* HANDLE_FIELD (type, 0); */
   HANDLE_FIELD (type_instance, 1);
 
   return (FC_TARGET_CONTINUE);
@@ -346,9 +597,8 @@ static int tr_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
 void module_register (void)
 {
-       target_proc_t tproc;
+       target_proc_t tproc = { 0 };
 
-       memset (&tproc, 0, sizeof (tproc));
        tproc.create  = tr_create;
        tproc.destroy = tr_destroy;
        tproc.invoke  = tr_invoke;
index 74652ff..22af4e3 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "filter_chain.h"
 
@@ -302,7 +303,6 @@ static int ts_config_add_data_source(ts_data_t *data, /* {{{ */
 {
        size_t new_data_sources_num;
        char **temp;
-       int i;
 
        /* Check number of arbuments. */
        if (ci->values_num < 1)
@@ -313,7 +313,7 @@ static int ts_config_add_data_source(ts_data_t *data, /* {{{ */
        }
 
        /* Check type of arguments */
-       for (i = 0; i < ci->values_num; i++)
+       for (int i = 0; i < ci->values_num; i++)
        {
                if (ci->values[i].type == OCONFIG_TYPE_STRING)
                        continue;
@@ -338,7 +338,7 @@ static int ts_config_add_data_source(ts_data_t *data, /* {{{ */
        data->data_sources = temp;
 
        /* Copy the strings, allocating memory as needed.  */
-       for (i = 0; i < ci->values_num; i++)
+       for (int i = 0; i < ci->values_num; i++)
        {
                size_t j;
 
@@ -369,8 +369,7 @@ static int ts_destroy (void **user_data) /* {{{ */
 
        if ((data != NULL) && (data->data_sources != NULL))
        {
-               size_t i;
-               for (i = 0; i < data->data_sources_num; i++)
+               for (size_t i = 0; i < data->data_sources_num; i++)
                        sfree (data->data_sources[i]);
                sfree (data->data_sources);
        }
@@ -385,7 +384,6 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
        ts_data_t *data;
        int status;
-       int i;
 
        data = calloc (1, sizeof (*data));
        if (data == NULL)
@@ -398,7 +396,7 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
        data->offset = NAN;
 
        status = 0;
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -446,7 +444,6 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
                notification_meta_t __attribute__((unused)) **meta, void **user_data)
 {
        ts_data_t *data;
-       size_t i;
 
        if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
                return (-EINVAL);
@@ -458,7 +455,7 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
                return (-EINVAL);
        }
 
-       for (i = 0; i < ds->ds_num; i++)
+       for (size_t i = 0; i < ds->ds_num; i++)
        {
                /* If we've got a list of data sources, is it in the list? */
                if (data->data_sources) {
@@ -490,9 +487,8 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
 void module_register (void)
 {
-       target_proc_t tproc;
+       target_proc_t tproc = { 0 };
 
-       memset (&tproc, 0, sizeof (tproc));
        tproc.create  = ts_create;
        tproc.destroy = ts_destroy;
        tproc.invoke  = ts_invoke;
index 6115639..6b44bcc 100644 (file)
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "filter_chain.h"
+#include "meta_data.h"
+#include "utils_subst.h"
+
+struct ts_key_list_s
+{
+  char *key;
+  struct ts_key_list_s *next;
+};
+typedef struct ts_key_list_s ts_key_list_t;
+
+static void ts_key_list_free (ts_key_list_t *l) /* {{{ */
+{
+  if (l == NULL)
+    return;
+
+  sfree (l->key);
+
+  if (l->next != NULL)
+    ts_key_list_free (l->next);
+
+  sfree (l);
+} /* }}} void ts_name_list_free */
 
 struct ts_data_s
 {
@@ -36,6 +59,7 @@ struct ts_data_s
   /* char *type; */
   char *type_instance;
   meta_data_t *meta;
+  ts_key_list_t *meta_delete;
 };
 typedef struct ts_data_s ts_data_t;
 
@@ -46,7 +70,7 @@ static int ts_util_get_key_and_string_wo_strdup (const oconfig_item_t *ci, char
       || (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);
+        "exactly two string arguments.", ci->key);
     return (-1);
   }
 
@@ -91,31 +115,105 @@ static int ts_config_add_meta (meta_data_t **dest, /* {{{ */
 
   if (strlen (key) == 0)
   {
-    ERROR ("Target `set': The `%s' option does not accept empty string as first argument.",
-        ci->key);
+    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);
+    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
+    /* 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 (-ENOMEM);
     }
   }
 
   return (meta_data_add_string (*dest, key, string));
 } /* }}} int ts_config_add_meta */
 
+static int ts_config_add_meta_delete (ts_key_list_t **dest, /* {{{ */
+    const oconfig_item_t *ci)
+{
+  ts_key_list_t *entry = NULL;
+
+  entry = calloc (1, sizeof (*entry));
+  if (entry == NULL)
+  {
+    ERROR ("ts_config_add_meta_delete: calloc failed.");
+    return (-ENOMEM);
+  }
+
+  if (cf_util_get_string (ci, &entry->key) != 0)
+  {
+    ts_key_list_free (entry);
+    return (-1);  /* An error has already been reported. */
+  }
+
+  if (strlen (entry->key) == 0)
+  {
+    ERROR ("Target `set': The `%s' option does not accept empty string as "
+        "first argument.", ci->key);
+    ts_key_list_free (entry);
+    return (-1);
+  }
+
+  entry->next = *dest;
+  *dest = entry;
+
+  return (0);
+} /* }}} int ts_config_add_meta_delete */
+
+static void ts_subst (char *dest, size_t size, const char *string, /* {{{ */
+    const value_list_t *vl)
+{
+  char temp[DATA_MAX_NAME_LEN];
+
+  /* Initialize the field with the template. */
+  sstrncpy (dest, string, size);
+
+  if (strchr (dest, '%') == NULL)
+    return;
+
+#define REPLACE_FIELD(t, v) \
+  if (subst_string (temp, sizeof (temp), dest, t, v) != NULL) \
+    sstrncpy (dest, temp, size);
+  REPLACE_FIELD ("%{host}", vl->host);
+  REPLACE_FIELD ("%{plugin}", vl->plugin);
+  REPLACE_FIELD ("%{plugin_instance}", vl->plugin_instance);
+  REPLACE_FIELD ("%{type}", vl->type);
+  REPLACE_FIELD ("%{type_instance}", vl->type_instance);
+
+  if (vl->meta != NULL)
+  {
+    char **meta_toc;
+    int meta_entries = meta_data_toc (vl->meta, &meta_toc);
+    for (int i = 0; i < meta_entries; i++)
+    {
+      char meta_name[DATA_MAX_NAME_LEN];
+      char *value_str;
+      const char *key = meta_toc[i];
+
+      ssnprintf (meta_name, sizeof (meta_name), "%%{meta:%s}", key);
+      if (meta_data_as_string (vl->meta, key, &value_str) != 0)
+        continue;
+
+      REPLACE_FIELD (meta_name, value_str);
+      sfree (value_str);
+    }
+
+    strarray_free (meta_toc, (size_t) meta_entries);
+  }
+} /* }}} int ts_subst */
+
 static int ts_destroy (void **user_data) /* {{{ */
 {
   ts_data_t *data;
@@ -133,6 +231,7 @@ static int ts_destroy (void **user_data) /* {{{ */
   /* free (data->type); */
   free (data->type_instance);
   meta_data_destroy(data->meta);
+  ts_key_list_free (data->meta_delete);
   free (data);
 
   return (0);
@@ -142,7 +241,6 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 {
   ts_data_t *data;
   int status;
-  int i;
 
   data = calloc (1, sizeof (*data));
   if (data == NULL)
@@ -157,9 +255,10 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
   /* data->type = NULL; */
   data->type_instance = NULL;
   data->meta = NULL;
+  data->meta_delete = NULL;
 
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -181,9 +280,11 @@ 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)
+    else if (strcasecmp ("MetaData", child->key) == 0)
       status = ts_config_add_meta (&data->meta, child,
           /* may be empty = */ 1);
+    else if (strcasecmp ("DeleteMetaData", child->key) == 0)
+      status = ts_config_add_meta_delete (&data->meta_delete, child);
     else
     {
       ERROR ("Target `set': The `%s' configuration option is not understood "
@@ -203,14 +304,30 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
         && (data->plugin_instance == NULL)
         /* && (data->type == NULL) */
         && (data->type_instance == NULL)
-        && (data->meta == NULL))
+        && (data->meta == NULL)
+        && (data->meta_delete == NULL))
     {
       ERROR ("Target `set': You need to set at least one of `Host', "
           "`Plugin', `PluginInstance', `TypeInstance', "
-          "`MetaDataSet' or `MetaDataEval'.");
+          "`MetaData', or `DeleteMetaData'.");
       status = -1;
     }
 
+    if (data->meta != NULL)
+    {
+      /* If data->meta_delete is NULL, this loop is a no-op. */
+      for (ts_key_list_t *l=data->meta_delete; l != NULL; l = l->next)
+      {
+        if (meta_data_type (data->meta, l->key) != 0)
+        {
+          /* MetaData and DeleteMetaData for the same key. */
+          ERROR ("Target `set': Can only have one of `MetaData' or "
+              "`DeleteMetaData' for any given key.");
+          status = -1;
+        }
+      }
+    }
+
     break;
   }
 
@@ -228,6 +345,8 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
     notification_meta_t __attribute__((unused)) **meta, void **user_data)
 {
   ts_data_t *data;
+  value_list_t orig;
+  meta_data_t *new_meta = NULL;
 
   if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
     return (-EINVAL);
@@ -239,26 +358,88 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
     return (-EINVAL);
   }
 
+  orig = *vl;
+
   if (data->meta != NULL)
   {
-    meta_data_clone_merge(&(vl->meta), data->meta);
+    char temp[DATA_MAX_NAME_LEN*2];
+    int meta_entries;
+    char **meta_toc;
+
+    if ((new_meta = meta_data_create()) == NULL)
+    {
+      ERROR ("Target `set': failed to create replacement metadata.");
+      return (-ENOMEM);
+    }
+
+    meta_entries = meta_data_toc (data->meta, &meta_toc);
+    for (int i = 0; i < meta_entries; i++)
+    {
+      const char *key = meta_toc[i];
+      char *string;
+      int status;
+
+      status = meta_data_get_string (data->meta, key, &string);
+      if (status)
+      {
+        ERROR ("Target `set': Unable to get replacement metadata value `%s'.",
+            key);
+        strarray_free (meta_toc, (size_t) meta_entries);
+        return (status);
+      }
+
+      ts_subst (temp, sizeof (temp), string, &orig);
+
+      DEBUG ("target_set: ts_invoke: setting metadata value for key `%s': "
+          "`%s'.", key, temp);
+
+      sfree (string);
+
+      status = meta_data_add_string (new_meta, key, temp);
+      if (status)
+      {
+        ERROR ("Target `set': Unable to set metadata value `%s'.", key);
+        strarray_free (meta_toc, (size_t) meta_entries);
+        return (status);
+      }
+    }
+
+    strarray_free (meta_toc, (size_t) meta_entries);
+  }
+
+#define SUBST_FIELD(f) \
+  if (data->f != NULL) { \
+    ts_subst (vl->f, sizeof (vl->f), data->f, &orig); \
+    DEBUG ("target_set: ts_invoke: setting "#f": `%s'.", vl->f); \
+  }
+  SUBST_FIELD (host);
+  SUBST_FIELD (plugin);
+  SUBST_FIELD (plugin_instance);
+  /* SUBST_FIELD (type); */
+  SUBST_FIELD (type_instance);
+
+  /* Need to merge the metadata in now, because of the shallow copy. */
+  if (new_meta != NULL)
+  {
+    meta_data_clone_merge(&(vl->meta), new_meta);
+    meta_data_destroy(new_meta);
   }
 
-#define SET_FIELD(f) if (data->f != NULL) { sstrncpy (vl->f, data->f, sizeof (vl->f)); }
-  SET_FIELD (host);
-  SET_FIELD (plugin);
-  SET_FIELD (plugin_instance);
-  /* SET_FIELD (type); */
-  SET_FIELD (type_instance);
+  /* If data->meta_delete is NULL, this loop is a no-op. */
+  for (ts_key_list_t *l=data->meta_delete; l != NULL; l = l->next)
+  {
+    DEBUG ("target_set: ts_invoke: deleting metadata value for key `%s'.",
+        l->key);
+    meta_data_delete(vl->meta, l->key);
+  }
 
   return (FC_TARGET_CONTINUE);
 } /* }}} int ts_invoke */
 
 void module_register (void)
 {
-       target_proc_t tproc;
+       target_proc_t tproc = { 0 };
 
-       memset (&tproc, 0, sizeof (tproc));
        tproc.create  = ts_create;
        tproc.destroy = ts_destroy;
        tproc.invoke  = ts_invoke;
index d85a181..3f2c958 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "filter_chain.h"
@@ -52,7 +53,6 @@ static void v5_swap_instances (value_list_t *vl) /* {{{ */
 static int v5_df (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_value;
 
   /* Can't upgrade if both instances have been set. */
   if ((vl->plugin_instance[0] != 0)
@@ -63,7 +63,7 @@ static int v5_df (const data_set_t *ds, value_list_t *vl) /* {{{ */
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = &new_value;
+  new_vl.values = &(value_t) { .gauge = NAN };
   new_vl.values_len = 1;
   new_vl.meta = NULL;
 
@@ -112,7 +112,6 @@ static int v5_interface (const data_set_t *ds, value_list_t *vl) /* {{{ */
 static int v5_mysql_qcache (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_value;
 
   if (vl->values_len != 5)
     return (FC_TARGET_STOP);
@@ -121,7 +120,7 @@ static int v5_mysql_qcache (const data_set_t *ds, value_list_t *vl) /* {{{ */
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = &new_value;
+  new_vl.values = &(value_t) { .gauge = NAN };
   new_vl.values_len = 1;
   new_vl.meta = NULL;
 
@@ -170,7 +169,6 @@ static int v5_mysql_qcache (const data_set_t *ds, value_list_t *vl) /* {{{ */
 static int v5_mysql_threads (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_value;
 
   if (vl->values_len != 4)
     return (FC_TARGET_STOP);
@@ -179,7 +177,7 @@ static int v5_mysql_threads (const data_set_t *ds, value_list_t *vl) /* {{{ */
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = &new_value;
+  new_vl.values = &(value_t) { .gauge = NAN };
   new_vl.values_len = 1;
   new_vl.meta = NULL;
 
@@ -223,7 +221,6 @@ static int v5_mysql_threads (const data_set_t *ds, value_list_t *vl) /* {{{ */
 static int v5_zfs_arc_counts (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_value;
   _Bool is_hits;
 
   if (vl->values_len != 4)
@@ -240,7 +237,7 @@ static int v5_zfs_arc_counts (const data_set_t *ds, value_list_t *vl) /* {{{ */
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = &new_value;
+  new_vl.values = &(value_t) { .gauge = NAN };
   new_vl.values_len = 1;
   new_vl.meta = NULL;
 
@@ -284,7 +281,6 @@ static int v5_zfs_arc_counts (const data_set_t *ds, value_list_t *vl) /* {{{ */
 static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_values[2];
 
   if (vl->values_len != 2)
     return (FC_TARGET_STOP);
@@ -293,8 +289,6 @@ static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ *
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = new_values;
-  new_vl.values_len = 2;
   new_vl.meta = NULL;
 
   /* Change the type/-instance to "io_octets-L2" */
@@ -302,8 +296,12 @@ static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ *
   sstrncpy (new_vl.type_instance, "L2", sizeof (new_vl.type_instance));
 
   /* Copy the actual values. */
-  new_vl.values[0].derive = (derive_t) vl->values[0].counter;
-  new_vl.values[1].derive = (derive_t) vl->values[1].counter;
+  value_t values[] = {
+    { .derive = (derive_t) vl->values[0].counter },
+    { .derive = (derive_t) vl->values[1].counter },
+  };
+  new_vl.values = values;
+  new_vl.values_len = STATIC_ARRAY_SIZE (values);
 
   /* Dispatch new value lists instead of this one */
   plugin_dispatch_values (&new_vl);
@@ -321,7 +319,6 @@ static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ *
 static int v5_zfs_arc_l2_size (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_value;
 
   if (vl->values_len != 1)
     return (FC_TARGET_STOP);
@@ -330,7 +327,7 @@ static int v5_zfs_arc_l2_size (const data_set_t *ds, value_list_t *vl) /* {{{ */
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = &new_value;
+  new_vl.values = &(value_t) { .gauge = NAN };
   new_vl.values_len = 1;
   new_vl.meta = NULL;
 
@@ -358,7 +355,6 @@ static int v5_zfs_arc_l2_size (const data_set_t *ds, value_list_t *vl) /* {{{ */
 static int v5_zfs_arc_ratio (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_value;
 
   if (vl->values_len != 1)
     return (FC_TARGET_STOP);
@@ -367,7 +363,7 @@ static int v5_zfs_arc_ratio (const data_set_t *ds, value_list_t *vl) /* {{{ */
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = &new_value;
+  new_vl.values = &(value_t) { .gauge = NAN };
   new_vl.values_len = 1;
   new_vl.meta = NULL;
 
@@ -396,7 +392,6 @@ static int v5_zfs_arc_ratio (const data_set_t *ds, value_list_t *vl) /* {{{ */
 static int v5_zfs_arc_size (const data_set_t *ds, value_list_t *vl) /* {{{ */
 {
   value_list_t new_vl;
-  value_t new_value;
 
   if (vl->values_len != 4)
     return (FC_TARGET_STOP);
@@ -405,7 +400,7 @@ static int v5_zfs_arc_size (const data_set_t *ds, value_list_t *vl) /* {{{ */
   memcpy (&new_vl, vl, sizeof (new_vl));
 
   /* Reset data we can't simply copy */
-  new_vl.values = &new_value;
+  new_vl.values = &(value_t) { .gauge = NAN };
   new_vl.values_len = 1;
   new_vl.meta = NULL;
 
@@ -463,9 +458,8 @@ static int v5_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
 void module_register (void)
 {
-       target_proc_t tproc;
+       target_proc_t tproc = { 0 };
 
-       memset (&tproc, 0, sizeof (tproc));
        tproc.create  = v5_create;
        tproc.destroy = v5_destroy;
        tproc.invoke  = v5_invoke;
index 6bc3384..e74e4bc 100644 (file)
@@ -58,6 +58,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -304,7 +305,6 @@ static void conn_submit_port_entry (port_entry_t *pe)
 {
   value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
-  int i;
 
   conn_prepare_vl (&vl, values);
 
@@ -314,7 +314,7 @@ static void conn_submit_port_entry (port_entry_t *pe)
     ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
        "%"PRIu16"-local", pe->port);
 
-    for (i = 1; i <= TCP_STATE_MAX; i++)
+    for (int i = 1; i <= TCP_STATE_MAX; i++)
     {
       vl.values[0].gauge = pe->count_local[i];
 
@@ -329,7 +329,7 @@ static void conn_submit_port_entry (port_entry_t *pe)
     ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
        "%"PRIu16"-remote", pe->port);
 
-    for (i = 1; i <= TCP_STATE_MAX; i++)
+    for (int i = 1; i <= TCP_STATE_MAX; i++)
     {
       vl.values[0].gauge = pe->count_remote[i];
 
@@ -344,13 +344,12 @@ static void conn_submit_port_total (void)
 {
   value_t values[1];
   value_list_t vl = VALUE_LIST_INIT;
-  int i;
 
   conn_prepare_vl (&vl, values);
 
   sstrncpy (vl.plugin_instance, "all", sizeof (vl.plugin_instance));
 
-  for (i = 1; i <= TCP_STATE_MAX; i++)
+  for (int i = 1; i <= TCP_STATE_MAX; i++)
   {
     vl.values[0].gauge = count_total[i];
 
@@ -362,12 +361,10 @@ static void conn_submit_port_total (void)
 
 static void conn_submit_all (void)
 {
-  port_entry_t *pe;
-
   if (port_collect_total)
     conn_submit_port_total ();
 
-  for (pe = port_list_head; pe != NULL; pe = pe->next)
+  for (port_entry_t *pe = port_list_head; pe != NULL; pe = pe->next)
     conn_submit_port_entry (pe);
 } /* void conn_submit_all */
 
@@ -485,10 +482,6 @@ static int conn_read_netlink (void)
 {
 #if HAVE_STRUCT_LINUX_INET_DIAG_REQ
   int fd;
-  struct sockaddr_nl nladdr;
-  struct nlreq req;
-  struct msghdr msg;
-  struct iovec iov;
   struct inet_diag_msg *r;
   char buf[8192];
 
@@ -503,34 +496,38 @@ static int conn_read_netlink (void)
     return (-1);
   }
 
-  memset(&nladdr, 0, sizeof(nladdr));
-  nladdr.nl_family = AF_NETLINK;
-
-  memset(&req, 0, sizeof(req));
-  req.nlh.nlmsg_len = sizeof(req);
-  req.nlh.nlmsg_type = TCPDIAG_GETSOCK;
-  /* NLM_F_ROOT: return the complete table instead of a single entry.
-   * NLM_F_MATCH: return all entries matching criteria (not implemented)
-   * NLM_F_REQUEST: must be set on all request messages */
-  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
-  req.nlh.nlmsg_pid = 0;
-  /* The sequence_number is used to track our messages. Since netlink is not
-   * reliable, we don't want to end up with a corrupt or incomplete old
-   * message in case the system is/was out of memory. */
-  req.nlh.nlmsg_seq = ++sequence_number;
-  req.r.idiag_family = AF_INET;
-  req.r.idiag_states = 0xfff;
-  req.r.idiag_ext = 0;
-
-  memset(&iov, 0, sizeof(iov));
-  iov.iov_base = &req;
-  iov.iov_len = sizeof(req);
-
-  memset(&msg, 0, sizeof(msg));
-  msg.msg_name = (void*)&nladdr;
-  msg.msg_namelen = sizeof(nladdr);
-  msg.msg_iov = &iov;
-  msg.msg_iovlen = 1;
+  struct sockaddr_nl nladdr = {
+    .nl_family = AF_NETLINK
+  };
+
+  struct nlreq req = {
+    .nlh.nlmsg_len = sizeof(req),
+    .nlh.nlmsg_type = TCPDIAG_GETSOCK,
+    /* NLM_F_ROOT: return the complete table instead of a single entry.
+     * NLM_F_MATCH: return all entries matching criteria (not implemented)
+     * NLM_F_REQUEST: must be set on all request messages */
+    .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
+    .nlh.nlmsg_pid = 0,
+    /* The sequence_number is used to track our messages. Since netlink is not
+     * reliable, we don't want to end up with a corrupt or incomplete old
+     * message in case the system is/was out of memory. */
+    .nlh.nlmsg_seq = ++sequence_number,
+    .r.idiag_family = AF_INET,
+    .r.idiag_states = 0xfff,
+    .r.idiag_ext = 0
+  };
+
+  struct iovec iov = {
+    .iov_base = &req,
+    .iov_len = sizeof(req)
+  };
+
+  struct msghdr msg = {
+    .msg_name = (void*)&nladdr,
+    .msg_namelen = sizeof(nladdr),
+    .msg_iov = &iov,
+    .msg_iovlen = 1
+  };
 
   if (sendmsg (fd, &msg, 0) < 0)
   {
@@ -1016,7 +1013,6 @@ static int conn_read (void)
 static int conn_read (void)
 {
   int size;
-  int i;
   int nconn;
   void *data;
   struct netinfo_header *header;
@@ -1058,7 +1054,7 @@ static int conn_read (void)
   nconn = header->size;
   conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header));
 
-  for (i=0; i < nconn; conn++, i++)
+  for (int i = 0; i < nconn; conn++, i++)
   {
     conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state);
   }
index 638109c..a709e79 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -120,12 +121,9 @@ static void tss2_submit_gauge (const char *plugin_instance,
        /*
         * Submits a gauge value to the collectd daemon
         */
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values     = values;
+       vl.values     = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "teamspeak2", sizeof (vl.plugin));
@@ -149,14 +147,14 @@ static void tss2_submit_io (const char *plugin_instance, const char *type,
        /*
         * Submits the io rx/tx tuple to the collectd daemon
         */
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = rx;
-       values[1].derive = tx;
+       value_t values[] = {
+               { .derive = rx },
+               { .derive = tx },
+       };
 
        vl.values     = values;
-       vl.values_len = 2;
+       vl.values_len = STATIC_ARRAY_SIZE (values);
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "teamspeak2", sizeof (vl.plugin));
 
@@ -198,9 +196,7 @@ static int tss2_get_socket (FILE **ret_read_fh, FILE **ret_write_fh)
         * Returns connected file objects or establishes the connection
         * if it's not already present
         */
-       struct addrinfo ai_hints;
        struct addrinfo *ai_head;
-       struct addrinfo *ai_ptr;
        int sd = -1;
        int status;
 
@@ -216,12 +212,11 @@ static int tss2_get_socket (FILE **ret_read_fh, FILE **ret_write_fh)
        }
 
        /* Get all addrs for this hostname */
-       memset (&ai_hints, 0, sizeof (ai_hints));
-#ifdef AI_ADDRCONFIG
-       ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-       ai_hints.ai_family = AF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_STREAM;
+       struct addrinfo ai_hints = {
+               .ai_family = AF_UNSPEC,
+               .ai_flags = AI_ADDRCONFIG,
+               .ai_socktype = SOCK_STREAM
+       };
 
        status = getaddrinfo ((config_host != NULL) ? config_host : DEFAULT_HOST,
                        (config_port != NULL) ? config_port : DEFAULT_PORT,
@@ -235,7 +230,7 @@ static int tss2_get_socket (FILE **ret_read_fh, FILE **ret_write_fh)
        }
 
        /* Try all given hosts until we can connect to one */
-       for (ai_ptr = ai_head; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+       for (struct addrinfo *ai_ptr = ai_head; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
        {
                /* Create socket */
                sd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
@@ -511,7 +506,7 @@ static int tss2_read_vserver (vserver_list_t *vserver)
        gauge_t packet_loss = NAN;
        int valid = 0;
 
-       char plugin_instance[DATA_MAX_NAME_LEN];
+       char plugin_instance[DATA_MAX_NAME_LEN] = { 0 };
 
        FILE *read_fh;
        FILE *write_fh;
@@ -527,8 +522,6 @@ static int tss2_read_vserver (vserver_list_t *vserver)
        if (vserver == NULL)
        {
                /* Request global information */
-               memset (plugin_instance, 0, sizeof (plugin_instance));
-
                status = tss2_send_request (write_fh, "gi\r\n");
        }
        else
@@ -773,7 +766,6 @@ static int tss2_read (void)
         * Poll function which collects global and vserver information
         * and submits it to collectd
         */
-       vserver_list_t *vserver;
        int success = 0;
        int status;
 
@@ -789,7 +781,7 @@ static int tss2_read (void)
        }
 
        /* Handle vservers */
-       for (vserver = server_list; vserver != NULL; vserver = vserver->next)
+       for (vserver_list_t *vserver = server_list; vserver != NULL; vserver = vserver->next)
        {
                status = tss2_read_vserver (vserver);
                if (status == 0)
index 186cf2b..f167546 100644 (file)
--- a/src/ted.c
+++ b/src/ted.c
@@ -35,9 +35,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H
 # include <termios.h>
@@ -74,7 +74,11 @@ static int ted_read_value(double *ret_power, double *ret_voltage)
     int package_buffer_pos;
 
     fd_set input;
-    struct timeval timeout;
+
+    /* Initialize timeout structure, set to 2 seconds */
+    struct timeval timeout = {
+      .tv_sec = 2
+    };
 
     int end_flag;
     int escape_flag;
@@ -87,11 +91,6 @@ static int ted_read_value(double *ret_power, double *ret_voltage)
     FD_ZERO (&input);
     FD_SET (fd, &input);
 
-    /* Initialize timeout structure, set to 2 seconds */
-    memset (&timeout, 0, sizeof (timeout));
-    timeout.tv_sec = 2;
-    timeout.tv_usec = 0;
-
     /* clear out anything in the buffer */
     tcflush (fd, TCIFLUSH);
 
@@ -108,7 +107,6 @@ static int ted_read_value(double *ret_power, double *ret_voltage)
     while (end_flag == 0)
     {
         ssize_t receive_buffer_length;
-        ssize_t i;
 
         /* check for timeout or input error*/
         status = select (fd + 1, &input, NULL, NULL, &timeout);
@@ -165,7 +163,7 @@ static int ted_read_value(double *ret_power, double *ret_voltage)
          * the beginning of the package has been found. */
 
         escape_flag = 0;
-        for (i = 0; i < receive_buffer_length; i++)
+        for (ssize_t i = 0; i < receive_buffer_length; i++)
         {
             /* Check if previous byte was the escape byte. */
             if (escape_flag == 1)
@@ -265,12 +263,9 @@ static int ted_open_device (void)
 
 static void ted_submit (const char *type, double value)
 {
-    value_t values[1];
     value_list_t vl = VALUE_LIST_INIT;
 
-    values[0].gauge = value;
-
-    vl.values = values;
+    vl.values = &(value_t) { .gauge = value };
     vl.values_len = 1;
     sstrncpy (vl.host, hostname_g, sizeof (vl.host));
     sstrncpy (vl.plugin, "ted", sizeof (vl.plugin));
@@ -312,7 +307,6 @@ static int ted_read (void)
     double power;
     double voltage;
     int status;
-    int i;
 
     status = ted_open_device ();
     if (status != 0)
@@ -320,7 +314,7 @@ static int ted_read (void)
 
     power = NAN;
     voltage = NAN;
-    for (i = 0; i <= conf_retries; i++)
+    for (int i = 0; i <= conf_retries; i++)
     {
         status = ted_read_value (&power, &voltage);
         if (status == 0)
index 54311a6..aa95dac 100644 (file)
@@ -20,9 +20,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_ignorelist.h"
 
 #if !KERNEL_LINUX
@@ -47,14 +47,11 @@ enum dev_type {
 };
 
 static void thermal_submit (const char *plugin_instance, enum dev_type dt,
-               gauge_t value)
+               value_t value)
 {
        value_list_t vl = VALUE_LIST_INIT;
-       value_t v;
-
-       v.gauge = value;
-       vl.values = &v;
 
+       vl.values = &value;
        vl.values_len = 1;
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -72,52 +69,26 @@ static void thermal_submit (const char *plugin_instance, enum dev_type dt,
 static int thermal_sysfs_device_read (const char __attribute__((unused)) *dir,
                const char *name, void __attribute__((unused)) *user_data)
 {
-       char filename[256];
-       char data[1024];
-       int len;
+       char filename[PATH_MAX];
        _Bool success = 0;
+       value_t value;
 
        if (device_list && ignorelist_match (device_list, name))
                return -1;
 
-       len = ssnprintf (filename, sizeof (filename),
-                       "%s/%s/temp", dirname_sysfs, name);
-       if ((len < 0) || ((size_t) len >= sizeof (filename)))
-               return -1;
-
-       len = (ssize_t) read_file_contents (filename, data, sizeof(data));
-       if (len > 1 && data[--len] == '\n') {
-               char *endptr = NULL;
-               double temp;
-
-               data[len] = 0;
-               errno = 0;
-               temp = strtod (data, &endptr) / 1000.0;
-
-               if (endptr == data + len && errno == 0) {
-                       thermal_submit(name, TEMP, temp);
-                       success = 1;
-               }
+       ssnprintf (filename, sizeof (filename), "%s/%s/temp", dirname_sysfs, name);
+       if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0)
+       {
+               value.gauge /= 1000.0;
+               thermal_submit(name, TEMP, value);
+               success = 1;
        }
 
-       len = ssnprintf (filename, sizeof (filename),
-                       "%s/%s/cur_state", dirname_sysfs, name);
-       if ((len < 0) || ((size_t) len >= sizeof (filename)))
-               return -1;
-
-       len = (ssize_t) read_file_contents (filename, data, sizeof(data));
-       if (len > 1 && data[--len] == '\n') {
-               char *endptr = NULL;
-               double state;
-
-               data[len] = 0;
-               errno = 0;
-               state = strtod (data, &endptr);
-
-               if (endptr == data + len && errno == 0) {
-                       thermal_submit(name, COOLING_DEV, state);
-                       success = 1;
-               }
+       ssnprintf (filename, sizeof (filename), "%s/%s/cur_state", dirname_sysfs, name);
+       if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0)
+       {
+               thermal_submit(name, COOLING_DEV, value);
+               success = 1;
        }
 
        return (success ? 0 : -1);
@@ -176,7 +147,7 @@ static int thermal_procfs_device_read (const char __attribute__((unused)) *dir,
                temp = (strtod (data + len, &endptr) + add) * factor;
 
                if (endptr != data + len && errno == 0) {
-                       thermal_submit(name, TEMP, temp);
+                       thermal_submit(name, TEMP, (value_t) { .gauge = temp });
                        return 0;
                }
        }
index 77ba3f3..1d9bcf9 100644 (file)
@@ -24,6 +24,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_avltree.h"
@@ -215,7 +216,6 @@ static int ut_config_type_hysteresis (threshold_t *th, oconfig_item_t *ci)
 
 static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci)
 {
-  int i;
   threshold_t th;
   int status = 0;
 
@@ -244,7 +244,7 @@ static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci)
   th.hysteresis = 0;
   th.flags = UT_FLAG_INTERESTING; /* interesting by default */
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -309,7 +309,6 @@ static int ut_config_plugin_instance (threshold_t *th, oconfig_item_t *ci)
 
 static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci)
 {
-  int i;
   threshold_t th;
   int status = 0;
 
@@ -331,7 +330,7 @@ static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci)
   memcpy (&th, th_orig, sizeof (th));
   sstrncpy (th.plugin, ci->values[0].value.string, sizeof (th.plugin));
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -355,7 +354,6 @@ static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci)
 
 static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci)
 {
-  int i;
   threshold_t th;
   int status = 0;
 
@@ -377,7 +375,7 @@ static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci)
   memcpy (&th, th_orig, sizeof (th));
   sstrncpy (th.host, ci->values[0].value.string, sizeof (th.host));
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
@@ -549,10 +547,9 @@ static int ut_report_state (const data_set_t *ds,
     {
       gauge_t value;
       gauge_t sum;
-      size_t i;
 
       sum = 0.0;
-      for (i = 0; i < vl->values_len; i++)
+      for (size_t i = 0; i < vl->values_len; i++)
       {
         if (isnan (values[i]))
           continue;
@@ -697,7 +694,6 @@ static int ut_check_one_threshold (const data_set_t *ds,
 { /* {{{ */
   int ret = -1;
   int ds_index = -1;
-  size_t i;
   gauge_t values_copy[ds->ds_num];
 
   memcpy (values_copy, values, sizeof (values_copy));
@@ -716,7 +712,7 @@ static int ut_check_one_threshold (const data_set_t *ds,
     }
 
     /* Prepare `sum' and `num'. */
-    for (i = 0; i < ds->ds_num; i++)
+    for (size_t i = 0; i < ds->ds_num; i++)
       if (!isnan (values[i]))
       {
         num++;
@@ -726,17 +722,17 @@ static int ut_check_one_threshold (const data_set_t *ds,
     if ((num == 0) /* All data sources are undefined. */
         || (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */
     {
-      for (i = 0; i < ds->ds_num; i++)
+      for (size_t i = 0; i < ds->ds_num; i++)
         values_copy[i] = NAN;
     }
     else /* We can actually calculate the percentage. */
     {
-      for (i = 0; i < ds->ds_num; i++)
+      for (size_t i = 0; i < ds->ds_num; i++)
         values_copy[i] = 100.0 * values[i] / sum;
     }
   } /* if (UT_FLAG_PERCENTAGE) */
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     int status;
 
@@ -866,12 +862,9 @@ static int ut_missing (const value_list_t *vl,
 
 static int ut_config (oconfig_item_t *ci)
 { /* {{{ */
-  int i;
   int status = 0;
   int old_size = c_avl_size (threshold_tree);
 
-  threshold_t th;
-
   if (threshold_tree == NULL)
   {
     threshold_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp);
@@ -882,17 +875,15 @@ static int ut_config (oconfig_item_t *ci)
     }
   }
 
-  memset (&th, '\0', sizeof (th));
-  th.warning_min = NAN;
-  th.warning_max = NAN;
-  th.failure_min = NAN;
-  th.failure_max = NAN;
-
-  th.hits = 0;
-  th.hysteresis = 0;
-  th.flags = UT_FLAG_INTERESTING; /* interesting by default */
+  threshold_t th = {
+    .warning_min = NAN,
+    .warning_max = NAN,
+    .failure_min = NAN,
+    .failure_max = NAN,
+    .flags = UT_FLAG_INTERESTING /* interesting by default */
+  };
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *option = ci->children + i;
 
index befbd50..154215f 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "utils_cache.h"
@@ -85,15 +86,12 @@ static void printerr (void)
                        ecode, tcrdberrmsg(ecode));
 }
 
-static void tt_submit (gauge_t val, const char* type)
+static void tt_submit (gauge_t value, const char* type)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = val;
-
-       vl.values = values;
-       vl.values_len = STATIC_ARRAY_SIZE (values);
+       vl.values = &(value_t) { .gauge = value };
+       vl.values_len = 1;
 
        sstrncpy (vl.host, config_host, sizeof (vl.host));
        sstrncpy (vl.plugin, "tokyotyrant", sizeof (vl.plugin));
index bd5d86c..e74cba2 100644 (file)
@@ -36,6 +36,7 @@
 #define _GNU_SOURCE
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_time.h"
@@ -523,10 +524,8 @@ turbostat_submit (const char *plugin_instance,
        gauge_t value)
 {
        value_list_t vl = VALUE_LIST_INIT;
-       value_t v;
 
-       v.gauge = value;
-       vl.values = &v;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, PLUGIN_NAME, sizeof (vl.plugin));
@@ -651,11 +650,10 @@ for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_dat
        struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
 {
        int retval;
-       unsigned int pkg_no, core_no, thread_no;
 
-       for (pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
-               for (core_no = 0; core_no < topology.num_cores; ++core_no) {
-                       for (thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
+       for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
+               for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) {
+                       for (unsigned int thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
                                struct thread_data *t;
                                struct core_data *c;
                                struct pkg_data *p;
@@ -691,11 +689,10 @@ for_all_cpus_delta(const struct thread_data *thread_new_base, const struct core_
                   const struct thread_data *thread_old_base, const struct core_data *core_old_base, const struct pkg_data *pkg_old_base)
 {
        int retval;
-       unsigned int pkg_no, core_no, thread_no;
 
-       for (pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
-               for (core_no = 0; core_no < topology.num_cores; ++core_no) {
-                       for (thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
+       for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
+               for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) {
+                       for (unsigned int thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
                                struct thread_data *t_delta;
                                const struct thread_data *t_old, *t_new;
                                struct core_data *c_delta;
@@ -1019,8 +1016,7 @@ parse_int_file(const char *fmt, ...)
 {
        va_list args;
        char path[PATH_MAX];
-       FILE *filep;
-       int len, value;
+       int len;
 
        va_start(args, fmt);
        len = vsnprintf(path, sizeof(path), fmt, args);
@@ -1030,18 +1026,13 @@ parse_int_file(const char *fmt, ...)
                return -1;
        }
 
-       filep = fopen(path, "r");
-       if (!filep) {
-               ERROR("turbostat plugin: Failed to open '%s'", path);
-               return -1;
-       }
-       if (fscanf(filep, "%d", &value) != 1) {
-               ERROR("turbostat plugin: Failed to parse number from '%s'", path);
-               fclose(filep);
+       value_t v;
+       if (parse_value_file (path, &v, DS_TYPE_DERIVE) != 0) {
+               ERROR ("turbostat plugin: Parsing \"%s\" failed.", path);
                return -1;
        }
-       fclose(filep);
-       return value;
+
+       return (int) v.derive;
 }
 
 static int
@@ -1149,7 +1140,6 @@ allocate_cpu_set(cpu_set_t ** set, size_t * size) {
 static int __attribute__((warn_unused_result))
 topology_probe(void)
 {
-       unsigned int i;
        int ret;
        unsigned int max_package_id, max_core_id, max_threads;
        max_package_id = max_core_id = max_threads = 0;
@@ -1186,7 +1176,7 @@ topology_probe(void)
         * For online cpus
         * find max_core_id, max_package_id
         */
-       for (i = 0; i <= topology.max_cpu_id; ++i) {
+       for (unsigned int i = 0; i <= topology.max_cpu_id; ++i) {
                unsigned int num_threads;
                struct cpu_topology *cpu = &topology.cpus[i];
 
@@ -1251,7 +1241,6 @@ err:
 static int
 allocate_counters(struct thread_data **threads, struct core_data **cores, struct pkg_data **packages)
 {
-       unsigned int i;
        unsigned int total_threads, total_cores;
 
        if ((topology.num_threads == 0)
@@ -1271,7 +1260,7 @@ allocate_counters(struct thread_data **threads, struct core_data **cores, struct
                return -1;
        }
 
-       for (i = 0; i < total_threads; ++i)
+       for (unsigned int i = 0; i < total_threads; ++i)
                (*threads)[i].cpu_id = topology.max_cpu_id + 1;
 
        total_cores = topology.num_cores * topology.num_packages;
@@ -1321,9 +1310,7 @@ init_counter(struct thread_data *thread_base, struct core_data *core_base,
 static void
 initialize_counters(void)
 {
-       unsigned int cpu_id;
-
-       for (cpu_id = 0; cpu_id <= topology.max_cpu_id; ++cpu_id) {
+       for (unsigned int cpu_id = 0; cpu_id <= topology.max_cpu_id; ++cpu_id) {
                if (cpu_is_not_present(cpu_id))
                        continue;
                init_counter(EVEN_COUNTERS, cpu_id);
@@ -1479,35 +1466,22 @@ out:
 static int
 check_permissions(void)
 {
-#ifdef HAVE_SYS_CAPABILITY_H
-       struct __user_cap_header_struct cap_header_data;
-       cap_user_header_t cap_header = &cap_header_data;
-       struct __user_cap_data_struct cap_data_data;
-       cap_user_data_t cap_data = &cap_data_data;
-       int ret = 0;
-#endif /* HAVE_SYS_CAPABILITY_H */
 
        if (getuid() == 0) {
                /* We have everything we need */
                return 0;
-#ifndef HAVE_SYS_CAPABILITY_H
+#if !defined(HAVE_SYS_CAPABILITY_H) && !defined(CAP_SYS_RAWIO)
        } else {
                ERROR("turbostat plugin: Initialization failed: this plugin "
                      "requires collectd to run as root");
                return -1;
        }
-#else /* HAVE_SYS_CAPABILITY_H */
+#else /* HAVE_SYS_CAPABILITY_H && CAP_SYS_RAWIO */
        }
 
-       /* check for CAP_SYS_RAWIO */
-       cap_header->pid = getpid();
-       cap_header->version = _LINUX_CAPABILITY_VERSION;
-       if (capget(cap_header, cap_data) < 0) {
-               ERROR("turbostat plugin: capget failed");
-               return -1;
-       }
+       int ret = 0;
 
-       if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
+       if (check_capability(CAP_SYS_RAWIO) != 0) {
                WARNING("turbostat plugin: Collectd doesn't have the "
                        "CAP_SYS_RAWIO capability. If you don't want to run "
                        "collectd as root, try running \"setcap "
@@ -1529,7 +1503,7 @@ check_permissions(void)
                      "collectd a special capability (CAP_SYS_RAWIO) and read "
                       "access to /dev/cpu/*/msr (see previous warnings)");
        return ret;
-#endif /* HAVE_SYS_CAPABILITY_H */
+#endif /* HAVE_SYS_CAPABILITY_H && CAP_SYS_RAWIO */
 }
 
 static int
index d89d411..e3da48a 100644 (file)
@@ -45,6 +45,7 @@ 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
+dilution_of_precision   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
@@ -73,6 +74,8 @@ duration                seconds:GAUGE:0:U
 email_check             value:GAUGE:0:U
 email_count             value:GAUGE:0:U
 email_size              value:GAUGE:0:U
+energy                  value:GAUGE:U:U
+energy_wh               value:GAUGE:U:U
 entropy                 value:GAUGE:0:4294967295
 errors                  value:DERIVE:0:U
 evicted_keys            value:DERIVE:0:U
@@ -178,7 +181,7 @@ 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
+power                   value:GAUGE:U:U
 pressure                value:GAUGE:0:U
 protocol_counter        value:DERIVE:0:U
 ps_code                 value:GAUGE:0:9223372036854775807
@@ -203,6 +206,7 @@ root_dispersion         value:GAUGE:U:U
 route_etx               value:GAUGE:0:U
 route_metric            value:GAUGE:0:U
 routes                  value:GAUGE:0:U
+satellites              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
index d4bf004..808ba98 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include "utils_cmd_flush.h"
 #include "utils_cmd_getval.h"
@@ -76,7 +76,7 @@ static pthread_t listen_thread = (pthread_t) 0;
  */
 static int us_open_socket (void)
 {
-       struct sockaddr_un sa;
+       struct sockaddr_un sa = { 0 };
        int status;
 
        sock_fd = socket (PF_UNIX, SOCK_STREAM, 0);
@@ -88,7 +88,6 @@ static int us_open_socket (void)
                return (-1);
        }
 
-       memset (&sa, '\0', sizeof (sa));
        sa.sun_family = AF_UNIX;
        sstrncpy (sa.sun_path, (sock_file != NULL) ? sock_file : US_DEFAULT_PATH,
                        sizeof (sa.sun_path));
index 345128d..34c3e85 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -57,14 +58,11 @@ static time_t boottime;
 extern kstat_ctl_t *kc;
 #endif /* #endif HAVE_LIBKSTAT */
 
-static void uptime_submit (gauge_t uptime)
+static void uptime_submit (gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = uptime;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
 
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -179,17 +177,13 @@ static int uptime_init (void) /* {{{ */
 /* #endif HAVE_LIBKSTAT */
 
 # elif HAVE_SYS_SYSCTL_H
-       struct timeval boottv;
+       struct timeval boottv = { 0 };
        size_t boottv_len;
        int status;
 
-       int mib[2];
-
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_BOOTTIME;
+       int mib[] = { CTL_KERN, KERN_BOOTTIME };
 
        boottv_len = sizeof (boottv);
-       memset (&boottv, 0, boottv_len);
 
        status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len,
                        /* new_value = */ NULL, /* new_length = */ 0);
index a4ee4ef..ce626ae 100644 (file)
@@ -26,6 +26,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
 
 static void users_submit (gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "users", sizeof (vl.plugin));
index 4106166..1876150 100644 (file)
@@ -27,6 +27,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_parse_option.h"
@@ -43,8 +44,6 @@ int handle_flush (FILE *fh, char *buffer)
        char **identifiers = NULL;
        size_t identifiers_num = 0;
 
-       size_t i;
-
 #define PRINT_TO_SOCK(fh, ...) \
        do { \
                if (fprintf (fh, __VA_ARGS__) < 0) { \
@@ -122,15 +121,14 @@ int handle_flush (FILE *fh, char *buffer)
                }
        } /* while (*buffer != 0) */
 
-       for (i = 0; (i == 0) || (i < plugins_num); i++)
+       for (size_t i = 0; (i == 0) || (i < plugins_num); i++)
        {
                char *plugin = NULL;
-               size_t j;
 
                if (plugins_num != 0)
                        plugin = plugins[i];
 
-               for (j = 0; (j == 0) || (j < identifiers_num); j++)
+               for (size_t j = 0; (j == 0) || (j < identifiers_num); j++)
                {
                        char *identifier = NULL;
                        int status;
index 80babe3..b2a0a23 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -53,7 +54,6 @@ int handle_getthreshold (FILE *fh, char *buffer)
   char *type;
   char *type_instance;
 
-  value_list_t vl;
   threshold_t threshold;
 
   int   status;
@@ -110,7 +110,9 @@ int handle_getthreshold (FILE *fh, char *buffer)
     return (-1);
   }
 
-  memset (&vl, 0, sizeof (vl));
+  value_list_t vl = {
+    .values = NULL
+  };
   sstrncpy (vl.host, host, sizeof (vl.host));
   sstrncpy (vl.plugin, plugin, sizeof (vl.plugin));
   if (plugin_instance != NULL)
@@ -120,7 +122,6 @@ int handle_getthreshold (FILE *fh, char *buffer)
     sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
   sfree (identifier_copy);
 
-  memset (&threshold, 0, sizeof (threshold));
   status = ut_search_threshold (&vl, &threshold);
   if (status == ENOENT)
   {
index 4d679f0..cd88760 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -60,7 +61,6 @@ int handle_getval (FILE *fh, char *buffer)
   const data_set_t *ds;
 
   int   status;
-  size_t i;
 
   if ((fh == NULL) || (buffer == NULL))
     return (-1);
@@ -145,7 +145,7 @@ int handle_getval (FILE *fh, char *buffer)
 
   print_to_socket (fh, "%zu Value%s found\n", values_num,
       (values_num == 1) ? "" : "s");
-  for (i = 0; i < values_num; i++)
+  for (size_t i = 0; i < values_num; i++)
   {
     print_to_socket (fh, "%s=", ds->ds[i].name);
     if (isnan (values[i]))
index b698388..afbd01d 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -33,8 +34,7 @@
 #include "utils_parse_option.h"
 
 #define free_everything_and_return(status) do { \
-    size_t j; \
-    for (j = 0; j < number; j++) { \
+    for (size_t j = 0; j < number; j++) { \
       sfree(names[j]); \
       names[j] = NULL; \
     } \
@@ -60,7 +60,6 @@ int handle_listval (FILE *fh, char *buffer)
   char **names = NULL;
   cdtime_t *times = NULL;
   size_t number = 0;
-  size_t i;
   int status;
 
   DEBUG ("utils_cmd_listval: handle_listval (fh = %p, buffer = %s);",
@@ -97,7 +96,7 @@ int handle_listval (FILE *fh, char *buffer)
 
   print_to_socket (fh, "%i Value%s found\n",
       (int) number, (number == 1) ? "" : "s");
-  for (i = 0; i < number; i++)
+  for (size_t i = 0; i < number; i++)
     print_to_socket (fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE (times[i]),
                names[i]);
 
index 145cd10..669ef83 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -119,7 +120,7 @@ static int set_option (notification_t *n, const char *option, const char *value)
 int handle_putnotif (FILE *fh, char *buffer)
 {
   char *command;
-  notification_t n;
+  notification_t n = { 0 };
   int status;
 
   if ((fh == NULL) || (buffer == NULL))
@@ -143,8 +144,6 @@ int handle_putnotif (FILE *fh, char *buffer)
     return (-1);
   }
 
-  memset (&n, '\0', sizeof (n));
-
   status = 0;
   while (*buffer != 0)
   {
index 4c40e55..bf3e2b6 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
index f9eaf88..79d77a2 100644 (file)
@@ -101,11 +101,10 @@ static unsigned int     crc32_tab[] = {
 uint32_t
 crc32_buffer(const unsigned char *s, size_t len)
 {
-    size_t      i;
     uint32_t   ret;
 
     ret = 0;
-    for (i = 0;  i < len;  i++)
+    for (size_t i = 0;  i < len;  i++)
         ret = crc32_tab[(ret ^ s[i]) & 0xff] ^ (ret >> 8);
     return ret;
 }
index 258c5cf..0509ff4 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_curl_stats.h"
 
@@ -159,7 +160,6 @@ static bool field_enabled (curl_stats_t *s, size_t offset)
 curl_stats_t *curl_stats_from_config (oconfig_item_t *ci)
 {
        curl_stats_t *s;
-       int i;
 
        if (ci == NULL)
                return NULL;
@@ -168,7 +168,7 @@ curl_stats_t *curl_stats_from_config (oconfig_item_t *ci)
        if (s == NULL)
                return NULL;
 
-       for (i = 0; i < ci->children_num; ++i)
+       for (int i = 0; i < ci->children_num; ++i)
        {
                oconfig_item_t *c = ci->children + i;
                size_t field;
@@ -210,7 +210,6 @@ int curl_stats_dispatch (curl_stats_t *s, CURL *curl,
                const char *hostname, const char *plugin, const char *plugin_instance)
 {
        value_list_t vl = VALUE_LIST_INIT;
-       size_t field;
 
        if (s == NULL)
                return 0;
@@ -228,7 +227,7 @@ int curl_stats_dispatch (curl_stats_t *s, CURL *curl,
        if (plugin_instance != NULL)
                sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
 
-       for (field = 0; field < STATIC_ARRAY_SIZE (field_specs); ++field)
+       for (size_t field = 0; field < STATIC_ARRAY_SIZE (field_specs); ++field)
        {
                int status;
 
index f708c62..b6d0bb4 100644 (file)
@@ -27,7 +27,6 @@
 #ifndef UTILS_CURL_STATS_H
 #define UTILS_CURL_STATS_H 1
 
-#include "configfile.h"
 #include "plugin.h"
 
 #include <curl/curl.h>
index f683fb5..bbee90a 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_db_query.h"
 
 /*
@@ -125,7 +125,6 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */
 {
   char **array;
   size_t array_len;
-  int i;
 
   if (ci->values_num < 1)
   {
@@ -134,7 +133,7 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */
     return (-1);
   }
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     if (ci->values[i].type != OCONFIG_TYPE_STRING)
     {
@@ -154,7 +153,7 @@ static int udb_config_add_string (char ***ret_array, /* {{{ */
   }
   *ret_array = array;
 
-  for (i = 0; i < ci->values_num; i++)
+  for (int i = 0; i < ci->values_num; i++)
   {
     array[array_len] = strdup (ci->values[i].value.string);
     if (array[array_len] == NULL)
@@ -199,8 +198,6 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */
     udb_query_t const *q, udb_query_preparation_area_t *q_area)
 {
   value_list_t vl = VALUE_LIST_INIT;
-  size_t i;
-  int status;
 
   assert (r != NULL);
   assert (r_area->ds != NULL);
@@ -215,7 +212,7 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */
   }
   vl.values_len = r_area->ds->ds_num;
 
-  for (i = 0; i < r->values_num; i++)
+  for (size_t i = 0; i < r->values_num; i++)
   {
     char *value_str = r_area->values_buffer[i];
 
@@ -257,15 +254,27 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */
   {
     if (r->instance_prefix == NULL)
     {
-      strjoin (vl.type_instance, sizeof (vl.type_instance),
+      int status = strjoin (vl.type_instance, sizeof (vl.type_instance),
           r_area->instances_buffer, r->instances_num, "-");
+      if (status < 0)
+      {
+        ERROR ("udb_result_submit: creating type_instance failed with status %d.",
+            status);
+        return (status);
+      }
     }
     else
     {
       char tmp[DATA_MAX_NAME_LEN];
 
-      strjoin (tmp, sizeof (tmp), r_area->instances_buffer,
+      int status = strjoin (tmp, sizeof (tmp), r_area->instances_buffer,
           r->instances_num, "-");
+      if (status < 0)
+      {
+        ERROR ("udb_result_submit: creating type_instance failed with status %d.",
+            status);
+        return (status);
+      }
       tmp[sizeof (tmp) - 1] = 0;
 
       snprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s",
@@ -285,9 +294,9 @@ static int udb_result_submit (udb_result_t *r, /* {{{ */
       return (-ENOMEM);
     }
 
-    for (i = 0; i < r->metadata_num; i++)
+    for (size_t i = 0; i < r->metadata_num; i++)
     {
-      status = meta_data_add_string (vl.meta, r->metadata[i],
+      int status = meta_data_add_string (vl.meta, r->metadata[i],
           r_area->metadata_buffer[i]);
       if (status != 0)
       {
@@ -331,17 +340,15 @@ static int udb_result_handle_result (udb_result_t *r, /* {{{ */
     udb_result_preparation_area_t *r_area,
     udb_query_t const *q, char **column_values)
 {
-  size_t i;
-
   assert (r && q_area && r_area);
 
-  for (i = 0; i < r->instances_num; i++)
+  for (size_t i = 0; i < r->instances_num; i++)
     r_area->instances_buffer[i] = column_values[r_area->instances_pos[i]];
 
-  for (i = 0; i < r->values_num; i++)
+  for (size_t i = 0; i < r->values_num; i++)
     r_area->values_buffer[i] = column_values[r_area->values_pos[i]];
 
-  for (i = 0; i < r->metadata_num; i++)
+  for (size_t i = 0; i < r->metadata_num; i++)
     r_area->metadata_buffer[i] = column_values[r_area->metadata_pos[i]];
 
   if (q->plugin_instance_from)
@@ -354,8 +361,6 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
     udb_result_preparation_area_t *prep_area,
     char **column_names, size_t column_num)
 {
-  size_t i;
-
   if ((r == NULL) || (prep_area == NULL))
     return (-EINVAL);
 
@@ -452,7 +457,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
   /* }}} */
 
   /* Determine the position of the plugin instance column {{{ */
-  for (i = 0; i < r->instances_num; i++)
+  for (size_t i = 0; i < r->instances_num; i++)
   {
     size_t j;
 
@@ -476,7 +481,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
 
 
   /* Determine the position of the value columns {{{ */
-  for (i = 0; i < r->values_num; i++)
+  for (size_t i = 0; i < r->values_num; i++)
   {
     size_t j;
 
@@ -499,7 +504,7 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
   } /* }}} for (i = 0; i < r->values_num; i++) */
 
   /* Determine the position of the metadata columns {{{ */
-  for (i = 0; i < r->metadata_num; i++)
+  for (size_t i = 0; i < r->metadata_num; i++)
   {
     size_t j;
 
@@ -527,23 +532,21 @@ static int udb_result_prepare_result (udb_result_t const *r, /* {{{ */
 
 static void udb_result_free (udb_result_t *r) /* {{{ */
 {
-  size_t i;
-
   if (r == NULL)
     return;
 
   sfree (r->type);
   sfree (r->instance_prefix);
 
-  for (i = 0; i < r->instances_num; i++)
+  for (size_t i = 0; i < r->instances_num; i++)
     sfree (r->instances[i]);
   sfree (r->instances);
 
-  for (i = 0; i < r->values_num; i++)
+  for (size_t i = 0; i < r->values_num; i++)
     sfree (r->values[i]);
   sfree (r->values);
 
-  for (i = 0; i < r->metadata_num; i++)
+  for (size_t i = 0; i < r->metadata_num; i++)
     sfree (r->metadata[i]);
   sfree (r->metadata);
 
@@ -557,7 +560,6 @@ static int udb_result_create (const char *query_name, /* {{{ */
 {
   udb_result_t *r;
   int status;
-  int i;
 
   if (ci->values_num != 0)
   {
@@ -581,7 +583,7 @@ static int udb_result_create (const char *query_name, /* {{{ */
 
   /* Fill the `udb_result_t' structure.. */
   status = 0;
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -679,7 +681,6 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
 
   udb_query_t *q;
   int status;
-  int i;
 
   if ((ret_query_list == NULL) || (ret_query_list_len == NULL))
     return (-EINVAL);
@@ -714,7 +715,7 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
   }
 
   /* Fill the `udb_query_t' structure.. */
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -801,12 +802,10 @@ int udb_query_create (udb_query_t ***ret_query_list, /* {{{ */
 
 void udb_query_free (udb_query_t **query_list, size_t query_list_len) /* {{{ */
 {
-  size_t i;
-
   if (query_list == NULL)
     return;
 
-  for (i = 0; i < query_list_len; i++)
+  for (size_t i = 0; i < query_list_len; i++)
     udb_query_free_one (query_list[i]);
 
   sfree (query_list);
@@ -816,7 +815,6 @@ int udb_query_pick_from_list_by_name (const char *name, /* {{{ */
     udb_query_t **src_list, size_t src_list_len,
     udb_query_t ***dst_list, size_t *dst_list_len)
 {
-  size_t i;
   int num_added;
 
   if ((name == NULL) || (src_list == NULL) || (dst_list == NULL)
@@ -828,7 +826,7 @@ int udb_query_pick_from_list_by_name (const char *name, /* {{{ */
   }
 
   num_added = 0;
-  for (i = 0; i < src_list_len; i++)
+  for (size_t i = 0; i < src_list_len; i++)
   {
     udb_query_t **tmp_list;
     size_t tmp_list_len;
@@ -989,9 +987,7 @@ int udb_query_handle_result (udb_query_t const *q, /* {{{ */
 #if defined(COLLECT_DEBUG) && COLLECT_DEBUG /* {{{ */
   do
   {
-    size_t i;
-
-    for (i = 0; i < prep_area->column_num; i++)
+    for (size_t i = 0; i < prep_area->column_num; i++)
     {
       DEBUG ("db query utils: udb_query_handle_result (%s, %s): "
           "column[%zu] = %s;",
@@ -1052,9 +1048,7 @@ int udb_query_prepare_result (udb_query_t const *q, /* {{{ */
 #if defined(COLLECT_DEBUG) && COLLECT_DEBUG
   do
   {
-    size_t i;
-
-    for (i = 0; i < column_num; i++)
+    for (size_t i = 0; i < column_num; i++)
     {
       DEBUG ("db query utils: udb_query_prepare_result: "
           "query = %s; column[%zu] = %s;",
index 8586adb..fe06de9 100644 (file)
@@ -27,8 +27,6 @@
 #ifndef UTILS_DB_QUERY_H
 #define UTILS_DB_QUERY_H 1
 
-#include "configfile.h"
-
 /*
  * Data types
  */
index a1e4222..3e80e86 100644 (file)
@@ -37,6 +37,7 @@
 #define _BSD_SOURCE
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 
@@ -194,9 +195,7 @@ static int cmp_in6_addr (const struct in6_addr *a,
 
 static inline int ignore_list_match (const struct in6_addr *addr)
 {
-    ip_list_t *ptr;
-
-    for (ptr = IgnoreList; ptr != NULL; ptr = ptr->next)
+    for (ip_list_t *ptr = IgnoreList; ptr != NULL; ptr = ptr->next)
        if (cmp_in6_addr (addr, &ptr->addr) == 0)
            return (1);
     return (0);
@@ -225,7 +224,6 @@ static void ignore_list_add (const struct in6_addr *addr)
 void ignore_list_add_name (const char *name)
 {
     struct addrinfo *ai_list;
-    struct addrinfo *ai_ptr;
     struct in6_addr  addr;
     int status;
 
@@ -233,7 +231,7 @@ void ignore_list_add_name (const char *name)
     if (status != 0)
        return;
 
-    for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+    for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
     {
        if (ai_ptr->ai_family == AF_INET)
        {
@@ -529,7 +527,7 @@ handle_ip(const struct ip *ip, int len)
            return (0);
     if (IPPROTO_UDP != ip->ip_p)
        return 0;
-    memcpy(buf, (void *) ip + offset, len - offset);
+    memcpy(buf, ((char *)ip) + offset, len - offset);
     if (0 == handle_udp((struct udphdr *) buf, len - offset))
        return 0;
     return 1;
@@ -751,22 +749,41 @@ const char *qtype_str(int t)
            case ns_t_srv:      return ("SRV");
            case ns_t_atma:     return ("ATMA");
            case ns_t_naptr:    return ("NAPTR");
+           case ns_t_opt:      return ("OPT");
+# if __NAMESER >= 19991006
            case ns_t_kx:       return ("KX");
            case ns_t_cert:     return ("CERT");
            case ns_t_a6:       return ("A6");
            case ns_t_dname:    return ("DNAME");
            case ns_t_sink:     return ("SINK");
-           case ns_t_opt:      return ("OPT");
-# if __NAMESER >= 19991006
            case ns_t_tsig:     return ("TSIG");
 # endif
+# if __NAMESER >= 20090302
+           case ns_t_apl:      return ("APL");
+           case ns_t_ds:       return ("DS");
+           case ns_t_sshfp:    return ("SSHFP");
+           case ns_t_ipseckey: return ("IPSECKEY");
+           case ns_t_rrsig:    return ("RRSIG");
+           case ns_t_nsec:     return ("NSEC");
+           case ns_t_dnskey:   return ("DNSKEY");
+           case ns_t_dhcid:    return ("DHCID");
+           case ns_t_nsec3:    return ("NSEC3");
+           case ns_t_nsec3param: return ("NSEC3PARAM");
+           case ns_t_hip:      return ("HIP");
+           case ns_t_spf:      return ("SPF");
            case ns_t_ixfr:     return ("IXFR");
+# endif
            case ns_t_axfr:     return ("AXFR");
            case ns_t_mailb:    return ("MAILB");
            case ns_t_maila:    return ("MAILA");
            case ns_t_any:      return ("ANY");
+# if __NAMESER >= 19991006
            case ns_t_zxfr:     return ("ZXFR");
-/* #endif __NAMESER >= 19991006 */
+# endif
+# if __NAMESER >= 20090302
+           case ns_t_dlv:       return ("DLV");
+# endif
+/* #endif __NAMESER >= 19991001 */
 #elif (defined (__BIND)) && (__BIND >= 19950621)
            case T_A:           return ("A"); /* 1 ... */
            case T_NS:          return ("NS");
index d1a580c..893bfbd 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 
 #include "utils_fbhash.h"
@@ -69,7 +70,7 @@ static int fbh_read_file (fbhash_t *h) /* {{{ */
 {
   FILE *fh;
   char buffer[4096];
-  struct flock fl;
+  struct flock fl = { 0 };
   c_avl_tree_t *tree;
   int status;
 
@@ -77,11 +78,8 @@ static int fbh_read_file (fbhash_t *h) /* {{{ */
   if (fh == NULL)
     return (-1);
 
-  memset (&fl, 0, sizeof (fl));
   fl.l_type = F_RDLCK;
   fl.l_whence = SEEK_SET;
-  fl.l_start = 0;
-  fl.l_len = 0; /* == entire file */
   /* TODO: Lock file? -> fcntl */
 
   status = fcntl (fileno (fh), F_SETLK, &fl);
@@ -177,11 +175,9 @@ static int fbh_read_file (fbhash_t *h) /* {{{ */
 
 static int fbh_check_file (fbhash_t *h) /* {{{ */
 {
-  struct stat statbuf;
+  struct stat statbuf = { 0 };
   int status;
 
-  memset (&statbuf, 0, sizeof (statbuf));
-
   status = stat (h->filename, &statbuf);
   if (status != 0)
     return (-1);
index eb5b4b3..0af586f 100644 (file)
@@ -22,6 +22,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 
@@ -84,14 +85,12 @@ static int gr_format_values (char *ret, size_t ret_len,
 static void gr_copy_escape_part (char *dst, const char *src, size_t dst_len,
     char escape_char)
 {
-    size_t i;
-
     memset (dst, 0, dst_len);
 
     if (src == NULL)
         return;
 
-    for (i = 0; i < dst_len; i++)
+    for (size_t i = 0; i < dst_len; i++)
     {
         if (src[i] == 0)
         {
@@ -151,18 +150,29 @@ static int gr_format_name (char *ret, int ret_len,
         sstrncpy (tmp_plugin, n_plugin, sizeof (tmp_plugin));
 
     if (n_type_instance[0] != '\0')
-        ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s",
-            n_type,
-            (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
-            n_type_instance);
+    {
+        if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0)
+            sstrncpy (tmp_type, n_type_instance, sizeof (tmp_type));
+        else
+            ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s",
+                n_type,
+                (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
+                n_type_instance);
+    }
     else
         sstrncpy (tmp_type, n_type, sizeof (tmp_type));
 
     /* Assert always_append_ds -> ds_name */
     assert (!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL));
     if (ds_name != NULL)
-        ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s",
-            prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name);
+    {
+        if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(tmp_plugin, tmp_type) == 0)
+            ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
+                prefix, n_host, postfix, tmp_plugin, ds_name);
+        else
+            ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s",
+                prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name);
+    }
     else
         ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
             prefix, n_host, postfix, tmp_plugin, tmp_type);
@@ -172,11 +182,9 @@ static int gr_format_name (char *ret, int ret_len,
 
 static void escape_graphite_string (char *buffer, char escape_char)
 {
-       char *head;
-
        assert (strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL);
 
-       for (head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN);
+       for (char *head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN);
             *head != '\0';
             head += strcspn(head, GRAPHITE_FORBIDDEN))
                *head = escape_char;
@@ -188,14 +196,13 @@ int format_graphite (char *buffer, size_t buffer_size,
     unsigned int flags)
 {
     int status = 0;
-    size_t i;
     int buffer_pos = 0;
 
     gauge_t *rates = NULL;
     if (flags & GRAPHITE_STORE_RATES)
       rates = uc_get_rate (ds, vl);
 
-    for (i = 0; i < ds->ds_num; i++)
+    for (size_t i = 0; i < ds->ds_num; i++)
     {
         char const *ds_name = NULL;
         char        key[10*DATA_MAX_NAME_LEN];
index 398defb..5165f9e 100644 (file)
 #define UTILS_FORMAT_GRAPHITE_H 1
 
 #include "collectd.h"
+
 #include "plugin.h"
 
 #define GRAPHITE_STORE_RATES        0x01
 #define GRAPHITE_SEPARATE_INSTANCES 0x02
 #define GRAPHITE_ALWAYS_APPEND_DS   0x04
+#define GRAPHITE_DROP_DUPE_FIELDS   0x08
 
 int format_graphite (char *buffer,
     size_t buffer_size, const data_set_t *ds,
index 800b421..5b5fcdf 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/utils_format_json.c
- * Copyright (C) 2009       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"),
  **/
 
 #include "collectd.h"
+
+#include "utils_format_json.h"
+
 #include "plugin.h"
 #include "common.h"
-
 #include "utils_cache.h"
-#include "utils_format_json.h"
+
+#if HAVE_LIBYAJL
+# include <yajl/yajl_common.h>
+# include <yajl/yajl_gen.h>
+# if HAVE_YAJL_YAJL_VERSION_H
+#  include <yajl/yajl_version.h>
+# endif
+# if defined(YAJL_MAJOR) && (YAJL_MAJOR > 1)
+#  define HAVE_YAJL_V2 1
+# endif
+#endif
 
 static int json_escape_string (char *buffer, size_t buffer_size, /* {{{ */
     const char *string)
 {
-  size_t src_pos;
   size_t dst_pos;
 
   if ((buffer == NULL) || (string == NULL))
@@ -56,7 +67,7 @@ static int json_escape_string (char *buffer, size_t buffer_size, /* {{{ */
 
   /* Escape special characters */
   BUFFER_ADD ('"');
-  for (src_pos = 0; string[src_pos] != 0; src_pos++)
+  for (size_t src_pos = 0; string[src_pos] != 0; src_pos++)
   {
     if ((string[src_pos] == '"')
         || (string[src_pos] == '\\'))
@@ -81,7 +92,6 @@ static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */
                 const data_set_t *ds, const value_list_t *vl, int store_rates)
 {
   size_t offset = 0;
-  size_t i;
   gauge_t *rates = NULL;
 
   memset (buffer, 0, buffer_size);
@@ -105,7 +115,7 @@ static int values_to_json (char *buffer, size_t buffer_size, /* {{{ */
 } while (0)
 
   BUFFER_ADD ("[");
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     if (i > 0)
       BUFFER_ADD (",");
@@ -160,7 +170,6 @@ static int dstypes_to_json (char *buffer, size_t buffer_size, /* {{{ */
                 const data_set_t *ds)
 {
   size_t offset = 0;
-  size_t i;
 
   memset (buffer, 0, buffer_size);
 
@@ -177,7 +186,7 @@ static int dstypes_to_json (char *buffer, size_t buffer_size, /* {{{ */
 } while (0)
 
   BUFFER_ADD ("[");
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     if (i > 0)
       BUFFER_ADD (",");
@@ -197,7 +206,6 @@ static int dsnames_to_json (char *buffer, size_t buffer_size, /* {{{ */
                 const data_set_t *ds)
 {
   size_t offset = 0;
-  size_t i;
 
   memset (buffer, 0, buffer_size);
 
@@ -214,7 +222,7 @@ static int dsnames_to_json (char *buffer, size_t buffer_size, /* {{{ */
 } while (0)
 
   BUFFER_ADD ("[");
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     if (i > 0)
       BUFFER_ADD (",");
@@ -235,7 +243,6 @@ static int meta_data_keys_to_json (char *buffer, size_t buffer_size, /* {{{ */
 {
   size_t offset = 0;
   int status;
-  size_t i;
 
   buffer[0] = 0;
 
@@ -250,7 +257,7 @@ static int meta_data_keys_to_json (char *buffer, size_t buffer_size, /* {{{ */
     offset += ((size_t) status); \
 } while (0)
 
-  for (i = 0; i < keys_num; ++i)
+  for (size_t i = 0; i < keys_num; ++i)
   {
     int type;
     char *key = keys[i];
@@ -314,7 +321,6 @@ static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
   char **keys = NULL;
   size_t keys_num;
   int status;
-  size_t i;
 
   if ((buffer == NULL) || (buffer_size == 0) || (meta == NULL))
     return (EINVAL);
@@ -326,7 +332,7 @@ static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
 
   status = meta_data_keys_to_json (buffer, buffer_size, meta, keys, keys_num);
 
-  for (i = 0; i < keys_num; ++i)
+  for (size_t i = 0; i < keys_num; ++i)
     sfree (keys[i]);
   sfree (keys);
 
@@ -498,4 +504,215 @@ int format_json_value_list (char *buffer, /* {{{ */
         store_rates, (*ret_buffer_free) - 2));
 } /* }}} int format_json_value_list */
 
+#if HAVE_LIBYAJL
+static int json_add_string (yajl_gen g, char const *str) /* {{{ */
+{
+  if (str == NULL)
+    return (int) yajl_gen_null (g);
+
+  return (int) yajl_gen_string (g, (unsigned char const *) str, (unsigned int) strlen (str));
+} /* }}} int json_add_string */
+
+#define JSON_ADD(g, str) do {                        \
+  yajl_gen_status status = json_add_string (g, str); \
+  if (status != yajl_gen_status_ok) { return -1; }   \
+} while (0)
+
+#define JSON_ADDF(g, format, ...) do {               \
+  char *str = ssnprintf_alloc (format, __VA_ARGS__); \
+  yajl_gen_status status = json_add_string (g, str); \
+  free (str);                                        \
+  if (status != yajl_gen_status_ok) { return -1; }   \
+} while (0)
+
+static int format_json_meta (yajl_gen g, notification_meta_t *meta) /* {{{ */
+{
+  if (meta == NULL)
+    return 0;
+
+  JSON_ADD (g, meta->name);
+  switch (meta->type)
+  {
+    case NM_TYPE_STRING:
+      JSON_ADD (g, meta->nm_value.nm_string);
+      break;
+    case NM_TYPE_SIGNED_INT:
+      JSON_ADDF (g, "%"PRIi64, meta->nm_value.nm_signed_int);
+      break;
+    case NM_TYPE_UNSIGNED_INT:
+      JSON_ADDF (g, "%"PRIu64, meta->nm_value.nm_unsigned_int);
+      break;
+    case NM_TYPE_DOUBLE:
+      JSON_ADDF (g, JSON_GAUGE_FORMAT, meta->nm_value.nm_double);
+      break;
+    case NM_TYPE_BOOLEAN:
+      JSON_ADD (g, meta->nm_value.nm_boolean ? "true" : "false");
+      break;
+    default:
+      ERROR ("format_json_meta: unknown meta data type %d (name \"%s\")", meta->type, meta->name);
+      yajl_gen_null (g);
+  }
+
+  return format_json_meta (g, meta->next);
+} /* }}} int format_json_meta */
+
+static int format_time (yajl_gen g, cdtime_t t) /* {{{ */
+{
+  char buffer[RFC3339NANO_SIZE] = "";
+
+  if (rfc3339nano (buffer, sizeof (buffer), t) != 0)
+    return -1;
+
+  JSON_ADD (g, buffer);
+  return 0;
+} /* }}} int format_time */
+
+static int format_alert (yajl_gen g, notification_t const *n) /* {{{ */
+{
+  yajl_gen_array_open (g);
+  yajl_gen_map_open (g); /* BEGIN alert */
+
+  /*
+   * labels
+   */
+  JSON_ADD (g, "labels");
+  yajl_gen_map_open (g); /* BEGIN labels */
+
+  JSON_ADD (g, "alertname");
+  if (strncmp (n->plugin, n->type, strlen (n->plugin)) == 0)
+    JSON_ADDF (g, "collectd_%s", n->type);
+  else
+    JSON_ADDF (g, "collectd_%s_%s", n->plugin, n->type);
+
+  JSON_ADD (g, "instance");
+  JSON_ADD (g, n->host);
+
+  /* mangling of plugin instance and type instance into labels is copied from
+   * the Prometheus collectd exporter. */
+  if (strlen (n->plugin_instance) > 0)
+  {
+    JSON_ADD (g, n->plugin);
+    JSON_ADD (g, n->plugin_instance);
+  }
+  if (strlen (n->type_instance) > 0)
+  {
+    if (strlen (n->plugin_instance) > 0)
+      JSON_ADD (g, "type");
+    else
+      JSON_ADD (g, n->plugin);
+    JSON_ADD (g, n->type_instance);
+  }
+
+  JSON_ADD (g, "severity");
+  JSON_ADD (g, (n->severity == NOTIF_FAILURE) ? "FAILURE"
+                   : (n->severity == NOTIF_WARNING) ? "WARNING"
+                   : (n->severity == NOTIF_OKAY) ? "OKAY"
+                   : "UNKNOWN");
+
+  JSON_ADD (g, "service");
+  JSON_ADD (g, "collectd");
+
+  yajl_gen_map_close (g); /* END labels */
+
+  /*
+   * annotations
+   */
+  JSON_ADD (g, "annotations");
+  yajl_gen_map_open (g); /* BEGIN annotations */
+
+  JSON_ADD (g, "summary");
+  JSON_ADD (g, n->message);
+
+  if (format_json_meta (g, n->meta) != 0)
+    return -1;
+
+  yajl_gen_map_close (g); /* END annotations */
+
+  JSON_ADD (g, "startsAt");
+  format_time (g, n->time);
+
+  yajl_gen_map_close (g); /* END alert */
+  yajl_gen_array_close (g);
+
+  return 0;
+} /* }}} format_alert */
+
+/*
+ * Format (prometheus/alertmanager v1):
+ *
+ * [{
+ *   "labels": {
+ *     "alertname": "collectd_cpu",
+ *     "instance":  "host.example.com",
+ *     "severity":  "FAILURE",
+ *     "service":   "collectd",
+ *     "cpu":       "0",
+ *     "type":      "wait"
+ *   },
+ *   "annotations": {
+ *     "summary": "...",
+ *     // meta
+ *   },
+ *   "startsAt": <rfc3339 time>,
+ *   "endsAt": <rfc3339 time>, // not used
+ * }]
+ */
+int format_json_notification (char *buffer, size_t buffer_size, /* {{{ */
+                              notification_t const *n)
+{
+  yajl_gen g;
+  unsigned char const *out;
+#if HAVE_YAJL_V2
+  size_t unused_out_len;
+#else
+  unsigned int unused_out_len;
+#endif
+
+  if ((buffer == NULL) || (n == NULL))
+    return EINVAL;
+
+#if HAVE_YAJL_V2
+  g = yajl_gen_alloc (NULL);
+  if (g == NULL)
+    return -1;
+# if COLLECT_DEBUG
+  yajl_gen_config (g, yajl_gen_beautify, 1);
+  yajl_gen_config (g, yajl_gen_validate_utf8, 1);
+# endif
+
+#else /* !HAVE_YAJL_V2 */
+  yajl_gen_config conf = { 0 };
+# if COLLECT_DEBUG
+  conf.beautify = 1;
+  conf.indentString = "  ";
+# endif
+  g = yajl_gen_alloc (&conf, NULL);
+  if (g == NULL)
+    return -1;
+#endif
+
+  if (format_alert (g, n) != 0)
+  {
+    yajl_gen_clear (g);
+    yajl_gen_free (g);
+    return -1;
+  }
+
+  /* copy to output buffer */
+  yajl_gen_get_buf (g, &out, &unused_out_len);
+  sstrncpy (buffer, (void *) out, buffer_size);
+
+  yajl_gen_clear (g);
+  yajl_gen_free (g);
+  return 0;
+} /* }}} format_json_notification */
+#else
+int format_json_notification (char *buffer, size_t buffer_size, /* {{{ */
+                              notification_t const *n)
+{
+  ERROR ("format_json_notification: Not available (requires libyajl).");
+  return ENOTSUP;
+} /* }}} int format_json_notification */
+#endif
+
 /* vim: set sw=2 sts=2 et fdm=marker : */
index f1fbb6e..a3eda30 100644 (file)
@@ -28,6 +28,7 @@
 #define UTILS_FORMAT_JSON_H 1
 
 #include "collectd.h"
+
 #include "plugin.h"
 
 #ifndef JSON_GAUGE_FORMAT
@@ -41,5 +42,7 @@ int format_json_value_list (char *buffer,
     const data_set_t *ds, const value_list_t *vl, int store_rates);
 int format_json_finalize (char *buffer,
     size_t *ret_buffer_fill, size_t *ret_buffer_free);
+int format_json_notification (char *buffer, size_t buffer_size,
+    notification_t const *n);
 
 #endif /* UTILS_FORMAT_JSON_H */
diff --git a/src/utils_format_json_test.c b/src/utils_format_json_test.c
new file mode 100644 (file)
index 0000000..d13c932
--- /dev/null
@@ -0,0 +1,182 @@
+/**
+ * collectd - src/utils_format_json_test.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>
+ */
+
+/* Workaround for Solaris 10 defining label_t
+ * Issue #1301
+ */
+
+#include "config.h"
+#if KERNEL_SOLARIS
+# ifndef _POSIX_C_SOURCE
+#  define _POSIX_C_SOURCE 200112L
+# endif
+# undef __EXTENSIONS__
+#endif
+
+#include "collectd.h"
+
+#include "testing.h"
+#include "utils_format_json.h"
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+
+#include <yajl/yajl_common.h>
+#include <yajl/yajl_parse.h>
+#if HAVE_YAJL_YAJL_VERSION_H
+# include <yajl/yajl_version.h>
+#endif
+#if YAJL_MAJOR > 1
+# define HAVE_YAJL_V2 1
+#endif
+
+typedef struct
+{
+  char const *key;
+  char const *value;
+} label_t;
+
+typedef struct
+{
+  label_t *expected_labels;
+  size_t   expected_labels_num;
+
+  label_t *current_label;
+} test_case_t;
+
+#if HAVE_YAJL_V2
+static int test_map_key (void *ctx, unsigned char const *key, size_t key_len)
+#else
+static int test_map_key (void *ctx, unsigned char const *key, unsigned int key_len)
+#endif
+{
+  test_case_t *c = ctx;
+  size_t i;
+
+  c->current_label = NULL;
+  for (i = 0; i < c->expected_labels_num; i++)
+  {
+    label_t *l = c->expected_labels + i;
+    if ((strlen (l->key) == key_len)
+        && (strncmp (l->key, (char const *) key, key_len) == 0))
+    {
+      c->current_label = l;
+      break;
+    }
+  }
+
+  return 1; /* continue */
+}
+
+static int expect_label (char const *name, char const *got, char const *want)
+{
+  _Bool ok = (strcmp (got, want) == 0);
+  char msg[1024];
+
+  if (ok)
+    snprintf (msg, sizeof (msg), "label[\"%s\"] = \"%s\"", name, got);
+  else
+    snprintf (msg, sizeof (msg), "label[\"%s\"] = \"%s\", want \"%s\"", name, got, want);
+
+  OK1 (ok, msg);
+  return 0;
+}
+
+#if HAVE_YAJL_V2
+static int test_string (void *ctx, unsigned char const *value, size_t value_len)
+#else
+static int test_string (void *ctx, unsigned char const *value, unsigned int value_len)
+#endif
+{
+  test_case_t *c = ctx;
+
+  if (c->current_label != NULL)
+  {
+    label_t *l = c->current_label;
+    char *got;
+    int status;
+
+    got = malloc (value_len + 1);
+    memmove (got, value, value_len);
+    got[value_len] = 0;
+
+    status = expect_label (l->key, got, l->value);
+
+    free (got);
+
+    if (status != 0)
+      return 0; /* abort */
+  }
+
+  return 1; /* continue */
+}
+
+static int expect_json_labels (char *json, label_t *labels, size_t labels_num)
+{
+  yajl_callbacks funcs = {
+    .yajl_string = test_string,
+    .yajl_map_key = test_map_key,
+  };
+
+  test_case_t c = { labels, labels_num, NULL };
+
+  yajl_handle hndl;
+#if HAVE_YAJL_V2
+  CHECK_NOT_NULL (hndl = yajl_alloc (&funcs, /* alloc = */ NULL, &c));
+#else
+  CHECK_NOT_NULL (hndl = yajl_alloc (&funcs, /* config = */ NULL, /* alloc = */ NULL, &c));
+#endif
+  OK (yajl_parse (hndl, (unsigned char *) json, strlen (json)) == yajl_status_ok);
+
+  yajl_free (hndl);
+  return 0;
+}
+
+DEF_TEST(notification)
+{
+  label_t labels[] = {
+    {"summary", "this is a message"},
+    {"alertname", "collectd_unit_test"},
+    {"instance", "example.com"},
+    {"service", "collectd"},
+    {"unit", "case"},
+  };
+
+  /* 1448284606.125 ^= 1555083754651779072 */
+  notification_t n = { NOTIF_WARNING, 1555083754651779072ULL, "this is a message",
+    "example.com", "unit", "", "test", "case", NULL };
+
+  char got[1024];
+  CHECK_ZERO (format_json_notification (got, sizeof (got), &n));
+  // printf ("got = \"%s\";\n", got);
+
+  return expect_json_labels (got, labels, STATIC_ARRAY_SIZE (labels));
+}
+
+int main (void)
+{
+  RUN_TEST(notification);
+
+  END_TEST;
+}
index 6258c49..41055c7 100644 (file)
@@ -26,6 +26,7 @@
 
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 
@@ -58,7 +59,6 @@
 static int kairosdb_escape_string (char *buffer, size_t buffer_size, /* {{{ */
     const char *string)
 {
-  size_t src_pos;
   size_t dst_pos;
 
   if ((buffer == NULL) || (string == NULL))
@@ -81,7 +81,7 @@ static int kairosdb_escape_string (char *buffer, size_t buffer_size, /* {{{ */
   /* Escape special characters */
   /* authorize -_. and alpha num but also escapes " */
   BUFFER_ADD ('"');
-  for (src_pos = 0; string[src_pos] != 0; src_pos++)
+  for (size_t src_pos = 0; string[src_pos] != 0; src_pos++)
   {
     if (isalnum(string[src_pos]) ||
       0x2d == string[src_pos] ||
@@ -222,7 +222,6 @@ static int value_list_to_kairosdb (char *buffer, size_t buffer_size, /* {{{ */
   char temp[512];
   size_t offset = 0;
   int status;
-  size_t i;
 
   memset (buffer, 0, buffer_size);
 
@@ -244,7 +243,7 @@ static int value_list_to_kairosdb (char *buffer, size_t buffer_size, /* {{{ */
   BUFFER_ADD (",\"%s\": %s", (key), temp); \
 } while (0)
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     /* All value lists have a leading comma. The first one will be replaced with
      * a square bracket in `format_kairosdb_finalize'. */
index 23cc862..764b0b1 100644 (file)
@@ -28,6 +28,7 @@
 #define UTILS_FORMAT_KAIROSDB_H 1
 
 #include "collectd.h"
+
 #include "plugin.h"
 
 #ifndef JSON_GAUGE_FORMAT
index 41af00c..c67752a 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "utils_latency.h"
 #include "common.h"
@@ -96,9 +97,8 @@ static void change_bin_width (latency_counter_t *lc, cdtime_t latency) /* {{{ */
   if (lc->num > 0) // if the histogram has data then iterate else skip
   {
       double width_change_ratio = ((double) old_bin_width) / ((double) new_bin_width);
-      size_t i;
 
-      for (i = 0; i < HISTOGRAM_NUM_BINS; i++)
+      for (size_t i = 0; i < HISTOGRAM_NUM_BINS; i++)
       {
          size_t new_bin = (size_t) (((double) i) * width_change_ratio);
          if (i == new_bin)
@@ -125,8 +125,8 @@ latency_counter_t *latency_counter_create (void) /* {{{ */
   if (lc == NULL)
     return (NULL);
 
-  latency_counter_reset (lc);
   lc->bin_width = HISTOGRAM_DEFAULT_BIN_WIDTH;
+  latency_counter_reset (lc);
   return (lc);
 } /* }}} latency_counter_t *latency_counter_create */
 
@@ -175,6 +175,28 @@ void latency_counter_reset (latency_counter_t *lc) /* {{{ */
     return;
 
   cdtime_t bin_width = lc->bin_width;
+  cdtime_t max_bin = (lc->max - 1) / lc->bin_width;
+
+/*
+  If max latency is REDUCE_THRESHOLD times less than histogram's range,
+  then cut it in half. REDUCE_THRESHOLD must be >= 2.
+  Value of 4 is selected to reduce frequent changes of bin width.
+*/
+#define REDUCE_THRESHOLD 4
+  if ((lc->num > 0) && (lc->bin_width >= HISTOGRAM_DEFAULT_BIN_WIDTH * 2)
+     && (max_bin < HISTOGRAM_NUM_BINS / REDUCE_THRESHOLD))
+  {
+    /* new bin width will be the previous power of 2 */
+    bin_width = bin_width / 2;
+
+    DEBUG("utils_latency: latency_counter_reset: max_latency = %.3f; "
+          "max_bin = %"PRIu64"; old_bin_width = %.3f; new_bin_width = %.3f;",
+        CDTIME_T_TO_DOUBLE (lc->max),
+        max_bin,
+        CDTIME_T_TO_DOUBLE (lc->bin_width),
+        CDTIME_T_TO_DOUBLE (bin_width));
+  }
+
   memset (lc, 0, sizeof (*lc));
 
   /* preserve bin width */
index 2cfa71b..cb56b08 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "utils_time.h"
 
 struct latency_counter_s;
index f275813..9c3b0ad 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "common.h" /* for STATIC_ARRAY_SIZE */
 #include "collectd.h"
+
 #include "testing.h"
 #include "utils_time.h"
 #include "utils_latency.h"
@@ -49,12 +50,11 @@ DEF_TEST(simple)
     { 99, 0.3,  99, 103, 20.6},
     /* { -1, 0.3,  99, 103, 20.6}, see issue #1139 */
   };
-  size_t i;
   latency_counter_t *l;
 
   CHECK_NOT_NULL (l = latency_counter_create ());
 
-  for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+  for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
     printf ("# case %zu: DOUBLE_TO_CDTIME_T(%g) = %"PRIu64"\n",
         i, cases[i].val, DOUBLE_TO_CDTIME_T (cases[i].val));
     latency_counter_add (l, DOUBLE_TO_CDTIME_T (cases[i].val));
@@ -71,12 +71,11 @@ DEF_TEST(simple)
 
 DEF_TEST(percentile)
 {
-  size_t i;
   latency_counter_t *l;
 
   CHECK_NOT_NULL (l = latency_counter_create ());
 
-  for (i = 0; i < 100; i++) {
+  for (size_t i = 0; i < 100; i++) {
     latency_counter_add (l, TIME_T_TO_CDTIME_T (((time_t) i) + 1));
   }
 
diff --git a/src/utils_lua.c b/src/utils_lua.c
new file mode 100644 (file)
index 0000000..f746655
--- /dev/null
@@ -0,0 +1,322 @@
+/**
+ * collectd - src/utils_lua.c
+ * Copyright (C) 2010       Florian 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 Forster <octo at collectd.org>
+ **/
+
+/* <lua5.1/luaconf.h> defines a macro using "sprintf". Although not used here,
+ * GCC will complain about the macro definition. */
+#define DONT_POISON_SPRINTF_YET
+
+#include "utils_lua.h"
+#include "common.h"
+
+static int ltoc_values(lua_State *L, /* {{{ */
+                       const data_set_t *ds, value_t *ret_values) {
+  if (!lua_istable(L, -1)) {
+    WARNING("ltoc_values: not a table");
+    return (-1);
+  }
+
+  /* Push initial key */
+  lua_pushnil(L); /* +1 = 1 */
+  size_t i = 0;
+  while (lua_next(L, -2) != 0) /* -1+2 = 2 || -1 = 0 */
+  {
+    if (i >= ds->ds_num) {
+      lua_pop(L, 2); /* -2 = 0 */
+      i++;
+      break;
+    }
+
+    ret_values[i] = luaC_tovalue(L, -1, ds->ds[i].type);
+
+    /* Pop the value */
+    lua_pop(L, 1); /* -1 = 1 */
+    i++;
+  } /* while (lua_next) */
+
+  if (i != ds->ds_num) {
+    WARNING("ltoc_values: invalid size for datasource \"%s\": expected %zu, "
+            "got %zu",
+            ds->type, ds->ds_num, i);
+    return (-1);
+  }
+
+  return (0);
+} /* }}} int ltoc_values */
+
+static int ltoc_table_values(lua_State *L, int idx, /* {{{ */
+                             const data_set_t *ds, value_list_t *vl) {
+  /* We're only called from "luaC_tovaluelist", which ensures that "idx" is an
+   * absolute index (i.e. a positive number) */
+  assert(idx > 0);
+
+  lua_getfield(L, idx, "values");
+  if (!lua_istable(L, -1)) {
+    WARNING("utils_lua: ltoc_table_values: The \"values\" member is a %s "
+            "value, not a table.",
+            lua_typename(L, lua_type(L, -1)));
+    lua_pop(L, 1);
+    return (-1);
+  }
+
+  vl->values_len = ds->ds_num;
+  vl->values = calloc(vl->values_len, sizeof(*vl->values));
+  if (vl->values == NULL) {
+    ERROR("utils_lua: calloc failed.");
+    vl->values_len = 0;
+    lua_pop(L, 1);
+    return (-1);
+  }
+
+  int status = ltoc_values(L, ds, vl->values);
+
+  lua_pop(L, 1);
+
+  if (status != 0) {
+    vl->values_len = 0;
+    sfree(vl->values);
+  }
+
+  return (status);
+} /* }}} int ltoc_table_values */
+
+static int luaC_pushvalues(lua_State *L, const data_set_t *ds,
+                           const value_list_t *vl) /* {{{ */
+{
+  assert(vl->values_len == ds->ds_num);
+
+  lua_newtable(L);
+  for (size_t i = 0; i < vl->values_len; i++) {
+    lua_pushinteger(L, (lua_Integer)i + 1);
+    luaC_pushvalue(L, vl->values[i], ds->ds[i].type);
+    lua_settable(L, -3);
+  }
+
+  return (0);
+} /* }}} int luaC_pushvalues */
+
+static int luaC_pushdstypes(lua_State *L, const data_set_t *ds) /* {{{ */
+{
+  lua_newtable(L);
+  for (size_t i = 0; i < ds->ds_num; i++) {
+    lua_pushinteger(L, (lua_Integer)i);
+    lua_pushstring(L, DS_TYPE_TO_STRING(ds->ds[i].type));
+    lua_settable(L, -3);
+  }
+
+  return (0);
+} /* }}} int luaC_pushdstypes */
+
+static int luaC_pushdsnames(lua_State *L, const data_set_t *ds) /* {{{ */
+{
+  lua_newtable(L);
+  for (size_t i = 0; i < ds->ds_num; i++) {
+    lua_pushinteger(L, (lua_Integer)i);
+    lua_pushstring(L, ds->ds[i].name);
+    lua_settable(L, -3);
+  }
+
+  return (0);
+} /* }}} int luaC_pushdsnames */
+
+/*
+ * Public functions
+ */
+cdtime_t luaC_tocdtime(lua_State *L, int idx) /* {{{ */
+{
+  if (!lua_isnumber(L, /* stack pos = */ idx))
+    return (0);
+
+  double d = lua_tonumber(L, idx);
+
+  return (DOUBLE_TO_CDTIME_T(d));
+} /* }}} int ltoc_table_cdtime */
+
+int luaC_tostringbuffer(lua_State *L, int idx, /* {{{ */
+                        char *buffer, size_t buffer_size) {
+  const char *str = lua_tostring(L, idx);
+  if (str == NULL)
+    return (-1);
+
+  sstrncpy(buffer, str, buffer_size);
+  return (0);
+} /* }}} int luaC_tostringbuffer */
+
+value_t luaC_tovalue(lua_State *L, int idx, int ds_type) /* {{{ */
+{
+  value_t v = { 0 };
+
+  if (!lua_isnumber(L, idx))
+    return (v);
+
+  if (ds_type == DS_TYPE_GAUGE)
+    v.gauge = (gauge_t)lua_tonumber(L, /* stack pos = */ -1);
+  else if (ds_type == DS_TYPE_DERIVE)
+    v.derive = (derive_t)lua_tointeger(L, /* stack pos = */ -1);
+  else if (ds_type == DS_TYPE_COUNTER)
+    v.counter = (counter_t)lua_tointeger(L, /* stack pos = */ -1);
+  else if (ds_type == DS_TYPE_ABSOLUTE)
+    v.absolute = (absolute_t)lua_tointeger(L, /* stack pos = */ -1);
+
+  return (v);
+} /* }}} value_t luaC_tovalue */
+
+value_list_t *luaC_tovaluelist(lua_State *L, int idx) /* {{{ */
+{
+#if COLLECT_DEBUG
+  int stack_top_before = lua_gettop(L);
+#endif
+
+  /* Convert relative indexes to absolute indexes, so it doesn't change when we
+   * push / pop stuff. */
+  if (idx < 1)
+    idx += lua_gettop(L) + 1;
+
+  /* Check that idx is in the valid range */
+  if ((idx < 1) || (idx > lua_gettop(L))) {
+    DEBUG("luaC_tovaluelist: idx(%d), top(%d)", idx, stack_top_before);
+    return (NULL);
+  }
+
+  value_list_t *vl = calloc(1, sizeof(*vl));
+  if (vl == NULL) {
+    DEBUG("luaC_tovaluelist: calloc failed");
+    return (NULL);
+  }
+
+  /* Push initial key */
+  lua_pushnil(L);
+  while (lua_next(L, idx) != 0) {
+    const char *key = lua_tostring(L, -2);
+
+    if (key == NULL) {
+      DEBUG("luaC_tovaluelist: Ignoring non-string key.");
+    } else if (strcasecmp("host", key) == 0)
+      luaC_tostringbuffer(L, -1, vl->host, sizeof(vl->host));
+    else if (strcasecmp("plugin", key) == 0)
+      luaC_tostringbuffer(L, -1, vl->plugin, sizeof(vl->plugin));
+    else if (strcasecmp("plugin_instance", key) == 0)
+      luaC_tostringbuffer(L, -1, vl->plugin_instance,
+                          sizeof(vl->plugin_instance));
+    else if (strcasecmp("type", key) == 0)
+      luaC_tostringbuffer(L, -1, vl->type, sizeof(vl->type));
+    else if (strcasecmp("type_instance", key) == 0)
+      luaC_tostringbuffer(L, -1, vl->type_instance,
+                          sizeof(vl->type_instance));
+    else if (strcasecmp("time", key) == 0)
+      vl->time = luaC_tocdtime(L, -1);
+    else if (strcasecmp("interval", key) == 0)
+      vl->interval = luaC_tocdtime(L, -1);
+    else if (strcasecmp("values", key) == 0) {
+      /* This key is not handled here, because we have to assure "type" is read
+       * first. */
+    } else {
+      DEBUG("luaC_tovaluelist: Ignoring unknown key \"%s\".", key);
+    }
+
+    /* Pop the value */
+    lua_pop(L, 1);
+  }
+
+  const data_set_t *ds = plugin_get_ds(vl->type);
+  if (ds == NULL) {
+    INFO("utils_lua: Unable to lookup type \"%s\".", vl->type);
+    sfree(vl);
+    return (NULL);
+  }
+
+  int status = ltoc_table_values(L, idx, ds, vl);
+  if (status != 0) {
+    WARNING("utils_lua: ltoc_table_values failed.");
+    sfree(vl);
+    return (NULL);
+  }
+
+#if COLLECT_DEBUG
+  assert(stack_top_before == lua_gettop(L));
+#endif
+  return (vl);
+} /* }}} value_list_t *luaC_tovaluelist */
+
+int luaC_pushcdtime(lua_State *L, cdtime_t t) /* {{{ */
+{
+  double d = CDTIME_T_TO_DOUBLE(t);
+
+  lua_pushnumber(L, (lua_Number)d);
+  return (0);
+} /* }}} int luaC_pushcdtime */
+
+int luaC_pushvalue(lua_State *L, value_t v, int ds_type) /* {{{ */
+{
+  if (ds_type == DS_TYPE_GAUGE)
+    lua_pushnumber(L, (lua_Number)v.gauge);
+  else if (ds_type == DS_TYPE_DERIVE)
+    lua_pushinteger(L, (lua_Integer)v.derive);
+  else if (ds_type == DS_TYPE_COUNTER)
+    lua_pushinteger(L, (lua_Integer)v.counter);
+  else if (ds_type == DS_TYPE_ABSOLUTE)
+    lua_pushinteger(L, (lua_Integer)v.absolute);
+  else
+    return (-1);
+  return (0);
+} /* }}} int luaC_pushvalue */
+
+int luaC_pushvaluelist(lua_State *L, const data_set_t *ds,
+                       const value_list_t *vl) /* {{{ */
+{
+  lua_newtable(L);
+
+  lua_pushstring(L, vl->host);
+  lua_setfield(L, -2, "host");
+
+  lua_pushstring(L, vl->plugin);
+  lua_setfield(L, -2, "plugin");
+  lua_pushstring(L, vl->plugin_instance);
+  lua_setfield(L, -2, "plugin_instance");
+
+  lua_pushstring(L, vl->type);
+  lua_setfield(L, -2, "type");
+  lua_pushstring(L, vl->type_instance);
+  lua_setfield(L, -2, "type_instance");
+
+  luaC_pushvalues(L, ds, vl);
+  lua_setfield(L, -2, "values");
+
+  luaC_pushdstypes(L, ds);
+  lua_setfield(L, -2, "dstypes");
+
+  luaC_pushdsnames(L, ds);
+  lua_setfield(L, -2, "dsnames");
+
+  luaC_pushcdtime(L, vl->time);
+  lua_setfield(L, -2, "time");
+
+  luaC_pushcdtime(L, vl->interval);
+  lua_setfield(L, -2, "interval");
+
+  return (0);
+} /* }}} int luaC_pushvaluelist */
+
+/* vim: set sw=2 sts=2 et fdm=marker : */
diff --git a/src/utils_lua.h b/src/utils_lua.h
new file mode 100644 (file)
index 0000000..b594190
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * collectd - src/utils_lua.h
+ * Copyright (C) 2010       Florian 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 Forster <octo at collectd.org>
+ **/
+
+#ifndef UTILS_LUA_H
+#define UTILS_LUA_H 1
+
+#include "collectd.h"
+#include "plugin.h"
+
+#ifndef DONT_POISON_SPRINTF_YET
+#error "Files including utils_lua.h need to define DONT_POISON_SPRINTF_YET."
+#endif
+#include <lua.h>
+
+/*
+ * access functions (stack -> C)
+ */
+cdtime_t luaC_tocdtime(lua_State *L, int idx);
+int luaC_tostringbuffer(lua_State *L, int idx, char *buffer,
+                        size_t buffer_size);
+value_t luaC_tovalue(lua_State *L, int idx, int ds_type);
+value_list_t *luaC_tovaluelist(lua_State *L, int idx);
+
+/*
+ * push functions (C -> stack)
+ */
+int luaC_pushcdtime(lua_State *L, cdtime_t t);
+int luaC_pushvalue(lua_State *L, value_t v, int ds_type);
+int luaC_pushvaluelist(lua_State *L, const data_set_t *ds,
+                       const value_list_t *vl);
+
+#endif /* UTILS_LUA_H */
+/* vim: set sw=2 sts=2 et fdm=marker : */
index a36882c..e527c25 100644 (file)
 # include "config.h"
 #endif
 
+#define _GNU_SOURCE
+
+#include "collectd.h"
+
+#include "utils_mount.h"
+
 #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 */
 
@@ -215,7 +217,6 @@ uuidcache_init(void)
        FILE *procpt;
        char uuid[16], *label = NULL;
        char device[110];
-       int firstPass;
        int handleOnFirst;
 
        if(uuidCache) {
@@ -227,7 +228,7 @@ uuidcache_init(void)
                return;
        }
 
-       for(firstPass = 1; firstPass >= 0; firstPass--) {
+       for(int firstPass = 1; firstPass >= 0; firstPass--) {
                fseek(procpt, 0, SEEK_SET);
                while(fgets(line, sizeof(line), procpt)) {
                        if(sscanf(line, " %d %d %d %[^\n ]",
@@ -317,14 +318,13 @@ static char *
 get_spec_by_uuid(const char *s)
 {
        char uuid[16];
-       int i;
 
        if(strlen(s) != 36
        || s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') {
                goto bad_uuid;
        }
 
-       for(i=0; i<16; i++) {
+       for(int i=0; i<16; i++) {
                if(*s == '-') {
                        s++;
                }
@@ -381,7 +381,6 @@ static char *get_device_name(const char *optstr)
 static cu_mount_t *cu_mount_listmntent (void)
 {
        cu_mount_t *last = *list;
-       struct tabmntent *p;
        struct mntent *mnt;
 
        struct tabmntent *mntlist;
@@ -393,7 +392,7 @@ static cu_mount_t *cu_mount_listmntent (void)
 #endif /* COLLECT_DEBUG */
        }
 
-       for(p = mntlist; p; p = p->next) {
+       for(struct tabmntent *p = mntlist; p; p = p->next) {
                char *loop = NULL, *device = NULL;
 
                mnt = p->ment;
@@ -450,7 +449,6 @@ static cu_mount_t *cu_mount_getfsstat (void)
        STRUCT_STATFS *buf;
 
        int num;
-       int i;
 
        cu_mount_t *first = NULL;
        cu_mount_t *last  = NULL;
@@ -483,7 +481,7 @@ static cu_mount_t *cu_mount_getfsstat (void)
                return (NULL);
        }
 
-       for (i = 0; i < num; i++)
+       for (int i = 0; i < num; i++)
        {
                if ((new = calloc (1, sizeof (*new))) == NULL)
                        break;
@@ -740,10 +738,9 @@ cu_mount_t *cu_mount_getlist(cu_mount_t **list)
 
 void cu_mount_freelist (cu_mount_t *list)
 {
-       cu_mount_t *this;
        cu_mount_t *next;
 
-       for (this = list; this != NULL; this = next)
+       for (cu_mount_t *this = list; this != NULL; this = next)
        {
                next = this->next;
 
index dc6f79f..c084deb 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "testing.h"
 #include "utils_mount.h"
index f3ec71a..3652a66 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "utils_parse_option.h"
 
 int parse_string (char **ret_buffer, char **ret_string)
index 6da5167..884de8f 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "utils_rrdcreate.h"
 
@@ -82,9 +83,7 @@ static pthread_mutex_t async_creation_lock = PTHREAD_MUTEX_INITIALIZER;
  */
 static void rra_free (int rra_num, char **rra_def) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < rra_num; i++)
+  for (int i = 0; i < rra_num; i++)
   {
     sfree (rra_def[i]);
   }
@@ -99,8 +98,7 @@ static void srrd_create_args_destroy (srrd_create_args_t *args)
   sfree (args->filename);
   if (args->argv != NULL)
   {
-    int i;
-    for (i = 0; i < args->argc; i++)
+    for (int i = 0; i < args->argc; i++)
       sfree (args->argv[i]);
     sfree (args->argv);
   }
@@ -172,7 +170,6 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
 
   int cdp_num;
   int cdp_len;
-  int i, j;
 
   /* The stepsize we use here: If it is user-set, use it. If not, use the
    * interval of the value-list. */
@@ -220,7 +217,7 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
   rra_num = 0;
 
   cdp_len = 0;
-  for (i = 0; i < rts_num; i++)
+  for (int i = 0; i < rts_num; i++)
   {
     int span = rts[i];
 
@@ -236,7 +233,7 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
     cdp_num = (int) ceil (((double) span)
         / ((double) (cdp_len * ss)));
 
-    for (j = 0; j < rra_types_num; j++)
+    for (int j = 0; j < rra_types_num; j++)
     {
       char buffer[128];
       int status;
@@ -269,9 +266,7 @@ static int rra_get (char ***ret, const value_list_t *vl, /* {{{ */
 
 static void ds_free (int ds_num, char **ds_def) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ds_num; i++)
+  for (int i = 0; i < ds_num; i++)
     if (ds_def[i] != NULL)
       free (ds_def[i]);
   free (ds_def);
index 6081c90..2ca9ddf 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "collectd.h"
 
+
 #include <pthread.h>
 #include <regex.h>
 
index 2d541ee..4466063 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "testing.h"
 #include "utils_vl_lookup.h"
 
@@ -90,7 +91,6 @@ static int checked_lookup_add (lookup_t *obj, /* {{{ */
   identifier_t ident;
   void *user_class;
 
-  memset (&ident, 0, sizeof (ident));
   strncpy (ident.host, host, sizeof (ident.host));
   strncpy (ident.plugin, plugin, sizeof (ident.plugin));
   strncpy (ident.plugin_instance, plugin_instance, sizeof (ident.plugin_instance));
index 3836e52..8bae376 100644 (file)
@@ -1,6 +1,7 @@
 /**
  * collectd - src/uuid.c
  * Copyright (C) 2007  Red Hat Inc.
+ * Copyright (C) 2015  Ruben Kerkhof
  *
  * 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
  **/
 
 #include "collectd.h"
+
 #include "common.h"
-#include "configfile.h"
 #include "plugin.h"
 
+#if HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
 #if HAVE_LIBHAL_H
 #include <libhal.h>
 #endif
@@ -47,18 +52,20 @@ looks_like_a_uuid (const char *uuid)
 {
     int len;
 
-    if (!uuid) return 0;
+    if (!uuid)
+        return (0);
 
     len = strlen (uuid);
 
     if (len < UUID_PRINTABLE_COMPACT_LENGTH)
-        return 0;
+        return (0);
 
     while (*uuid) {
-        if (!isxdigit ((int)*uuid) && *uuid != '-') return 0;
+        if (!isxdigit ((int)*uuid) && *uuid != '-')
+            return (0);
         uuid++;
     }
-    return 1;
+    return (1);
 }
 
 static char *
@@ -86,26 +93,52 @@ uuid_parse_dmidecode(FILE *file)
         if (!looks_like_a_uuid (fields[1]))
             continue;
 
-        return strdup (fields[1]);
+        return (strdup (fields[1]));
     }
-    return NULL;
+    return (NULL);
 }
 
 static char *
 uuid_get_from_dmidecode(void)
 {
-    FILE *dmidecode = popen("dmidecode 2>/dev/null", "r");
+    FILE *dmidecode = popen("dmidecode -t system 2>/dev/null", "r");
     char *uuid;
 
-    if (!dmidecode) {
-        return NULL;
-    }
+    if (!dmidecode)
+        return (NULL);
 
     uuid = uuid_parse_dmidecode(dmidecode);
 
     pclose(dmidecode);
-    return uuid;
+    return (uuid);
+}
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
+static char *
+uuid_get_from_sysctlbyname(const char *name)
+{
+    char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1];
+    size_t len = sizeof (uuid);
+    if (sysctlbyname(name, &uuid, &len, NULL, 0) == -1)
+        return NULL;
+    return (strdup (uuid));
+}
+#elif defined(__OpenBSD__)
+static char *
+uuid_get_from_sysctl(void)
+{
+    char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1];
+    size_t len = sizeof (uuid);
+    int mib[2];
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_UUID;
+
+    if (sysctl(mib, 2, uuid, &len, NULL, 0) == -1)
+        return NULL;
+    return (strdup (uuid));
 }
+#endif
 
 #if HAVE_LIBHAL_H
 
@@ -122,50 +155,42 @@ uuid_get_from_hal(void)
 
     dbus_error_init(&error);
 
-    if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) ) {
+    if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)))
         goto bailout_nobus;
-    }
 
     ctx = libhal_ctx_new();
     libhal_ctx_set_dbus_connection(ctx, con);
 
-    if (!libhal_ctx_init(ctx, &error)) {
+    if (!libhal_ctx_init(ctx, &error))
         goto bailout;
-    }
 
     if (!libhal_device_property_exists(ctx,
                                        UUID_PATH,
                                        UUID_PROPERTY,
-                                       &error)) {
+                                       &error))
         goto bailout;
-    }
 
     char *uuid  = libhal_device_get_property_string(ctx,
                                                     UUID_PATH,
                                                     UUID_PROPERTY,
                                                     &error);
-    if (looks_like_a_uuid (uuid)) {
-        return uuid;
-    }
+    if (looks_like_a_uuid (uuid))
+        return (uuid);
 
  bailout:
     {
         DBusError ctxerror;
         dbus_error_init(&ctxerror);
-        if (!(libhal_ctx_shutdown(ctx, &ctxerror))) {
+        if (!(libhal_ctx_shutdown(ctx, &ctxerror)))
             dbus_error_free(&ctxerror);
-        }
     }
 
     libhal_ctx_free(ctx);
-    //dbus_connection_unref(con);
 
  bailout_nobus:
-    if (dbus_error_is_set(&error)) {
-        /*printf("Error %s\n", error.name);*/
+    if (dbus_error_is_set(&error))
         dbus_error_free(&error);
-    }
-    return NULL;
+    return (NULL);
 }
 #endif
 
@@ -177,16 +202,16 @@ uuid_get_from_file(const char *path)
 
     file = fopen (path, "r");
     if (file == NULL)
-        return NULL;
+        return (NULL);
 
     if (!fgets(uuid, sizeof(uuid), file)) {
         fclose(file);
-        return NULL;
+        return (NULL);
     }
     fclose(file);
     strstripnewline (uuid);
 
-    return strdup (uuid);
+    return (strdup (uuid));
 }
 
 static char *
@@ -195,25 +220,40 @@ uuid_get_local(void)
     char *uuid;
 
     /* Check /etc/uuid / UUIDFile before any other method. */
-    if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL){
-        return uuid;
-    }
+    if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL)
+        return (uuid);
+
+#if defined(__APPLE__)
+    if ((uuid = uuid_get_from_sysctlbyname("kern.uuid")) != NULL)
+        return (uuid);
+#elif defined(__FreeBSD__)
+    if ((uuid = uuid_get_from_sysctlbyname("kern.hostuuid")) != NULL)
+        return (uuid);
+#elif defined(__NetBSD__)
+    if ((uuid = uuid_get_from_sysctlbyname("machdep.dmi.system-uuid")) != NULL)
+        return (uuid);
+#elif defined(__OpenBSD__)
+    if ((uuid = uuid_get_from_sysctl()) != NULL)
+        return (uuid);
+#elif defined(__linux__)
+    if ((uuid = uuid_get_from_file("/sys/class/dmi/id/product_uuid")) != NULL)
+        return (uuid);
+#endif
 
 #if HAVE_LIBHAL_H
-    if ((uuid = uuid_get_from_hal()) != NULL) {
-        return uuid;
-    }
+    if ((uuid = uuid_get_from_hal()) != NULL)
+        return (uuid);
 #endif
 
-    if ((uuid = uuid_get_from_dmidecode()) != NULL) {
-        return uuid;
-    }
+    if ((uuid = uuid_get_from_dmidecode()) != NULL)
+        return (uuid);
 
-    if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) {
-        return uuid;
-    }
+#if defined(__linux__)
+    if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL)
+        return (uuid);
+#endif
 
-    return NULL;
+    return (NULL);
 }
 
 static int
@@ -222,14 +262,13 @@ uuid_config (const char *key, const char *value)
     if (strcasecmp (key, "UUIDFile") == 0) {
         char *tmp = strdup (value);
         if (tmp == NULL)
-            return -1;
+            return (-1);
         sfree (uuidfile);
         uuidfile = tmp;
-    } else {
-        return 1;
+        return (0);
     }
 
-    return 0;
+    return (1);
 }
 
 static int
@@ -240,11 +279,11 @@ uuid_init (void)
     if (uuid) {
         sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN);
         sfree (uuid);
-        return 0;
+        return (0);
     }
 
     WARNING ("uuid: could not read UUID using any known method");
-    return 0;
+    return (0);
 }
 
 void module_register (void)
index 771d4a4..18f5902 100644 (file)
@@ -24,9 +24,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #if HAVE_VARNISH_V4
 #include <vapi/vsm.h>
@@ -117,22 +117,16 @@ static int varnish_submit_gauge (const char *plugin_instance, /* {{{ */
                const char *category, const char *type, const char *type_instance,
                uint64_t gauge_value)
 {
-       value_t value;
-
-       value.gauge = (gauge_t) gauge_value;
-
-       return (varnish_submit (plugin_instance, category, type, type_instance, value));
+       return (varnish_submit (plugin_instance, category, type, type_instance,
+                               (value_t) { .gauge = (gauge_t) gauge_value }));
 } /* }}} int varnish_submit_gauge */
 
 static int varnish_submit_derive (const char *plugin_instance, /* {{{ */
                const char *category, const char *type, const char *type_instance,
                uint64_t derive_value)
 {
-       value_t value;
-
-       value.derive = (derive_t) derive_value;
-
-       return (varnish_submit (plugin_instance, category, type, type_instance, value));
+       return (varnish_submit (plugin_instance, category, type, type_instance,
+                               (value_t) { .derive = (derive_t) derive_value }));
 } /* }}} int varnish_submit_derive */
 
 #if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
@@ -938,7 +932,6 @@ static int varnish_config_apply_default (user_config_t *conf) /* {{{ */
 static int varnish_init (void) /* {{{ */
 {
        user_config_t *conf;
-       user_data_t ud;
 
        if (have_instance)
                return (0);
@@ -952,14 +945,14 @@ static int varnish_init (void) /* {{{ */
 
        varnish_config_apply_default (conf);
 
-       ud.data = conf;
-       ud.free_func = varnish_config_free;
-
        plugin_register_complex_read (/* group = */ "varnish",
                        /* name      = */ "varnish/localhost",
                        /* callback  = */ varnish_read,
                        /* interval  = */ 0,
-                       /* user data = */ &ud);
+                       &(user_data_t) {
+                               .data = conf,
+                               .free_func = varnish_config_free,
+                       });
 
        return (0);
 } /* }}} int varnish_init */
@@ -967,9 +960,7 @@ static int varnish_init (void) /* {{{ */
 static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
 {
        user_config_t *conf;
-       user_data_t ud;
        char callback_name[DATA_MAX_NAME_LEN];
-       int i;
 
        conf = calloc (1, sizeof (*conf));
        if (conf == NULL)
@@ -1004,7 +995,7 @@ static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
                return (EINVAL);
        }
 
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
@@ -1132,14 +1123,14 @@ static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
        ssnprintf (callback_name, sizeof (callback_name), "varnish/%s",
                        (conf->instance == NULL) ? "localhost" : conf->instance);
 
-       ud.data = conf;
-       ud.free_func = varnish_config_free;
-
        plugin_register_complex_read (/* group = */ "varnish",
                        /* name      = */ callback_name,
                        /* callback  = */ varnish_read,
                        /* interval  = */ 0,
-                       /* user data = */ &ud);
+                       &(user_data_t) {
+                               .data = conf,
+                               .free_func = varnish_config_free,
+                       });
 
        have_instance = 1;
 
@@ -1148,9 +1139,7 @@ static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
 
 static int varnish_config (oconfig_item_t *ci) /* {{{ */
 {
-       int i;
-
-       for (i = 0; i < ci->children_num; i++)
+       for (int i = 0; i < ci->children_num; i++)
        {
                oconfig_item_t *child = ci->children + i;
 
index 16bb77b..99fe42d 100644 (file)
@@ -20,9 +20,9 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 #include "utils_ignorelist.h"
 #include "utils_complain.h"
 
@@ -154,7 +154,7 @@ static int refresh_lists (void);
 static void
 init_value_list (value_list_t *vl, virDomainPtr dom)
 {
-    int i, n;
+    int n;
     const char *name;
     char uuid[VIR_UUID_STRING_BUFLEN];
 
@@ -163,7 +163,7 @@ init_value_list (value_list_t *vl, virDomainPtr dom)
     vl->host[0] = '\0';
 
     /* Construct the hostname field according to HostnameFormat. */
-    for (i = 0; i < HF_MAX_FIELDS; ++i) {
+    for (int i = 0; i < HF_MAX_FIELDS; ++i) {
         if (hostname_format[i] == hf_none)
             continue;
 
@@ -194,7 +194,7 @@ init_value_list (value_list_t *vl, virDomainPtr dom)
     vl->host[sizeof (vl->host) - 1] = '\0';
 
     /* Construct the plugin instance field according to PluginInstanceFormat. */
-    for (i = 0; i < PLGINST_MAX_FIELDS; ++i) {
+    for (int i = 0; i < PLGINST_MAX_FIELDS; ++i) {
         if (plugin_instance_format[i] == plginst_none)
             continue;
 
@@ -223,103 +223,71 @@ init_value_list (value_list_t *vl, virDomainPtr dom)
 
 } /* void init_value_list */
 
-static void
-memory_submit (gauge_t memory, virDomainPtr dom)
+static void submit (virDomainPtr dom,
+                    char const *type, char const *type_instance,
+                    value_t *values, size_t values_len)
 {
-    value_t values[1];
     value_list_t vl = VALUE_LIST_INIT;
-
     init_value_list (&vl, dom);
 
-    values[0].gauge = memory;
-
     vl.values = values;
-    vl.values_len = 1;
+    vl.values_len = values_len;
 
-    sstrncpy (vl.type, "memory", sizeof (vl.type));
-    sstrncpy (vl.type_instance, "total", sizeof (vl.type_instance));
+    sstrncpy (vl.type, type, sizeof (vl.type));
+    if (type_instance != NULL)
+        sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
 
     plugin_dispatch_values (&vl);
 }
 
 static void
-memory_stats_submit (gauge_t memory, virDomainPtr dom, int tag_index)
+memory_submit (gauge_t value, virDomainPtr dom)
+{
+    submit (dom, "memory", "total", &(value_t) { .gauge = value }, 1);
+}
+
+static void
+memory_stats_submit (gauge_t value, virDomainPtr dom, int tag_index)
 {
     static const char *tags[] = { "swap_in", "swap_out", "major_fault", "minor_fault",
                                     "unused", "available", "actual_balloon", "rss"};
 
-    value_t values[1];
-    value_list_t vl = VALUE_LIST_INIT;
-
-    init_value_list (&vl, dom);
-
-    values[0].gauge = memory;
-
-    vl.values = values;
-    vl.values_len = 1;
-
-    sstrncpy (vl.type, "memory", sizeof (vl.type));
-    sstrncpy (vl.type_instance, tags[tag_index], sizeof (vl.type_instance));
+    if ((tag_index < 0) || (tag_index >= STATIC_ARRAY_SIZE (tags))) {
+        ERROR ("virt plugin: Array index out of bounds: tag_index = %d", tag_index);
+        return;
+    }
 
-    plugin_dispatch_values (&vl);
+    submit (dom, "memory", tags[tag_index], &(value_t) { .gauge = value }, 1);
 }
 
 static void
-cpu_submit (unsigned long long cpu_time,
+cpu_submit (unsigned long long value,
             virDomainPtr dom, const char *type)
 {
-    value_t values[1];
-    value_list_t vl = VALUE_LIST_INIT;
-
-    init_value_list (&vl, dom);
-
-    values[0].derive = cpu_time;
-
-    vl.values = values;
-    vl.values_len = 1;
-
-    sstrncpy (vl.type, type, sizeof (vl.type));
-
-    plugin_dispatch_values (&vl);
+    submit (dom, type, NULL, &(value_t) { .derive = (derive_t) value }, 1);
 }
 
 static void
-vcpu_submit (derive_t cpu_time,
+vcpu_submit (derive_t value,
              virDomainPtr dom, int vcpu_nr, const char *type)
 {
-    value_t values[1];
-    value_list_t vl = VALUE_LIST_INIT;
+    char type_instance[DATA_MAX_NAME_LEN];
 
-    init_value_list (&vl, dom);
-
-    values[0].derive = cpu_time;
-    vl.values = values;
-    vl.values_len = 1;
+    ssnprintf (type_instance, sizeof (type_instance), "%d", vcpu_nr);
 
-    sstrncpy (vl.type, type, sizeof (vl.type));
-    ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%d", vcpu_nr);
-
-    plugin_dispatch_values (&vl);
+    submit (dom, type, type_instance, &(value_t) { .derive = value }, 1);
 }
 
 static void
 submit_derive2 (const char *type, derive_t v0, derive_t v1,
              virDomainPtr dom, const char *devname)
 {
-    value_t values[2];
-    value_list_t vl = VALUE_LIST_INIT;
-
-    init_value_list (&vl, dom);
+    value_t values[] = {
+        { .derive = v0 },
+        { .derive = v1 },
+    };
 
-    values[0].derive = v0;
-    values[1].derive = v1;
-    vl.values = values;
-    vl.values_len = 2;
-
-    sstrncpy (vl.type, type, sizeof (vl.type));
-    sstrncpy (vl.type_instance, devname, sizeof (vl.type_instance));
-
-    plugin_dispatch_values (&vl);
+    submit (dom, type, devname, values, STATIC_ARRAY_SIZE (values));
 } /* void submit_derive2 */
 
 static int
@@ -394,7 +362,7 @@ lv_config (const char *key, const char *value)
     if (strcasecmp (key, "HostnameFormat") == 0) {
         char *value_copy;
         char *fields[HF_MAX_FIELDS];
-        int i, n;
+        int n;
 
         value_copy = strdup (value);
         if (value_copy == NULL) {
@@ -409,7 +377,7 @@ lv_config (const char *key, const char *value)
             return -1;
         }
 
-        for (i = 0; i < n; ++i) {
+        for (int i = 0; i < n; ++i) {
             if (strcasecmp (fields[i], "hostname") == 0)
                 hostname_format[i] = hf_hostname;
             else if (strcasecmp (fields[i], "name") == 0)
@@ -424,7 +392,7 @@ lv_config (const char *key, const char *value)
         }
         sfree (value_copy);
 
-        for (i = n; i < HF_MAX_FIELDS; ++i)
+        for (int i = n; i < HF_MAX_FIELDS; ++i)
             hostname_format[i] = hf_none;
 
         return 0;
@@ -433,7 +401,7 @@ lv_config (const char *key, const char *value)
     if (strcasecmp (key, "PluginInstanceFormat") == 0) {
         char *value_copy;
         char *fields[PLGINST_MAX_FIELDS];
-        int i, n;
+        int n;
 
         value_copy = strdup (value);
         if (value_copy == NULL) {
@@ -448,7 +416,7 @@ lv_config (const char *key, const char *value)
             return -1;
         }
 
-        for (i = 0; i < n; ++i) {
+        for (int i = 0; i < n; ++i) {
             if (strcasecmp (fields[i], "none") == 0) {
                 plugin_instance_format[i] = plginst_none;
                 break;
@@ -464,7 +432,7 @@ lv_config (const char *key, const char *value)
         }
         sfree (value_copy);
 
-        for (i = n; i < PLGINST_MAX_FIELDS; ++i)
+        for (int i = n; i < PLGINST_MAX_FIELDS; ++i)
             plugin_instance_format[i] = plginst_none;
 
         return 0;
@@ -492,7 +460,6 @@ static int
 lv_read (void)
 {
     time_t t;
-    int i;
 
     if (conn == NULL) {
         /* `conn_string == NULL' is acceptable. */
@@ -522,25 +489,24 @@ lv_read (void)
     }
 
 #if 0
-    for (i = 0; i < nr_domains; ++i)
+    for (int i = 0; i < nr_domains; ++i)
         fprintf (stderr, "domain %s\n", virDomainGetName (domains[i]));
-    for (i = 0; i < nr_block_devices; ++i)
+    for (int i = 0; i < nr_block_devices; ++i)
         fprintf  (stderr, "block device %d %s:%s\n",
                   i, virDomainGetName (block_devices[i].dom),
                   block_devices[i].path);
-    for (i = 0; i < nr_interface_devices; ++i)
+    for (int i = 0; i < nr_interface_devices; ++i)
         fprintf (stderr, "interface device %d %s:%s\n",
                  i, virDomainGetName (interface_devices[i].dom),
                  interface_devices[i].path);
 #endif
 
     /* Get CPU usage, memory, VCPU usage for each domain. */
-    for (i = 0; i < nr_domains; ++i) {
+    for (int i = 0; i < nr_domains; ++i) {
         virDomainInfo info;
         virVcpuInfoPtr vinfo = NULL;
         virDomainMemoryStatPtr minfo = NULL;
         int status;
-        int j;
 
         status = virDomainGetInfo (domains[i], &info);
         if (status != 0)
@@ -575,7 +541,7 @@ lv_read (void)
             continue;
         }
 
-        for (j = 0; j < info.nrVirtCpu; ++j)
+        for (int j = 0; j < info.nrVirtCpu; ++j)
             vcpu_submit (vinfo[j].cpuTime,
                     domains[i], vinfo[j].number, "virt_vcpu");
 
@@ -596,7 +562,7 @@ lv_read (void)
             continue;
         }
 
-        for (j = 0; j < status; j++) {
+        for (int j = 0; j < status; j++) {
             memory_stats_submit ((gauge_t) minfo[j].val * 1024, domains[i], minfo[j].tag);
         }
 
@@ -605,7 +571,7 @@ lv_read (void)
 
 
     /* Get block device stats for each domain. */
-    for (i = 0; i < nr_block_devices; ++i) {
+    for (int i = 0; i < nr_block_devices; ++i) {
         struct _virDomainBlockStats stats;
 
         if (virDomainBlockStats (block_devices[i].dom, block_devices[i].path,
@@ -624,7 +590,7 @@ lv_read (void)
     } /* for (nr_block_devices) */
 
     /* Get interface stats for each domain. */
-    for (i = 0; i < nr_interface_devices; ++i) {
+    for (int i = 0; i < nr_interface_devices; ++i) {
         struct _virDomainInterfaceStats stats;
         char *display_name = NULL;
 
@@ -682,7 +648,6 @@ refresh_lists (void)
     }
 
     if (n > 0) {
-        int i;
         int *domids;
 
         /* Get list of domains. */
@@ -704,14 +669,13 @@ refresh_lists (void)
         free_domains ();
 
         /* Fetch each domain and add it to the list, unless ignore. */
-        for (i = 0; i < n; ++i) {
+        for (int i = 0; i < n; ++i) {
             virDomainPtr dom = NULL;
             const char *name;
             char *xml = NULL;
             xmlDocPtr xml_doc = NULL;
             xmlXPathContextPtr xpath_ctx = NULL;
             xmlXPathObjectPtr xpath_obj = NULL;
-            int j;
 
             dom = virDomainLookupByID (conn, domids[i]);
             if (dom == NULL) {
@@ -758,7 +722,7 @@ refresh_lists (void)
                 xpath_obj->nodesetval == NULL)
                 goto cont;
 
-            for (j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
+            for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
                 xmlNodePtr node;
                 char *path = NULL;
 
@@ -787,16 +751,15 @@ refresh_lists (void)
 
             xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval;
 
-            for (j = 0; j < xml_interfaces->nodeNr; ++j) {
+            for (int j = 0; j < xml_interfaces->nodeNr; ++j) {
                 char *path = NULL;
                 char *address = NULL;
                 xmlNodePtr xml_interface;
 
                 xml_interface = xml_interfaces->nodeTab[j];
                 if (!xml_interface) continue;
-                xmlNodePtr child = NULL;
 
-                for (child = xml_interface->children; child; child = child->next) {
+                for (xmlNodePtr child = xml_interface->children; child; child = child->next) {
                     if (child->type != XML_ELEMENT_NODE) continue;
 
                     if (xmlStrEqual(child->name, (const xmlChar *) "target")) {
@@ -835,10 +798,8 @@ refresh_lists (void)
 static void
 free_domains (void)
 {
-    int i;
-
     if (domains) {
-        for (i = 0; i < nr_domains; ++i)
+        for (int i = 0; i < nr_domains; ++i)
             virDomainFree (domains[i]);
         sfree (domains);
     }
@@ -868,10 +829,8 @@ add_domain (virDomainPtr dom)
 static void
 free_block_devices (void)
 {
-    int i;
-
     if (block_devices) {
-        for (i = 0; i < nr_block_devices; ++i)
+        for (int i = 0; i < nr_block_devices; ++i)
             sfree (block_devices[i].path);
         sfree (block_devices);
     }
@@ -908,10 +867,8 @@ add_block_device (virDomainPtr dom, const char *path)
 static void
 free_interface_devices (void)
 {
-    int i;
-
     if (interface_devices) {
-        for (i = 0; i < nr_interface_devices; ++i) {
+        for (int i = 0; i < nr_interface_devices; ++i) {
             sfree (interface_devices[i].path);
             sfree (interface_devices[i].address);
             sfree (interface_devices[i].number);
index f501706..027f7bd 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -64,12 +65,13 @@ static void submit (const char *plugin_instance, const char *type,
 static void submit_two (const char *plugin_instance, const char *type,
     const char *type_instance, derive_t c0, derive_t c1)
 {
-  value_t values[2];
-
-  values[0].derive = c0;
-  values[1].derive = c1;
+  value_t values[] = {
+    { .derive = c0 },
+    { .derive = c1 },
+  };
 
-  submit (plugin_instance, type, type_instance, values, 2);
+  submit (plugin_instance, type, type_instance,
+      values, STATIC_ARRAY_SIZE (values));
 } /* void submit_one */
 
 static void submit_one (const char *plugin_instance, const char *type,
index 1d957eb..f3a2b5a 100644 (file)
@@ -27,6 +27,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -55,11 +56,11 @@ static int vserver_init (void)
 static void traffic_submit (const char *plugin_instance,
                const char *type_instance, derive_t rx, derive_t tx)
 {
-       value_t values[2];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].derive = rx;
-       values[1].derive = tx;
+       value_t values[] = {
+               { .derive = rx },
+               { .derive = tx },
+       };
 
        vl.values = values;
        vl.values_len = STATIC_ARRAY_SIZE (values);
@@ -75,12 +76,12 @@ static void traffic_submit (const char *plugin_instance,
 static void load_submit (const char *plugin_instance,
                gauge_t snum, gauge_t mnum, gauge_t lnum)
 {
-       value_t values[3];
        value_list_t vl = VALUE_LIST_INIT;
-
-       values[0].gauge = snum;
-       values[1].gauge = mnum;
-       values[2].gauge = lnum;
+       value_t values[] = {
+               { .gauge = snum },
+               { .gauge = mnum },
+               { .gauge = lnum },
+       };
 
        vl.values = values;
        vl.values_len = STATIC_ARRAY_SIZE (values);
@@ -96,13 +97,10 @@ static void submit_gauge (const char *plugin_instance, const char *type,
                const char *type_instance, gauge_t value)
 
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
-       vl.values_len = STATIC_ARRAY_SIZE (values);
+       vl.values = &(value_t) { .gauge = value };
+       vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin));
        sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
index 8445af2..7d57fea 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -53,12 +54,9 @@ static double wireless_dbm_to_watt (double dbm)
 static void wireless_submit (const char *plugin_instance, const char *type,
                double value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "wireless", sizeof (vl.plugin));
index 64794be..ebc5ce2 100644 (file)
@@ -43,9 +43,9 @@
   */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include "utils_complain.h"
 #include "utils_format_graphite.h"
@@ -193,9 +193,7 @@ static int wg_flush_nolock (cdtime_t timeout, struct wg_callback *cb)
 
 static int wg_callback_init (struct wg_callback *cb)
 {
-    struct addrinfo ai_hints;
     struct addrinfo *ai_list;
-    struct addrinfo *ai_ptr;
     cdtime_t now;
     int status;
 
@@ -211,19 +209,16 @@ static int wg_callback_init (struct wg_callback *cb)
         return (EAGAIN);
     cb->last_connect_time = now;
 
-    memset (&ai_hints, 0, sizeof (ai_hints));
-#ifdef AI_ADDRCONFIG
-    ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-    ai_hints.ai_family = AF_UNSPEC;
+    struct addrinfo ai_hints = {
+        .ai_family = AF_UNSPEC,
+        .ai_flags  = AI_ADDRCONFIG
+    };
 
     if (0 == strcasecmp ("tcp", cb->protocol))
         ai_hints.ai_socktype = SOCK_STREAM;
     else
         ai_hints.ai_socktype = SOCK_DGRAM;
 
-    ai_list = NULL;
-
     status = getaddrinfo (cb->node, cb->service, &ai_hints, &ai_list);
     if (status != 0)
     {
@@ -233,7 +228,7 @@ static int wg_callback_init (struct wg_callback *cb)
     }
 
     assert (ai_list != NULL);
-    for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+    for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
     {
         cb->sock_fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
                 ai_ptr->ai_protocol);
@@ -244,6 +239,8 @@ static int wg_callback_init (struct wg_callback *cb)
             continue;
         }
 
+        set_sock_opts (cb->sock_fd);
+
         status = connect (cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
         if (status != 0)
         {
@@ -406,7 +403,7 @@ static int wg_send_message (char const *message, struct wg_callback *cb)
 static int wg_write_messages (const data_set_t *ds, const value_list_t *vl,
         struct wg_callback *cb)
 {
-    char buffer[WG_SEND_BUF_SIZE];
+    char buffer[WG_SEND_BUF_SIZE] = { 0 };
     int status;
 
     if (0 != strcmp (ds->type, vl->type))
@@ -416,7 +413,6 @@ static int wg_write_messages (const data_set_t *ds, const value_list_t *vl,
         return -1;
     }
 
-    memset (buffer, 0, sizeof (buffer));
     status = format_graphite (buffer, sizeof (buffer), ds, vl,
             cb->prefix, cb->postfix, cb->escape_char, cb->format_flags);
     if (status != 0) /* error message has been printed already. */
@@ -449,11 +445,9 @@ static int wg_write (const data_set_t *ds, const value_list_t *vl,
 static int config_set_char (char *dest,
         oconfig_item_t *ci)
 {
-    char buffer[4];
+    char buffer[4] = { 0 };
     int status;
 
-    memset (buffer, 0, sizeof (buffer));
-
     status = cf_util_get_string_buffer (ci, buffer, sizeof (buffer));
     if (status != 0)
         return (status);
@@ -480,9 +474,7 @@ static int config_set_char (char *dest,
 static int wg_config_node (oconfig_item_t *ci)
 {
     struct wg_callback *cb;
-    user_data_t user_data;
     char callback_name[DATA_MAX_NAME_LEN];
-    int i;
     int status = 0;
 
     cb = calloc (1, sizeof (*cb));
@@ -519,7 +511,7 @@ static int wg_config_node (oconfig_item_t *ci)
     pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
     C_COMPLAIN_INIT (&cb->init_complaint);
 
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
@@ -556,6 +548,9 @@ static int wg_config_node (oconfig_item_t *ci)
         else if (strcasecmp ("AlwaysAppendDS", child->key) == 0)
             cf_util_get_flag (child, &cb->format_flags,
                     GRAPHITE_ALWAYS_APPEND_DS);
+        else if (strcasecmp ("DropDuplicateFields", child->key) == 0)
+            cf_util_get_flag (child, &cb->format_flags,
+                    GRAPHITE_DROP_DUPE_FIELDS);
         else if (strcasecmp ("EscapeCharacter", child->key) == 0)
             config_set_char (&cb->escape_char, child);
         else
@@ -583,22 +578,20 @@ static int wg_config_node (oconfig_item_t *ci)
         ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s",
                 cb->name);
 
-    memset (&user_data, 0, sizeof (user_data));
-    user_data.data = cb;
-    user_data.free_func = wg_callback_free;
-    plugin_register_write (callback_name, wg_write, &user_data);
+    plugin_register_write (callback_name, wg_write,
+            &(user_data_t) {
+                .data = cb,
+                .free_func = wg_callback_free,
+            });
 
-    user_data.free_func = NULL;
-    plugin_register_flush (callback_name, wg_flush, &user_data);
+    plugin_register_flush (callback_name, wg_flush, &(user_data_t) { .data = cb });
 
     return (0);
 }
 
 static int wg_config (oconfig_item_t *ci)
 {
-    int i;
-
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
index 2d8e553..3d1fe3d 100644 (file)
@@ -24,6 +24,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 #include "utils_format_json.h"
@@ -64,6 +65,8 @@ struct wh_callback_s
 #define WH_FORMAT_JSON     1
 #define WH_FORMAT_KAIROSDB 2
         int format;
+        _Bool send_metrics;
+        _Bool send_notifications;
 
         CURL *curl;
         struct curl_slist *headers;
@@ -94,6 +97,9 @@ static void wh_log_http_error (wh_callback_t *cb)
 
 static void wh_reset_buffer (wh_callback_t *cb)  /* {{{ */
 {
+        if ((cb == NULL) || (cb->send_buffer == NULL))
+                return;
+
         memset (cb->send_buffer, 0, cb->send_buffer_size);
         cb->send_buffer_free = cb->send_buffer_size;
         cb->send_buffer_fill = 0;
@@ -107,11 +113,12 @@ static void wh_reset_buffer (wh_callback_t *cb)  /* {{{ */
         }
 } /* }}} wh_reset_buffer */
 
-static int wh_send_buffer (wh_callback_t *cb) /* {{{ */
+/* must hold cb->send_lock when calling */
+static int wh_post_nolock (wh_callback_t *cb, char const *data) /* {{{ */
 {
         int status = 0;
 
-        curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, cb->send_buffer);
+        curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, data);
         status = curl_easy_perform (cb->curl);
 
         wh_log_http_error (cb);
@@ -123,7 +130,7 @@ static int wh_send_buffer (wh_callback_t *cb) /* {{{ */
                                 status, cb->curl_errbuf);
         }
         return (status);
-} /* }}} wh_send_buffer */
+} /* }}} wh_post_nolock */
 
 static int wh_callback_init (wh_callback_t *cb) /* {{{ */
 {
@@ -243,7 +250,7 @@ static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */
                         return (0);
                 }
 
-                status = wh_send_buffer (cb);
+                status = wh_post_nolock (cb, cb->send_buffer);
                 wh_reset_buffer (cb);
         }
         else if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB)
@@ -265,7 +272,7 @@ static int wh_flush_nolock (cdtime_t timeout, wh_callback_t *cb) /* {{{ */
                         return (status);
                 }
 
-                status = wh_send_buffer (cb);
+                status = wh_post_nolock (cb, cb->send_buffer);
                 wh_reset_buffer (cb);
         }
         else
@@ -293,15 +300,11 @@ static int wh_flush (cdtime_t timeout, /* {{{ */
 
         pthread_mutex_lock (&cb->send_lock);
 
-        if (cb->curl == NULL)
+        if (wh_callback_init (cb) != 0)
         {
-                status = wh_callback_init (cb);
-                if (status != 0)
-                {
-                        ERROR ("write_http plugin: wh_callback_init failed.");
-                        pthread_mutex_unlock (&cb->send_lock);
-                        return (-1);
-                }
+                ERROR ("write_http plugin: wh_callback_init failed.");
+                pthread_mutex_unlock (&cb->send_lock);
+                return (-1);
         }
 
         status = wh_flush_nolock (timeout, cb);
@@ -319,7 +322,8 @@ static void wh_callback_free (void *data) /* {{{ */
 
         cb = data;
 
-        wh_flush_nolock (/* timeout = */ 0, cb);
+        if (cb->send_buffer != NULL)
+                wh_flush_nolock (/* timeout = */ 0, cb);
 
         if (cb->curl != NULL)
         {
@@ -358,7 +362,11 @@ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{
 
         int status;
 
-        if (0 != strcmp (ds->type, vl->type)) {
+        /* sanity checks, primarily to make static analyzers happy. */
+        if ((cb == NULL) || (cb->send_buffer == NULL))
+                return -1;
+
+        if (strcmp (ds->type, vl->type) == 0) {
                 ERROR ("write_http plugin: DS type does not match "
                                 "value list type");
                 return -1;
@@ -393,16 +401,11 @@ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{
         }
 
         pthread_mutex_lock (&cb->send_lock);
-
-        if (cb->curl == NULL)
+        if (wh_callback_init (cb) != 0)
         {
-                status = wh_callback_init (cb);
-                if (status != 0)
-                {
-                        ERROR ("write_http plugin: wh_callback_init failed.");
-                        pthread_mutex_unlock (&cb->send_lock);
-                        return (-1);
-                }
+                ERROR ("write_http plugin: wh_callback_init failed.");
+                pthread_mutex_unlock (&cb->send_lock);
+                return (-1);
         }
 
         if (command_len >= cb->send_buffer_free)
@@ -416,6 +419,9 @@ static int wh_write_command (const data_set_t *ds, const value_list_t *vl, /* {{
         }
         assert (command_len < cb->send_buffer_free);
 
+        /* Make scan-build happy. */
+        assert (cb->send_buffer != NULL);
+
         /* `command_len + 1' because `command_len' does not include the
          * trailing null byte. Neither does `send_buffer_fill'. */
         memcpy (cb->send_buffer + cb->send_buffer_fill,
@@ -441,16 +447,11 @@ static int wh_write_json (const data_set_t *ds, const value_list_t *vl, /* {{{ *
         int status;
 
         pthread_mutex_lock (&cb->send_lock);
-
-        if (cb->curl == NULL)
+        if (wh_callback_init (cb) != 0)
         {
-                status = wh_callback_init (cb);
-                if (status != 0)
-                {
-                        ERROR ("write_http plugin: wh_callback_init failed.");
-                        pthread_mutex_unlock (&cb->send_lock);
-                        return (-1);
-                }
+                ERROR ("write_http plugin: wh_callback_init failed.");
+                pthread_mutex_unlock (&cb->send_lock);
+                return (-1);
         }
 
         status = format_json_value_list (cb->send_buffer,
@@ -553,6 +554,7 @@ static int wh_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
                 return (-EINVAL);
 
         cb = user_data->data;
+        assert (cb->send_metrics);
 
         switch(cb->format) {
             case WH_FORMAT_JSON:
@@ -568,6 +570,39 @@ static int wh_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
         return (status);
 } /* }}} int wh_write */
 
+static int wh_notify (notification_t const *n, user_data_t *ud) /* {{{ */
+{
+        wh_callback_t *cb;
+        char alert[4096];
+        int status;
+
+        if ((ud == NULL) || (ud->data == NULL))
+                return (EINVAL);
+
+        cb = ud->data;
+        assert (cb->send_notifications);
+
+        status = format_json_notification (alert, sizeof (alert), n);
+        if (status != 0)
+        {
+                ERROR ("write_http plugin: formatting notification failed");
+                return status;
+        }
+
+        pthread_mutex_lock (&cb->send_lock);
+        if (wh_callback_init (cb) != 0)
+        {
+                ERROR ("write_http plugin: wh_callback_init failed.");
+                pthread_mutex_unlock (&cb->send_lock);
+                return (-1);
+        }
+
+        status = wh_post_nolock (cb, alert);
+        pthread_mutex_unlock (&cb->send_lock);
+
+        return (status);
+} /* }}} int wh_notify */
+
 static int config_set_format (wh_callback_t *cb, /* {{{ */
                 oconfig_item_t *ci)
 {
@@ -621,10 +656,8 @@ 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 = calloc (1, sizeof (*cb));
         if (cb == NULL)
@@ -640,7 +673,8 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
         cb->timeout = 0;
         cb->log_http_error = 0;
         cb->headers = NULL;
-
+        cb->send_metrics = 1;
+        cb->send_notifications = 0;
 
         pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
 
@@ -650,7 +684,7 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
         if (strcasecmp ("URL", ci->key) == 0)
                 cf_util_get_string (ci, &cb->location);
 
-        for (i = 0; i < ci->children_num; i++)
+        for (int i = 0; i < ci->children_num; i++)
         {
                 oconfig_item_t *child = ci->children + i;
 
@@ -709,6 +743,10 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
                 }
                 else if (strcasecmp ("Format", child->key) == 0)
                         status = config_set_format (cb, child);
+                else if (strcasecmp ("Metrics", child->key) == 0)
+                        cf_util_get_boolean (child, &cb->send_metrics);
+                else if (strcasecmp ("Notifications", child->key) == 0)
+                        cf_util_get_boolean (child, &cb->send_notifications);
                 else if (strcasecmp ("StoreRates", child->key) == 0)
                         status = cf_util_get_boolean (child, &cb->store_rates);
                 else if (strcasecmp ("BufferSize", child->key) == 0)
@@ -746,6 +784,14 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
                 return (-1);
         }
 
+        if (!cb->send_metrics && !cb->send_notifications)
+        {
+                ERROR ("write_http plugin: Neither metrics nor notifications "
+                       "are enabled for \"%s\".", cb->name);
+                wh_callback_free (cb);
+                return (-1);
+        }
+
         if (cb->low_speed_limit > 0)
                 cb->low_speed_time = CDTIME_T_TO_TIME_T(plugin_get_interval());
 
@@ -773,22 +819,34 @@ static int wh_config_node (oconfig_item_t *ci) /* {{{ */
         DEBUG ("write_http: Registering write callback '%s' with URL '%s'",
                         callback_name, cb->location);
 
-        memset (&user_data, 0, sizeof (user_data));
-        user_data.data = cb;
-        user_data.free_func = NULL;
+        user_data_t user_data = {
+                .data = cb
+        };
+
         plugin_register_flush (callback_name, wh_flush, &user_data);
 
         user_data.free_func = wh_callback_free;
-        plugin_register_write (callback_name, wh_write, &user_data);
+
+        if (cb->send_metrics)
+        {
+                plugin_register_write (callback_name, wh_write, &user_data);
+                user_data.free_func = NULL;
+
+                plugin_register_flush (callback_name, wh_flush, &user_data);
+        }
+
+        if (cb->send_notifications)
+        {
+                plugin_register_notification (callback_name, wh_notify, &user_data);
+                user_data.free_func = NULL;
+        }
 
         return (0);
 } /* }}} int wh_config_node */
 
 static int wh_config (oconfig_item_t *ci) /* {{{ */
 {
-        int i;
-
-        for (i = 0; i < ci->children_num; i++)
+        for (int i = 0; i < ci->children_num; i++)
         {
                 oconfig_item_t *child = ci->children + i;
 
index 6b5bc39..75da6aa 100644 (file)
@@ -25,9 +25,9 @@
  */
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 #include "utils_cmd_putval.h"
 #include "utils_format_graphite.h"
 #include "utils_format_json.h"
@@ -240,13 +240,11 @@ static void kafka_topic_context_free(void *p) /* {{{ */
 static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{ */
 {
     int                          status;
-    int                          i;
     struct kafka_topic_context  *tctx;
     char                        *key = NULL;
     char                        *val;
     char                         callback_name[DATA_MAX_NAME_LEN];
     char                         errbuf[1024];
-    user_data_t                  ud;
     oconfig_item_t              *child;
     rd_kafka_conf_res_t          ret;
 
@@ -292,7 +290,7 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
         goto errout;
     }
 
-    for (i = 0; i < ci->children_num; i++) {
+    for (int i = 0; i < ci->children_num; i++) {
         /*
          * The code here could be simplified but makes room
          * for easy adding of new options later on.
@@ -385,10 +383,11 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
     ssnprintf(callback_name, sizeof(callback_name),
               "write_kafka/%s", tctx->topic_name);
 
-    ud.data = tctx;
-    ud.free_func = kafka_topic_context_free;
-
-    status = plugin_register_write (callback_name, kafka_write, &ud);
+    status = plugin_register_write (callback_name, kafka_write,
+            &(user_data_t) {
+                .data = tctx,
+                .free_func = kafka_topic_context_free,
+            });
     if (status != 0) {
         WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
                 "failed with status %i.",
@@ -411,7 +410,6 @@ static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{
 
 static int kafka_config(oconfig_item_t *ci) /* {{{ */
 {
-    int                          i;
     oconfig_item_t              *child;
     rd_kafka_conf_t             *conf;
     rd_kafka_conf_res_t          ret;
@@ -421,7 +419,7 @@ static int kafka_config(oconfig_item_t *ci) /* {{{ */
         WARNING("cannot allocate kafka configuration.");
         return -1;
     }
-    for (i = 0; i < ci->children_num; i++)  {
+    for (int i = 0; i < ci->children_num; i++)  {
         child = &ci->children[i];
 
         if (strcasecmp("Topic", child->key) == 0) {
index db09849..e10a912 100644 (file)
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include "utils_format_graphite.h"
+#include "utils_format_json.h"
 
 #include <netdb.h>
 
-#define WL_BUF_SIZE 8192
+#define WL_BUF_SIZE 16384
+
+#define WL_FORMAT_GRAPHITE 1
+#define WL_FORMAT_JSON 2
 
-static int wl_write_messages (const data_set_t *ds, const value_list_t *vl)
+/* Plugin:WriteLog has to also operate without a config, so use a global. */
+int wl_format = WL_FORMAT_GRAPHITE;
+
+static int wl_write_graphite (const data_set_t *ds, const value_list_t *vl)
 {
-    char buffer[WL_BUF_SIZE];
+    char buffer[WL_BUF_SIZE] = { 0 };
     int status;
 
     if (0 != strcmp (ds->type, vl->type))
     {
-        ERROR ("write_log plugin: DS type does not match "
-                "value list type");
+        ERROR ("write_log plugin: DS type does not match value list type");
         return -1;
     }
 
-    memset (buffer, 0, sizeof (buffer));
     status = format_graphite (buffer, sizeof (buffer), ds, vl,
                               NULL, NULL, '_', 0);
     if (status != 0) /* error message has been printed already. */
@@ -57,20 +62,95 @@ static int wl_write_messages (const data_set_t *ds, const value_list_t *vl)
     INFO ("write_log values:\n%s", buffer);
 
     return (0);
-} /* int wl_write_messages */
+} /* int wl_write_graphite */
+
+static int wl_write_json (const data_set_t *ds, const value_list_t *vl)
+{
+    char buffer[WL_BUF_SIZE] = { 0 };
+    size_t bfree = sizeof(buffer);
+    size_t bfill = 0;
+
+    if (0 != strcmp (ds->type, vl->type))
+    {
+        ERROR ("write_log plugin: DS type does not match value list type");
+        return -1;
+    }
+
+    format_json_initialize(buffer, &bfill, &bfree);
+    format_json_value_list(buffer, &bfill, &bfree, ds, vl,
+                           /* store rates = */ 0);
+    format_json_finalize(buffer, &bfill, &bfree);
+
+    INFO ("write_log values:\n%s", buffer);
+
+    return (0);
+} /* int wl_write_json */
 
 static int wl_write (const data_set_t *ds, const value_list_t *vl,
-        user_data_t *user_data)
+        __attribute__ ((unused)) user_data_t *user_data)
 {
-    int status;
+    int status = 0;
 
-    status = wl_write_messages (ds, vl);
+    if (wl_format == WL_FORMAT_GRAPHITE)
+    {
+        status = wl_write_graphite (ds, vl);
+    }
+    else if (wl_format == WL_FORMAT_JSON)
+    {
+        status = wl_write_json (ds, vl);
+    }
 
     return (status);
 }
 
+static int wl_config (oconfig_item_t *ci) /* {{{ */
+{
+    _Bool format_seen = 0;
+
+    for (int i = 0; i < ci->children_num; i++)
+    {
+        oconfig_item_t *child = ci->children + i;
+
+        if (strcasecmp ("Format", child->key) == 0)
+        {
+            char str[16];
+
+            if (cf_util_get_string_buffer (child, str, sizeof (str)) != 0)
+                continue;
+
+            if (format_seen)
+            {
+                WARNING ("write_log plugin: Redefining option `%s'.",
+                    child->key);
+            }
+            format_seen = 1;
+
+            if (strcasecmp ("Graphite", str) == 0)
+                wl_format = WL_FORMAT_GRAPHITE;
+            else if (strcasecmp ("JSON", str) == 0)
+                wl_format = WL_FORMAT_JSON;
+            else
+            {
+                ERROR ("write_log plugin: Unknown format `%s' for option `%s'.",
+                    str, child->key);
+                return (-EINVAL);
+            }
+        }
+        else
+        {
+            ERROR ("write_log plugin: Invalid configuration option: `%s'.",
+                child->key);
+            return (-EINVAL);
+        }
+    }
+
+    return (0);
+} /* }}} int wl_config */
+
 void module_register (void)
 {
+    plugin_register_complex_config ("write_log", wl_config);
+    /* If config is supplied, the global wl_format will be set. */
     plugin_register_write ("write_log", wl_write, NULL);
 }
 
index fb80ba2..796574e 100644 (file)
@@ -29,9 +29,9 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 #include "utils_cache.h"
 
 #if HAVE_STDINT_H
@@ -75,7 +75,6 @@ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */
 {
   bson *ret;
   gauge_t *rates;
-  int i;
 
   ret = bson_alloc (); /* matched by bson_dealloc() */
   if (ret == NULL)
@@ -107,7 +106,7 @@ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */
   bson_append_string (ret, "type_instance", vl->type_instance);
 
   bson_append_start_array (ret, "values"); /* {{{ */
-  for (i = 0; i < ds->ds_num; i++)
+  for (int i = 0; i < ds->ds_num; i++)
   {
     char key[16];
 
@@ -129,7 +128,7 @@ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */
   bson_append_finish_array (ret); /* }}} values */
 
   bson_append_start_array (ret, "dstypes"); /* {{{ */
-  for (i = 0; i < ds->ds_num; i++)
+  for (int i = 0; i < ds->ds_num; i++)
   {
     char key[16];
 
@@ -143,7 +142,7 @@ static bson *wm_create_bson (const data_set_t *ds, /* {{{ */
   bson_append_finish_array (ret); /* }}} dstypes */
 
   bson_append_start_array (ret, "dsnames"); /* {{{ */
-  for (i = 0; i < ds->ds_num; i++)
+  for (int i = 0; i < ds->ds_num; i++)
   {
     char key[16];
 
@@ -270,7 +269,6 @@ static int wm_config_node (oconfig_item_t *ci) /* {{{ */
 {
   wm_node_t *node;
   int status;
-  int i;
 
   node = calloc (1, sizeof (*node));
   if (node == NULL)
@@ -288,7 +286,7 @@ static int wm_config_node (oconfig_item_t *ci) /* {{{ */
     return (status);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -338,14 +336,14 @@ static int wm_config_node (oconfig_item_t *ci) /* {{{ */
   if (status == 0)
   {
     char cb_name[DATA_MAX_NAME_LEN];
-    user_data_t ud;
 
     ssnprintf (cb_name, sizeof (cb_name), "write_mongodb/%s", node->name);
 
-    ud.data = node;
-    ud.free_func = wm_config_free;
-
-    status = plugin_register_write (cb_name, wm_write, &ud);
+    status = plugin_register_write (cb_name, wm_write,
+                   &(user_data_t) {
+                           .data = node,
+                           .free_func = wm_config_free,
+                   });
     INFO ("write_mongodb plugin: registered write plugin %s %d",cb_name,status);
   }
 
@@ -357,9 +355,7 @@ static int wm_config_node (oconfig_item_t *ci) /* {{{ */
 
 static int wm_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
index 5c299a4..def3d9c 100644 (file)
@@ -25,9 +25,9 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 
 #include <sys/time.h>
 #include <hiredis/hiredis.h>
@@ -63,7 +63,7 @@ static int wr_write (const data_set_t *ds, /* {{{ */
   wr_node_t *node = ud->data;
   char ident[512];
   char key[512];
-  char value[512];
+  char value[512] = { 0 };
   char time[24];
   size_t value_size;
   char *value_ptr;
@@ -78,7 +78,6 @@ static int wr_write (const data_set_t *ds, /* {{{ */
       ident);
   ssnprintf (time, sizeof (time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
 
-  memset (value, 0, sizeof (value));
   value_size = sizeof (value);
   value_ptr = &value[0];
   status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
@@ -168,7 +167,6 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
   wr_node_t *node;
   int timeout;
   int status;
-  int i;
 
   node = calloc (1, sizeof (*node));
   if (node == NULL)
@@ -191,7 +189,7 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
     return (status);
   }
 
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
@@ -233,14 +231,14 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
   if (status == 0)
   {
     char cb_name[DATA_MAX_NAME_LEN];
-    user_data_t ud;
 
     ssnprintf (cb_name, sizeof (cb_name), "write_redis/%s", node->name);
 
-    ud.data = node;
-    ud.free_func = wr_config_free;
-
-    status = plugin_register_write (cb_name, wr_write, &ud);
+    status = plugin_register_write (cb_name, wr_write,
+        &(user_data_t) {
+          .data = node,
+          .free_func = wr_config_free,
+        });
   }
 
   if (status != 0)
@@ -251,9 +249,7 @@ static int wr_config_node (oconfig_item_t *ci) /* {{{ */
 
 static int wr_config (oconfig_item_t *ci) /* {{{ */
 {
-  int i;
-
-  for (i = 0; i < ci->children_num; i++)
+  for (int i = 0; i < ci->children_num; i++)
   {
     oconfig_item_t *child = ci->children + i;
 
index ac6b8fb..20f2e10 100644 (file)
 
 #include "collectd.h"
 
-
-#include "plugin.h"
 #include "common.h"
-#include "configfile.h"
+#include "plugin.h"
 #include "utils_cache.h"
 #include "utils_complain.h"
 #include "write_riemann_threshold.h"
 #include <errno.h>
 #include <riemann/riemann-client.h>
 
-#define RIEMANN_HOST           "localhost"
-#define RIEMANN_PORT           5555
-#define RIEMANN_TTL_FACTOR      2.0
-#define RIEMANN_BATCH_MAX      8192
+#define RIEMANN_HOST "localhost"
+#define RIEMANN_PORT 5555
+#define RIEMANN_TTL_FACTOR 2.0
+#define RIEMANN_BATCH_MAX 8192
 
 struct riemann_host {
-    c_complain_t init_complaint;
-       char                    *name;
-       char                    *event_service_prefix;
-       pthread_mutex_t  lock;
-    _Bool            batch_mode;
-       _Bool            notifications;
-       _Bool            check_thresholds;
-       _Bool                    store_rates;
-       _Bool                    always_append_ds;
-       char                    *node;
-       int                      port;
-       riemann_client_type_t    client_type;
-       riemann_client_t        *client;
-       double                   ttl_factor;
-    cdtime_t         batch_init;
-    int              batch_max;
-    int              batch_timeout;
-       int                          reference_count;
-  riemann_message_t    *batch_msg;
-       char                     *tls_ca_file;
-       char                     *tls_cert_file;
-       char                     *tls_key_file;
-       struct timeval timeout;
+  c_complain_t init_complaint;
+  char *name;
+  char *event_service_prefix;
+  pthread_mutex_t lock;
+  _Bool batch_mode;
+  _Bool notifications;
+  _Bool check_thresholds;
+  _Bool store_rates;
+  _Bool always_append_ds;
+  char *node;
+  int port;
+  riemann_client_type_t client_type;
+  riemann_client_t *client;
+  double ttl_factor;
+  cdtime_t batch_init;
+  int batch_max;
+  int batch_timeout;
+  int reference_count;
+  riemann_message_t *batch_msg;
+  char *tls_ca_file;
+  char *tls_cert_file;
+  char *tls_key_file;
+  struct timeval timeout;
 };
 
-static char    **riemann_tags;
-static size_t    riemann_tags_num;
-static char    **riemann_attrs;
-static size_t     riemann_attrs_num;
+static char **riemann_tags;
+static size_t riemann_tags_num;
+static char **riemann_attrs;
+static size_t riemann_attrs_num;
 
 /* host->lock must be held when calling this function. */
 static int wrr_connect(struct riemann_host *host) /* {{{ */
 {
-       char const              *node;
-       int                      port;
-
-       if (host->client)
-               return 0;
-
-       node = (host->node != NULL) ? host->node : RIEMANN_HOST;
-       port = (host->port) ? host->port : RIEMANN_PORT;
-
-       host->client = NULL;
-
-       host->client = riemann_client_create(host->client_type, node, port,
-                                            RIEMANN_CLIENT_OPTION_TLS_CA_FILE, host->tls_ca_file,
-                                            RIEMANN_CLIENT_OPTION_TLS_CERT_FILE, host->tls_cert_file,
-                                            RIEMANN_CLIENT_OPTION_TLS_KEY_FILE, host->tls_key_file,
-                                            RIEMANN_CLIENT_OPTION_NONE);
-       if (host->client == NULL) {
-        c_complain (LOG_ERR, &host->init_complaint,
-                    "write_riemann plugin: Unable to connect to Riemann at %s:%d",
-                    node, port);
-               return -1;
-       }
-       if (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;
-               }
-       }
-
-    c_release (LOG_INFO, &host->init_complaint,
-               "write_riemann plugin: Successfully connected to %s:%d",
+  char const *node;
+  int port;
+
+  if (host->client)
+    return 0;
+
+  node = (host->node != NULL) ? host->node : RIEMANN_HOST;
+  port = (host->port) ? host->port : RIEMANN_PORT;
+
+  host->client = NULL;
+
+  host->client = riemann_client_create(
+      host->client_type, node, port, RIEMANN_CLIENT_OPTION_TLS_CA_FILE,
+      host->tls_ca_file, RIEMANN_CLIENT_OPTION_TLS_CERT_FILE,
+      host->tls_cert_file, RIEMANN_CLIENT_OPTION_TLS_KEY_FILE,
+      host->tls_key_file, RIEMANN_CLIENT_OPTION_NONE);
+  if (host->client == NULL) {
+    c_complain(LOG_ERR, &host->init_complaint,
+               "write_riemann plugin: Unable to connect to Riemann at %s:%d",
                node, port);
+    return -1;
+  }
+#if RCC_VERSION_NUMBER >= 0x010800
+  if (host->timeout.tv_sec != 0) {
+    if (riemann_client_set_timeout(host->client, &host->timeout) != 0) {
+      riemann_client_free(host->client);
+      host->client = NULL;
+      c_complain(LOG_ERR, &host->init_complaint,
+                 "write_riemann plugin: Unable to connect to Riemann at %s:%d",
+                 node, port);
+      return -1;
+    }
+  }
+#endif
+
+  set_sock_opts(riemann_client_get_fd(host->client));
+
+  c_release(LOG_INFO, &host->init_complaint,
+            "write_riemann plugin: Successfully connected to %s:%d", node,
+            port);
 
-       return 0;
+  return 0;
 } /* }}} int wrr_connect */
 
 /* host->lock must be held when calling this function. */
 static int wrr_disconnect(struct riemann_host *host) /* {{{ */
 {
-       if (!host->client)
-               return (0);
+  if (!host->client)
+    return (0);
 
-       riemann_client_free(host->client);
-       host->client = NULL;
+  riemann_client_free(host->client);
+  host->client = NULL;
 
-       return (0);
+  return (0);
 } /* }}} int wrr_disconnect */
 
 /**
@@ -137,468 +139,440 @@ static int wrr_disconnect(struct riemann_host *host) /* {{{ */
  *
  * Acquires the host lock, disconnects on errors.
  */
-static int wrr_send_nolock(struct riemann_host *host, riemann_message_t *msg) /* {{{ */
+static int wrr_send_nolock(struct riemann_host *host,
+                           riemann_message_t *msg) /* {{{ */
 {
-       int status = 0;
+  int status = 0;
+
+  status = wrr_connect(host);
+  if (status != 0) {
+    return status;
+  }
 
-       status = wrr_connect(host);
-       if (status != 0) {
-               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->client_type != RIEMANN_CLIENT_UDP) {
+    riemann_message_t *response;
+
+    response = riemann_client_recv_message(host->client);
+
+    if (response == NULL) {
+      wrr_disconnect(host);
+      return errno;
     }
+    riemann_message_free(response);
+  }
 
-       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->client_type != RIEMANN_CLIENT_UDP)
-       {
-               riemann_message_t *response;
-
-               response = riemann_client_recv_message(host->client);
-
-               if (response == NULL)
-               {
-                       wrr_disconnect(host);
-                       return errno;
-               }
-               riemann_message_free(response);
-       }
-
-       return 0;
+  return 0;
 } /* }}} int wrr_send */
 
-static int wrr_send(struct riemann_host *host, riemann_message_t *msg)
-{
-    int status = 0;
+static int wrr_send(struct riemann_host *host, riemann_message_t *msg) {
+  int status = 0;
 
-    pthread_mutex_lock (&host->lock);
-    status = wrr_send_nolock(host, msg);
-    pthread_mutex_unlock (&host->lock);
-    return status;
+  pthread_mutex_lock(&host->lock);
+  status = wrr_send_nolock(host, msg);
+  pthread_mutex_unlock(&host->lock);
+  return status;
 }
 
-static riemann_message_t *wrr_notification_to_message(struct riemann_host *host, /* {{{ */
-               notification_t const *n)
-{
-       riemann_message_t *msg;
-       riemann_event_t *event;
-       char service_buffer[6 * DATA_MAX_NAME_LEN];
-       char const *severity;
-       notification_meta_t *meta;
-       size_t i;
-
-       switch (n->severity)
-       {
-               case NOTIF_OKAY:        severity = "ok"; break;
-               case NOTIF_WARNING:     severity = "warning"; break;
-               case NOTIF_FAILURE:     severity = "critical"; break;
-               default:                severity = "unknown";
-       }
-
-       format_name(service_buffer, sizeof(service_buffer),
-                   /* host = */ "", n->plugin, n->plugin_instance,
-                   n->type, n->type_instance);
-
-       event = riemann_event_create(RIEMANN_EVENT_FIELD_HOST, n->host,
-                                    RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(n->time),
-                                    RIEMANN_EVENT_FIELD_TAGS, "notification", NULL,
-                                    RIEMANN_EVENT_FIELD_STATE, severity,
-                                    RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
-                                    RIEMANN_EVENT_FIELD_NONE);
-
-       if (n->host[0] != 0)
-               riemann_event_string_attribute_add(event, "host", n->host);
-       if (n->plugin[0] != 0)
-               riemann_event_string_attribute_add(event, "plugin", n->plugin);
-       if (n->plugin_instance[0] != 0)
-               riemann_event_string_attribute_add(event, "plugin_instance", n->plugin_instance);
-
-       if (n->type[0] != 0)
-               riemann_event_string_attribute_add(event, "type", n->type);
-       if (n->type_instance[0] != 0)
-               riemann_event_string_attribute_add(event, "type_instance", n->type_instance);
-
-       for (i = 0; i < riemann_attrs_num; i += 2)
-               riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i+1]);
-
-       for (i = 0; i < riemann_tags_num; i++)
-               riemann_event_tag_add(event, riemann_tags[i]);
-
-       if (n->message[0] != 0)
-               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)
-               {
-                       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_string_attribute_add(event, meta->name, meta->nm_value.nm_string);
-                       continue;
-               }
-       }
-
-       msg = riemann_message_create_with_events(event, NULL);
-       if (msg == NULL)
-       {
-               ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
-               riemann_event_free (event);
-               return (NULL);
-       }
-
-       DEBUG("write_riemann plugin: Successfully created message for notification: "
-             "host = \"%s\", service = \"%s\", state = \"%s\"",
-             event->host, event->service, event->state);
-       return (msg);
+static riemann_message_t *
+wrr_notification_to_message(struct riemann_host *host, /* {{{ */
+                            notification_t const *n) {
+  riemann_message_t *msg;
+  riemann_event_t *event;
+  char service_buffer[6 * DATA_MAX_NAME_LEN];
+  char const *severity;
+
+  switch (n->severity) {
+  case NOTIF_OKAY:
+    severity = "ok";
+    break;
+  case NOTIF_WARNING:
+    severity = "warning";
+    break;
+  case NOTIF_FAILURE:
+    severity = "critical";
+    break;
+  default:
+    severity = "unknown";
+  }
+
+  format_name(service_buffer, sizeof(service_buffer),
+              /* host = */ "", n->plugin, n->plugin_instance, n->type,
+              n->type_instance);
+
+  event = riemann_event_create(
+      RIEMANN_EVENT_FIELD_HOST, n->host, RIEMANN_EVENT_FIELD_TIME,
+      (int64_t)CDTIME_T_TO_TIME_T(n->time), RIEMANN_EVENT_FIELD_TAGS,
+      "notification", NULL, RIEMANN_EVENT_FIELD_STATE, severity,
+      RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
+      RIEMANN_EVENT_FIELD_NONE);
+
+  if (n->host[0] != 0)
+    riemann_event_string_attribute_add(event, "host", n->host);
+  if (n->plugin[0] != 0)
+    riemann_event_string_attribute_add(event, "plugin", n->plugin);
+  if (n->plugin_instance[0] != 0)
+    riemann_event_string_attribute_add(event, "plugin_instance",
+                                       n->plugin_instance);
+
+  if (n->type[0] != 0)
+    riemann_event_string_attribute_add(event, "type", n->type);
+  if (n->type_instance[0] != 0)
+    riemann_event_string_attribute_add(event, "type_instance",
+                                       n->type_instance);
+
+  for (size_t i = 0; i < riemann_attrs_num; i += 2)
+    riemann_event_string_attribute_add(event, riemann_attrs[i],
+                                       riemann_attrs[i + 1]);
+
+  for (size_t i = 0; i < riemann_tags_num; i++)
+    riemann_event_tag_add(event, riemann_tags[i]);
+
+  if (n->message[0] != 0)
+    riemann_event_string_attribute_add(event, "description", n->message);
+
+  /* Pull in values from threshold and add extra attributes */
+  for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) {
+    if (strcasecmp("CurrentValue", meta->name) == 0 &&
+        meta->type == NM_TYPE_DOUBLE) {
+      riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
+                        (double)meta->nm_value.nm_double,
+                        RIEMANN_EVENT_FIELD_NONE);
+      continue;
+    }
+
+    if (meta->type == NM_TYPE_STRING) {
+      riemann_event_string_attribute_add(event, meta->name,
+                                         meta->nm_value.nm_string);
+      continue;
+    }
+  }
+
+  msg = riemann_message_create_with_events(event, NULL);
+  if (msg == NULL) {
+    ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
+    riemann_event_free(event);
+    return (NULL);
+  }
+
+  DEBUG("write_riemann plugin: Successfully created message for notification: "
+        "host = \"%s\", service = \"%s\", state = \"%s\"",
+        event->host, event->service, event->state);
+  return (msg);
 } /* }}} riemann_message_t *wrr_notification_to_message */
 
-static riemann_event_t *wrr_value_to_event(struct riemann_host const *host, /* {{{ */
-                                          data_set_t const *ds,
-                                          value_list_t const *vl, size_t index,
-                                          gauge_t const *rates,
-                                          int status)
-{
-       riemann_event_t *event;
-       char name_buffer[5 * DATA_MAX_NAME_LEN];
-       char service_buffer[6 * DATA_MAX_NAME_LEN];
-       size_t i;
-
-       event = riemann_event_new();
-       if (event == NULL)
-       {
-               ERROR("write_riemann plugin: riemann_event_new() failed.");
-               return (NULL);
-       }
-
-       format_name(name_buffer, sizeof(name_buffer),
-                   /* host = */ "", vl->plugin, vl->plugin_instance,
-                   vl->type, vl->type_instance);
-       if (host->always_append_ds || (ds->ds_num > 1))
-       {
-               if (host->event_service_prefix == NULL)
-                       ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
-                                 &name_buffer[1], ds->ds[index].name);
-               else
-                       ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
-                                 host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
-       }
-       else
-       {
-               if (host->event_service_prefix == NULL)
-                       sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
-               else
-                       ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
-                                 host->event_service_prefix, &name_buffer[1]);
-       }
-
-       riemann_event_set(event,
-                         RIEMANN_EVENT_FIELD_HOST, vl->host,
-                         RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(vl->time),
-                         RIEMANN_EVENT_FIELD_TTL, (float) CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
-                         RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES,
-                         "plugin", vl->plugin,
-                         "type", vl->type,
-                         "ds_name", ds->ds[index].name,
-                         NULL,
-                         RIEMANN_EVENT_FIELD_SERVICE, service_buffer,
-                         RIEMANN_EVENT_FIELD_NONE);
-
-       if (host->check_thresholds) {
-               const char *state = NULL;
-
-               switch (status) {
-                       case STATE_OKAY:
-                               state = "ok";
-                               break;
-                       case STATE_ERROR:
-                               state = "critical";
-                               break;
-                       case STATE_WARNING:
-                               state = "warning";
-                               break;
-                       case STATE_MISSING:
-                               state = "unknown";
-                               break;
-               }
-               if (state)
-                       riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
-                                         RIEMANN_EVENT_FIELD_NONE);
-       }
-
-       if (vl->plugin_instance[0] != 0)
-               riemann_event_string_attribute_add(event, "plugin_instance", vl->plugin_instance);
-       if (vl->type_instance[0] != 0)
-               riemann_event_string_attribute_add(event, "type_instance", vl->type_instance);
-
-       if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL))
-       {
-               char ds_type[DATA_MAX_NAME_LEN];
-
-               ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
-                         DS_TYPE_TO_STRING(ds->ds[index].type));
-               riemann_event_string_attribute_add(event, "ds_type", ds_type);
-       }
-       else
-       {
-               riemann_event_string_attribute_add(event, "ds_type",
+static riemann_event_t *
+wrr_value_to_event(struct riemann_host const *host, /* {{{ */
+                   data_set_t const *ds, value_list_t const *vl, size_t index,
+                   gauge_t const *rates, int status) {
+  riemann_event_t *event;
+  char name_buffer[5 * DATA_MAX_NAME_LEN];
+  char service_buffer[6 * DATA_MAX_NAME_LEN];
+  size_t i;
+
+  event = riemann_event_new();
+  if (event == NULL) {
+    ERROR("write_riemann plugin: riemann_event_new() failed.");
+    return (NULL);
+  }
+
+  format_name(name_buffer, sizeof(name_buffer),
+              /* host = */ "", vl->plugin, vl->plugin_instance, vl->type,
+              vl->type_instance);
+  if (host->always_append_ds || (ds->ds_num > 1)) {
+    if (host->event_service_prefix == NULL)
+      ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
+                &name_buffer[1], ds->ds[index].name);
+    else
+      ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
+                host->event_service_prefix, &name_buffer[1],
+                ds->ds[index].name);
+  } else {
+    if (host->event_service_prefix == NULL)
+      sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
+    else
+      ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
+                host->event_service_prefix, &name_buffer[1]);
+  }
+
+  riemann_event_set(
+      event, RIEMANN_EVENT_FIELD_HOST, vl->host, RIEMANN_EVENT_FIELD_TIME,
+      (int64_t)CDTIME_T_TO_TIME_T(vl->time), RIEMANN_EVENT_FIELD_TTL,
+      (float)CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
+      RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES, "plugin", vl->plugin, "type",
+      vl->type, "ds_name", ds->ds[index].name, NULL,
+      RIEMANN_EVENT_FIELD_SERVICE, service_buffer, RIEMANN_EVENT_FIELD_NONE);
+
+  if (host->check_thresholds) {
+    const char *state = NULL;
+
+    switch (status) {
+    case STATE_OKAY:
+      state = "ok";
+      break;
+    case STATE_ERROR:
+      state = "critical";
+      break;
+    case STATE_WARNING:
+      state = "warning";
+      break;
+    case STATE_MISSING:
+      state = "unknown";
+      break;
+    }
+    if (state)
+      riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
+                        RIEMANN_EVENT_FIELD_NONE);
+  }
+
+  if (vl->plugin_instance[0] != 0)
+    riemann_event_string_attribute_add(event, "plugin_instance",
+                                       vl->plugin_instance);
+  if (vl->type_instance[0] != 0)
+    riemann_event_string_attribute_add(event, "type_instance",
+                                       vl->type_instance);
+
+  if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
+    char ds_type[DATA_MAX_NAME_LEN];
+
+    ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
+              DS_TYPE_TO_STRING(ds->ds[index].type));
+    riemann_event_string_attribute_add(event, "ds_type", ds_type);
+  } else {
+    riemann_event_string_attribute_add(event, "ds_type",
                                        DS_TYPE_TO_STRING(ds->ds[index].type));
-       }
-
-       {
-               char ds_index[DATA_MAX_NAME_LEN];
-
-               ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
-               riemann_event_string_attribute_add(event, "ds_index", ds_index);
-       }
-
-       for (i = 0; i < riemann_attrs_num; i += 2)
-               riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i +1]);
-
-       for (i = 0; i < riemann_tags_num; i++)
-               riemann_event_tag_add(event, riemann_tags[i]);
-
-       if (ds->ds[index].type == DS_TYPE_GAUGE)
-       {
-               riemann_event_set(event,
-                                 RIEMANN_EVENT_FIELD_METRIC_D,
-                                 (double) vl->values[index].gauge,
-                                 RIEMANN_EVENT_FIELD_NONE);
-       }
-       else if (rates != NULL)
-       {
-               riemann_event_set(event,
-                                 RIEMANN_EVENT_FIELD_METRIC_D,
-                                 (double) rates[index],
-                                 RIEMANN_EVENT_FIELD_NONE);
-       }
-       else
-       {
-               int64_t metric;
-
-               if (ds->ds[index].type == DS_TYPE_DERIVE)
-                       metric = (int64_t) vl->values[index].derive;
-               else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
-                       metric = (int64_t) vl->values[index].absolute;
-               else
-                       metric = (int64_t) vl->values[index].counter;
-
-               riemann_event_set(event,
-                                 RIEMANN_EVENT_FIELD_METRIC_S64,
-                                 (int64_t) metric,
-                                 RIEMANN_EVENT_FIELD_NONE);
-       }
-
-       DEBUG("write_riemann plugin: Successfully created message for metric: "
-             "host = \"%s\", service = \"%s\"",
-             event->host, event->service);
-       return (event);
+  }
+
+  {
+    char ds_index[DATA_MAX_NAME_LEN];
+
+    ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
+    riemann_event_string_attribute_add(event, "ds_index", ds_index);
+  }
+
+  for (i = 0; i < riemann_attrs_num; i += 2)
+    riemann_event_string_attribute_add(event, riemann_attrs[i],
+                                       riemann_attrs[i + 1]);
+
+  for (i = 0; i < riemann_tags_num; i++)
+    riemann_event_tag_add(event, riemann_tags[i]);
+
+  if (ds->ds[index].type == DS_TYPE_GAUGE) {
+    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
+                      (double)vl->values[index].gauge,
+                      RIEMANN_EVENT_FIELD_NONE);
+  } else if (rates != NULL) {
+    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)rates[index],
+                      RIEMANN_EVENT_FIELD_NONE);
+  } else {
+    int64_t metric;
+
+    if (ds->ds[index].type == DS_TYPE_DERIVE)
+      metric = (int64_t)vl->values[index].derive;
+    else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
+      metric = (int64_t)vl->values[index].absolute;
+    else
+      metric = (int64_t)vl->values[index].counter;
+
+    riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_S64, (int64_t)metric,
+                      RIEMANN_EVENT_FIELD_NONE);
+  }
+
+  DEBUG("write_riemann plugin: Successfully created message for metric: "
+        "host = \"%s\", service = \"%s\"",
+        event->host, event->service);
+  return (event);
 } /* }}} riemann_event_t *wrr_value_to_event */
 
-static riemann_message_t *wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */
-                                                   data_set_t const *ds,
-                                                   value_list_t const *vl,
-                                                   int *statuses)
-{
-       riemann_message_t *msg;
-       size_t i;
-       gauge_t *rates = NULL;
-
-       /* Initialize the Msg structure. */
-       msg = riemann_message_new();
-       if (msg == NULL)
-       {
-               ERROR ("write_riemann plugin: riemann_message_new failed.");
-               return (NULL);
-       }
-
-       if (host->store_rates)
-       {
-               rates = uc_get_rate(ds, vl);
-               if (rates == NULL)
-               {
-                       ERROR("write_riemann plugin: uc_get_rate failed.");
-                       riemann_message_free(msg);
-                       return (NULL);
-               }
-       }
-
-       for (i = 0; i < vl->values_len; i++)
-       {
-               riemann_event_t *event;
-
-               event = wrr_value_to_event(host, ds, vl,
-                                          (int) i, rates, statuses[i]);
-               if (event == NULL)
-               {
-                       riemann_message_free(msg);
-                       sfree(rates);
-                       return (NULL);
-               }
-               riemann_message_append_events(msg, event, NULL);
-       }
-
-       sfree(rates);
-       return (msg);
+static riemann_message_t *
+wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */
+                          data_set_t const *ds, value_list_t const *vl,
+                          int *statuses) {
+  riemann_message_t *msg;
+  size_t i;
+  gauge_t *rates = NULL;
+
+  /* Initialize the Msg structure. */
+  msg = riemann_message_new();
+  if (msg == NULL) {
+    ERROR("write_riemann plugin: riemann_message_new failed.");
+    return (NULL);
+  }
+
+  if (host->store_rates) {
+    rates = uc_get_rate(ds, vl);
+    if (rates == NULL) {
+      ERROR("write_riemann plugin: uc_get_rate failed.");
+      riemann_message_free(msg);
+      return (NULL);
+    }
+  }
+
+  for (i = 0; i < vl->values_len; i++) {
+    riemann_event_t *event;
+
+    event = wrr_value_to_event(host, ds, vl, (int)i, rates, statuses[i]);
+    if (event == NULL) {
+      riemann_message_free(msg);
+      sfree(rates);
+      return (NULL);
+    }
+    riemann_message_append_events(msg, event, NULL);
+  }
+
+  sfree(rates);
+  return (msg);
 } /* }}} riemann_message_t *wrr_value_list_to_message */
 
 /*
  * Always call while holding host->lock !
  */
-static int wrr_batch_flush_nolock(cdtime_t timeout,
-                                 struct riemann_host *host)
-{
-       cdtime_t    now;
-       int         status = 0;
-
-    now = cdtime();
-       if (timeout > 0) {
-               if ((host->batch_init + timeout) > now) {
-                       return status;
-        }
-       }
-       wrr_send_nolock(host, host->batch_msg);
-       riemann_message_free(host->batch_msg);
-
-       host->batch_init = now;
-       host->batch_msg = NULL;
-       return status;
+static int wrr_batch_flush_nolock(cdtime_t timeout, struct riemann_host *host) {
+  cdtime_t now;
+  int status = 0;
+
+  now = cdtime();
+  if (timeout > 0) {
+    if ((host->batch_init + timeout) > now) {
+      return status;
+    }
+  }
+  wrr_send_nolock(host, host->batch_msg);
+  riemann_message_free(host->batch_msg);
+
+  host->batch_init = now;
+  host->batch_msg = NULL;
+  return status;
 }
 
 static int wrr_batch_flush(cdtime_t timeout,
-        const char *identifier __attribute__((unused)),
-        user_data_t *user_data)
-{
-       struct riemann_host *host;
-       int status;
-
-       if (user_data == NULL)
-               return (-EINVAL);
-
-       host = user_data->data;
-       pthread_mutex_lock(&host->lock);
-       status = wrr_batch_flush_nolock(timeout, host);
-       if (status != 0)
-        c_complain (LOG_ERR, &host->init_complaint,
-                    "write_riemann plugin: riemann_client_send failed with status %i",
-                    status);
-    else
-        c_release (LOG_DEBUG, &host->init_complaint, "write_riemann plugin: batch sent.");
+                           const char *identifier __attribute__((unused)),
+                           user_data_t *user_data) {
+  struct riemann_host *host;
+  int status;
+
+  if (user_data == NULL)
+    return (-EINVAL);
 
-       pthread_mutex_unlock(&host->lock);
-       return 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;
 }
 
 static int wrr_batch_add_value_list(struct riemann_host *host, /* {{{ */
-                                   data_set_t const *ds,
-                                   value_list_t const *vl,
-                                   int *statuses)
-{
-       riemann_message_t *msg;
-       size_t len;
-       int ret;
-    cdtime_t timeout;
-
-       msg = wrr_value_list_to_message(host, ds, vl, statuses);
-       if (msg == NULL)
-               return -1;
-
-       pthread_mutex_lock(&host->lock);
-
-       if (host->batch_msg == NULL) {
-               host->batch_msg = msg;
-       } else {
-               int status;
-
-               status = riemann_message_append_events_n(host->batch_msg,
-                                                        msg->n_events,
-                                                        msg->events);
-               msg->n_events = 0;
-               msg->events = NULL;
-
-               riemann_message_free(msg);
-
-               if (status != 0) {
-                       pthread_mutex_unlock(&host->lock);
-                       ERROR("write_riemann plugin: out of memory");
-                       return -1;
-               }
-       }
-
-       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);
-        }
+                                    data_set_t const *ds,
+                                    value_list_t const *vl, int *statuses) {
+  riemann_message_t *msg;
+  size_t len;
+  int ret;
+  cdtime_t timeout;
+
+  msg = wrr_value_list_to_message(host, ds, vl, statuses);
+  if (msg == NULL)
+    return -1;
+
+  pthread_mutex_lock(&host->lock);
+
+  if (host->batch_msg == NULL) {
+    host->batch_msg = msg;
+  } else {
+    int status;
+
+    status = riemann_message_append_events_n(host->batch_msg, msg->n_events,
+                                             msg->events);
+    msg->n_events = 0;
+    msg->events = NULL;
+
+    riemann_message_free(msg);
+
+    if (status != 0) {
+      pthread_mutex_unlock(&host->lock);
+      ERROR("write_riemann plugin: out of memory");
+      return -1;
     }
+  }
 
-       pthread_mutex_unlock(&host->lock);
-       return ret;
+  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;
 } /* }}} riemann_message_t *wrr_batch_add_value_list */
 
 static int wrr_notification(const notification_t *n, user_data_t *ud) /* {{{ */
 {
-       int                      status;
-       struct riemann_host     *host = ud->data;
-       riemann_message_t       *msg;
+  int status;
+  struct riemann_host *host = ud->data;
+  riemann_message_t *msg;
 
-       if (!host->notifications)
-               return 0;
+  if (!host->notifications)
+    return 0;
 
-    /*
-     * Never batch for notifications, send them ASAP
-     */
-       msg = wrr_notification_to_message(host, n);
-       if (msg == NULL)
-               return (-1);
-
-       status = wrr_send(host, msg);
-       if (status != 0)
-        c_complain (LOG_ERR, &host->init_complaint,
-                    "write_riemann plugin: riemann_client_send failed with status %i",
-                    status);
-    else
-        c_release (LOG_DEBUG, &host->init_complaint,
-                   "write_riemann plugin: riemann_client_send succeeded");
+  /*
+   * Never batch for notifications, send them ASAP
+   */
+  msg = wrr_notification_to_message(host, n);
+  if (msg == NULL)
+    return (-1);
 
-       riemann_message_free(msg);
-       return (status);
+  status = wrr_send(host, msg);
+  if (status != 0)
+    c_complain(
+        LOG_ERR, &host->init_complaint,
+        "write_riemann plugin: riemann_client_send failed with status %i",
+        status);
+  else
+    c_release(LOG_DEBUG, &host->init_complaint,
+              "write_riemann plugin: riemann_client_send succeeded");
+
+  riemann_message_free(msg);
+  return (status);
 } /* }}} int wrr_notification */
 
 static int wrr_write(const data_set_t *ds, /* {{{ */
-             const value_list_t *vl,
-             user_data_t *ud)
-{
-       int                      status = 0;
-       int                      statuses[vl->values_len];
-       struct riemann_host     *host = ud->data;
-       riemann_message_t       *msg;
-
-       if (host->check_thresholds) {
-               status = write_riemann_threshold_check(ds, vl, statuses);
+                     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));
+    memset(statuses, 0, sizeof(statuses));
   }
 
   if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
-      wrr_batch_add_value_list(host, ds, vl, statuses);
+    wrr_batch_add_value_list(host, ds, vl, statuses);
   } else {
     msg = wrr_value_list_to_message(host, ds, vl, statuses);
     if (msg == NULL)
@@ -613,7 +587,7 @@ static int wrr_write(const data_set_t *ds, /* {{{ */
 
 static void wrr_free(void *p) /* {{{ */
 {
-  struct riemann_host  *host = p;
+  struct riemann_host *host = p;
 
   if (host == NULL)
     return;
@@ -621,11 +595,10 @@ static void wrr_free(void *p) /* {{{ */
   pthread_mutex_lock(&host->lock);
 
   host->reference_count--;
-  if (host->reference_count > 0)
-    {
-      pthread_mutex_unlock(&host->lock);
-      return;
-    }
+  if (host->reference_count > 0) {
+    pthread_mutex_unlock(&host->lock);
+    return;
+  }
 
   wrr_disconnect(host);
 
@@ -635,19 +608,18 @@ static void wrr_free(void *p) /* {{{ */
 
 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;
+  struct riemann_host *host = NULL;
+  int status = 0;
+  int i;
+  oconfig_item_t *child;
+  char callback_name[DATA_MAX_NAME_LEN];
 
   if ((host = calloc(1, sizeof(*host))) == NULL) {
-    ERROR ("write_riemann plugin: calloc failed.");
+    ERROR("write_riemann plugin: calloc failed.");
     return ENOMEM;
   }
   pthread_mutex_init(&host->lock, NULL);
-  C_COMPLAIN_INIT (&host->init_complaint);
+  C_COMPLAIN_INIT(&host->init_complaint);
   host->reference_count = 1;
   host->node = NULL;
   host->port = 0;
@@ -709,9 +681,13 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
       if (status != 0)
         break;
     } else if (strcasecmp("Timeout", child->key) == 0) {
+#if RCC_VERSION_NUMBER >= 0x010800
       status = cf_util_get_int(child, (int *)&host->timeout.tv_sec);
       if (status != 0)
         break;
+#else
+      WARNING("write_riemann plugin: The Timeout option is not supported. Please upgrade the Riemann client to at least 1.8.0.");
+#endif
     } else if (strcasecmp("Port", child->key) == 0) {
       host->port = cf_util_get_port_number(child);
       if (host->port == -1) {
@@ -722,15 +698,14 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
       }
     } 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;
-        }
+      status = cf_util_get_string_buffer(child, tmp, sizeof(tmp));
+      if (status != 0) {
+        ERROR("write_riemann plugin: cf_util_get_"
+              "string_buffer failed with "
+              "status %i.",
+              status);
+        break;
+      }
 
       if (strcasecmp("UDP", tmp) == 0)
         host->client_type = RIEMANN_CLIENT_UDP;
@@ -746,38 +721,37 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
                 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;
-        }
+      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;
-        }
+      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;
-        }
+      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);
+      status = cf_util_get_boolean(child, &host->always_append_ds);
       if (status != 0)
         break;
     } else if (strcasecmp("TTLFactor", child->key) == 0) {
@@ -809,7 +783,8 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
       }
     } else {
       WARNING("write_riemann plugin: ignoring unknown config "
-              "option: \"%s\"", child->key);
+              "option: \"%s\"",
+              child->key);
     }
   }
   if (status != 0) {
@@ -819,8 +794,11 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
 
   ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
             host->name);
-  ud.data = host;
-  ud.free_func = wrr_free;
+
+  user_data_t ud = {
+    .data = host,
+    .free_func = wrr_free
+  };
 
   pthread_mutex_lock(&host->lock);
 
@@ -837,8 +815,7 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
   else /* success */
     host->reference_count++;
 
-  status = plugin_register_notification(callback_name,
-                                        wrr_notification, &ud);
+  status = plugin_register_notification(callback_name, wrr_notification, &ud);
   if (status != 0)
     WARNING("write_riemann plugin: plugin_register_notification (\"%s\") "
             "failed with status %i.",
@@ -846,16 +823,15 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
   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 (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);
+  }
 
   host->reference_count--;
   pthread_mutex_unlock(&host->lock);
@@ -865,15 +841,15 @@ static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
 
 static int wrr_config(oconfig_item_t *ci) /* {{{ */
 {
-  int           i;
-  oconfig_item_t       *child;
-  int           status;
+  int i;
+  oconfig_item_t *child;
+  int status;
 
-  for (i = 0; i < ci->children_num; i++)  {
+  for (i = 0; i < ci->children_num; i++) {
     child = &ci->children[i];
 
     if (strcasecmp("Node", child->key) == 0) {
-      wrr_config_node (child);
+      wrr_config_node(child);
     } else if (strcasecmp(child->key, "attribute") == 0) {
       char *key = NULL;
       char *val = NULL;
@@ -919,8 +895,7 @@ static int wrr_config(oconfig_item_t *ci) /* {{{ */
   return (0);
 } /* }}} int wrr_config */
 
-void module_register(void)
-{
+void module_register(void) {
   plugin_register_complex_config("write_riemann", wrr_config);
 }
 
index a4249ec..f2ba9dc 100644 (file)
@@ -26,6 +26,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 #include "utils_avltree.h"
@@ -130,7 +131,6 @@ static int ut_check_one_threshold (const data_set_t *ds,
     int *statuses)
 { /* {{{ */
   int ret = -1;
-  size_t i;
   int status;
   gauge_t values_copy[ds->ds_num];
 
@@ -150,7 +150,7 @@ static int ut_check_one_threshold (const data_set_t *ds,
     }
 
     /* Prepare `sum' and `num'. */
-    for (i = 0; i < ds->ds_num; i++)
+    for (size_t i = 0; i < ds->ds_num; i++)
       if (!isnan (values[i]))
       {
         num++;
@@ -160,17 +160,17 @@ static int ut_check_one_threshold (const data_set_t *ds,
     if ((num == 0) /* All data sources are undefined. */
         || (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */
     {
-      for (i = 0; i < ds->ds_num; i++)
+      for (size_t i = 0; i < ds->ds_num; i++)
         values_copy[i] = NAN;
     }
     else /* We can actually calculate the percentage. */
     {
-      for (i = 0; i < ds->ds_num; i++)
+      for (size_t i = 0; i < ds->ds_num; i++)
         values_copy[i] = 100.0 * values[i] / sum;
     }
   } /* if (UT_FLAG_PERCENTAGE) */
 
-  for (i = 0; i < ds->ds_num; i++)
+  for (size_t i = 0; i < ds->ds_num; i++)
   {
     status = ut_check_one_data_source (ds, vl, th, values_copy, i);
     if (status != -1) {
index d37792b..d764d26 100644 (file)
@@ -27,9 +27,9 @@
 #define _GNU_SOURCE
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
-#include "configfile.h"
 #include "utils_cache.h"
 #include <arpa/inet.h>
 #include <errno.h>
 #define SENSU_HOST             "localhost"
 #define SENSU_PORT             "3030"
 
+#ifdef HAVE_ASPRINTF
+#define my_asprintf asprintf
+#define my_vasprintf vasprintf
+#else
+/*
+ * asprintf() is available from Solaris 10 update 11.
+ * For older versions, use asprintf() portable implementation from
+ * https://github.com/littlstar/asprintf.c/blob/master/
+ * copyright (c) 2014 joseph werle <joseph.werle@gmail.com> under MIT license.
+ */
+
+static int my_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;
+}
+
+static int my_asprintf(char **str, const char *fmt, ...) {
+       int size = 0;
+       va_list args;
+       // init variadic argumens
+       va_start(args, fmt);
+       // format and get size
+       size = my_vasprintf(str, fmt, args);
+       // toss args
+       va_end(args);
+       return size;
+}
+
+#endif
+
 struct str_list {
        int nb_strs;
        char **strs;
@@ -94,8 +143,7 @@ static int add_str_to_list(struct str_list *strs,
 
 static void free_str_list(struct str_list *strs) /* {{{ */
 {
-       int i;
-       for (i=0; i<strs->nb_strs; i++)
+       for (int i=0; i<strs->nb_strs; i++)
                free(strs->strs[i]);
        free(strs->strs);
 }
@@ -104,25 +152,24 @@ static void free_str_list(struct str_list *strs) /* {{{ */
 static int sensu_connect(struct sensu_host *host) /* {{{ */
 {
        int                      e;
-       struct addrinfo         *ai, hints;
        char const              *node;
        char const              *service;
 
        // Resolve the target if we haven't done already
        if (!(host->flags & F_READY)) {
-               memset(&hints, 0, sizeof(hints));
                memset(&service, 0, sizeof(service));
                host->res = NULL;
-               hints.ai_family = AF_INET;
-               hints.ai_socktype = SOCK_STREAM;
-#ifdef AI_ADDRCONFIG
-               hints.ai_flags |= AI_ADDRCONFIG;
-#endif
 
                node = (host->node != NULL) ? host->node : SENSU_HOST;
                service = (host->service != NULL) ? host->service : SENSU_PORT;
 
-               if ((e = getaddrinfo(node, service, &hints, &(host->res))) != 0) {
+               struct addrinfo ai_hints = {
+                       .ai_family = AF_INET,
+                       .ai_flags = AI_ADDRCONFIG,
+                       .ai_socktype = SOCK_STREAM
+               };
+
+               if ((e = getaddrinfo(node, service, &ai_hints, &(host->res))) != 0) {
                        ERROR("write_sensu plugin: Unable to resolve host \"%s\": %s",
                                        node, gai_strerror(e));
                        return -1;
@@ -134,7 +181,7 @@ static int sensu_connect(struct sensu_host *host) /* {{{ */
 
        struct linger so_linger;
        host->s = -1;
-       for (ai = host->res; ai != NULL; ai = ai->ai_next) {
+       for (struct addrinfo *ai = host->res; ai != NULL; ai = ai->ai_next) {
                // create the socket
                if ((host->s = socket(ai->ai_family,
                                      ai->ai_socktype,
@@ -148,6 +195,8 @@ static int sensu_connect(struct sensu_host *host) /* {{{ */
                if (setsockopt(host->s, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger) != 0)
                        WARNING("write_sensu plugin: failed to set socket close() lingering");
 
+               set_sock_opts(host->s);
+
                // connect the socket
                if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) {
                        close(host->s);
@@ -178,7 +227,6 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) /
        int res;
        char *ret_str = NULL;
        char *temp_str;
-       int i;
        if (list->nb_strs == 0) {
                ret_str = malloc(sizeof(char));
                if (ret_str == NULL) {
@@ -188,14 +236,14 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) /
                ret_str[0] = '\0';
        }
 
-       res = asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]);
+       res = my_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++) {
-               res = asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]);
+       for (int i=1; i<list->nb_strs; i++) {
+               res = my_asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]);
                free(temp_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -203,7 +251,7 @@ static char *build_json_str_list(const char *tag, struct str_list const *list) /
                }
                temp_str = ret_str;
        }
-       res = asprintf(&ret_str, "%s]", temp_str);
+       res = my_asprintf(&ret_str, "%s]", temp_str);
        free(temp_str);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -260,9 +308,8 @@ static int sensu_format_name2(char *ret, int ret_len,
 
 static void in_place_replace_sensu_name_reserved(char *orig_name) /* {{{ */
 {
-       int i;
        int len=strlen(orig_name);
-       for (i=0; i<len; i++) {
+       for (int i=0; i<len; i++) {
                // some plugins like ipmi generate special characters in metric name
                switch(orig_name[i]) {
                        case '(': orig_name[i] = '_'; break;
@@ -283,7 +330,6 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
 {
        char name_buffer[5 * DATA_MAX_NAME_LEN];
        char service_buffer[6 * DATA_MAX_NAME_LEN];
-       size_t i;
        char *ret_str;
        char *temp_str;
        char *value_str;
@@ -307,7 +353,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
                }
        }
        else {
-               res = asprintf(&ret_str, "%s, %s", part1, handlers_str);
+               res = my_asprintf(&ret_str, "%s, %s", part1, handlers_str);
                free(handlers_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -316,7 +362,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        }
 
        // incorporate the plugin name information
-       res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin);
+       res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin);
        free(ret_str);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -325,7 +371,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        ret_str = temp_str;
 
        // incorporate the plugin type
-       res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type);
+       res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type);
        free(ret_str);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -335,7 +381,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
 
        // incorporate the plugin instance if any
        if (vl->plugin_instance[0] != 0) {
-               res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance);
+               res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -346,7 +392,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
 
        // incorporate the plugin type instance if any
        if (vl->type_instance[0] != 0) {
-               res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance);
+               res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -359,7 +405,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        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));
-               res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type);
+               res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -367,7 +413,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
                }
                ret_str = temp_str;
        } else {
-               res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type));
+               res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type));
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -377,7 +423,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        }
 
        // incorporate the data source name
-       res = asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name);
+       res = my_asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name);
        free(ret_str);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -389,7 +435,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        {
                char ds_index[DATA_MAX_NAME_LEN];
                ssnprintf (ds_index, sizeof (ds_index), "%zu", index);
-               res = asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index);
+               res = my_asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -399,8 +445,8 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        }
 
        // add key value attributes from config if any
-       for (i = 0; i < sensu_attrs_num; i += 2) {
-               res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
+       for (size_t i = 0; i < sensu_attrs_num; i += 2) {
+               res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -411,7 +457,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
 
        // incorporate sensu tags from config if any
        if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) {
-               res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
+               res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -422,14 +468,14 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
 
        // calculate the value and set to a string
        if (ds->ds[index].type == DS_TYPE_GAUGE) {
-               res = asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge);
+               res = my_asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge);
                if (res == -1) {
                        free(ret_str);
                        ERROR("write_sensu plugin: Unable to alloc memory");
                        return NULL;
                }
        } else if (rates != NULL) {
-               res = asprintf(&value_str, GAUGE_FORMAT, rates[index]);
+               res = my_asprintf(&value_str, GAUGE_FORMAT, rates[index]);
                if (res == -1) {
                        free(ret_str);
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -437,7 +483,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
                }
        } else {
                if (ds->ds[index].type == DS_TYPE_DERIVE) {
-                       res = asprintf(&value_str, "%"PRIi64, vl->values[index].derive);
+                       res = my_asprintf(&value_str, "%"PRIi64, vl->values[index].derive);
                        if (res == -1) {
                                free(ret_str);
                                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -445,7 +491,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
                        }
                }
                else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) {
-                       res = asprintf(&value_str, "%"PRIu64, vl->values[index].absolute);
+                       res = my_asprintf(&value_str, "%"PRIu64, vl->values[index].absolute);
                        if (res == -1) {
                                free(ret_str);
                                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -453,7 +499,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
                        }
                }
                else {
-                       res = asprintf(&value_str, "%llu", vl->values[index].counter);
+                       res = my_asprintf(&value_str, "%llu", vl->values[index].counter);
                        if (res == -1) {
                                free(ret_str);
                                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -485,7 +531,7 @@ static char *sensu_value_to_json(struct sensu_host const *host, /* {{{ */
        in_place_replace_sensu_name_reserved(service_buffer);
 
        // finalize the buffer by setting the output and closing curly bracket
-       res = asprintf(&temp_str, "%s, \"output\": \"%s %s %ld\"}\n", ret_str, service_buffer, value_str, CDTIME_T_TO_TIME_T(vl->time));
+       res = my_asprintf(&temp_str, "%s, \"output\": \"%s %s %lld\"}\n",ret_str, service_buffer, value_str, (long long)CDTIME_T_TO_TIME_T(vl->time));
        free(ret_str);
        free(value_str);
        if (res == -1) {
@@ -590,7 +636,6 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
 {
        char service_buffer[6 * DATA_MAX_NAME_LEN];
        char const *severity;
-       notification_meta_t *meta;
        char *ret_str;
        char *temp_str;
        int status;
@@ -614,7 +659,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
                        severity = "UNKNOWN";
                        status = 3;
        }
-       res = asprintf(&temp_str, "{\"status\": %d", status);
+       res = my_asprintf(&temp_str, "{\"status\": %d", status);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
                return NULL;
@@ -622,7 +667,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
        ret_str = temp_str;
 
        // incorporate the timestamp
-       res = asprintf(&temp_str, "%s, \"timestamp\": %ld", ret_str, CDTIME_T_TO_TIME_T(n->time));
+       res = my_asprintf(&temp_str, "%s, \"timestamp\": %lld", ret_str, (long long)CDTIME_T_TO_TIME_T(n->time));
        free(ret_str);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -638,7 +683,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
        }
        // incorporate the handlers
        if (strlen(handlers_str) != 0) {
-               res = asprintf(&temp_str, "%s, %s", ret_str, handlers_str);
+               res = my_asprintf(&temp_str, "%s, %s", ret_str, handlers_str);
                free(ret_str);
                free(handlers_str);
                if (res == -1) {
@@ -652,7 +697,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
 
        // incorporate the plugin name information if any
        if (n->plugin[0] != 0) {
-               res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin);
+               res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -663,7 +708,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
 
        // incorporate the plugin type if any
        if (n->type[0] != 0) {
-               res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type);
+               res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -674,7 +719,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
 
        // incorporate the plugin instance if any
        if (n->plugin_instance[0] != 0) {
-               res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance);
+               res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -685,7 +730,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
 
        // incorporate the plugin type instance if any
        if (n->type_instance[0] != 0) {
-               res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance);
+               res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -696,7 +741,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
 
        // add key value attributes from config if any
        for (i = 0; i < sensu_attrs_num; i += 2) {
-               res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
+               res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -707,7 +752,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
 
        // incorporate sensu tags from config if any
        if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) {
-               res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
+               res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
                free(ret_str);
                if (res == -1) {
                        ERROR("write_sensu plugin: Unable to alloc memory");
@@ -722,7 +767,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
                                n->type, n->type_instance, host->separator);
        // replace sensu event name chars that are considered illegal
        in_place_replace_sensu_name_reserved(service_buffer);
-       res = asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]);
+       res = my_asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]);
        free(ret_str);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -738,7 +783,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
                        free(ret_str);
                        return NULL;
                }
-               res = asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg);
+               res = my_asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg);
                free(ret_str);
                free(msg);
                if (res == -1) {
@@ -749,9 +794,9 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
        }
 
        // Pull in values from threshold and add extra attributes
-       for (meta = n->meta; meta != NULL; meta = meta->next) {
+       for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) {
                if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE) {
-                       res = asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double);
+                       res = my_asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double);
                        free(ret_str);
                        if (res == -1) {
                                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -760,7 +805,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
                        ret_str = temp_str;
                }
                if (meta->type == NM_TYPE_STRING) {
-                       res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string);
+                       res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string);
                        free(ret_str);
                        if (res == -1) {
                                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -771,7 +816,7 @@ static char *sensu_notification_to_json(struct sensu_host *host, /* {{{ */
        }
 
        // close the curly bracket
-       res = asprintf(&temp_str, "%s}\n", ret_str);
+       res = my_asprintf(&temp_str, "%s}\n", ret_str);
        free(ret_str);
        if (res == -1) {
                ERROR("write_sensu plugin: Unable to alloc memory");
@@ -838,7 +883,6 @@ static int sensu_write(const data_set_t *ds, /* {{{ */
        int statuses[vl->values_len];
        struct sensu_host       *host = ud->data;
        gauge_t *rates = NULL;
-       size_t i;
        char *msg;
 
        pthread_mutex_lock(&host->lock);
@@ -852,7 +896,7 @@ static int sensu_write(const data_set_t *ds, /* {{{ */
                        return -1;
                }
        }
-       for (i = 0; i < vl->values_len; i++) {
+       for (size_t i = 0; i < vl->values_len; i++) {
                msg = sensu_value_to_json(host, ds, vl, (int) i, rates, statuses[i]);
                if (msg == NULL) {
                        sfree(rates);
@@ -932,10 +976,8 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */
 {
        struct sensu_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_sensu plugin: calloc failed.");
@@ -967,7 +1009,7 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */
                return -1;
        }
 
-       for (i = 0; i < ci->children_num; i++) {
+       for (int i = 0; i < ci->children_num; i++) {
                child = &ci->children[i];
                status = 0;
 
@@ -1065,8 +1107,11 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */
        }
 
        ssnprintf(callback_name, sizeof(callback_name), "write_sensu/%s", host->name);
-       ud.data = host;
-       ud.free_func = sensu_free;
+
+       user_data_t ud = {
+               .data = host,
+               .free_func = sensu_free
+       };
 
        pthread_mutex_lock(&host->lock);
 
@@ -1108,7 +1153,6 @@ static int sensu_config_node(oconfig_item_t *ci) /* {{{ */
 
 static int sensu_config(oconfig_item_t *ci) /* {{{ */
 {
-       int              i;
        oconfig_item_t  *child;
        int              status;
        struct str_list sensu_tags_arr;
@@ -1116,7 +1160,7 @@ static int sensu_config(oconfig_item_t *ci) /* {{{ */
        sensu_tags_arr.nb_strs = 0;
        sensu_tags_arr.strs = NULL;
 
-       for (i = 0; i < ci->children_num; i++)  {
+       for (int i = 0; i < ci->children_num; i++)  {
                child = &ci->children[i];
 
                if (strcasecmp("Node", child->key) == 0) {
index 2bd2707..b670f3a 100644 (file)
@@ -42,9 +42,9 @@
  */
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
-#include "configfile.h"
 
 #include "utils_cache.h"
 
@@ -155,9 +155,7 @@ static int wt_flush_nolock(cdtime_t timeout, struct wt_callback *cb)
 
 static int wt_callback_init(struct wt_callback *cb)
 {
-    struct addrinfo ai_hints;
     struct addrinfo *ai_list;
-    struct addrinfo *ai_ptr;
     int status;
 
     const char *node = cb->node ? cb->node : WT_DEFAULT_NODE;
@@ -166,14 +164,11 @@ static int wt_callback_init(struct wt_callback *cb)
     if (cb->sock_fd > 0)
         return 0;
 
-    memset(&ai_hints, 0, sizeof(ai_hints));
-#ifdef AI_ADDRCONFIG
-    ai_hints.ai_flags    |= AI_ADDRCONFIG;
-#endif
-    ai_hints.ai_family   = AF_UNSPEC;
-    ai_hints.ai_socktype = SOCK_STREAM;
-
-    ai_list = NULL;
+    struct addrinfo ai_hints = {
+        .ai_family = AF_UNSPEC,
+        .ai_flags = AI_ADDRCONFIG,
+        .ai_socktype = SOCK_STREAM
+    };
 
     status = getaddrinfo(node, service, &ai_hints, &ai_list);
     if (status != 0)
@@ -184,13 +179,15 @@ static int wt_callback_init(struct wt_callback *cb)
     }
 
     assert (ai_list != NULL);
-    for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+    for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
     {
         cb->sock_fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype,
                              ai_ptr->ai_protocol);
         if (cb->sock_fd < 0)
             continue;
 
+        set_sock_opts(cb->sock_fd);
+
         status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
         if (status != 0)
         {
@@ -506,7 +503,6 @@ static int wt_write_messages(const data_set_t *ds, const value_list_t *vl,
     char values[512];
 
     int status;
-    size_t i;
 
     if (0 != strcmp(ds->type, vl->type))
     {
@@ -515,7 +511,7 @@ static int wt_write_messages(const data_set_t *ds, const value_list_t *vl,
         return -1;
     }
 
-    for (i = 0; i < ds->ds_num; i++)
+    for (size_t i = 0; i < ds->ds_num; i++)
     {
         const char *ds_name = NULL;
 
@@ -574,9 +570,7 @@ static int wt_write(const data_set_t *ds, const value_list_t *vl,
 static int wt_config_tsd(oconfig_item_t *ci)
 {
     struct wt_callback *cb;
-    user_data_t user_data;
     char callback_name[DATA_MAX_NAME_LEN];
-    int i;
 
     cb = calloc(1, sizeof(*cb));
     if (cb == NULL)
@@ -592,7 +586,7 @@ static int wt_config_tsd(oconfig_item_t *ci)
 
     pthread_mutex_init (&cb->send_lock, NULL);
 
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
@@ -617,9 +611,11 @@ static int wt_config_tsd(oconfig_item_t *ci)
               cb->node != NULL ? cb->node : WT_DEFAULT_NODE,
               cb->service != NULL ? cb->service : WT_DEFAULT_SERVICE);
 
-    memset(&user_data, 0, sizeof(user_data));
-    user_data.data = cb;
-    user_data.free_func = wt_callback_free;
+    user_data_t user_data = {
+        .data = cb,
+        .free_func = wt_callback_free
+    };
+
     plugin_register_write(callback_name, wt_write, &user_data);
 
     user_data.free_func = NULL;
@@ -630,9 +626,7 @@ static int wt_config_tsd(oconfig_item_t *ci)
 
 static int wt_config(oconfig_item_t *ci)
 {
-    int i;
-
-    for (i = 0; i < ci->children_num; i++)
+    for (int i = 0; i < ci->children_num; i++)
     {
         oconfig_item_t *child = ci->children + i;
 
index 2b87235..93575df 100644 (file)
@@ -20,6 +20,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -53,7 +54,7 @@ static int xencpu_init (void)
     {
         ERROR ("xencpu: xc_interface_open() failed");
         return (-1);
-    };
+    }
 
     xc_physinfo_t *physinfo;
 
@@ -71,7 +72,7 @@ static int xencpu_init (void)
         xc_interface_close(xc_handle);
         free(physinfo);
         return (-1);
-    };
+    }
 
     num_cpus = physinfo->nr_cpus;
     free(physinfo);
@@ -107,14 +108,11 @@ static int xencpu_shutdown (void)
     return 0;
 } /* static int xencpu_shutdown */
 
-static void submit_value (int cpu_num, gauge_t percent)
+static void submit_value (int cpu_num, gauge_t value)
 {
-    value_t values[1];
     value_list_t vl = VALUE_LIST_INIT;
 
-    values[0].gauge = percent;
-
-    vl.values = values;
+    vl.values = &(value_t) { .gauge = value };
     vl.values_len = 1;
 
     sstrncpy (vl.host, hostname_g, sizeof (vl.host));
@@ -141,12 +139,13 @@ static int xencpu_read (void)
         return (-1);
     }
 
-    int cpu, status;
-    for (cpu = 0; cpu < nr_cpus; cpu++) {
+    int status;
+    for (int 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]);
+        status = value_to_rate (&rate,
+                                (value_t) { .derive = cpu_info[cpu].idletime }, DS_TYPE_DERIVE,
+                                now, &cpu_states[cpu]);
         if (status == 0) {
             submit_value(cpu, 100 - rate/10000000);
         }
index 29f2acd..2ba3082 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "plugin.h"
 #include "common.h"
 
@@ -34,12 +35,9 @@ static gint xmms_session;
 
 static void cxmms_submit (const char *type, gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = value;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "xmms", sizeof (vl.plugin));
index 37a918b..e411085 100644 (file)
@@ -28,6 +28,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -89,12 +90,10 @@ static long long get_zfs_value(kstat_t *ksp, const char *key)
 
 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)
+       for (llentry_t *e = llist_head (ksp); e != NULL; e = e->next)
        {
                sfree (e->key);
                sfree (e->value);
@@ -139,7 +138,7 @@ static long long get_zfs_value(kstat_t *dummy __attribute__((unused)),
 }
 #endif
 
-static void za_submit (const char* type, const char* type_instance, value_t* values, int values_len)
+static void za_submit (const char* type, const char* type_instance, value_t* values, size_t values_len)
 {
        value_list_t vl = VALUE_LIST_INIT;
 
@@ -156,45 +155,34 @@ static void za_submit (const char* type, const char* type_instance, value_t* val
 
 static void za_submit_gauge (const char* type, const char* type_instance, gauge_t value)
 {
-       value_t vv;
-
-       vv.gauge = value;
-       za_submit (type, type_instance, &vv, 1);
+       za_submit (type, type_instance, &(value_t) { .gauge = value }, 1);
 }
 
 static int za_read_derive (kstat_t *ksp, const char *kstat_value,
     const char *type, const char *type_instance)
 {
-  long long tmp;
-  value_t v;
-
-  tmp = get_zfs_value (ksp, (char *)kstat_value);
+  long long tmp = get_zfs_value (ksp, (char *)kstat_value);
   if (tmp == -1LL)
   {
     WARNING ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
     return (-1);
   }
 
-  v.derive = (derive_t) tmp;
-  za_submit (type, type_instance, /* values = */ &v, /* values_num = */ 1);
+  za_submit (type, type_instance, &(value_t) { .derive = (derive_t) tmp }, /* values_num = */ 1);
   return (0);
 }
 
 static int za_read_gauge (kstat_t *ksp, const char *kstat_value,
     const char *type, const char *type_instance)
 {
-  long long tmp;
-  value_t v;
-
-  tmp = get_zfs_value (ksp, (char *)kstat_value);
+  long long tmp = get_zfs_value (ksp, (char *)kstat_value);
   if (tmp == -1LL)
   {
     WARNING ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
     return (-1);
   }
 
-  v.gauge = (gauge_t) tmp;
-  za_submit (type, type_instance, /* values = */ &v, /* values_num = */ 1);
+  za_submit (type, type_instance, &(value_t) { .gauge = (gauge_t) tmp }, /* values_num = */ 1);
   return (0);
 }
 
@@ -216,7 +204,6 @@ static void za_submit_ratio (const char* type_instance, gauge_t hits, gauge_t mi
 static int za_read (void)
 {
        gauge_t  arc_hits, arc_misses, l2_hits, l2_misses;
-       value_t  l2_io[2];
        kstat_t  *ksp   = NULL;
 
 #if defined(KERNEL_LINUX)
@@ -295,10 +282,6 @@ static int za_read (void)
        za_read_derive (ksp, "deleted",  "cache_operation", "deleted");
 #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 */
@@ -336,10 +319,11 @@ static int za_read (void)
        za_submit_ratio ("L2", l2_hits, l2_misses);
 
        /* I/O */
-       l2_io[0].derive = get_zfs_value(ksp, "l2_read_bytes");
-       l2_io[1].derive = get_zfs_value(ksp, "l2_write_bytes");
-
-       za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
+       value_t  l2_io[] = {
+               { .derive = (derive_t) get_zfs_value(ksp, "l2_read_bytes") },
+               { .derive = (derive_t) get_zfs_value(ksp, "l2_write_bytes") },
+       };
+       za_submit ("io_octets", "L2", l2_io, STATIC_ARRAY_SIZE (l2_io));
 
 #if defined(KERNEL_LINUX)
        free_zfs_values (ksp);
index 87c6517..d9e46f5 100644 (file)
@@ -31,6 +31,7 @@
 #endif
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -133,7 +134,7 @@ zone_submit_values(c_avl_tree_t *tree)
        while (c_avl_pick (tree, (void **)&zoneid, (void **)&stats) == 0)
        {
                if (getzonenamebyid(*zoneid, zonename, sizeof( zonename )) == -1) {
-                       WARNING("zone plugin: error retreiving zonename");
+                       WARNING("zone plugin: error retrieving zonename");
                } else {
                        zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu));
                }
index 860e93d..7e55191 100644 (file)
@@ -25,6 +25,7 @@
  **/
 
 #include "collectd.h"
+
 #include "common.h"
 #include "plugin.h"
 
@@ -65,14 +66,11 @@ static int zookeeper_config(const char *key, const char *value)
        return 0;
 }
 
-static void zookeeper_submit_gauge (const char * type, const char * type_inst, gauge_t val)
+static void zookeeper_submit_gauge (const char * type, const char * type_inst, gauge_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].gauge = val;
-
-       vl.values = values;
+       vl.values = &(value_t) { .gauge = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "zookeeper", sizeof (vl.plugin));
@@ -83,14 +81,11 @@ static void zookeeper_submit_gauge (const char * type, const char * type_inst, g
        plugin_dispatch_values (&vl);
 } /* zookeeper_submit_gauge */
 
-static void zookeeper_submit_derive (const char * type, const char * type_inst, derive_t val)
+static void zookeeper_submit_derive (const char * type, const char * type_inst, derive_t value)
 {
-       value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
 
-       values[0].derive = val;
-
-       vl.values = values;
+       vl.values = &(value_t) { .derive = value };
        vl.values_len = 1;
        sstrncpy (vl.host, hostname_g, sizeof (vl.host));
        sstrncpy (vl.plugin, "zookeeper", sizeof (vl.plugin));
@@ -105,18 +100,18 @@ static int zookeeper_connect (void)
 {
        int sk = -1;
        int status;
-       struct addrinfo ai_hints;
-       struct addrinfo *ai;
        struct addrinfo *ai_list;
        const char *host;
        const char *port;
 
-       memset (&ai_hints, '\0', sizeof (ai_hints));
-       ai_hints.ai_family   = AF_UNSPEC;
-       ai_hints.ai_socktype = SOCK_STREAM;
-
        host = (zk_host != NULL) ? zk_host : ZOOKEEPER_DEF_HOST;
        port = (zk_port != NULL) ? zk_port : ZOOKEEPER_DEF_PORT;
+
+       struct addrinfo ai_hints = {
+               .ai_family   = AF_UNSPEC,
+               .ai_socktype = SOCK_STREAM
+       };
+
        status = getaddrinfo (host, port, &ai_hints, &ai_list);
        if (status != 0)
        {
@@ -128,7 +123,7 @@ static int zookeeper_connect (void)
                return (-1);
        }
 
-       for (ai = ai_list; ai != NULL; ai = ai->ai_next)
+       for (struct addrinfo *ai = ai_list; ai != NULL; ai = ai->ai_next)
        {
                sk = socket (ai->ai_family, SOCK_STREAM, 0);
                if (sk < 0)
index 70b8c26..2ef5279 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-DEFAULT_VERSION="5.5.2.git"
+DEFAULT_VERSION="5.6.0.git"
 
 if [ -d .git ]; then
        VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"