Merge branch 'collectd-5.7'
authorRuben Kerkhof <ruben@rubenkerkhof.com>
Thu, 1 Jun 2017 18:38:17 +0000 (20:38 +0200)
committerRuben Kerkhof <ruben@rubenkerkhof.com>
Thu, 1 Jun 2017 18:38:17 +0000 (20:38 +0200)
1  2 
src/amqp.c
src/bind.c
src/daemon/utils_cache.c
src/utils_format_graphite.c

diff --combined src/amqp.c
@@@ -164,16 -164,16 +164,16 @@@ static char *camqp_bytes_cstring(amqp_b
    char *ret;
  
    if ((in == NULL) || (in->bytes == NULL))
 -    return (NULL);
 +    return NULL;
  
    ret = malloc(in->len + 1);
    if (ret == NULL)
 -    return (NULL);
 +    return NULL;
  
    memcpy(ret, in->bytes, in->len);
    ret[in->len] = 0;
  
 -  return (ret);
 +  return ret;
  } /* }}} char *camqp_bytes_cstring */
  
  static _Bool camqp_is_error(camqp_config_t *conf) /* {{{ */
  
    r = amqp_get_rpc_reply(conf->connection);
    if (r.reply_type == AMQP_RESPONSE_NORMAL)
 -    return (0);
 +    return 0;
  
 -  return (1);
 +  return 1;
  } /* }}} _Bool camqp_is_error */
  
  static char *camqp_strerror(camqp_config_t *conf, /* {{{ */
    case AMQP_RESPONSE_LIBRARY_EXCEPTION:
  #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO
      if (r.library_errno)
 -      return (sstrerror(r.library_errno, buffer, buffer_size));
 +      return sstrerror(r.library_errno, buffer, buffer_size);
  #else
      if (r.library_error)
 -      return (sstrerror(r.library_error, buffer, buffer_size));
 +      return sstrerror(r.library_error, buffer, buffer_size);
  #endif
      else
        sstrncpy(buffer, "End of stream", buffer_size);
      ssnprintf(buffer, buffer_size, "Unknown reply type %i", (int)r.reply_type);
    }
  
 -  return (buffer);
 +  return buffer;
  } /* }}} char *camqp_strerror */
  
  #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO
@@@ -245,7 -245,7 +245,7 @@@ static int camqp_create_exchange(camqp_
    amqp_exchange_declare_ok_t *ed_ret;
  
    if (conf->exchange_type == NULL)
 -    return (0);
 +    return 0;
  
    ed_ret = amqp_exchange_declare(
        conf->connection,
      ERROR("amqp plugin: amqp_exchange_declare failed: %s",
            camqp_strerror(conf, errbuf, sizeof(errbuf)));
      camqp_close_connection(conf);
 -    return (-1);
 +    return -1;
    }
  
    INFO("amqp plugin: Successfully created exchange \"%s\" "
         "with type \"%s\".",
         conf->exchange, conf->exchange_type);
  
 -  return (0);
 +  return 0;
  } /* }}} int camqp_create_exchange */
  #else
  static int camqp_create_exchange(camqp_config_t *conf) /* {{{ */
    struct amqp_table_entry_t_ argument_table_entries[1];
  
    if (conf->exchange_type == NULL)
 -    return (0);
 +    return 0;
  
    /* Valid arguments: "auto_delete", "internal" */
    argument_table.num_entries = STATIC_ARRAY_SIZE(argument_table_entries);
      ERROR("amqp plugin: amqp_exchange_declare failed: %s",
            camqp_strerror(conf, errbuf, sizeof(errbuf)));
      camqp_close_connection(conf);
 -    return (-1);
 +    return -1;
    }
  
    INFO("amqp plugin: Successfully created exchange \"%s\" "
         "with type \"%s\".",
         conf->exchange, conf->exchange_type);
  
 -  return (0);
 +  return 0;
  } /* }}} int camqp_create_exchange */
  #endif
  
@@@ -333,7 -333,7 +333,7 @@@ static int camqp_setup_queue(camqp_conf
    if (qd_ret == NULL) {
      ERROR("amqp plugin: amqp_queue_declare failed.");
      camqp_close_connection(conf);
 -    return (-1);
 +    return -1;
    }
  
    if (conf->queue == NULL) {
      if (conf->queue == NULL) {
        ERROR("amqp plugin: camqp_bytes_cstring failed.");
        camqp_close_connection(conf);
 -      return (-1);
 +      return -1;
      }
  
      INFO("amqp plugin: Created queue \"%s\".", conf->queue);
        ERROR("amqp plugin: amqp_queue_bind failed: %s",
              camqp_strerror(conf, errbuf, sizeof(errbuf)));
        camqp_close_connection(conf);
 -      return (-1);
 +      return -1;
      }
  
      DEBUG("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".",
      ERROR("amqp plugin: amqp_basic_consume failed: %s",
            camqp_strerror(conf, errbuf, sizeof(errbuf)));
      camqp_close_connection(conf);
 -    return (-1);
 +    return -1;
    }
  
 -  return (0);
 +  return 0;
  } /* }}} int camqp_setup_queue */
  
  static int camqp_connect(camqp_config_t *conf) /* {{{ */
  #endif
  
    if (conf->connection != NULL)
 -    return (0);
 +    return 0;
  
    time_t now = time(NULL);
    if (now < (last_connect_time + conf->connection_retry_delay)) {
      DEBUG("amqp plugin: skipping connection retry, "
            "ConnectionRetryDelay: %d",
            conf->connection_retry_delay);
 -    return (1);
 +    return 1;
    } else {
      DEBUG("amqp plugin: retrying connection");
      last_connect_time = now;
    conf->connection = amqp_new_connection();
    if (conf->connection == NULL) {
      ERROR("amqp plugin: amqp_new_connection failed.");
 -    return (ENOMEM);
 +    return ENOMEM;
    }
  
  #ifdef HAVE_AMQP_TCP_SOCKET
      ERROR("amqp plugin: amqp_tcp_socket_new failed.");
      amqp_destroy_connection(conf->connection);
      conf->connection = NULL;
 -    return (ENOMEM);
 +    return ENOMEM;
    }
  
    status = amqp_socket_open(socket, CONF(conf, host), conf->port);
            sstrerror(status, errbuf, sizeof(errbuf)));
      amqp_destroy_connection(conf->connection);
      conf->connection = NULL;
 -    return (status);
 +    return status;
    }
  #else /* HAVE_AMQP_TCP_SOCKET */
  #define CLOSE_SOCKET() close(sockfd)
            sstrerror(status, errbuf, sizeof(errbuf)));
      amqp_destroy_connection(conf->connection);
      conf->connection = NULL;
 -    return (status);
 +    return status;
    }
    amqp_set_sockfd(conf->connection, sockfd);
  #endif
      amqp_destroy_connection(conf->connection);
      CLOSE_SOCKET();
      conf->connection = NULL;
 -    return (1);
 +    return 1;
    }
  
    amqp_channel_open(conf->connection, /* channel = */ 1);
      amqp_destroy_connection(conf->connection);
      CLOSE_SOCKET();
      conf->connection = NULL;
 -    return (1);
 +    return 1;
    }
  
    INFO("amqp plugin: Successfully opened connection to vhost \"%s\" "
  
    status = camqp_create_exchange(conf);
    if (status != 0)
 -    return (status);
 +    return status;
  
    if (!conf->publish)
 -    return (camqp_setup_queue(conf));
 -  return (0);
 +    return camqp_setup_queue(conf);
 +  return 0;
  } /* }}} int camqp_connect */
  
  static int camqp_shutdown(void) /* {{{ */
  
    DEBUG("amqp plugin: All subscriber threads exited.");
  
 -  return (0);
 +  return 0;
  } /* }}} int camqp_shutdown */
  
  /*
@@@ -550,17 -550,17 +550,17 @@@ static int camqp_read_body(camqp_config
        ERROR("amqp plugin: amqp_simple_wait_frame failed: %s",
              sstrerror(status, errbuf, sizeof(errbuf)));
        camqp_close_connection(conf);
 -      return (status);
 +      return status;
      }
  
      if (frame.frame_type != AMQP_FRAME_BODY) {
        NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type);
 -      return (-1);
 +      return -1;
      }
  
      if ((body_size - received) < frame.payload.body_fragment.len) {
        WARNING("amqp plugin: Body is larger than indicated by header.");
 -      return (-1);
 +      return -1;
      }
  
      memcpy(body_ptr, frame.payload.body_fragment.bytes,
      status = cmd_handle_putval(stderr, body);
      if (status != 0)
        ERROR("amqp plugin: cmd_handle_putval failed with status %i.", status);
 -    return (status);
 +    return status;
    } else if (strcasecmp("application/json", content_type) == 0) {
      ERROR("amqp plugin: camqp_read_body: Parsing JSON data has not "
            "been implemented yet. FIXME!");
 -    return (0);
 +    return 0;
    } else {
      ERROR("amqp plugin: camqp_read_body: Unknown content type \"%s\".",
            content_type);
 -    return (EINVAL);
 +    return EINVAL;
    }
  
    /* not reached */
 -  return (0);
 +  return 0;
  } /* }}} int camqp_read_body */
  
  static int camqp_read_header(camqp_config_t *conf) /* {{{ */
      ERROR("amqp plugin: amqp_simple_wait_frame failed: %s",
            sstrerror(status, errbuf, sizeof(errbuf)));
      camqp_close_connection(conf);
 -    return (status);
 +    return status;
    }
  
    if (frame.frame_type != AMQP_FRAME_HEADER) {
      NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type);
 -    return (-1);
 +    return -1;
    }
  
    properties = frame.payload.properties.decoded;
    content_type = camqp_bytes_cstring(&properties->content_type);
    if (content_type == NULL) {
      ERROR("amqp plugin: Unable to determine content type.");
 -    return (-1);
 +    return -1;
    }
  
    status = camqp_read_body(conf, (size_t)frame.payload.properties.body_size,
                             content_type);
  
    sfree(content_type);
 -  return (status);
 +  return status;
  } /* }}} int camqp_read_header */
  
  static void *camqp_subscribe_thread(void *user_data) /* {{{ */
  
    camqp_config_free(conf);
    pthread_exit(NULL);
 -  return (NULL);
 +  return NULL;
  } /* }}} void *camqp_subscribe_thread */
  
  static int camqp_subscribe_init(camqp_config_t *conf) /* {{{ */
    if (tmp == NULL) {
      ERROR("amqp plugin: realloc failed.");
      sfree(subscriber_threads);
 -    return (ENOMEM);
 +    return ENOMEM;
    }
    subscriber_threads = tmp;
    tmp = subscriber_threads + subscriber_threads_num;
      char errbuf[1024];
      ERROR("amqp plugin: pthread_create failed: %s",
            sstrerror(status, errbuf, sizeof(errbuf)));
 -    return (status);
 +    return status;
    }
  
    subscriber_threads_num++;
  
 -  return (0);
 +  return 0;
  } /* }}} int camqp_subscribe_init */
  
  /*
@@@ -714,7 -714,7 +714,7 @@@ static int camqp_write_locked(camqp_con
  
    status = camqp_connect(conf);
    if (status != 0)
 -    return (status);
 +    return status;
  
    amqp_basic_properties_t props = {._flags = AMQP_BASIC_CONTENT_TYPE_FLAG |
                                               AMQP_BASIC_DELIVERY_MODE_FLAG |
      camqp_close_connection(conf);
    }
  
 -  return (status);
 +  return status;
  } /* }}} int camqp_write_locked */
  
  static int camqp_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */
    int status;
  
    if ((ds == NULL) || (vl == NULL) || (conf == NULL))
 -    return (EINVAL);
 +    return EINVAL;
  
    if (conf->routing_key != NULL) {
      sstrncpy(routing_key, conf->routing_key, sizeof(routing_key));
      status = cmd_create_putval(buffer, sizeof(buffer), ds, vl);
      if (status != 0) {
        ERROR("amqp plugin: cmd_create_putval failed with status %i.", status);
 -      return (status);
 +      return status;
      }
    } else if (conf->format == CAMQP_FORMAT_JSON) {
      size_t bfree = sizeof(buffer);
                          conf->postfix, conf->escape_char, conf->graphite_flags);
      if (status != 0) {
        ERROR("amqp plugin: format_graphite failed with status %i.", status);
 -      return (status);
 +      return status;
      }
    } else {
      ERROR("amqp plugin: Invalid format (%i).", conf->format);
 -    return (-1);
 +    return -1;
    }
  
    pthread_mutex_lock(&conf->lock);
    status = camqp_write_locked(conf, buffer, routing_key);
    pthread_mutex_unlock(&conf->lock);
  
 -  return (status);
 +  return status;
  } /* }}} int camqp_write */
  
  /*
@@@ -816,7 -816,7 +816,7 @@@ static int camqp_config_set_format(ocon
    string = NULL;
    status = cf_util_get_string(ci, &string);
    if (status != 0)
 -    return (status);
 +    return status;
  
    assert(string != NULL);
    if (strcasecmp("Command", string) == 0)
  
    free(string);
  
 -  return (0);
 +  return 0;
  } /* }}} int config_set_string */
  
  static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */
    conf = calloc(1, sizeof(*conf));
    if (conf == NULL) {
      ERROR("amqp plugin: calloc failed.");
 -    return (ENOMEM);
 +    return ENOMEM;
    }
  
    /* Initialize "conf" {{{ */
    status = cf_util_get_string(ci, &conf->name);
    if (status != 0) {
      sfree(conf);
 -    return (status);
 +    return status;
    }
  
    for (int i = 0; i < ci->children_num; i++) {
        status = cf_util_get_string(child, &conf->password);
      else if (strcasecmp("Exchange", child->key) == 0)
        status = cf_util_get_string(child, &conf->exchange);
-     else if ((strcasecmp("ExchangeType", child->key) == 0) && !publish)
+     else if (strcasecmp("ExchangeType", child->key) == 0)
        status = cf_util_get_string(child, &conf->exchange_type);
      else if ((strcasecmp("Queue", child->key) == 0) && !publish)
        status = cf_util_get_string(child, &conf->queue);
  
    if (status != 0) {
      camqp_config_free(conf);
 -    return (status);
 +    return status;
    }
  
    if (conf->exchange != NULL) {
                               });
      if (status != 0) {
        camqp_config_free(conf);
 -      return (status);
 +      return status;
      }
    } else {
      status = camqp_subscribe_init(conf);
      if (status != 0) {
        camqp_config_free(conf);
 -      return (status);
 +      return status;
      }
    }
  
 -  return (0);
 +  return 0;
  } /* }}} int camqp_config_connection */
  
  static int camqp_config(oconfig_item_t *ci) /* {{{ */
                child->key);
    } /* for (ci->children_num) */
  
 -  return (0);
 +  return 0;
  } /* }}} int camqp_config */
  
  void module_register(void) {
    plugin_register_complex_config("amqp", camqp_config);
    plugin_register_shutdown("amqp", camqp_shutdown);
  } /* void module_register */
 -
 -/* vim: set sw=4 sts=4 et fdm=marker : */
diff --combined src/bind.c
@@@ -271,7 -271,7 +271,7 @@@ static size_t bind_curl_callback(void *
    size_t len = size * nmemb;
  
    if (len == 0)
 -    return (len);
 +    return len;
  
    if ((bind_buffer_fill + len) >= bind_buffer_size) {
      char *temp;
      temp = realloc(bind_buffer, bind_buffer_fill + len + 1);
      if (temp == NULL) {
        ERROR("bind plugin: realloc failed.");
 -      return (0);
 +      return 0;
      }
      bind_buffer = temp;
      bind_buffer_size = bind_buffer_fill + len + 1;
    bind_buffer_fill += len;
    bind_buffer[bind_buffer_fill] = 0;
  
 -  return (len);
 +  return len;
  } /* }}} size_t bind_curl_callback */
  
  /*
@@@ -301,7 -301,7 +301,7 @@@ static int bind_xml_table_callback(cons
    translation_table_ptr_t *table = (translation_table_ptr_t *)user_data;
  
    if (table == NULL)
 -    return (-1);
 +    return -1;
  
    for (size_t i = 0; i < table->table_length; i++) {
      if (strcmp(table->table[i].xml_name, name) != 0)
      break;
    }
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_table_callback */
  
  /*
@@@ -325,12 -325,12 +325,12 @@@ static int bind_xml_list_callback(cons
    list_info_ptr_t *list_info = (list_info_ptr_t *)user_data;
  
    if (list_info == NULL)
 -    return (-1);
 +    return -1;
  
    submit(current_time, list_info->plugin_instance, list_info->type,
           /* type instance = */ name, value);
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_list_callback */
  
  static int bind_xml_read_derive(xmlDoc *doc, xmlNode *node, /* {{{ */
    str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
    if (str_ptr == NULL) {
      ERROR("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed.");
 -    return (-1);
 +    return -1;
    }
  
    status = parse_value(str_ptr, &value, DS_TYPE_DERIVE);
      ERROR("bind plugin: Parsing string \"%s\" to derive value failed.",
            str_ptr);
      xmlFree(str_ptr);
 -    return (-1);
 +    return -1;
    }
  
    xmlFree(str_ptr);
    *ret_value = value.derive;
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_read_derive */
  
  static int bind_xml_read_gauge(xmlDoc *doc, xmlNode *node, /* {{{ */
    str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
    if (str_ptr == NULL) {
      ERROR("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed.");
 -    return (-1);
 +    return -1;
    }
  
    errno = 0;
        ERROR("bind plugin: bind_xml_read_gauge: strtod failed with overflow.");
      else
        ERROR("bind plugin: bind_xml_read_gauge: strtod failed.");
 -    return (-1);
 +    return -1;
    }
  
    *ret_value = (gauge_t)value;
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_read_gauge */
  
  static int bind_xml_read_timestamp(const char *xpath_expression, /* {{{ */
    if (xpathObj == NULL) {
      ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
            xpath_expression);
 -    return (-1);
 +    return -1;
    }
  
    if ((xpathObj->nodesetval == NULL) || (xpathObj->nodesetval->nodeNr < 1)) {
      xmlXPathFreeObject(xpathObj);
 -    return (-1);
 +    return -1;
    }
  
    if (xpathObj->nodesetval->nodeNr != 1) {
      ERROR("bind plugin: bind_xml_read_timestamp: "
            "node->xmlChildrenNode == NULL");
      xmlXPathFreeObject(xpathObj);
 -    return (-1);
 +    return -1;
    }
  
    str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
    if (str_ptr == NULL) {
      ERROR("bind plugin: bind_xml_read_timestamp: xmlNodeListGetString failed.");
      xmlXPathFreeObject(xpathObj);
 -    return (-1);
 +    return -1;
    }
  
    tmp = strptime(str_ptr, "%Y-%m-%dT%T", &tm);
    if (tmp == NULL) {
      ERROR("bind plugin: bind_xml_read_timestamp: strptime failed.");
      xmlXPathFreeObject(xpathObj);
 -    return (-1);
 +    return -1;
    }
  
  #if HAVE_TIMEGM
      char errbuf[1024];
      ERROR("bind plugin: timegm() failed: %s",
            sstrerror(errno, errbuf, sizeof(errbuf)));
 -    return (-1);
 +    return -1;
    }
    *ret_value = t;
  #else
      char errbuf[1024];
      ERROR("bind plugin: mktime() failed: %s",
            sstrerror(errno, errbuf, sizeof(errbuf)));
 -    return (-1);
 +    return -1;
    }
    /* mktime assumes that tm is local time. Luckily, it also sets timezone to
     * the offset used for the conversion, and we undo the conversion to convert
  #endif
  
    xmlXPathFreeObject(xpathObj);
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_read_timestamp */
  
  /*
@@@ -485,7 -485,7 +485,7 @@@ static int bind_parse_generic_name_valu
    if (xpathObj == NULL) {
      ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
            xpath_expression);
 -    return (-1);
 +    return -1;
    }
  
    num_entries = 0;
          status = bind_xml_read_gauge(doc, counter, &value.gauge);
        else
          status = bind_xml_read_derive(doc, counter, &value.derive);
-       if (status != 0)
+       if (status != 0) {
+         xmlFree(name);
          continue;
+       }
  
        status = (*list_callback)(name, value, current_time, user_data);
        if (status == 0)
  
    xmlXPathFreeObject(xpathObj);
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_parse_generic_name_value */
  
  /*
@@@ -564,7 -566,7 +566,7 @@@ static int bind_parse_generic_value_lis
    if (xpathObj == NULL) {
      ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
            xpath_expression);
 -    return (-1);
 +    return -1;
    }
  
    num_entries = 0;
  
    xmlXPathFreeObject(xpathObj);
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_parse_generic_value_list */
  
  /*
@@@ -626,7 -628,7 +628,7 @@@ static int bind_parse_generic_name_attr
    if (xpathObj == NULL) {
      ERROR("bind plugin: Unable to evaluate XPath expression `%s'.",
            xpath_expression);
 -    return (-1);
 +    return -1;
    }
  
    num_entries = 0;
          status = bind_xml_read_gauge(doc, child, &value.gauge);
        else
          status = bind_xml_read_derive(doc, child, &value.derive);
-       if (status != 0)
+       if (status != 0) {
+         xmlFree(attr_name);
          continue;
+       }
  
        status = (*list_callback)(attr_name, value, current_time, user_data);
        if (status == 0)
          num_entries++;
+       xmlFree(attr_name);
      }
    }
  
  
    xmlXPathFreeObject(xpathObj);
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_parse_generic_name_attr_value_list */
  
  static int bind_xml_stats_handle_zone(int version, xmlDoc *doc, /* {{{ */
      path_obj = xmlXPathEvalExpression(BAD_CAST "name", path_ctx);
      if (path_obj == NULL) {
        ERROR("bind plugin: xmlXPathEvalExpression failed.");
 -      return (-1);
 +      return -1;
      }
  
      for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr);
  
    if (zone_name == NULL) {
      ERROR("bind plugin: Could not determine zone name.");
 -    return (-1);
 +    return -1;
    }
  
    for (j = 0; j < view->zones_num; j++) {
    zone_name = NULL;
  
    if (j >= view->zones_num)
 -    return (0);
 +    return 0;
  
    zone_name = view->zones[j];
  
      }
    } /* }}} */
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_stats_handle_zone */
  
  static int bind_xml_stats_search_zones(int version, xmlDoc *doc, /* {{{ */
    zone_path_context = xmlXPathNewContext(doc);
    if (zone_path_context == NULL) {
      ERROR("bind plugin: xmlXPathNewContext failed.");
 -    return (-1);
 +    return -1;
    }
  
    zone_nodes = xmlXPathEvalExpression(BAD_CAST "zones/zone", path_ctx);
    if (zone_nodes == NULL) {
      ERROR("bind plugin: Cannot find any <view> tags.");
      xmlXPathFreeContext(zone_path_context);
 -    return (-1);
 +    return -1;
    }
  
    for (int i = 0; i < zone_nodes->nodesetval->nodeNr; i++) {
  
    xmlXPathFreeObject(zone_nodes);
    xmlXPathFreeContext(zone_path_context);
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_stats_search_zones */
  
  static int bind_xml_stats_handle_view(int version, xmlDoc *doc, /* {{{ */
  
      if (view_name == NULL) {
        ERROR("bind plugin: Could not determine view name.");
 -      return (-1);
 +      return -1;
      }
  
      for (j = 0; j < views_num; j++) {
      path_obj = xmlXPathEvalExpression(BAD_CAST "name", path_ctx);
      if (path_obj == NULL) {
        ERROR("bind plugin: xmlXPathEvalExpression failed.");
 -      return (-1);
 +      return -1;
      }
  
      for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr);
      if (view_name == NULL) {
        ERROR("bind plugin: Could not determine view name.");
        xmlXPathFreeObject(path_obj);
 -      return (-1);
 +      return -1;
      }
  
      for (j = 0; j < views_num; j++) {
    }
  
    if (j >= views_num)
 -    return (0);
 +    return 0;
  
    view = views + j;
  
      bind_xml_stats_search_zones(version, doc, path_ctx, node, view,
                                  current_time);
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_stats_handle_view */
  
  static int bind_xml_stats_search_views(int version, xmlDoc *doc, /* {{{ */
    view_path_context = xmlXPathNewContext(doc);
    if (view_path_context == NULL) {
      ERROR("bind plugin: xmlXPathNewContext failed.");
 -    return (-1);
 +    return -1;
    }
  
    view_nodes = xmlXPathEvalExpression(BAD_CAST "views/view", xpathCtx);
    if (view_nodes == NULL) {
      ERROR("bind plugin: Cannot find any <view> tags.");
      xmlXPathFreeContext(view_path_context);
 -    return (-1);
 +    return -1;
    }
  
    for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++) {
  
    xmlXPathFreeObject(view_nodes);
    xmlXPathFreeContext(view_path_context);
 -  return (0);
 +  return 0;
  } /* }}} int bind_xml_stats_search_views */
  
  static void bind_xml_stats_v3(xmlDoc *doc, /* {{{ */
@@@ -1261,7 -1267,7 +1267,7 @@@ static int bind_xml_stats(int version, 
                                     &current_time);
    if (status != 0) {
      ERROR("bind plugin: Reading `server/current-time' failed.");
 -    return (-1);
 +    return -1;
    }
    DEBUG("bind plugin: Current server time is %i.", (int)current_time);
  
@@@ -1310,14 -1316,14 +1316,14 @@@ static int bind_xml(const char *data) /
    doc = xmlParseMemory(data, strlen(data));
    if (doc == NULL) {
      ERROR("bind plugin: xmlParseMemory failed.");
 -    return (-1);
 +    return -1;
    }
  
    xpathCtx = xmlXPathNewContext(doc);
    if (xpathCtx == NULL) {
      ERROR("bind plugin: xmlXPathNewContext failed.");
      xmlFreeDoc(doc);
 -    return (-1);
 +    return -1;
    }
  
    //
      xmlXPathFreeContext(xpathCtx);
      xmlFreeDoc(doc);
  
 -    return (ret);
 +    return ret;
    }
  
    //
      ERROR("bind plugin: Cannot find the <statistics> tag.");
      xmlXPathFreeContext(xpathCtx);
      xmlFreeDoc(doc);
 -    return (-1);
 +    return -1;
    } else if (xpathObj->nodesetval == NULL) {
      ERROR("bind plugin: xmlXPathEvalExpression failed.");
      xmlXPathFreeObject(xpathObj);
      xmlXPathFreeContext(xpathCtx);
      xmlFreeDoc(doc);
 -    return (-1);
 +    return -1;
    }
  
    for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) {
    xmlXPathFreeContext(xpathCtx);
    xmlFreeDoc(doc);
  
 -  return (ret);
 +  return ret;
  } /* }}} int bind_xml */
  
  static int bind_config_set_bool(const char *name, int *var, /* {{{ */
      WARNING("bind plugin: The `%s' option needs "
              "exactly one boolean argument.",
              name);
 -    return (-1);
 +    return -1;
    }
  
    if (ci->values[0].value.boolean)
@@@ -1461,24 -1467,24 +1467,24 @@@ static int bind_config_add_view_zone(cb
    if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
      WARNING("bind plugin: The `Zone' option needs "
              "exactly one string argument.");
 -    return (-1);
 +    return -1;
    }
  
    tmp = realloc(view->zones, sizeof(char *) * (view->zones_num + 1));
    if (tmp == NULL) {
      ERROR("bind plugin: realloc failed.");
 -    return (-1);
 +    return -1;
    }
    view->zones = tmp;
  
    view->zones[view->zones_num] = strdup(ci->values[0].value.string);
    if (view->zones[view->zones_num] == NULL) {
      ERROR("bind plugin: strdup failed.");
 -    return (-1);
 +    return -1;
    }
    view->zones_num++;
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_config_add_view_zone */
  
  static int bind_config_add_view(oconfig_item_t *ci) /* {{{ */
  
    if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
      WARNING("bind plugin: `View' blocks need exactly one string argument.");
 -    return (-1);
 +    return -1;
    }
  
    tmp = realloc(views, sizeof(*views) * (views_num + 1));
    if (tmp == NULL) {
      ERROR("bind plugin: realloc failed.");
 -    return (-1);
 +    return -1;
    }
    views = tmp;
    tmp = views + views_num;
    if (tmp->name == NULL) {
      ERROR("bind plugin: strdup failed.");
      sfree(views);
 -    return (-1);
 +    return -1;
    }
  
    for (int i = 0; i < ci->children_num; i++) {
    } /* for (i = 0; i < ci->children_num; i++) */
  
    views_num++;
 -  return (0);
 +  return 0;
  } /* }}} int bind_config_add_view */
  
  static int bind_config(oconfig_item_t *ci) /* {{{ */
            (child->values[0].type != OCONFIG_TYPE_STRING)) {
          WARNING("bind plugin: The `Url' option needs "
                  "exactly one string argument.");
 -        return (-1);
 +        return -1;
        }
  
        sfree(url);
      }
    }
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_config */
  
  static int bind_init(void) /* {{{ */
  {
    if (curl != NULL)
 -    return (0);
 +    return 0;
  
    curl = curl_easy_init();
    if (curl == NULL) {
      ERROR("bind plugin: bind_init: curl_easy_init failed.");
 -    return (-1);
 +    return -1;
    }
  
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
                                                          plugin_get_interval()));
  #endif
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_init */
  
  static int bind_read(void) /* {{{ */
  
    if (curl == NULL) {
      ERROR("bind plugin: I don't have a CURL object.");
 -    return (-1);
 +    return -1;
    }
  
    bind_buffer_fill = 0;
    if (curl_easy_perform(curl) != CURLE_OK) {
      ERROR("bind plugin: curl_easy_perform failed: %s", bind_curl_error);
 -    return (-1);
 +    return -1;
    }
  
    status = bind_xml(bind_buffer);
    if (status != 0)
 -    return (-1);
 +    return -1;
    else
 -    return (0);
 +    return 0;
  } /* }}} int bind_read */
  
  static int bind_shutdown(void) /* {{{ */
      curl = NULL;
    }
  
 -  return (0);
 +  return 0;
  } /* }}} int bind_shutdown */
  
  void module_register(void) {
    plugin_register_read("bind", bind_read);
    plugin_register_shutdown("bind", bind_shutdown);
  } /* void module_register */
 -
 -/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */
diff --combined src/daemon/utils_cache.c
@@@ -83,7 -83,7 +83,7 @@@ static int cache_compare(const cache_en
  #if COLLECT_DEBUG
    assert((a != NULL) && (b != NULL));
  #endif
 -  return (strcmp(a->name, b->name));
 +  return strcmp(a->name, b->name);
  } /* int cache_compare */
  
  static cache_entry_t *cache_alloc(size_t values_num) {
@@@ -92,7 -92,7 +92,7 @@@
    ce = calloc(1, sizeof(*ce));
    if (ce == NULL) {
      ERROR("utils_cache: cache_alloc: calloc failed.");
 -    return (NULL);
 +    return NULL;
    }
    ce->values_num = values_num;
  
      sfree(ce->values_raw);
      sfree(ce);
      ERROR("utils_cache: cache_alloc: calloc failed.");
 -    return (NULL);
 +    return NULL;
    }
  
    ce->history = NULL;
    ce->history_length = 0;
    ce->meta = NULL;
  
 -  return (ce);
 +  return ce;
  } /* cache_entry_t *cache_alloc */
  
  static void cache_free(cache_entry_t *ce) {
@@@ -148,14 -148,14 +148,14 @@@ static int uc_insert(const data_set_t *
    key_copy = strdup(key);
    if (key_copy == NULL) {
      ERROR("uc_insert: strdup failed.");
 -    return (-1);
 +    return -1;
    }
  
    ce = cache_alloc(ds->ds_num);
    if (ce == NULL) {
      sfree(key_copy);
      ERROR("uc_insert: cache_alloc (%zu) failed.", ds->ds_num);
 -    return (-1);
 +    return -1;
    }
  
    sstrncpy(ce->name, key, sizeof(ce->name));
              ds->ds[i].type);
        sfree(key_copy);
        cache_free(ce);
 -      return (-1);
 +      return -1;
      } /* switch (ds->ds[i].type) */
    }   /* for (i) */
  
    if (c_avl_insert(cache_tree, key_copy, ce) != 0) {
      sfree(key_copy);
      ERROR("uc_insert: c_avl_insert failed.");
 -    return (-1);
 +    return -1;
    }
  
    DEBUG("uc_insert: Added %s to the cache.", key);
 -  return (0);
 +  return 0;
  } /* int uc_insert */
  
  int uc_init(void) {
      cache_tree =
          c_avl_create((int (*)(const void *, const void *))cache_compare);
  
 -  return (0);
 +  return 0;
  } /* int uc_init */
  
  int uc_check_timeout(void) {
-   cdtime_t now = cdtime();
    struct {
      char *key;
      cdtime_t time;
    size_t expired_num = 0;
  
    pthread_mutex_lock(&cache_lock);
+   cdtime_t now = cdtime();
  
    /* Build a list of entries to be flushed */
    c_avl_iterator_t *iter = c_avl_get_iterator(cache_tree);
  
    if (expired_num == 0) {
      sfree(expired);
 -    return (0);
 +    return 0;
    }
  
    /* Call the "missing" callback for each value. Do this before removing the
    pthread_mutex_unlock(&cache_lock);
  
    sfree(expired);
 -  return (0);
 +  return 0;
  } /* int uc_check_timeout */
  
  int uc_update(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_update: FORMAT_VL failed.");
 -    return (-1);
 +    return -1;
    }
  
    pthread_mutex_lock(&cache_lock);
    {
      status = uc_insert(ds, vl, name);
      pthread_mutex_unlock(&cache_lock);
 -    return (status);
 +    return status;
    }
  
    assert(ce != NULL);
             "last cache update = %.3f;",
             name, CDTIME_T_TO_DOUBLE(vl->time),
             CDTIME_T_TO_DOUBLE(ce->last_time));
 -    return (-1);
 +    return -1;
    }
  
    for (size_t i = 0; i < ds->ds_num; i++) {
        pthread_mutex_unlock(&cache_lock);
        ERROR("uc_update: Don't know how to handle data source type %i.",
              ds->ds[i].type);
 -      return (-1);
 +      return -1;
      } /* switch (ds->ds[i].type) */
  
      DEBUG("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (0);
 +  return 0;
  } /* int uc_update */
  
  int uc_get_rate_by_name(const char *name, gauge_t **ret_values,
  
      /* remove missing values from getval */
      if (ce->state == STATE_MISSING) {
+       DEBUG("utils_cache: uc_get_rate_by_name: requested metric \"%s\" is in "
+             "state \"missing\".",
+             name);
        status = -1;
      } else {
        ret_num = ce->values_num;
      *ret_values_num = ret_num;
    }
  
 -  return (status);
 +  return status;
  } /* gauge_t *uc_get_rate_by_name */
  
  gauge_t *uc_get_rate(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("utils_cache: uc_get_rate: FORMAT_VL failed.");
 -    return (NULL);
 +    return NULL;
    }
  
    status = uc_get_rate_by_name(name, &ret, &ret_num);
    if (status != 0)
 -    return (NULL);
 +    return NULL;
  
    /* This is important - the caller has no other way of knowing how many
     * values are returned. */
-   if (ret_num != (size_t)ds->ds_num) {
+   if (ret_num != ds->ds_num) {
      ERROR("utils_cache: uc_get_rate: ds[%s] has %zu values, "
            "but uc_get_rate_by_name returned %zu.",
            ds->type, ds->ds_num, ret_num);
      sfree(ret);
 +    return NULL;
 +  }
 +
 +  return ret;
 +} /* gauge_t *uc_get_rate */
 +
 +int uc_get_value_by_name(const char *name, value_t **ret_values,
 +                         size_t *ret_values_num) {
 +  value_t *ret = NULL;
 +  size_t ret_num = 0;
 +  cache_entry_t *ce = NULL;
 +  int status = 0;
 +
 +  pthread_mutex_lock(&cache_lock);
 +
 +  if (c_avl_get(cache_tree, name, (void *) &ce) == 0) {
 +    assert(ce != NULL);
 +
 +    /* remove missing values from getval */
 +    if (ce->state == STATE_MISSING) {
 +      status = -1;
 +    } else {
 +      ret_num = ce->values_num;
 +      ret = malloc(ret_num * sizeof(*ret));
 +      if (ret == NULL) {
 +        ERROR("utils_cache: uc_get_value_by_name: malloc failed.");
 +        status = -1;
 +      } else {
 +        memcpy(ret, ce->values_raw, ret_num * sizeof(value_t));
 +      }
 +    }
 +  }
 +  else {
 +    DEBUG("utils_cache: uc_get_value_by_name: No such value: %s", name);
 +    status = -1;
 +  }
 +
 +  pthread_mutex_unlock(&cache_lock);
 +
 +  if (status == 0) {
 +    *ret_values = ret;
 +    *ret_values_num = ret_num;
 +  }
 +
 +  return (status);
 +} /* int uc_get_value_by_name */
 +
 +value_t *uc_get_value(const data_set_t *ds, const value_list_t *vl) {
 +  char name[6 * DATA_MAX_NAME_LEN];
 +  value_t *ret = NULL;
 +  size_t ret_num = 0;
 +  int status;
 +
 +  if (FORMAT_VL(name, sizeof(name), vl) != 0) {
 +    ERROR("utils_cache: uc_get_value: FORMAT_VL failed.");
 +    return (NULL);
 +  }
 +
 +  status = uc_get_value_by_name(name, &ret, &ret_num);
 +  if (status != 0)
 +    return (NULL);
 +
 +  /* This is important - the caller has no other way of knowing how many
 +   * values are returned. */
 +  if (ret_num != (size_t) ds->ds_num) {
 +    ERROR("utils_cache: uc_get_value: ds[%s] has %zu values, "
 +          "but uc_get_value_by_name returned %zu.", ds->type, ds->ds_num,
 +          ret_num);
 +    sfree(ret);
      return (NULL);
    }
  
    return (ret);
 -} /* gauge_t *uc_get_rate */
 +} /* value_t *uc_get_value */
  
  size_t uc_get_size(void) {
    size_t size_arrays = 0;
    size_arrays = (size_t)c_avl_size(cache_tree);
    pthread_mutex_unlock(&cache_lock);
  
 -  return (size_arrays);
 +  return size_arrays;
  }
  
  int uc_get_names(char ***ret_names, cdtime_t **ret_times, size_t *ret_number) {
    int status = 0;
  
    if ((ret_names == NULL) || (ret_number == NULL))
 -    return (-1);
 +    return -1;
  
    pthread_mutex_lock(&cache_lock);
  
      /* Handle the "no values" case here, to avoid the error message when
       * calloc() returns NULL. */
      pthread_mutex_unlock(&cache_lock);
 -    return (0);
 +    return 0;
    }
  
    names = calloc(size_arrays, sizeof(*names));
      sfree(names);
      sfree(times);
      pthread_mutex_unlock(&cache_lock);
 -    return (ENOMEM);
 +    return ENOMEM;
    }
  
    iter = c_avl_get_iterator(cache_tree);
      sfree(names);
      sfree(times);
  
 -    return (-1);
 +    return -1;
    }
  
    *ret_names = names;
      sfree(times);
    *ret_number = number;
  
 -  return (0);
 +  return 0;
  } /* int uc_get_names */
  
  int uc_get_state(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_get_state: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_get_state */
  
  int uc_set_state(const data_set_t *ds, const value_list_t *vl, int state) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_set_state: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_set_state */
  
  int uc_get_history_by_name(const char *name, gauge_t *ret_history,
    status = c_avl_get(cache_tree, name, (void *)&ce);
    if (status != 0) {
      pthread_mutex_unlock(&cache_lock);
 -    return (-ENOENT);
 +    return -ENOENT;
    }
  
    if (((size_t)ce->values_num) != num_ds) {
      pthread_mutex_unlock(&cache_lock);
 -    return (-EINVAL);
 +    return -EINVAL;
    }
  
    /* Check if there are enough values available. If not, increase the buffer
          realloc(ce->history, sizeof(*ce->history) * num_steps * ce->values_num);
      if (tmp == NULL) {
        pthread_mutex_unlock(&cache_lock);
 -      return (-ENOMEM);
 +      return -ENOMEM;
      }
  
      for (size_t i = ce->history_length * ce->values_num;
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (0);
 +  return 0;
  } /* int uc_get_history_by_name */
  
  int uc_get_history(const data_set_t *ds, const value_list_t *vl,
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("utils_cache: uc_get_history: FORMAT_VL failed.");
 -    return (-1);
 +    return -1;
    }
  
 -  return (uc_get_history_by_name(name, ret_history, num_steps, num_ds));
 +  return uc_get_history_by_name(name, ret_history, num_steps, num_ds);
  } /* int uc_get_history */
  
  int uc_get_hits(const data_set_t *ds, const value_list_t *vl) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_get_hits: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_get_hits */
  
  int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_set_hits: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_set_hits */
  
  int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step) {
  
    if (FORMAT_VL(name, sizeof(name), vl) != 0) {
      ERROR("uc_inc_hits: FORMAT_VL failed.");
 -    return (STATE_ERROR);
 +    return STATE_ERROR;
    }
  
    pthread_mutex_lock(&cache_lock);
  
    pthread_mutex_unlock(&cache_lock);
  
 -  return (ret);
 +  return ret;
  } /* int uc_inc_hits */
  
  /*
@@@ -829,24 -762,24 +831,24 @@@ uc_iter_t *uc_get_iterator(void) 
  
    iter = (uc_iter_t *)calloc(1, sizeof(*iter));
    if (iter == NULL)
 -    return (NULL);
 +    return NULL;
  
    pthread_mutex_lock(&cache_lock);
  
    iter->iter = c_avl_get_iterator(cache_tree);
    if (iter->iter == NULL) {
      free(iter);
 -    return (NULL);
 +    return NULL;
    }
  
 -  return (iter);
 +  return iter;
  } /* uc_iter_t *uc_get_iterator */
  
  int uc_iterator_next(uc_iter_t *iter, char **ret_name) {
    int status;
  
    if (iter == NULL)
 -    return (-1);
 +    return -1;
  
    while ((status = c_avl_iterator_next(iter->iter, (void *)&iter->name,
                                         (void *)&iter->entry)) == 0) {
    if (status != 0) {
      iter->name = NULL;
      iter->entry = NULL;
 -    return (-1);
 +    return -1;
    }
  
    if (ret_name != NULL)
      *ret_name = iter->name;
  
 -  return (0);
 +  return 0;
  } /* int uc_iterator_next */
  
  void uc_iterator_destroy(uc_iter_t *iter) {
  
  int uc_iterator_get_time(uc_iter_t *iter, cdtime_t *ret_time) {
    if ((iter == NULL) || (iter->entry == NULL) || (ret_time == NULL))
 -    return (-1);
 +    return -1;
  
    *ret_time = iter->entry->last_time;
 -  return (0);
 +  return 0;
  } /* int uc_iterator_get_name */
  
  int uc_iterator_get_values(uc_iter_t *iter, value_t **ret_values,
                             size_t *ret_num) {
    if ((iter == NULL) || (iter->entry == NULL) || (ret_values == NULL) ||
        (ret_num == NULL))
 -    return (-1);
 +    return -1;
  
    *ret_values =
        calloc(iter->entry->values_num, sizeof(*iter->entry->values_raw));
    if (*ret_values == NULL)
 -    return (-1);
 +    return -1;
    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;
  
 -  return (0);
 +  return 0;
  } /* int uc_iterator_get_values */
  
  int uc_iterator_get_interval(uc_iter_t *iter, cdtime_t *ret_interval) {
    if ((iter == NULL) || (iter->entry == NULL) || (ret_interval == NULL))
 -    return (-1);
 +    return -1;
  
    *ret_interval = iter->entry->interval;
 -  return (0);
 +  return 0;
  } /* int uc_iterator_get_name */
  
  /*
@@@ -924,7 -857,7 +926,7 @@@ static meta_data_t *uc_get_meta(const v
    status = FORMAT_VL(name, sizeof(name), vl);
    if (status != 0) {
      ERROR("utils_cache: uc_get_meta: FORMAT_VL failed.");
 -    return (NULL);
 +    return NULL;
    }
  
    pthread_mutex_lock(&cache_lock);
    status = c_avl_get(cache_tree, name, (void *)&ce);
    if (status != 0) {
      pthread_mutex_unlock(&cache_lock);
 -    return (NULL);
 +    return NULL;
    }
    assert(ce != NULL);
  
    if (ce->meta == NULL)
      pthread_mutex_unlock(&cache_lock);
  
 -  return (ce->meta);
 +  return ce->meta;
  } /* }}} meta_data_t *uc_get_meta */
  
  /* Sorry about this preprocessor magic, but it really makes this file much
      int status;                                                                \
      meta = uc_get_meta(vl);                                                    \
      if (meta == NULL)                                                          \
 -      return (-1);                                                             \
 +      return -1;                                                               \
      status = wrap_function(meta, key);                                         \
      pthread_mutex_unlock(&cache_lock);                                         \
 -    return (status);                                                           \
 +    return status;                                                             \
    }
  int uc_meta_data_exists(const value_list_t *vl,
                          const char *key) UC_WRAP(meta_data_exists)
      int status;                                                                \
      meta = uc_get_meta(vl);                                                    \
      if (meta == NULL)                                                          \
 -      return (-1);                                                             \
 +      return -1;                                                               \
      status = wrap_function(meta, key, value);                                  \
      pthread_mutex_unlock(&cache_lock);                                         \
 -    return (status);                                                           \
 +    return status;                                                             \
    }
          int uc_meta_data_add_string(const value_list_t *vl, const char *key,
                                      const char *value)
                                                  const char *key, _Bool *value)
                                                  UC_WRAP(meta_data_get_boolean)
  #undef UC_WRAP
 -
 -    /* vim: set sw=2 ts=8 sts=2 tw=78 : */
@@@ -48,9 -48,9 +48,9 @@@ static int gr_format_values(char *ret, 
    do {                                                                         \
      status = ssnprintf(ret + offset, ret_len - offset, __VA_ARGS__);           \
      if (status < 1) {                                                          \
 -      return (-1);                                                             \
 +      return -1;                                                               \
      } else if (((size_t)status) >= (ret_len - offset)) {                       \
 -      return (-1);                                                             \
 +      return -1;                                                               \
      } else                                                                     \
        offset += ((size_t)status);                                              \
    } while (0)
    else {
      ERROR("gr_format_values plugin: Unknown data source type: %i",
            ds->ds[ds_num].type);
 -    return (-1);
 +    return -1;
    }
  
  #undef BUFFER_ADD
  
 -  return (0);
 +  return 0;
  }
  
  static void gr_copy_escape_part(char *dst, const char *src, size_t dst_len,
@@@ -161,7 -161,7 +161,7 @@@ static int gr_format_name(char *ret, in
      ssnprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, tmp_plugin,
                tmp_type);
  
 -  return (0);
 +  return 0;
  }
  
  static void escape_graphite_string(char *buffer, char escape_char) {
@@@ -180,8 -180,13 +180,13 @@@ int format_graphite(char *buffer, size_
    int buffer_pos = 0;
  
    gauge_t *rates = NULL;
-   if (flags & GRAPHITE_STORE_RATES)
+   if (flags & GRAPHITE_STORE_RATES) {
      rates = uc_get_rate(ds, vl);
+     if (rates == NULL) {
+       ERROR("format_graphite: error with uc_get_rate");
+       return -1;
+     }
+   }
  
    for (size_t i = 0; i < ds->ds_num; i++) {
      char const *ds_name = NULL;
      if (status != 0) {
        ERROR("format_graphite: error with gr_format_name");
        sfree(rates);
 -      return (status);
 +      return status;
      }
  
      escape_graphite_string(key, escape_char);
      if (status != 0) {
        ERROR("format_graphite: error with gr_format_values");
        sfree(rates);
 -      return (status);
 +      return status;
      }
  
      /* Compute the graphite command */
              "Need %zu bytes.",
              message_len + 1);
        sfree(rates);
 -      return (-ENOMEM);
 +      return -ENOMEM;
      }
  
      /* Append it in case we got multiple data set */
      if ((buffer_pos + message_len) >= buffer_size) {
        ERROR("format_graphite: target buffer too small");
        sfree(rates);
 -      return (-ENOMEM);
 +      return -ENOMEM;
      }
      memcpy((void *)(buffer + buffer_pos), message, message_len);
      buffer_pos += message_len;
      buffer[buffer_pos] = '\0';
    }
    sfree(rates);
 -  return (status);
 +  return status;
  } /* int format_graphite */
 -
 -/* vim: set sw=2 sts=2 et fdm=marker : */