Merge branch 'collectd-5.5'
authorFlorian Forster <octo@collectd.org>
Mon, 30 Nov 2015 10:35:40 +0000 (11:35 +0100)
committerFlorian Forster <octo@collectd.org>
Mon, 30 Nov 2015 10:37:10 +0000 (11:37 +0100)
1  2 
src/Makefile.am
src/ceph.c
src/daemon/plugin_mock.c
src/snmp.c

diff --combined src/Makefile.am
@@@ -6,6 -6,10 +6,6 @@@ SUBDIRS += daemo
  
  PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex '\<module_register\>'
  
 -if COMPILER_IS_GCC
 -AM_CFLAGS = -Wall -Werror
 -endif
 -
  AM_CPPFLAGS = -I$(srcdir)/daemon
  AM_CPPFLAGS += -DPREFIX='"${prefix}"'
  AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
@@@ -19,37 -23,13 +19,37 @@@ AM_CPPFLAGS += -DPKGDATADIR='"${pkgdata
  
  AUTOMAKE_OPTIONS = subdir-objects
  
 -noinst_LTLIBRARIES = libmount.la liblookup.la
 +noinst_LTLIBRARIES =
 +check_PROGRAMS =
 +TESTS =
  
 -libmount_la_SOURCES = utils_mount.c utils_mount.h
 -libmount_la_LIBADD = daemon/libcommon.la
 +noinst_LTLIBRARIES += liblatency.la
 +liblatency_la_SOURCES = utils_latency.c utils_latency.h
 +check_PROGRAMS += test_utils_latency
 +TESTS += test_utils_latency
 +test_utils_latency_SOURCES = utils_latency_test.c testing.h
 +test_utils_latency_LDADD = liblatency.la daemon/libcommon.la daemon/libplugin_mock.la -lm
  
 +noinst_LTLIBRARIES += liblookup.la
  liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h
 -liblookup_la_LIBADD = daemon/libavltree.la daemon/libcommon.la
 +liblookup_la_LIBADD = daemon/libavltree.la
 +check_PROGRAMS += test_utils_vl_lookup
 +TESTS += test_utils_vl_lookup
 +test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
 +test_utils_vl_lookup_LDADD = liblookup.la daemon/libcommon.la daemon/libplugin_mock.la
 +if BUILD_WITH_LIBKSTAT
 +test_utils_vl_lookup_LDADD += -lkstat
 +endif
 +
 +noinst_LTLIBRARIES += libmount.la
 +libmount_la_SOURCES = utils_mount.c utils_mount.h
 +check_PROGRAMS += test_utils_mount
 +TESTS += test_utils_mount
 +test_utils_mount_SOURCES = utils_mount_test.c testing.h
 +test_utils_mount_LDADD = libmount.la daemon/libcommon.la daemon/libplugin_mock.la
 +if BUILD_WITH_LIBKSTAT
 +test_utils_mount_LDADD += -lkstat
 +endif
  
  sbin_PROGRAMS = collectdmon
  bin_PROGRAMS = collectd-nagios collectdctl collectd-tg
@@@ -84,8 -64,7 +84,8 @@@ collectdctl_LDADD += libcollectdclient/
  collectdctl_DEPENDENCIES = libcollectdclient/libcollectdclient.la
  
  collectd_tg_SOURCES = collectd-tg.c
 -collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/libcollectdclient/collectd -I$(top_builddir)/src/libcollectdclient/collectd
 +collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) \
 +                     -I$(top_srcdir)/src/libcollectdclient/collectd -I$(top_builddir)/src/libcollectdclient/collectd
  collectd_tg_LDADD = daemon/libheap.la
  if BUILD_WITH_LIBSOCKET
  collectd_tg_LDADD += -lsocket
@@@ -337,9 -316,6 +337,9 @@@ endi
  if BUILD_WITH_LIBUDEV
  disk_la_LIBADD += -ludev
  endif
 +if BUILD_FREEBSD
 +disk_la_LIBADD += -ldevstat -lgeom
 +endif
  if BUILD_WITH_PERFSTAT
  disk_la_LIBADD += -lperfstat
  endif
@@@ -468,8 -444,6 +468,8 @@@ pkglib_LTLIBRARIES += ipvs.l
  ipvs_la_SOURCES = ipvs.c
  if IP_VS_H_NEEDS_KERNEL_CFLAGS
  ipvs_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
 +else
 +ipvs_la_CFLAGS = $(AM_CFLAGS)
  endif
  ipvs_la_LDFLAGS = $(PLUGIN_LDFLAGS)
  endif
@@@ -640,14 -614,6 +640,14 @@@ modbus_la_CFLAGS = $(AM_CFLAGS) $(BUILD
  modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS)
  endif
  
 +if BUILD_PLUGIN_MQTT
 +pkglib_LTLIBRARIES += mqtt.la
 +mqtt_la_SOURCES = mqtt.c
 +mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +mqtt_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
 +mqtt_la_LIBADD = $(BUILD_WITH_LIBMOSQUITTO_LIBS)
 +endif
 +
  if BUILD_PLUGIN_MULTIMETER
  pkglib_LTLIBRARIES += multimeter.la
  multimeter_la_SOURCES = multimeter.c
@@@ -972,9 -938,10 +972,9 @@@ endi
  
  if BUILD_PLUGIN_STATSD
  pkglib_LTLIBRARIES += statsd.la
 -statsd_la_SOURCES = statsd.c \
 -                    utils_latency.h utils_latency.c
 +statsd_la_SOURCES = statsd.c
  statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 -statsd_la_LIBADD = -lpthread -lm
 +statsd_la_LIBADD = liblatency.la -lpthread -lm
  endif
  
  if BUILD_PLUGIN_SWAP
@@@ -1306,13 -1273,6 +1306,13 @@@ endi
  
  BUILT_SOURCES += $(dist_man_MANS)
  
 +if BUILD_PLUGIN_ZONE
 +pkglib_LTLIBRARIES += zone.la
 +zone_la_SOURCES = zone.c
 +zone_la_CFLAGS = $(AM_CFLAGS)
 +zone_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 +endif
 +
  dist_man_MANS = collectd.1 \
                collectd.conf.5 \
                collectd-email.5 \
@@@ -1366,30 -1326,25 +1366,30 @@@ EXTRA_DIST +=   collectd.conf.pod 
                echo "$@ has some POD errors!"; false; \
        fi
  
 +AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@)
 +am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@)
 +am__v_PROTOC_C_0 = @echo "  PROTOC-C    " $@;
 +am__v_PROTOC_C_1 =
 +
  # Protocol buffer for the "pinba" plugin.
  EXTRA_DIST += pinba.proto
 -if HAVE_PROTOC_C
 +if BUILD_PLUGIN_PINBA
  CLEANFILES += pinba.pb-c.c pinba.pb-c.h
  BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h
  
  pinba.pb-c.c pinba.pb-c.h: pinba.proto
 -      protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto
 +      $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto
  endif
  
  # Protocol buffer for the "write_riemann" plugin.
  EXTRA_DIST += riemann.proto
 -if HAVE_PROTOC_C
 +if BUILD_PLUGIN_WRITE_RIEMANN
  CLEANFILES += riemann.pb-c.c riemann.pb-c.h
  
  BUILT_SOURCES += riemann.pb-c.c riemann.pb-c.h
  
  riemann.pb-c.c riemann.pb-c.h: riemann.proto
 -      protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto
 +      $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto
  endif
  
  install-exec-hook:
@@@ -1410,4 -1365,21 +1410,11 @@@ uninstall-hook
        rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
        rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
  
 -check_PROGRAMS = test_utils_mount test_utils_vl_lookup
 -
 -test_utils_mount_SOURCES = utils_mount_test.c testing.h
 -test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
 -
 -test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
 -test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
 -
 -TESTS = test_utils_mount test_utils_vl_lookup
--
+ if BUILD_PLUGIN_CEPH
+ test_plugin_ceph_SOURCES = ceph_test.c
+ test_plugin_ceph_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+ test_plugin_ceph_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+ test_plugin_ceph_LDADD = daemon/libcommon.la daemon/libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS)
+ check_PROGRAMS += test_plugin_ceph
+ TESTS += test_plugin_ceph
+ endif
diff --combined src/ceph.c
@@@ -1,6 -1,7 +1,7 @@@
  /**
   * collectd - src/ceph.c
   * Copyright (C) 2011  New Dream Network
+  * Copyright (C) 2015  Florian octo Forster
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License as published by the
   * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
   *
   * Authors:
-  *   Colin McCabe <cmccabe@alumni.cmu.edu>
-  *   Dennis Zou <yunzou@cisco.com>
-  *   Dan Ryder <daryder@cisco.com>
+  *   Colin McCabe <cmccabe at alumni.cmu.edu>
+  *   Dennis Zou <yunzou at cisco.com>
+  *   Dan Ryder <daryder at cisco.com>
+  *   Florian octo Forster <octo at collectd.org>
   **/
  
  #define _DEFAULT_SOURCE
@@@ -43,6 -45,7 +45,6 @@@
  #include <stdlib.h>
  #include <string.h>
  #include <strings.h>
 -#include <sys/socket.h>
  #include <sys/time.h>
  #include <sys/types.h>
  #include <sys/un.h>
@@@ -419,140 -422,140 +421,140 @@@ static void ceph_daemon_free(struct cep
      sfree(d);
  }
  
- /**
-  * Compact ds name by removing special characters and trimming length to
-  * DATA_MAX_NAME_LEN if necessary
-  */
- static void compact_ds_name(char *source, char *dest)
- {
-     int keys_num = 0, i;
-     char *save_ptr = NULL, *tmp_ptr = source;
-     char *keys[16];
-     char len_str[3];
-     char tmp[DATA_MAX_NAME_LEN];
-     size_t key_chars_remaining = (DATA_MAX_NAME_LEN-1);
-     int reserved = 0;
-     int offset = 0;
-     memset(tmp, 0, sizeof(tmp));
-     if(source == NULL || dest == NULL || source[0] == '\0' || dest[0] != '\0')
-     {
-         return;
-     }
-     size_t src_len = strlen(source);
-     snprintf(len_str, sizeof(len_str), "%zu", src_len);
-     unsigned char append_status = 0x0;
-     append_status |= (source[src_len - 1] == '-') ? 0x1 : 0x0;
-     append_status |= (source[src_len - 1] == '+') ? 0x2 : 0x0;
-     while ((keys[keys_num] = strtok_r(tmp_ptr, ":_-+", &save_ptr)) != NULL)
-     {
-         tmp_ptr = NULL;
-         /** capitalize 1st char **/
-         keys[keys_num][0] = toupper(keys[keys_num][0]);
-         keys_num++;
-         if(keys_num >= 16)
-         {
-             break;
-         }
-     }
-     /** concatenate each part of source string **/
-     for(i = 0; i < keys_num; i++)
-     {
-         strncat(tmp, keys[i], key_chars_remaining);
-         key_chars_remaining -= strlen(keys[i]);
-     }
-     tmp[DATA_MAX_NAME_LEN - 1] = '\0';
-     /** to coordinate limitation of length of type_instance
-      *  we will truncate ds_name
-      *  when the its length is more than
-      *  DATA_MAX_NAME_LEN
-      */
-     if(strlen(tmp) > DATA_MAX_NAME_LEN - 1)
+ /* compact_ds_name removed the special characters ":", "_", "-" and "+" from the
+  * intput string. Characters following these special characters are capitalized.
+  * Trailing "+" and "-" characters are replaces with the strings "Plus" and
+  * "Minus". */
+ static int compact_ds_name (char *buffer, size_t buffer_size, char const *src)
+ {
+     char *src_copy;
+     size_t src_len;
+     char *ptr = buffer;
+     size_t ptr_size = buffer_size;
+     _Bool append_plus = 0;
+     _Bool append_minus = 0;
+     if ((buffer == NULL) || (buffer_size <= strlen ("Minus")) || (src == NULL))
+       return EINVAL;
+     src_copy = strdup (src);
+     src_len = strlen(src);
+     /* Remove trailing "+" and "-". */
+     if (src_copy[src_len - 1] == '+')
      {
-         append_status |= 0x4;
-         /** we should reserve space for
-          * len_str
-          */
-         reserved += 2;
+         append_plus = 1;
+         src_len--;
+         src_copy[src_len] = 0;
      }
-     if(append_status & 0x1)
+     else if (src_copy[src_len - 1] == '-')
      {
-         /** we should reserve space for
-          * "Minus"
-          */
-         reserved += 5;
+         append_minus = 1;
+         src_len--;
+         src_copy[src_len] = 0;
      }
-     if(append_status & 0x2)
+     /* Split at special chars, capitalize first character, append to buffer. */
+     char *dummy = src_copy;
+     char *token;
+     char *save_ptr = NULL;
+     while ((token = strtok_r (dummy, ":_-+", &save_ptr)) != NULL)
      {
-         /** we should reserve space for
-          * "Plus"
-          */
-         reserved += 4;
+         size_t len;
+         dummy = NULL;
+         token[0] = toupper ((int) token[0]);
+         assert (ptr_size > 1);
+         len = strlen (token);
+         if (len >= ptr_size)
+             len = ptr_size - 1;
+         assert (len > 0);
+         assert (len < ptr_size);
+         sstrncpy (ptr, token, len + 1);
+         ptr += len;
+         ptr_size -= len;
+         assert (*ptr == 0);
+         if (ptr_size <= 1)
+             break;
      }
-     snprintf(dest, DATA_MAX_NAME_LEN - reserved, "%s", tmp);
-     offset = strlen(dest);
-     switch (append_status)
+     /* Append "Plus" or "Minus" if "+" or "-" has been stripped above. */
+     if (append_plus || append_minus)
      {
-         case 0x1:
-             memcpy(dest + offset, "Minus", 5);
-             break;
-         case 0x2:
-             memcpy(dest + offset, "Plus", 5);
-             break;
-         case 0x4:
-             memcpy(dest + offset, len_str, 2);
-             break;
-         case 0x5:
-             memcpy(dest + offset, "Minus", 5);
-             memcpy(dest + offset + 5, len_str, 2);
-             break;
-         case 0x6:
-             memcpy(dest + offset, "Plus", 4);
-             memcpy(dest + offset + 4, len_str, 2);
-             break;
-         default:
-             break;
+         char const *append = "Plus";
+         if (append_minus)
+             append = "Minus";
+         size_t offset = buffer_size - (strlen (append) + 1);
+         if (offset > strlen (buffer))
+             offset = strlen (buffer);
+         sstrncpy (buffer + offset, append, buffer_size - offset);
      }
+     sfree (src_copy);
+     return 0;
+ }
+ static _Bool has_suffix (char const *str, char const *suffix)
+ {
+     size_t str_len = strlen (str);
+     size_t suffix_len = strlen (suffix);
+     size_t offset;
+     if (suffix_len > str_len)
+         return 0;
+     offset = str_len - suffix_len;
+     if (strcmp (str + offset, suffix) == 0)
+         return 1;
+     return 0;
+ }
+ /* count_parts returns the number of elements a "foo.bar.baz" style key has. */
+ static size_t count_parts (char const *key)
+ {
+     char const *ptr;
+     size_t parts_num = 0;
+     for (ptr = key; ptr != NULL; ptr = strchr (ptr + 1, '.'))
+         parts_num++;
+     return parts_num;
  }
  
  /**
   * Parse key to remove "type" if this is for schema and initiate compaction
   */
- static int parse_keys(const char *key_str, char *ds_name)
+ static int parse_keys (char *buffer, size_t buffer_size, const char *key_str)
  {
-     char *ptr, *rptr;
-     size_t ds_name_len = 0;
-     /**
-      * allow up to 100 characters before compaction - compact_ds_name will not
-      * allow more than DATA_MAX_NAME_LEN chars
-      */
-     int max_str_len = 100;
-     char tmp_ds_name[max_str_len];
-     memset(tmp_ds_name, 0, sizeof(tmp_ds_name));
-     if(ds_name == NULL || key_str == NULL ||  key_str[0] == '\0' ||
-                                                             ds_name[0] != '\0')
-     {
-         return -1;
-     }
-     if((ptr = strchr(key_str, '.')) == NULL
-             || (rptr = strrchr(key_str, '.')) == NULL)
+     char tmp[2 * buffer_size];
+     if (buffer == NULL || buffer_size == 0 || key_str == NULL || strlen (key_str) == 0)
+         return EINVAL;
+     if ((count_parts (key_str) > 2) && has_suffix (key_str, ".type"))
      {
-         memcpy(tmp_ds_name, key_str, max_str_len - 1);
-         goto compact;
-     }
+         /* strip ".type" suffix iff the key has more than two parts. */
+         size_t sz = strlen (key_str) - strlen (".type") + 1;
  
-     ds_name_len = (rptr - ptr) > max_str_len ? max_str_len : (rptr - ptr);
-     if((ds_name_len == 0) || strncmp(rptr + 1, "type", 4))
-     { /** copy whole key **/
-         memcpy(tmp_ds_name, key_str, max_str_len - 1);
+         if (sz > sizeof (tmp))
+             sz = sizeof (tmp);
+         sstrncpy (tmp, key_str, sz);
      }
      else
-     {/** more than two keys **/
-         memcpy(tmp_ds_name, key_str, ((rptr - key_str) > (max_str_len - 1) ?
-                 (max_str_len - 1) : (rptr - key_str)));
+     {
+         sstrncpy (tmp, key_str, sizeof (tmp));
      }
  
-     compact: compact_ds_name(tmp_ds_name, ds_name);
-     return 0;
+     return compact_ds_name (buffer, buffer_size, tmp);
  }
  
  /**
@@@ -604,7 -607,7 +606,7 @@@ static int ceph_daemon_add_ds_entry(str
              ((pc_type & PERFCOUNTER_LATENCY) ? DSET_LATENCY : DSET_BYTES);
      d->ds_types[d->ds_num] = type;
  
-     if(parse_keys(name, ds_name))
+     if (parse_keys(ds_name, sizeof (ds_name), name))
      {
          return 1;
      }
@@@ -956,7 -959,7 +958,7 @@@ static int node_handler_fetch_data(voi
      char ds_name[DATA_MAX_NAME_LEN];
      memset(ds_name, 0, sizeof(ds_name));
  
-     if(parse_keys(key, ds_name))
+     if (parse_keys (ds_name, sizeof (ds_name), key))
      {
          return 1;
      }
@@@ -1082,7 -1085,6 +1084,7 @@@ static int cconn_connect(struct cconn *
      {
          ERROR("ceph plugin: cconn_connect: connect(%d) failed: error %d",
              fd, err);
 +        close(fd);
          return err;
      }
  
          err = -errno;
          ERROR("ceph plugin: cconn_connect: fcntl(%d, O_NONBLOCK) error %d",
              fd, err);
 +        close(fd);
          return err;
      }
      io->asok = fd;
diff --combined src/daemon/plugin_mock.c
  
  #include "plugin.h"
  
 +#if HAVE_LIBKSTAT
 +kstat_ctl_t *kc = NULL;
 +#endif /* HAVE_LIBKSTAT */
 +
+ char hostname_g[] = "example.com";
+ int plugin_register_complex_config (const char *type, int (*callback) (oconfig_item_t *))
+ {
+   return ENOTSUP;
+ }
+ int plugin_register_init (const char *name, plugin_init_cb callback)
+ {
+   return ENOTSUP;
+ }
+ int plugin_register_read (const char *name, int (*callback) (void))
+ {
+   return ENOTSUP;
+ }
+ int plugin_register_shutdown (const char *name, int (*callback) (void))
+ {
+   return ENOTSUP;
+ }
+ int plugin_dispatch_values (value_list_t const *vl)
+ {
+   return ENOTSUP;
+ }
  void plugin_log (int level, char const *format, ...)
  {
    char buffer[1024];
@@@ -42,4 -65,9 +69,9 @@@
    printf ("plugin_log (%i, \"%s\");\n", level, buffer);
  }
  
+ cdtime_t plugin_get_interval (void)
+ {
+   return TIME_T_TO_CDTIME_T (10);
+ }
  /* vim: set sw=2 sts=2 et : */
diff --combined src/snmp.c
@@@ -61,7 -61,7 +61,7 @@@ struct data_definition_
    instance_t instance;
    char *instance_prefix;
    oid_t *values;
 -  int values_len;
 +  size_t values_len;
    double scale;
    double shift;
    struct data_definition_s *next;
@@@ -313,7 -313,7 +313,7 @@@ static int csnmp_config_add_data_value
    dd->values = (oid_t *) malloc (sizeof (oid_t) * ci->values_num);
    if (dd->values == NULL)
      return (-1);
 -  dd->values_len = ci->values_num;
 +  dd->values_len = (size_t) ci->values_num;
  
    for (i = 0; i < ci->values_num; i++)
    {
@@@ -459,7 -459,7 +459,7 @@@ static int csnmp_config_add_data (oconf
      return (-1);
    }
  
 -  DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %i }",
 +  DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %zu }",
        dd->name, dd->type, (dd->is_table != 0) ? "true" : "false", dd->values_len);
  
    if (data_head == NULL)
@@@ -645,6 -645,7 +645,6 @@@ static int csnmp_config_add_host (oconf
    /* Registration stuff. */
    char cb_name[DATA_MAX_NAME_LEN];
    user_data_t cb_data;
 -  struct timespec cb_interval;
  
    hd = (host_definition_t *) malloc (sizeof (host_definition_t));
    if (hd == NULL)
  
    status = cf_util_get_string(ci, &hd->name);
    if (status != 0)
+   {
+     sfree (hd);
      return status;
+   }
  
    hd->sess_handle = NULL;
    hd->interval = 0;
    cb_data.data = hd;
    cb_data.free_func = csnmp_host_definition_destroy;
  
 -  CDTIME_T_TO_TIMESPEC (hd->interval, &cb_interval);
 -
    status = plugin_register_complex_read (/* group = */ NULL, cb_name,
 -      csnmp_read_host, /* interval = */ &cb_interval,
 -      /* user_data = */ &cb_data);
 +      csnmp_read_host, hd->interval, /* user_data = */ &cb_data);
    if (status != 0)
    {
      ERROR ("snmp plugin: Registering complex read function failed.");
@@@ -1048,10 -1055,6 +1051,10 @@@ static value_t csnmp_value_list_to_valu
    return (ret);
  } /* value_t csnmp_value_list_to_value */
  
 +/* csnmp_strvbcopy_hexstring converts the bit string contained in "vb" to a hex
 + * representation and writes it to dst. Returns zero on success and ENOMEM if
 + * dst is not large enough to hold the string. dst is guaranteed to be
 + * nul-terminated. */
  static int csnmp_strvbcopy_hexstring (char *dst, /* {{{ */
      const struct variable_list *vb, size_t dst_size)
  {
    size_t buffer_free;
    size_t i;
  
 +  dst[0] = 0;
 +
    buffer_ptr = dst;
    buffer_free = dst_size;
  
  
      status = snprintf (buffer_ptr, buffer_free,
          (i == 0) ? "%02x" : ":%02x", (unsigned int) vb->val.bitstring[i]);
 +    assert (status >= 0);
  
 -    if (status >= buffer_free)
 +    if (((size_t) status) >= buffer_free) /* truncated */
      {
 -      buffer_ptr += (buffer_free - 1);
 -      *buffer_ptr = 0;
 -      return (dst_size + (buffer_free - status));
 +      dst[dst_size - 1] = 0;
 +      return ENOMEM;
      }
      else /* if (status < buffer_free) */
      {
 -      buffer_ptr += status;
 -      buffer_free -= status;
 +      buffer_ptr  += (size_t) status;
 +      buffer_free -= (size_t) status;
      }
    }
  
 -  return ((int) (dst_size - buffer_free));
 +  return 0;
  } /* }}} int csnmp_strvbcopy_hexstring */
  
 +/* csnmp_strvbcopy copies the octet string or bit string contained in vb to
 + * dst. If non-printable characters are detected, it will switch to a hex
 + * representation of the string. Returns zero on success, EINVAL if vb does not
 + * contain a string and ENOMEM if dst is not large enough to contain the
 + * string. */
  static int csnmp_strvbcopy (char *dst, /* {{{ */
      const struct variable_list *vb, size_t dst_size)
  {
      dst[i] = src[i];
    }
    dst[num_chars] = 0;
 +  dst[dst_size - 1] = 0;
  
 -  return ((int) vb->val_len);
 +  if (dst_size <= vb->val_len)
 +    return ENOMEM;
 +
 +  return 0;
  } /* }}} int csnmp_strvbcopy */
  
  static int csnmp_instance_list_add (csnmp_list_instances_t **head,
@@@ -1234,7 -1226,7 +1237,7 @@@ static int csnmp_dispatch_table (host_d
    csnmp_list_instances_t *instance_list_ptr;
    csnmp_table_values_t **value_table_ptr;
  
 -  int i;
 +  size_t i;
    _Bool have_more;
    oid_t current_suffix;
  
  
    instance_list_ptr = instance_list;
  
 -  value_table_ptr = calloc ((size_t) data->values_len, sizeof (*value_table_ptr));
 +  value_table_ptr = calloc (data->values_len, sizeof (*value_table_ptr));
    if (value_table_ptr == NULL)
      return (-1);
    for (i = 0; i < data->values_len; i++)
@@@ -1392,7 -1384,7 +1395,7 @@@ static int csnmp_read_table (host_defin
  
    const data_set_t *ds;
  
 -  uint32_t oid_list_len = (uint32_t) (data->values_len + 1);
 +  size_t oid_list_len = data->values_len + 1;
    /* Holds the last OID returned by the device. We use this in the GETNEXT
     * request to proceed. */
    oid_t oid_list[oid_list_len];
    _Bool oid_list_todo[oid_list_len];
  
    int status;
 -  int i;
 -  uint32_t j;
 +  size_t i;
  
    /* `value_list_head' and `value_list_tail' implement a linked list for each
     * value. `instance_list_head' and `instance_list_tail' implement a linked list of
  
    if (ds->ds_num != data->values_len)
    {
 -    ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
 +    ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu",
          data->type, ds->ds_num, data->values_len);
      return (-1);
    }
    else /* no InstanceFrom option specified. */
      oid_list_len--;
  
 -  for (j = 0; j < oid_list_len; j++)
 -    oid_list_todo[j] = 1;
 +  for (i = 0; i < oid_list_len; i++)
 +    oid_list_todo[i] = 1;
  
    /* We're going to construct n linked lists, one for each "value".
     * value_list_head will contain pointers to the heads of these linked lists,
      }
  
      oid_list_todo_num = 0;
 -    for (j = 0; j < oid_list_len; j++)
 +    for (i = 0; i < oid_list_len; i++)
      {
        /* Do not rerequest already finished OIDs */
 -      if (!oid_list_todo[j])
 +      if (!oid_list_todo[i])
          continue;
        oid_list_todo_num++;
 -      snmp_add_null_var (req, oid_list[j].oid, oid_list[j].oid_len);
 +      snmp_add_null_var (req, oid_list[i].oid, oid_list[i].oid_len);
      }
  
      if (oid_list_todo_num == 0)
          ret = csnmp_oid_suffix (&suffix, &vb_name, data->values + i);
          if (ret != 0)
          {
 -          DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
 +          DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; "
                "Value probably left its subtree.",
                host->name, data->name, i);
            oid_list_todo[i] = 0;
          if ((value_list_tail[i] != NULL)
              && (csnmp_oid_compare (&suffix, &value_list_tail[i]->suffix) <= 0))
          {
 -          DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
 +          DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; "
                "Suffix is not increasing.",
                host->name, data->name, i);
            oid_list_todo[i] = 0;
@@@ -1673,7 -1666,7 +1676,7 @@@ static int csnmp_read_value (host_defin
    value_list_t vl = VALUE_LIST_INIT;
  
    int status;
 -  int i;
 +  size_t i;
  
    DEBUG ("snmp plugin: csnmp_read_value (host = %s, data = %s)",
        host->name, data->name);
  
    if (ds->ds_num != data->values_len)
    {
 -    ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
 +    ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu",
          data->type, ds->ds_num, data->values_len);
      return (-1);
    }