Merge branch 'collectd-5.7' into collectd-5.8
authorFlorian Forster <octo@collectd.org>
Mon, 4 Dec 2017 07:23:26 +0000 (08:23 +0100)
committerFlorian Forster <octo@collectd.org>
Mon, 4 Dec 2017 07:23:26 +0000 (08:23 +0100)
1  2 
src/exec.c
src/perl.c
src/powerdns.c
src/rrdtool.c
src/table.c

diff --combined src/exec.c
@@@ -108,26 -108,26 +108,26 @@@ static int exec_config_exec(oconfig_ite
  
    if (ci->children_num != 0) {
      WARNING("exec plugin: The config option `%s' may not be a block.", ci->key);
 -    return (-1);
 +    return -1;
    }
    if (ci->values_num < 2) {
      WARNING("exec plugin: The config option `%s' needs at least two "
              "arguments.",
              ci->key);
 -    return (-1);
 +    return -1;
    }
    if ((ci->values[0].type != OCONFIG_TYPE_STRING) ||
        (ci->values[1].type != OCONFIG_TYPE_STRING)) {
      WARNING("exec plugin: The first two arguments to the `%s' option must "
              "be string arguments.",
              ci->key);
 -    return (-1);
 +    return -1;
    }
  
    pl = calloc(1, sizeof(*pl));
    if (pl == NULL) {
      ERROR("exec plugin: calloc failed.");
 -    return (-1);
 +    return -1;
    }
  
    if (strcasecmp("NotificationExec", ci->key) == 0)
    if (pl->user == NULL) {
      ERROR("exec plugin: strdup failed.");
      sfree(pl);
 -    return (-1);
 +    return -1;
    }
  
    pl->group = strchr(pl->user, ':');
      ERROR("exec plugin: strdup failed.");
      sfree(pl->user);
      sfree(pl);
 -    return (-1);
 +    return -1;
    }
  
    pl->argv = calloc(ci->values_num, sizeof(*pl->argv));
      sfree(pl->exec);
      sfree(pl->user);
      sfree(pl);
 -    return (-1);
 +    return -1;
    }
  
    {
      sfree(pl->exec);
      sfree(pl->user);
      sfree(pl);
 -    return (-1);
 +    return -1;
    }
  
    for (i = 1; i < (ci->values_num - 1); i++) {
        pl->argv[i] = strdup(ci->values[i + 1].value.string);
      } else {
        if (ci->values[i + 1].type == OCONFIG_TYPE_NUMBER) {
 -        ssnprintf(buffer, sizeof(buffer), "%lf",
 -                  ci->values[i + 1].value.number);
 +        snprintf(buffer, sizeof(buffer), "%lf", ci->values[i + 1].value.number);
        } else {
          if (ci->values[i + 1].value.boolean)
            sstrncpy(buffer, "true", sizeof(buffer));
      sfree(pl->exec);
      sfree(pl->user);
      sfree(pl);
 -    return (-1);
 +    return -1;
    }
  
    for (i = 0; pl->argv[i] != NULL; i++) {
    pl->next = pl_head;
    pl_head = pl;
  
 -  return (0);
 +  return 0;
  } /* int exec_config_exec }}} */
  
  static int exec_config(oconfig_item_t *ci) /* {{{ */
      }
    } /* for (i) */
  
 -  return (0);
 +  return 0;
  } /* int exec_config }}} */
  
  static void set_environment(void) /* {{{ */
    char buffer[1024];
  
  #ifdef HAVE_SETENV
 -  ssnprintf(buffer, sizeof(buffer), "%.3f",
 -            CDTIME_T_TO_DOUBLE(plugin_get_interval()));
 +  snprintf(buffer, sizeof(buffer), "%.3f",
 +           CDTIME_T_TO_DOUBLE(plugin_get_interval()));
    setenv("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1);
  
    sstrncpy(buffer, hostname_g, sizeof(buffer));
    setenv("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1);
  #else
 -  ssnprintf(buffer, sizeof(buffer), "COLLECTD_INTERVAL=%.3f",
 -            CDTIME_T_TO_DOUBLE(plugin_get_interval()));
 +  snprintf(buffer, sizeof(buffer), "COLLECTD_INTERVAL=%.3f",
 +           CDTIME_T_TO_DOUBLE(plugin_get_interval()));
    putenv(buffer);
  
 -  ssnprintf(buffer, sizeof(buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
 +  snprintf(buffer, sizeof(buffer), "COLLECTD_HOSTNAME=%s", hostname_g);
    putenv(buffer);
  #endif
  } /* }}} void set_environment */
@@@ -331,7 -332,7 +331,7 @@@ static int create_pipe(int fd_pipe[2]) 
    if (status != 0) {
      ERROR("exec plugin: pipe failed: %s",
            sstrerror(errno, errbuf, sizeof(errbuf)));
 -    return (-1);
 +    return -1;
    }
  
    return 0;
@@@ -370,7 -371,7 +370,7 @@@ static int fork_child(program_list_t *p
    struct passwd sp;
  
    if (pl->pid != 0)
 -    return (-1);
 +    return -1;
  
    long int nambuf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
    if (nambuf_size <= 0)
    /* The group configured in the configfile is set as effective group, because
     * this way the forked process can (re-)gain the user's primary group. */
    egid = -1;
 -  if (NULL != pl->group) {
 -    if ('\0' != *pl->group) {
 +  if (pl->group != NULL) {
 +    if (*pl->group != '\0') {
        struct group *gr_ptr = NULL;
        struct group gr;
  
        char grbuf[grbuf_size];
  
        status = getgrnam_r(pl->group, &gr, grbuf, sizeof(grbuf), &gr_ptr);
 -      if (0 != status) {
 +      if (status != 0) {
          ERROR("exec plugin: Failed to get group information "
                "for group ``%s'': %s",
                pl->group, sstrerror(status, errbuf, sizeof(errbuf)));
          goto failed;
        }
 -      if (NULL == gr_ptr) {
 +      if (gr_ptr == NULL) {
          ERROR("exec plugin: No such group: `%s'", pl->group);
          goto failed;
        }
    else
      close(fd_pipe_err[0]);
  
 -  return (pid);
 +  return pid;
  
  failed:
    close_pipe(fd_pipe_in);
    close_pipe(fd_pipe_out);
    close_pipe(fd_pipe_err);
  
 -  return (-1);
 +  return -1;
  } /* int fork_child }}} */
  
  static int parse_line(char *buffer) /* {{{ */
  {
    if (strncasecmp("PUTVAL", buffer, strlen("PUTVAL")) == 0)
 -    return (cmd_handle_putval(stdout, buffer));
 +    return cmd_handle_putval(stdout, buffer);
    else if (strncasecmp("PUTNOTIF", buffer, strlen("PUTNOTIF")) == 0)
 -    return (handle_putnotif(stdout, buffer));
 +    return handle_putnotif(stdout, buffer);
    else {
      ERROR("exec plugin: Unable to parse command, ignoring line: \"%s\"",
            buffer);
 -    return (-1);
 +    return -1;
    }
  } /* int parse_line }}} */
  
@@@ -667,7 -668,7 +667,7 @@@ static void *exec_read_one(void *arg) /
      close(fd_err);
  
    pthread_exit((void *)0);
 -  return (NULL);
 +  return NULL;
  } /* void *exec_read_one }}} */
  
  static void *exec_notification_one(void *arg) /* {{{ */
    n->meta = NULL;
    sfree(arg);
    pthread_exit((void *)0);
 -  return (NULL);
 +  return NULL;
  } /* void *exec_notification_one }}} */
  
  static int exec_init(void) /* {{{ */
    }
  #endif
  
 -  return (0);
 +  return 0;
  } /* int exec_init }}} */
  
  static int exec_read(void) /* {{{ */
  
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-     plugin_thread_create(&t, &attr, exec_read_one, (void *)pl, "exec read");
+     int status =
+         plugin_thread_create(&t, &attr, exec_read_one, (void *)pl, "exec read");
+     if (status != 0) {
+       ERROR("exec plugin: plugin_thread_create failed.");
+     }
      pthread_attr_destroy(&attr);
    } /* for (pl) */
  
 -  return (0);
 +  return 0;
  } /* int exec_read }}} */
  
  static int exec_notification(const notification_t *n, /* {{{ */
  
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-     plugin_thread_create(&t, &attr, exec_notification_one, (void *)pln,
-                          "exec notify");
+     int status = plugin_thread_create(&t, &attr, exec_notification_one,
+                                       (void *)pln, "exec notify");
+     if (status != 0) {
+       ERROR("exec plugin: plugin_thread_create failed.");
+     }
      pthread_attr_destroy(&attr);
    } /* for (pl) */
  
 -  return (0);
 +  return 0;
  } /* }}} int exec_notification */
  
  static int exec_shutdown(void) /* {{{ */
    } /* while (pl) */
    pl_head = NULL;
  
 -  return (0);
 +  return 0;
  } /* int exec_shutdown }}} */
  
  void module_register(void) {
                                 /* user_data = */ NULL);
    plugin_register_shutdown("exec", exec_shutdown);
  } /* void module_register */
 -
 -/*
 - * vim:shiftwidth=2:softtabstop=2:tabstop=8:fdm=marker
 - */
diff --combined src/perl.c
@@@ -38,7 -38,9 +38,7 @@@
  
  #undef DONT_POISON_SPRINTF_YET
  
 -#if HAVE_STDBOOL_H
  #include <stdbool.h>
 -#endif
  
  #include <EXTERN.h>
  #include <perl.h>
@@@ -261,6 -263,12 +261,6 @@@ struct 
                   {"Collectd::NOTIF_WARNING", NOTIF_WARNING},
                   {"Collectd::NOTIF_OKAY", NOTIF_OKAY},
                   {"", 0}};
 -
 -struct {
 -  char name[64];
 -  char *var;
 -} g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
 -
  /*
   * Helper functions for data type conversion.
   */
@@@ -418,6 -426,8 +418,6 @@@ static int hv2value_list(pTHX_ HV *hash
  
    if (NULL != (tmp = hv_fetch(hash, "host", 4, 0)))
      sstrncpy(vl->host, SvPV_nolen(*tmp), sizeof(vl->host));
 -  else
 -    sstrncpy(vl->host, hostname_g, sizeof(vl->host));
  
    if (NULL != (tmp = hv_fetch(hash, "plugin", 6, 0)))
      sstrncpy(vl->plugin, SvPV_nolen(*tmp), sizeof(vl->plugin));
@@@ -706,10 -716,8 +706,8 @@@ static int value_list2hv(pTHX_ value_li
  
  static int notification_meta2av(pTHX_ notification_meta_t *meta, AV *array) {
    int meta_num = 0;
-   while (meta) {
+   for (notification_meta_t *m = meta; m != NULL; m = m->next) {
      ++meta_num;
-     meta = meta->next;
    }
  
    av_extend(array, meta_num);
@@@ -874,12 -882,12 +872,12 @@@ static int oconfig_item2hv(pTHX_ oconfi
  static char *get_module_name(char *buf, size_t buf_len, const char *module) {
    int status = 0;
    if (base_name[0] == '\0')
 -    status = ssnprintf(buf, buf_len, "%s", module);
 +    status = snprintf(buf, buf_len, "%s", module);
    else
 -    status = ssnprintf(buf, buf_len, "%s::%s", base_name, module);
 +    status = snprintf(buf, buf_len, "%s::%s", base_name, module);
    if ((status < 0) || ((unsigned int)status >= buf_len))
 -    return (NULL);
 -  return (buf);
 +    return NULL;
 +  return buf;
  } /* char *get_module_name */
  
  /*
@@@ -1618,19 -1626,18 +1616,19 @@@ static void _plugin_register_generic_us
        ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL);
      }
  
 -    if (0 == ret)
 +    if (0 == ret) {
        ret = plugin_register_flush(pluginname, perl_flush, &userdata);
 +    } else {
 +      free(userdata.data);
 +    }
    } else {
      ret = -1;
    }
  
    if (0 == ret)
      XSRETURN_YES;
 -  else {
 -    free(userdata.data);
 +  else
      XSRETURN_EMPTY;
 -  }
  } /* static void _plugin_register_generic_userdata ( ... ) */
  
  /*
@@@ -2093,7 -2100,7 +2091,7 @@@ static int perl_init(void) 
    /* Lock the base thread to avoid race conditions with c_ithread_create().
     * See https://github.com/collectd/collectd/issues/9 and
     *     https://github.com/collectd/collectd/issues/1706 for details.
 -  */
 +   */
    assert(aTHX == perl_threads->head->interp);
    pthread_mutex_lock(&perl_threads->mutex);
  
@@@ -2184,7 -2191,7 +2182,7 @@@ static void perl_log(int level, const c
    /* Lock the base thread if this is not called from one of the read threads
     * to avoid race conditions with c_ithread_create(). See
     * https://github.com/collectd/collectd/issues/9 for details.
 -  */
 +   */
  
    if (aTHX == perl_threads->head->interp)
      pthread_mutex_lock(&perl_threads->mutex);
@@@ -2395,11 -2402,6 +2393,11 @@@ static void xs_init(pTHX) 
     * accessing any such variable (this is basically the same as using
     * tie() in Perl) */
    /* global strings */
 +  struct {
 +    char name[64];
 +    char *var;
 +  } g_strings[] = {{"Collectd::hostname_g", hostname_g}, {"", NULL}};
 +
    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);
@@@ -2507,7 -2509,7 +2505,7 @@@ static int perl_config_loadplugin(pTHX
  
    if (NULL == get_module_name(module_name, sizeof(module_name), value)) {
      log_err("Invalid module name %s", value);
 -    return (1);
 +    return 1;
    }
  
    if (0 != init_pi(perl_argc, perl_argv))
@@@ -2733,3 -2735,5 +2731,3 @@@ void module_register(void) 
    plugin_register_complex_config("perl", perl_config);
    return;
  } /* void module_register (void) */
 -
 -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
diff --combined src/powerdns.c
@@@ -379,8 -379,8 +379,8 @@@ static void submit(const char *plugin_i
    plugin_dispatch_values(&vl);
  } /* }}} static void submit */
  
- static int powerdns_get_data_dgram(list_item_t *item, /* {{{ */
-                                    char **ret_buffer, size_t *ret_buffer_size) {
+ static int powerdns_get_data_dgram(list_item_t *item, char **ret_buffer) {
+   /* {{{ */
    int sd;
    int status;
  
    sd = socket(PF_UNIX, item->socktype, 0);
    if (sd < 0) {
      FUNC_ERROR("socket");
 -    return (-1);
 +    return -1;
    }
  
    sa_unix.sun_family = AF_UNIX;
    if ((status != 0) && (errno != ENOENT)) {
      SOCK_ERROR("unlink", sa_unix.sun_path);
      close(sd);
 -    return (-1);
 +    return -1;
    }
  
    do /* while (0) */
    unlink(sa_unix.sun_path);
  
    if (status != 0)
 -    return (-1);
 +    return -1;
  
    assert(buffer_size > 0);
    buffer = malloc(buffer_size);
    if (buffer == NULL) {
      FUNC_ERROR("malloc");
 -    return (-1);
 +    return -1;
    }
  
    memcpy(buffer, temp, buffer_size - 1);
    buffer[buffer_size - 1] = 0;
  
    *ret_buffer = buffer;
-   *ret_buffer_size = buffer_size;
 -  return (0);
 +  return 0;
  } /* }}} int powerdns_get_data_dgram */
  
- static int powerdns_get_data_stream(list_item_t *item, /* {{{ */
-                                     char **ret_buffer,
-                                     size_t *ret_buffer_size) {
+ static int powerdns_get_data_stream(list_item_t *item, char **ret_buffer) {
+   /* {{{ */
    int sd;
    int status;
  
    sd = socket(PF_UNIX, item->socktype, 0);
    if (sd < 0) {
      FUNC_ERROR("socket");
 -    return (-1);
 +    return -1;
    }
  
    struct timeval timeout;
    if (status != 0) {
      FUNC_ERROR("setsockopt");
      close(sd);
 -    return (-1);
 +    return -1;
    }
  
    status =
    if (status != 0) {
      SOCK_ERROR("connect", item->sockaddr.sun_path);
      close(sd);
 -    return (-1);
 +    return -1;
    }
  
    /* strlen + 1, because we need to send the terminating NULL byte, too. */
    if (status < 0) {
      SOCK_ERROR("send", item->sockaddr.sun_path);
      close(sd);
 -    return (-1);
 +    return -1;
    }
  
    while (42) {
      if (status < 0) {
        SOCK_ERROR("recv", item->sockaddr.sun_path);
        break;
-     } else if (status == 0)
+     } else if (status == 0) {
        break;
+     }
  
      buffer_new = realloc(buffer, buffer_size + status + 1);
      if (buffer_new == NULL) {
        FUNC_ERROR("realloc");
-       status = -1;
+       status = ENOMEM;
        break;
      }
      buffer = buffer_new;
    } /* while (42) */
    close(sd);
  
-   if (status < 0) {
+   if (status != 0) {
      sfree(buffer);
-   } else {
-     assert(status == 0);
-     *ret_buffer = buffer;
-     *ret_buffer_size = buffer_size;
+     return status;
    }
  
-   return status;
+   *ret_buffer = buffer;
+   return 0;
  } /* }}} int powerdns_get_data_stream */
  
- static int powerdns_get_data(list_item_t *item, char **ret_buffer,
-                              size_t *ret_buffer_size) {
+ static int powerdns_get_data(list_item_t *item, char **ret_buffer) {
    if (item->socktype == SOCK_DGRAM)
-     return powerdns_get_data_dgram(item, ret_buffer, ret_buffer_size);
 -    return (powerdns_get_data_dgram(item, ret_buffer));
++    return powerdns_get_data_dgram(item, ret_buffer);
    else if (item->socktype == SOCK_STREAM)
-     return powerdns_get_data_stream(item, ret_buffer, ret_buffer_size);
 -    return (powerdns_get_data_stream(item, ret_buffer));
++    return powerdns_get_data_stream(item, ret_buffer);
    else {
      ERROR("powerdns plugin: Unknown socket type: %i", (int)item->socktype);
 -    return (-1);
 +    return -1;
    }
  } /* int powerdns_get_data */
  
  static int powerdns_read_server(list_item_t *item) /* {{{ */
  {
-   char *buffer = NULL;
-   size_t buffer_size = 0;
-   int status;
-   char *dummy;
-   char *saveptr;
-   char *key;
-   char *value;
-   const char *const *fields;
-   int fields_num;
    if (item->command == NULL)
      item->command = strdup(SERVER_COMMAND);
    if (item->command == NULL) {
      ERROR("powerdns plugin: strdup failed.");
 -    return (-1);
 +    return -1;
    }
  
-   status = powerdns_get_data(item, &buffer, &buffer_size);
-   if (status != 0)
-     return -1;
+   char *buffer = NULL;
+   int status = powerdns_get_data(item, &buffer);
+   if (status != 0) {
+     ERROR("powerdns plugin: powerdns_get_data failed.");
 -    return (status);
++    return status;
+   }
+   if (buffer == NULL) {
+     return EINVAL;
+   }
  
+   const char *const *fields = default_server_fields;
+   int fields_num = default_server_fields_num;
    if (item->fields_num != 0) {
      fields = (const char *const *)item->fields;
      fields_num = item->fields_num;
-   } else {
-     fields = default_server_fields;
-     fields_num = default_server_fields_num;
    }
  
    assert(fields != NULL);
  
    /* corrupt-packets=0,deferred-cache-inserts=0,deferred-cache-lookup=0,latency=0,packetcache-hit=0,packetcache-miss=0,packetcache-size=0,qsize-q=0,query-cache-hit=0,query-cache-miss=0,recursing-answers=0,recursing-questions=0,servfail-packets=0,tcp-answers=0,tcp-queries=0,timedout-packets=0,udp-answers=0,udp-queries=0,udp4-answers=0,udp4-queries=0,udp6-answers=0,udp6-queries=0,
     */
-   dummy = buffer;
-   saveptr = NULL;
+   char *dummy = buffer;
+   char *saveptr = NULL;
+   char *key;
    while ((key = strtok_r(dummy, ",", &saveptr)) != NULL) {
      dummy = NULL;
  
-     value = strchr(key, '=');
+     char *value = strchr(key, '=');
      if (value == NULL)
        break;
  
  
    sfree(buffer);
  
 -  return (0);
 +  return 0;
  } /* }}} int powerdns_read_server */
  
  /*
@@@ -656,7 -644,7 +644,7 @@@ static int powerdns_update_recursor_com
    int status;
  
    if (li == NULL)
 -    return (0);
 +    return 0;
  
    if (li->fields_num < 1) {
      sstrncpy(buffer, RECURSOR_COMMAND, sizeof(buffer));
                       /* seperator = */ " ");
      if (status < 0) {
        ERROR("powerdns plugin: strjoin failed.");
 -      return (-1);
 +      return -1;
      }
      buffer[sizeof(buffer) - 1] = 0;
      size_t len = strlen(buffer);
    li->command = strdup(buffer);
    if (li->command == NULL) {
      ERROR("powerdns plugin: strdup failed.");
 -    return (-1);
 +    return -1;
    }
  
 -  return (0);
 +  return 0;
  } /* }}} int powerdns_update_recursor_command */
  
  static int powerdns_read_recursor(list_item_t *item) /* {{{ */
  {
    char *buffer = NULL;
-   size_t buffer_size = 0;
    int status;
  
    char *dummy;
      status = powerdns_update_recursor_command(item);
      if (status != 0) {
        ERROR("powerdns plugin: powerdns_update_recursor_command failed.");
 -      return (-1);
 +      return -1;
      }
  
      DEBUG("powerdns plugin: powerdns_read_recursor: item->command = %s;",
    }
    assert(item->command != NULL);
  
-   status = powerdns_get_data(item, &buffer, &buffer_size);
+   status = powerdns_get_data(item, &buffer);
    if (status != 0) {
      ERROR("powerdns plugin: powerdns_get_data failed.");
 -    return (-1);
 +    return -1;
    }
  
    keys_list = strdup(item->command);
    if (keys_list == NULL) {
      FUNC_ERROR("strdup");
      sfree(buffer);
 -    return (-1);
 +    return -1;
    }
  
    key_saveptr = NULL;
    sfree(buffer);
    sfree(keys_list);
  
 -  return (0);
 +  return 0;
  } /* }}} int powerdns_read_recursor */
  
  static int powerdns_config_add_collect(list_item_t *li, /* {{{ */
    if (ci->values_num < 1) {
      WARNING("powerdns plugin: The `Collect' option needs "
              "at least one argument.");
 -    return (-1);
 +    return -1;
    }
  
    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 "
                "the `Collect' option.");
 -      return (-1);
 +      return -1;
      }
  
    temp =
        realloc(li->fields, sizeof(char *) * (li->fields_num + ci->values_num));
    if (temp == NULL) {
      WARNING("powerdns plugin: realloc failed.");
 -    return (-1);
 +    return -1;
    }
    li->fields = temp;
  
    /* Invalidate a previously computed command */
    sfree(li->command);
  
 -  return (0);
 +  return 0;
  } /* }}} int powerdns_config_add_collect */
  
  static int powerdns_config_add_server(oconfig_item_t *ci) /* {{{ */
    if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
      WARNING("powerdns plugin: `%s' needs exactly one string argument.",
              ci->key);
 -    return (-1);
 +    return -1;
    }
  
    item = calloc(1, sizeof(*item));
    if (item == NULL) {
      ERROR("powerdns plugin: calloc failed.");
 -    return (-1);
 +    return -1;
    }
  
    item->instance = strdup(ci->values[0].value.string);
    if (item->instance == NULL) {
      ERROR("powerdns plugin: strdup failed.");
      sfree(item);
 -    return (-1);
 +    return -1;
    }
  
    /*
    } else {
      /* We must never get here.. */
      assert(0);
 -    return (-1);
 +    return -1;
    }
  
    status = 0;
    if (status != 0) {
      sfree(socket_temp);
      sfree(item);
 -    return (-1);
 +    return -1;
    }
  
    DEBUG("powerdns plugin: Add server: instance = %s;", item->instance);
  
    sfree(socket_temp);
 -  return (0);
 +  return 0;
  } /* }}} int powerdns_config_add_server */
  
  static int powerdns_config(oconfig_item_t *ci) /* {{{ */
  
      if (list == NULL) {
        ERROR("powerdns plugin: `llist_create' failed.");
 -      return (-1);
 +      return -1;
      }
    }
  
        } else {
          char *temp = strdup(option->values[0].value.string);
          if (temp == NULL)
 -          return (1);
 +          return 1;
          sfree(local_sockpath);
          local_sockpath = temp;
        }
      }
    } /* for (i = 0; i < ci->children_num; i++) */
  
 -  return (0);
 +  return 0;
  } /* }}} int powerdns_config */
  
  static int powerdns_read(void) {
      item->func(item);
    }
  
 -  return (0);
 +  return 0;
  } /* static int powerdns_read */
  
  static int powerdns_shutdown(void) {
    if (list == NULL)
 -    return (0);
 +    return 0;
  
    for (llentry_t *e = llist_head(list); e != NULL; e = e->next) {
      list_item_t *item = (list_item_t *)e->value;
    llist_destroy(list);
    list = NULL;
  
 -  return (0);
 +  return 0;
  } /* static int powerdns_shutdown */
  
  void module_register(void) {
    plugin_register_read("powerdns", powerdns_read);
    plugin_register_shutdown("powerdns", powerdns_shutdown);
  } /* void module_register */
 -
 -/* vim: set sw=2 sts=2 ts=8 fdm=marker : */
diff --combined src/rrdtool.c
  /*
   * Private types
   */
 -struct rrd_cache_s {
 +typedef struct rrd_cache_s {
    int values_num;
    char **values;
    cdtime_t first_value;
    cdtime_t last_value;
    int64_t random_variation;
    enum { FLAG_NONE = 0x00, FLAG_QUEUED = 0x01, FLAG_FLUSHQ = 0x02 } flags;
 -};
 -typedef struct rrd_cache_s rrd_cache_t;
 +} rrd_cache_t;
  
  enum rrd_queue_dir_e { QUEUE_INSERT_FRONT, QUEUE_INSERT_BACK };
  typedef enum rrd_queue_dir_e rrd_queue_dir_t;
@@@ -109,16 -110,19 +109,16 @@@ static int do_shutdown = 0
  #if HAVE_THREADSAFE_LIBRRD
  static int srrd_update(char *filename, char *template, int argc,
                         const char **argv) {
 -  int status;
 -
    optind = 0; /* bug in librrd? */
    rrd_clear_error();
  
 -  status = rrd_update_r(filename, template, argc, (void *)argv);
 -
 +  int status = rrd_update_r(filename, template, argc, (void *)argv);
    if (status != 0) {
      WARNING("rrdtool plugin: rrd_update_r (%s) failed: %s", filename,
              rrd_get_error());
    }
  
 -  return (status);
 +  return status;
  } /* int srrd_update */
  /* #endif HAVE_THREADSAFE_LIBRRD */
  
@@@ -136,7 -140,7 +136,7 @@@ static int srrd_update(char *filename, 
    new_argv = malloc((new_argc + 1) * sizeof(*new_argv));
    if (new_argv == NULL) {
      ERROR("rrdtool plugin: malloc failed.");
 -    return (-1);
 +    return -1;
    }
  
    new_argv[0] = "update";
  
    sfree(new_argv);
  
 -  return (status);
 +  return status;
  } /* int srrd_update */
  #endif /* !HAVE_THREADSAFE_LIBRRD */
  
@@@ -173,9 -177,9 +173,9 @@@ static int value_list_to_string_multipl
    memset(buffer, '\0', buffer_len);
  
    tt = CDTIME_T_TO_TIME_T(vl->time);
 -  status = ssnprintf(buffer, buffer_len, "%u", (unsigned int)tt);
 +  status = snprintf(buffer, buffer_len, "%u", (unsigned int)tt);
    if ((status < 1) || (status >= buffer_len))
 -    return (-1);
 +    return -1;
    offset = status;
  
    for (size_t i = 0; i < ds->ds_num; i++) {
          (ds->ds[i].type != DS_TYPE_GAUGE) &&
          (ds->ds[i].type != DS_TYPE_DERIVE) &&
          (ds->ds[i].type != DS_TYPE_ABSOLUTE))
 -      return (-1);
 +      return -1;
  
      if (ds->ds[i].type == DS_TYPE_COUNTER)
 -      status = ssnprintf(buffer + offset, buffer_len - offset, ":%llu",
 -                         vl->values[i].counter);
 +      status = snprintf(buffer + offset, buffer_len - offset, ":%llu",
 +                        vl->values[i].counter);
      else if (ds->ds[i].type == DS_TYPE_GAUGE)
 -      status = ssnprintf(buffer + offset, buffer_len - offset, ":" GAUGE_FORMAT,
 -                         vl->values[i].gauge);
 +      status = snprintf(buffer + offset, buffer_len - offset, ":" GAUGE_FORMAT,
 +                        vl->values[i].gauge);
      else if (ds->ds[i].type == DS_TYPE_DERIVE)
 -      status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
 -                         vl->values[i].derive);
 +      status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
 +                        vl->values[i].derive);
      else /*if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */
 -      status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
 -                         vl->values[i].absolute);
 +      status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
 +                        vl->values[i].absolute);
  
      if ((status < 1) || (status >= (buffer_len - offset)))
 -      return (-1);
 +      return -1;
  
      offset += status;
    } /* for ds->ds_num */
  
 -  return (0);
 +  return 0;
  } /* int value_list_to_string_multiple */
  
  static int value_list_to_string(char *buffer, int buffer_len,
    time_t tt;
  
    if (ds->ds_num != 1)
 -    return (value_list_to_string_multiple(buffer, buffer_len, ds, vl));
 +    return value_list_to_string_multiple(buffer, buffer_len, ds, vl);
  
    tt = CDTIME_T_TO_TIME_T(vl->time);
    switch (ds->ds[0].type) {
    case DS_TYPE_DERIVE:
 -    status = ssnprintf(buffer, buffer_len, "%u:%" PRIi64, (unsigned)tt,
 -                       vl->values[0].derive);
 +    status = snprintf(buffer, buffer_len, "%u:%" PRIi64, (unsigned)tt,
 +                      vl->values[0].derive);
      break;
    case DS_TYPE_GAUGE:
 -    status = ssnprintf(buffer, buffer_len, "%u:" GAUGE_FORMAT, (unsigned)tt,
 -                       vl->values[0].gauge);
 +    status = snprintf(buffer, buffer_len, "%u:" GAUGE_FORMAT, (unsigned)tt,
 +                      vl->values[0].gauge);
      break;
    case DS_TYPE_COUNTER:
 -    status = ssnprintf(buffer, buffer_len, "%u:%llu", (unsigned)tt,
 -                       vl->values[0].counter);
 +    status = snprintf(buffer, buffer_len, "%u:%llu", (unsigned)tt,
 +                      vl->values[0].counter);
      break;
    case DS_TYPE_ABSOLUTE:
 -    status = ssnprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
 -                       vl->values[0].absolute);
 +    status = snprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
 +                      vl->values[0].absolute);
      break;
    default:
 -    return (EINVAL);
 +    return EINVAL;
    }
  
    if ((status < 1) || (status >= buffer_len))
 -    return (ENOMEM);
 +    return ENOMEM;
  
 -  return (0);
 +  return 0;
  } /* int value_list_to_string */
  
  static int value_list_to_filename(char *buffer, size_t buffer_size,
      size_t datadir_len = strlen(datadir) + 1;
  
      if (datadir_len >= buffer_size)
 -      return (ENOMEM);
 +      return ENOMEM;
  
      sstrncpy(buffer, datadir, buffer_size);
      buffer[datadir_len - 1] = '/';
  
    status = FORMAT_VL(buffer, buffer_size, vl);
    if (status != 0)
 -    return (status);
 +    return status;
  
    len = strlen(buffer);
    assert(len < buffer_size);
    buffer_size -= len;
  
    if (buffer_size <= sizeof(suffix))
 -    return (ENOMEM);
 +    return ENOMEM;
  
    memcpy(buffer, suffix, sizeof(suffix));
 -  return (0);
 +  return 0;
  } /* int value_list_to_filename */
  
  static void *rrd_queue_thread(void __attribute__((unused)) * data) {
    } /* while (42) */
  
    pthread_exit((void *)0);
 -  return ((void *)0);
 +  return (void *)0;
  } /* void *rrd_queue_thread */
  
  static int rrd_queue_enqueue(const char *filename, rrd_queue_t **head,
  
    queue_entry = malloc(sizeof(*queue_entry));
    if (queue_entry == NULL)
 -    return (-1);
 +    return -1;
  
    queue_entry->filename = strdup(filename);
    if (queue_entry->filename == NULL) {
      free(queue_entry);
 -    return (-1);
 +    return -1;
    }
  
    queue_entry->next = NULL;
    pthread_cond_signal(&queue_cond);
    pthread_mutex_unlock(&queue_lock);
  
 -  return (0);
 +  return 0;
  } /* int rrd_queue_enqueue */
  
  static int rrd_queue_dequeue(const char *filename, rrd_queue_t **head,
  
    if (this == NULL) {
      pthread_mutex_unlock(&queue_lock);
 -    return (-1);
 +    return -1;
    }
  
    if (prev == NULL)
    sfree(this->filename);
    sfree(this);
  
 -  return (0);
 +  return 0;
  } /* int rrd_queue_dequeue */
  
  /* XXX: You must hold "cache_lock" when calling this function! */
@@@ -563,7 -567,7 +563,7 @@@ static int rrd_cache_flush_identifier(c
  
    if (identifier == NULL) {
      rrd_cache_flush(timeout);
 -    return (0);
 +    return 0;
    }
  
    now = cdtime();
      INFO("rrdtool plugin: rrd_cache_flush_identifier: "
           "c_avl_get (%s) failed. Does that file really exist?",
           key);
 -    return (status);
 +    return status;
    }
  
    if (rc->flags == FLAG_FLUSHQ) {
        rc->flags = FLAG_FLUSHQ;
    }
  
 -  return (status);
 +  return status;
  } /* int rrd_cache_flush_identifier */
  
  static int64_t rrd_get_random_variation(void) {
    if (random_timeout == 0)
 -    return (0);
 +    return 0;
  
    return (int64_t)cdrand_range(-random_timeout, random_timeout);
  } /* int64_t rrd_get_random_variation */
@@@ -620,16 -624,15 +620,15 @@@ static int rrd_cache_insert(const char 
    if (cache == NULL) {
      pthread_mutex_unlock(&cache_lock);
      WARNING("rrdtool plugin: cache == NULL.");
 -    return (-1);
 +    return -1;
    }
  
-   c_avl_get(cache, filename, (void *)&rc);
-   if (rc == NULL) {
+   int status = c_avl_get(cache, filename, (void *)&rc);
+   if ((status != 0) || (rc == NULL)) {
      rc = malloc(sizeof(*rc));
      if (rc == NULL) {
        pthread_mutex_unlock(&cache_lock);
 -      return (-1);
 +      return -1;
      }
      rc->values_num = 0;
      rc->values = NULL;
      DEBUG("rrdtool plugin: (rc->last_value = %" PRIu64 ") "
            ">= (value_time = %" PRIu64 ")",
            rc->last_value, value_time);
 -    return (-1);
 +    return -1;
    }
  
    values_new =
      sfree(cache_key);
      sfree(rc->values);
      sfree(rc);
 -    return (-1);
 +    return -1;
    }
    rc->values = values_new;
  
        sfree(rc->values[0]);
        sfree(rc->values);
        sfree(rc);
 -      return (-1);
 +      return -1;
      }
  
      c_avl_insert(cache, cache_key, rc);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (0);
 +  return 0;
  } /* int rrd_cache_insert */
  
  static int rrd_cache_destroy(void) /* {{{ */
  
    if (cache == NULL) {
      pthread_mutex_unlock(&cache_lock);
 -    return (0);
 +    return 0;
    }
  
    while (c_avl_pick(cache, &key, &value) == 0) {
    }
  
    pthread_mutex_unlock(&cache_lock);
 -  return (0);
 +  return 0;
  } /* }}} int rrd_cache_destroy */
  
  static int rrd_compare_numeric(const void *a_ptr, const void *b_ptr) {
    int b = *((int *)b_ptr);
  
    if (a < b)
 -    return (-1);
 +    return -1;
    else if (a > b)
 -    return (1);
 +    return 1;
    else
 -    return (0);
 +    return 0;
  } /* int rrd_compare_numeric */
  
  static int rrd_write(const data_set_t *ds, const value_list_t *vl,
                       user_data_t __attribute__((unused)) * user_data) {
 -  struct stat statbuf;
 -  char filename[512];
 -  char values[512];
 -  int status;
  
    if (do_shutdown)
 -    return (0);
 +    return 0;
  
    if (0 != strcmp(ds->type, vl->type)) {
      ERROR("rrdtool plugin: DS type does not match value list type");
      return -1;
    }
  
 +  char filename[PATH_MAX];
    if (value_list_to_filename(filename, sizeof(filename), vl) != 0)
 -    return (-1);
 +    return -1;
  
 +  char values[32 * (ds->ds_num + 1)];
    if (value_list_to_string(values, sizeof(values), ds, vl) != 0)
 -    return (-1);
 +    return -1;
  
 +  struct stat statbuf = {0};
    if (stat(filename, &statbuf) == -1) {
      if (errno == ENOENT) {
 -      status = cu_rrd_create_file(filename, ds, vl, &rrdcreate_config);
 -      if (status != 0)
 -        return (-1);
 -      else if (rrdcreate_config.async)
 -        return (0);
 +      if (cu_rrd_create_file(filename, ds, vl, &rrdcreate_config) != 0) {
 +        return -1;
 +      } else if (rrdcreate_config.async) {
 +        return 0;
 +      }
      } else {
        char errbuf[1024];
 -      ERROR("stat(%s) failed: %s", filename,
 +      ERROR("rrdtool plugin: stat(%s) failed: %s", filename,
              sstrerror(errno, errbuf, sizeof(errbuf)));
 -      return (-1);
 +      return -1;
      }
    } else if (!S_ISREG(statbuf.st_mode)) {
 -    ERROR("stat(%s): Not a regular file!", filename);
 -    return (-1);
 +    ERROR("rrdtool plugin: stat(%s): Not a regular file!", filename);
 +    return -1;
    }
  
 -  status = rrd_cache_insert(filename, values, vl->time);
 -
 -  return (status);
 +  return rrd_cache_insert(filename, values, vl->time);
  } /* int rrd_write */
  
  static int rrd_flush(cdtime_t timeout, const char *identifier,
  
    if (cache == NULL) {
      pthread_mutex_unlock(&cache_lock);
 -    return (0);
 +    return 0;
    }
  
    rrd_cache_flush_identifier(timeout, identifier);
  
    pthread_mutex_unlock(&cache_lock);
 -  return (0);
 +  return 0;
  } /* int rrd_flush */
  
  static int rrd_config(const char *key, const char *value) {
                        "be greater than 0.\n");
        ERROR("rrdtool: `CacheTimeout' must "
              "be greater than 0.\n");
 -      return (1);
 +      return 1;
      }
      cache_timeout = DOUBLE_TO_CDTIME_T(tmp);
    } else if (strcasecmp("CacheFlush", key) == 0) {
                        "be greater than 0.\n");
        ERROR("rrdtool: `CacheFlush' must "
              "be greater than 0.\n");
 -      return (1);
 +      return 1;
      }
      cache_flush_timeout = DOUBLE_TO_CDTIME_T(tmp);
    } else if (strcasecmp("DataDir", key) == 0) {
      tmp = strdup(value);
      if (tmp == NULL) {
        ERROR("rrdtool plugin: strdup failed.");
 -      return (1);
 +      return 1;
      }
  
      len = strlen(tmp);
      if (len == 0) {
        ERROR("rrdtool plugin: Invalid \"DataDir\" option.");
        sfree(tmp);
 -      return (1);
 +      return 1;
      }
  
      if (datadir != NULL) {
                        "be greater than 0.\n");
        ERROR("rrdtool: `RRARows' must "
              "be greater than 0.\n");
 -      return (1);
 +      return 1;
      }
      rrdcreate_config.rrarows = tmp;
    } else if (strcasecmp("RRATimespan", key) == 0) {
  
      value_copy = strdup(value);
      if (value_copy == NULL)
 -      return (1);
 +      return 1;
  
      dummy = value_copy;
      while ((ptr = strtok_r(dummy, ", \t", &saveptr)) != NULL) {
          fprintf(stderr, "rrdtool: realloc failed.\n");
          ERROR("rrdtool: realloc failed.\n");
          free(value_copy);
 -        return (1);
 +        return 1;
        }
        rrdcreate_config.timespans = tmp_alloc;
        rrdcreate_config.timespans[rrdcreate_config.timespans_num] = atoi(ptr);
                        "be in the range 0 to 1 (exclusive).");
        ERROR("rrdtool: `XFF' must "
              "be in the range 0 to 1 (exclusive).");
 -      return (1);
 +      return 1;
      }
      rrdcreate_config.xff = tmp;
    } else if (strcasecmp("WritesPerSecond", key) == 0) {
      if (wps < 0.0) {
        fprintf(stderr, "rrdtool: `WritesPerSecond' must be "
                        "greater than or equal to zero.");
 -      return (1);
 +      return 1;
      } else if (wps == 0.0) {
        write_rate = 0.0;
      } else {
        random_timeout = DOUBLE_TO_CDTIME_T(tmp);
      }
    } else {
 -    return (-1);
 +    return -1;
    }
 -  return (0);
 +  return 0;
  } /* int rrd_config */
  
  static int rrd_shutdown(void) {
  
    rrd_cache_destroy();
  
 -  return (0);
 +  return 0;
  } /* int rrd_shutdown */
  
  static int rrd_init(void) {
    static int init_once = 0;
 -  int status;
  
    if (init_once != 0)
 -    return (0);
 +    return 0;
    init_once = 1;
  
    if (rrdcreate_config.heartbeat <= 0)
    if (cache == NULL) {
      pthread_mutex_unlock(&cache_lock);
      ERROR("rrdtool plugin: c_avl_create failed.");
 -    return (-1);
 +    return -1;
    }
  
    cache_flush_last = cdtime();
      cache_flush_timeout = 0;
    } else if (cache_flush_timeout < cache_timeout) {
      INFO("rrdtool plugin: \"CacheFlush %.3f\" is less than \"CacheTimeout "
-          "%.3f\". "
-          "Ajusting \"CacheFlush\" to %.3f seconds.",
+          "%.3f\". Adjusting \"CacheFlush\" to %.3f seconds.",
           CDTIME_T_TO_DOUBLE(cache_flush_timeout),
           CDTIME_T_TO_DOUBLE(cache_timeout),
           CDTIME_T_TO_DOUBLE(cache_timeout * 10));
  
    pthread_mutex_unlock(&cache_lock);
  
 -  status =
 +  int status =
        plugin_thread_create(&queue_thread, /* attr = */ NULL, rrd_queue_thread,
                             /* args = */ NULL, "rrdtool queue");
    if (status != 0) {
      ERROR("rrdtool plugin: Cannot create queue-thread.");
 -    return (-1);
 +    return -1;
    }
    queue_thread_running = 1;
  
          rrdcreate_config.heartbeat, rrdcreate_config.rrarows,
          rrdcreate_config.xff);
  
 -  return (0);
 +  return 0;
  } /* int rrd_init */
  
  void module_register(void) {
diff --combined src/table.c
@@@ -55,7 -55,6 +55,7 @@@ typedef struct 
  typedef struct {
    char *file;
    char *sep;
 +  char *plugin_name;
    char *instance;
  
    tbl_result_t *results;
@@@ -78,6 -77,10 +78,10 @@@ static void tbl_result_setup(tbl_result
  } /* tbl_result_setup */
  
  static void tbl_result_clear(tbl_result_t *res) {
+   if (res == NULL) {
+     return;
+   }
    sfree(res->type);
  
    sfree(res->instance_prefix);
@@@ -93,7 -96,6 +97,7 @@@
  static void tbl_setup(tbl_t *tbl, char *file) {
    tbl->file = sstrdup(file);
    tbl->sep = NULL;
 +  tbl->plugin_name = NULL;
    tbl->instance = NULL;
  
    tbl->results = NULL;
  } /* tbl_setup */
  
  static void tbl_clear(tbl_t *tbl) {
+   if (tbl == NULL) {
+     return;
+   }
    sfree(tbl->file);
    sfree(tbl->sep);
 +  sfree(tbl->plugin_name);
    sfree(tbl->instance);
  
+   /* (tbl->results == NULL) -> (tbl->results_num == 0) */
+   assert((tbl->results != NULL) || (tbl->results_num == 0));
    for (size_t i = 0; i < tbl->results_num; ++i)
      tbl_result_clear(tbl->results + i);
    sfree(tbl->results);
@@@ -250,8 -257,6 +260,8 @@@ static int tbl_config_table(oconfig_ite
  
      if (0 == strcasecmp(c->key, "Separator"))
        tbl_config_set_s(c->key, &tbl->sep, c);
 +    else if (0 == strcasecmp(c->key, "Plugin"))
 +      tbl_config_set_s(c->key, &tbl->plugin_name, c);
      else if (0 == strcasecmp(c->key, "Instance"))
        tbl_config_set_s(c->key, &tbl->instance, c);
      else if (0 == strcasecmp(c->key, "Result"))
@@@ -366,8 -371,7 +376,8 @@@ static int tbl_result_dispatch(tbl_t *t
    vl.values = values;
    vl.values_len = STATIC_ARRAY_SIZE(values);
  
 -  sstrncpy(vl.plugin, "table", sizeof(vl.plugin));
 +  sstrncpy(vl.plugin, (tbl->plugin_name != NULL) ? tbl->plugin_name : "table",
 +           sizeof(vl.plugin));
    sstrncpy(vl.plugin_instance, tbl->instance, sizeof(vl.plugin_instance));
    sstrncpy(vl.type, res->type, sizeof(vl.type));
  
@@@ -520,3 -524,5 +530,3 @@@ void module_register(void) 
    plugin_register_complex_config("table", tbl_config);
    plugin_register_init("table", tbl_init);
  } /* module_register */
 -
 -/* vim: set sw=4 ts=4 tw=78 noexpandtab : */