示例#1
0
/*
 * 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 NULL; /* Error already logged. */

  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\" from '%s' doesn't match "
            "any of the nodes.",
            expr, from_option);
    xmlXPathFreeObject(values_node_obj);
    return NULL;
  }

  if (tmp_size > 1) {
    WARNING("curl_xml plugin: "
            "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 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\" 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 NULL;
  }

  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 */
示例#2
0
static int  cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
    char const *host,
    xmlXPathContextPtr xpath_ctx, const data_set_t *ds, 
    char *base_xpath, cx_xpath_t *xpath)
{
  int total_nodes;
  int i;

  xmlXPathObjectPtr base_node_obj = NULL;
  xmlNodeSetPtr base_nodes = NULL;

  value_list_t vl = VALUE_LIST_INIT;

  base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath); 
  if (base_node_obj == NULL)
    return -1; /* error is logged already */

  base_nodes = base_node_obj->nodesetval;
  total_nodes = (base_nodes) ? base_nodes->nodeNr : 0;

  if (total_nodes == 0)
  {
     ERROR ("curl_xml plugin: "
              "xpath expression \"%s\" doesn't match any of the nodes. "
              "Skipping the xpath block...", base_xpath);
     xmlXPathFreeObject (base_node_obj);
     return -1;
  }

  /* If base_xpath returned multiple results, then */
  /* Instance in the xpath block is required */ 
  if (total_nodes > 1 && xpath->instance == NULL)
  {
    ERROR ("curl_xml plugin: "
             "InstanceFrom is must in xpath block since the base xpath expression \"%s\" "
             "returned multiple results. Skipping the xpath block...", base_xpath);
    return -1;
  }

  /* set the values for the value_list */
  vl.values_len = ds->ds_num;
  sstrncpy (vl.type, xpath->type, sizeof (vl.type));
  sstrncpy (vl.plugin, "curl_xml", sizeof (vl.plugin));
  sstrncpy (vl.host, (host != NULL) ? host : hostname_g, sizeof (vl.host));
  if (plugin_instance != NULL)
    sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); 

  for (i = 0; i < total_nodes; i++)
  {
    int status;

    xpath_ctx->node = base_nodes->nodeTab[i];

    status = cx_handle_instance_xpath (xpath_ctx, xpath, &vl,
        /* is_table = */ (total_nodes > 1));
    if (status != 0)
      continue; /* An error has already been reported. */

    status = cx_handle_all_value_xpaths (xpath_ctx, xpath, ds, &vl);
    if (status != 0)
      continue; /* An error has been logged. */
  } /* for (i = 0; i < total_nodes; i++) */

  /* free up the allocated memory */
  xmlXPathFreeObject (base_node_obj); 

  return (0); 
} /* }}} cx_handle_base_xpath */
示例#3
0
static int cx_handle_instance_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
    cx_xpath_t *xpath, value_list_t *vl,
    _Bool is_table)
{
  xmlXPathObjectPtr instance_node_obj = NULL;
  xmlNodeSetPtr instance_node = NULL;

  memset (vl->type_instance, 0, sizeof (vl->type_instance));

  /* If the base xpath returns more than one block, the result is assumed to be
   * a table. The `Instance' option is not optional in this case. Check for the
   * condition and inform the user. */
  if (is_table && (xpath->instance == NULL))
  {
    WARNING ("curl_xml plugin: "
        "Base-XPath %s is a table (more than one result was returned), "
        "but no instance-XPath has been defined.",
        xpath->path);
    return (-1);
  }

  /* instance has to be an xpath expression */
  if (xpath->instance != NULL)
  {
    int tmp_size;

    instance_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST 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);
      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]);
      ssnprintf (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]);
      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);

  return (0);
} /* }}} int cx_handle_instance_xpath */
示例#4
0
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, BAD_CAST xpath->values[index].path);
  if (values_node_obj == NULL)
    return (-1); /* Error already logged. */

  values_node = values_node_obj->nodesetval;
  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);
    xmlXPathFreeObject (values_node_obj);
    return (-1);
  }

  if (tmp_size > 1)
  {
    WARNING ("curl_xml plugin: "
        "relative xpath expression \"%s\" is expected to return "
        "only one node. Skipping...", xpath->values[index].path);
    xmlXPathFreeObject (values_node_obj);
    return (-1);
  }

  /* 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);
    xmlXPathFreeObject (values_node_obj);
    return (-1);
  }

  node_value = (char *) xmlNodeGetContent(values_node->nodeTab[0]);
  switch (ds->ds[index].type)
  {
    case DS_TYPE_COUNTER:
      vl->values[index].counter = (counter_t) strtoull (node_value,
          /* endptr = */ NULL, /* base = */ 0);
      break;
    case DS_TYPE_DERIVE:
      vl->values[index].derive = (derive_t) strtoll (node_value,
          /* endptr = */ NULL, /* base = */ 0);
      break;
    case DS_TYPE_ABSOLUTE:
      vl->values[index].absolute = (absolute_t) strtoull (node_value,
          /* endptr = */ NULL, /* base = */ 0);
      break;
    case DS_TYPE_GAUGE: 
      vl->values[index].gauge = (gauge_t) strtod (node_value,
          /* endptr = */ NULL);
  }

  /* free up object */
  xmlXPathFreeObject (values_node_obj);
  sfree (node_value);

  /* We have reached here which means that
   * we have got something to work */
  return (0);
} /* }}} int cx_handle_single_value_xpath */
示例#5
0
static int cx_handle_xpath(const cx_t *db, /* {{{ */
                           xmlXPathContextPtr xpath_ctx, cx_xpath_t *xpath) {

  const data_set_t *ds = plugin_get_ds(xpath->type);
  if (cx_check_type(ds, xpath) != 0)
    return -1;

  xmlXPathObjectPtr base_node_obj = cx_evaluate_xpath(xpath_ctx, xpath->path);
  if (base_node_obj == NULL)
    return -1; /* error is logged already */

  xmlNodeSetPtr base_nodes = base_node_obj->nodesetval;
  int total_nodes = (base_nodes) ? base_nodes->nodeNr : 0;

  if (total_nodes == 0) {
    ERROR("curl_xml plugin: "
          "xpath expression \"%s\" doesn't match any of the nodes. "
          "Skipping the xpath block...",
          xpath->path);
    xmlXPathFreeObject(base_node_obj);
    return -1;
  }

  /* If base_xpath returned multiple results, then */
  /* InstanceFrom or PluginInstanceFrom in the xpath block is required */
  if (total_nodes > 1 && xpath->instance == NULL &&
      xpath->plugin_instance_from == NULL) {
    ERROR("curl_xml plugin: "
          "InstanceFrom or PluginInstanceFrom is must in xpath block "
          "since the base xpath expression \"%s\" "
          "returned multiple results. Skipping the xpath block...",
          xpath->path);
    xmlXPathFreeObject(base_node_obj);
    return -1;
  }

  value_list_t vl = VALUE_LIST_INIT;

  /* set the values for the value_list */
  vl.values_len = ds->ds_num;
  sstrncpy(vl.type, xpath->type, sizeof(vl.type));
  sstrncpy(vl.plugin, (db->plugin_name != NULL) ? db->plugin_name : "curl_xml",
           sizeof(vl.plugin));
  sstrncpy(vl.host, cx_host(db), sizeof(vl.host));

  for (int i = 0; i < total_nodes; i++) {
    xpath_ctx->node = base_nodes->nodeTab[i];

    if (db->instance != NULL)
      sstrncpy(vl.plugin_instance, db->instance, sizeof(vl.plugin_instance));

    if (cx_handle_instance_xpath(xpath_ctx, xpath, &vl) != 0)
      continue; /* An error has already been reported. */

    if (cx_handle_all_value_xpaths(xpath_ctx, xpath, ds, &vl) != 0)
      continue; /* An error has been logged. */
  }             /* for (i = 0; i < total_nodes; i++) */

  /* free up the allocated memory */
  xmlXPathFreeObject(base_node_obj);

  return 0;
} /* }}} cx_handle_xpath */