char *user;
char *pass;
char *credentials;
- _Bool digest;
- _Bool verify_peer;
- _Bool verify_host;
+ bool digest;
+ bool verify_peer;
+ bool verify_host;
char *cacert;
char *post_body;
int timeout;
while (le != NULL) {
llentry_t *le_next = le->next;
+ /* this also frees xpath->path used for le->key */
cx_xpath_free(le->value);
le = le_next;
}
llist_destroy(list);
-} /* }}} void cx_list_free */
+} /* }}} void cx_xpath_list_free */
static void cx_free(void *arg) /* {{{ */
{
}
if (ds->ds_num != xpath->values_len) {
- WARNING("curl_xml plugin: DataSet `%s' requires %zu values, but config "
- "talks about %zu",
+ WARNING("curl_xml plugin: DataSet `%s' requires %" PRIsz
+ " values, but config talks about %" PRIsz,
xpath->type, ds->ds_num, xpath->values_len);
return -1;
}
return -1;
} /* }}} cx_if_not_text_node */
-static int cx_handle_single_value_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
- cx_xpath_t *xpath, const data_set_t *ds,
- value_list_t *vl, int index) {
- xmlXPathObjectPtr values_node_obj;
- xmlNodeSetPtr values_node;
- int tmp_size;
- char *node_value;
-
- values_node_obj = cx_evaluate_xpath(xpath_ctx, xpath->values[index].path);
+/*
+ * Returned value should be freed with xmlFree().
+ */
+static char *cx_get_text_node_value(xmlXPathContextPtr xpath_ctx, /* {{{ */
+ char *expr, const char *from_option) {
+ xmlXPathObjectPtr values_node_obj = cx_evaluate_xpath(xpath_ctx, expr);
if (values_node_obj == NULL)
- return -1; /* Error already logged. */
+ return NULL; /* Error already logged. */
- values_node = values_node_obj->nodesetval;
- tmp_size = (values_node) ? values_node->nodeNr : 0;
+ xmlNodeSetPtr values_node = values_node_obj->nodesetval;
+ size_t tmp_size = (values_node) ? values_node->nodeNr : 0;
if (tmp_size == 0) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" doesn't match any of the nodes. "
- "Skipping...",
- xpath->values[index].path);
+ "relative xpath expression \"%s\" from '%s' doesn't match "
+ "any of the nodes.",
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
- return -1;
+ return NULL;
}
if (tmp_size > 1) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" is expected to return "
- "only one node. Skipping...",
- xpath->values[index].path);
+ "relative xpath expression \"%s\" from '%s' is expected to return "
+ "only one text node. Skipping the node.",
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
- return -1;
+ return NULL;
}
/* ignoring the element if other than textnode/attribute*/
if (cx_if_not_text_node(values_node->nodeTab[0])) {
WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" is expected to return "
- "only text/attribute node which is not the case. Skipping...",
- xpath->values[index].path);
+ "relative xpath expression \"%s\" from '%s' is expected to return "
+ "only text/attribute node which is not the case. "
+ "Skipping the node.",
+ expr, from_option);
xmlXPathFreeObject(values_node_obj);
- return -1;
+ return NULL;
}
- node_value = (char *)xmlNodeGetContent(values_node->nodeTab[0]);
+ char *node_value = (char *)xmlNodeGetContent(values_node->nodeTab[0]);
+
+ /* free up object */
+ xmlXPathFreeObject(values_node_obj);
+
+ return node_value;
+} /* }}} char * cx_get_text_node_value */
+
+static int cx_handle_single_value_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
+ cx_xpath_t *xpath, const data_set_t *ds,
+ value_list_t *vl, int index) {
+
+ char *node_value = cx_get_text_node_value(
+ xpath_ctx, xpath->values[index].path, "ValuesFrom");
+
+ if (node_value == NULL)
+ return -1;
+
switch (ds->ds[index].type) {
case DS_TYPE_COUNTER:
vl->values[index].counter =
/* endptr = */ NULL);
}
- /* free up object */
- xmlXPathFreeObject(values_node_obj);
- sfree(node_value);
+ xmlFree(node_value);
/* We have reached here which means that
* we have got something to work */
static int cx_handle_instance_xpath(xmlXPathContextPtr xpath_ctx, /* {{{ */
cx_xpath_t *xpath, value_list_t *vl) {
- xmlXPathObjectPtr instance_node_obj = NULL;
- xmlNodeSetPtr instance_node = NULL;
-
- memset(vl->type_instance, 0, sizeof(vl->type_instance));
-
- /* instance has to be an xpath expression */
+ /* Handle type instance */
if (xpath->instance != NULL) {
- int tmp_size;
-
- instance_node_obj = cx_evaluate_xpath(xpath_ctx, xpath->instance);
- if (instance_node_obj == NULL)
- return -1; /* error is logged already */
-
- instance_node = instance_node_obj->nodesetval;
- tmp_size = (instance_node) ? instance_node->nodeNr : 0;
-
- if (tmp_size <= 0) {
- WARNING(
- "curl_xml plugin: "
- "relative xpath expression for 'InstanceFrom' \"%s\" doesn't match "
- "any of the nodes. Skipping the node.",
- xpath->instance);
- xmlXPathFreeObject(instance_node_obj);
+ char *node_value =
+ cx_get_text_node_value(xpath_ctx, xpath->instance, "InstanceFrom");
+ if (node_value == NULL)
return -1;
- }
-
- if (tmp_size > 1) {
- WARNING("curl_xml plugin: "
- "relative xpath expression for 'InstanceFrom' \"%s\" is expected "
- "to return only one text node. Skipping the node.",
- xpath->instance);
- xmlXPathFreeObject(instance_node_obj);
- return -1;
- }
- /* ignoring the element if other than textnode/attribute */
- if (cx_if_not_text_node(instance_node->nodeTab[0])) {
- WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" is expected to return only "
- "text node "
- "which is not the case. Skipping the node.",
- xpath->instance);
- xmlXPathFreeObject(instance_node_obj);
- return -1;
- }
- } /* if (xpath->instance != NULL) */
-
- if (xpath->instance_prefix != NULL) {
- if (instance_node != NULL) {
- char *node_value = (char *)xmlNodeGetContent(instance_node->nodeTab[0]);
+ if (xpath->instance_prefix != NULL)
snprintf(vl->type_instance, sizeof(vl->type_instance), "%s%s",
xpath->instance_prefix, node_value);
- sfree(node_value);
- } else
- sstrncpy(vl->type_instance, xpath->instance_prefix,
- sizeof(vl->type_instance));
- } else {
- /* If instance_prefix and instance_node are NULL, then
- * don't set the type_instance */
- if (instance_node != NULL) {
- char *node_value = (char *)xmlNodeGetContent(instance_node->nodeTab[0]);
+ else
sstrncpy(vl->type_instance, node_value, sizeof(vl->type_instance));
- sfree(node_value);
- }
- }
- /* Free `instance_node_obj' this late, because `instance_node' points to
- * somewhere inside this structure. */
- xmlXPathFreeObject(instance_node_obj);
+ xmlFree(node_value);
+ } else if (xpath->instance_prefix != NULL)
+ sstrncpy(vl->type_instance, xpath->instance_prefix,
+ sizeof(vl->type_instance));
- /* Part 2, handle PluginInstanceFrom */
- instance_node_obj = NULL;
- instance_node = NULL;
-
- /* plugin_instance_from has to be an xpath expression */
+ /* Handle plugin instance */
if (xpath->plugin_instance_from != NULL) {
- instance_node_obj =
- cx_evaluate_xpath(xpath_ctx, xpath->plugin_instance_from);
- if (instance_node_obj == NULL)
- return -1; /* error is already logged */
-
- instance_node = instance_node_obj->nodesetval;
- int tmp_size = (instance_node) ? instance_node->nodeNr : 0;
-
- if (tmp_size <= 0) {
- WARNING("curl_xml plugin: "
- "relative xpath expression for 'PluginInstanceFrom' \"%s\" "
- "doesn't match any of the nodes. Skipping the node.",
- xpath->plugin_instance_from);
- xmlXPathFreeObject(instance_node_obj);
- return -1;
- }
-
- if (tmp_size > 1) {
- WARNING("curl_xml plugin: "
- "relative xpath expression for 'PluginInstanceFrom' \"%s\" "
- "is expected to return only one text node. Skipping the node.",
- xpath->plugin_instance_from);
- xmlXPathFreeObject(instance_node_obj);
- return -1;
- }
+ char *node_value = cx_get_text_node_value(
+ xpath_ctx, xpath->plugin_instance_from, "PluginInstanceFrom");
- /* ignoring the element if other than textnode/attribute */
- if (cx_if_not_text_node(instance_node->nodeTab[0])) {
- WARNING("curl_xml plugin: "
- "relative xpath expression \"%s\" is expected to return only "
- "text node which is not the case. Skipping the node.",
- xpath->plugin_instance_from);
- xmlXPathFreeObject(instance_node_obj);
+ if (node_value == NULL)
return -1;
- }
-
- if (instance_node != NULL) {
- char *node_value = (char *)xmlNodeGetContent(instance_node->nodeTab[0]);
- sstrncpy(vl->plugin_instance, node_value, sizeof(vl->plugin_instance));
- sfree(node_value);
- }
- /* Free `instance_node_obj' this late, because `instance_node' points to
- * somewhere inside this structure. */
- xmlXPathFreeObject(instance_node_obj);
- } /* if (xpath->plugin_instance_from != NULL) */
+ sstrncpy(vl->plugin_instance, node_value, sizeof(vl->plugin_instance));
+ xmlFree(node_value);
+ }
return 0;
} /* }}} int cx_handle_instance_xpath */
"since the base xpath expression \"%s\" "
"returned multiple results. Skipping the xpath block...",
xpath->path);
+ xmlXPathFreeObject(base_node_obj);
return -1;
}
return -1;
}
- if (db->xpath_list == NULL) {
- db->xpath_list = llist_create();
- if (db->xpath_list == NULL) {
- ERROR("curl_xml plugin: list creation failed.");
- cx_xpath_free(xpath);
- return -1;
- }
+ if (xpath->values_len == 0) {
+ WARNING("curl_xml plugin: `ValuesFrom' missing in `xpath' block.");
+ cx_xpath_free(xpath);
+ return -1;
}
llentry_t *le = llentry_create(xpath->path, xpath);
static int cx_config_add_url(oconfig_item_t *ci) /* {{{ */
{
- int status = 0;
-
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("curl_xml plugin: The `URL' block "
"needs exactly one string argument.");
return -1;
}
- db->timeout = -1;
+ db->instance = strdup("default");
+ if (db->instance == NULL) {
+ ERROR("curl_xml plugin: strdup failed.");
+ sfree(db);
+ return -1;
+ }
- if (strcasecmp("URL", ci->key) == 0) {
- status = cf_util_get_string(ci, &db->url);
- if (status != 0) {
- sfree(db);
- return status;
- }
- } else {
- ERROR("curl_xml plugin: cx_config: "
- "Invalid key: %s",
- ci->key);
- cx_free(db);
+ db->xpath_list = llist_create();
+ if (db->xpath_list == NULL) {
+ ERROR("curl_xml plugin: list creation failed.");
+ sfree(db->instance);
+ sfree(db);
return -1;
}
+ db->timeout = -1;
+
+ int status = cf_util_get_string(ci, &db->url);
+ if (status != 0) {
+ llist_destroy(db->xpath_list);
+ sfree(db->instance);
+ sfree(db);
+ return status;
+ }
+
+ cdtime_t interval = 0;
+
/* Fill the `cx_t' structure.. */
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *child = ci->children + i;
status = cf_util_get_string(child, &db->post_body);
else if (strcasecmp("Namespace", child->key) == 0)
status = cx_config_add_namespace(db, child);
+ else if (strcasecmp("Interval", child->key) == 0)
+ status = cf_util_get_cdtime(child, &interval);
else if (strcasecmp("Timeout", child->key) == 0)
status = cf_util_get_int(child, &db->timeout);
else if (strcasecmp("Statistics", child->key) == 0) {
break;
}
- if (status == 0) {
- if (db->xpath_list == NULL) {
- WARNING("curl_xml plugin: No (valid) `xpath' block "
- "within `URL' block `%s'.",
- db->url);
- status = -1;
- }
- if (status == 0)
- status = cx_init_curl(db);
+ if (status != 0) {
+ cx_free(db);
+ return status;
}
- /* If all went well, register this database for reading */
- if (status == 0) {
- if (db->instance == NULL)
- db->instance = strdup("default");
-
- DEBUG("curl_xml plugin: Registering new read callback: %s", db->instance);
-
- char *cb_name = ssnprintf_alloc("curl_xml-%s-%s", db->instance, db->url);
+ if (llist_size(db->xpath_list) == 0) {
+ WARNING("curl_xml plugin: No `xpath' block within `URL' block `%s'.",
+ db->url);
+ cx_free(db);
+ return -1;
+ }
- plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
- /* interval = */ 0,
- &(user_data_t){
- .data = db, .free_func = cx_free,
- });
- sfree(cb_name);
- } else {
+ if (cx_init_curl(db) != 0) {
cx_free(db);
return -1;
}
+ /* If all went well, register this database for reading */
+ DEBUG("curl_xml plugin: Registering new read callback: %s", db->instance);
+
+ char *cb_name = ssnprintf_alloc("curl_xml-%s-%s", db->instance, db->url);
+
+ plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
+ /* interval = */ interval,
+ &(user_data_t){
+ .data = db, .free_func = cx_free,
+ });
+ sfree(cb_name);
return 0;
} /* }}} int cx_config_add_url */