+ for (j = 0; j < view->zones_num; j++)
+ {
+ if (strcasecmp (zone_name, view->zones[j]) == 0)
+ break;
+ }
+
+ xmlFree (zone_name);
+ zone_name = NULL;
+
+ if (j >= views_num)
+ {
+ xmlXPathFreeObject (path_obj);
+ return (0);
+ }
+
+ zone_name = view->zones[j];
+
+ DEBUG ("bind plugin: bind_xml_stats_handle_zone: Found zone `%s'.",
+ zone_name);
+
+ { /* Parse the <counters> tag {{{ */
+ char plugin_instance[DATA_MAX_NAME_LEN];
+ translation_table_ptr_t table_ptr =
+ {
+ nsstats_translation_table,
+ nsstats_translation_table_length,
+ plugin_instance
+ };
+
+ ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-zone-%s",
+ view->name, zone_name);
+
+ bind_parse_generic_value_list (/* xpath = */ "counters",
+ /* callback = */ bind_xml_table_callback,
+ /* user_data = */ &table_ptr,
+ doc, path_ctx, current_time, DS_TYPE_COUNTER);
+ } /* }}} */
+
+ xmlXPathFreeObject (path_obj);
+
+ return (0);
+} /* }}} int bind_xml_stats_handle_zone */
+
+static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */
+ xmlXPathContext *path_ctx, xmlNode *node, cb_view_t *view,
+ time_t current_time)
+{
+ xmlXPathObject *zone_nodes = NULL;
+ xmlXPathContext *zone_path_context;
+ int i;
+
+ zone_path_context = xmlXPathNewContext (doc);
+ if (zone_path_context == NULL)
+ {
+ ERROR ("bind plugin: xmlXPathNewContext failed.");
+ 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);
+ }
+
+ for (i = 0; i < zone_nodes->nodesetval->nodeNr; i++)
+ {
+ xmlNode *node;
+
+ node = zone_nodes->nodesetval->nodeTab[i];
+ assert (node != NULL);
+
+ zone_path_context->node = node;
+
+ bind_xml_stats_handle_zone (version, doc, zone_path_context, node, view,
+ current_time);
+ }
+
+ xmlXPathFreeObject (zone_nodes);
+ xmlXPathFreeContext (zone_path_context);
+ return (0);
+} /* }}} int bind_xml_stats_search_zones */
+
+static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */
+ xmlXPathContext *path_ctx, xmlNode *node, time_t current_time)
+{
+ xmlXPathObject *path_obj;
+ char *view_name = NULL;
+ cb_view_t *view;
+ int i;
+ size_t j;
+
+ path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx);
+ if (path_obj == NULL)
+ {
+ ERROR ("bind plugin: xmlXPathEvalExpression failed.");
+ return (-1);
+ }
+
+ for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++)
+ {
+ view_name = (char *) xmlNodeListGetString (doc,
+ path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1);
+ if (view_name != NULL)
+ break;
+ }
+
+ if (view_name == NULL)
+ {
+ ERROR ("bind plugin: Could not determine view name.");
+ xmlXPathFreeObject (path_obj);
+ return (-1);
+ }
+
+ for (j = 0; j < views_num; j++)
+ {
+ if (strcasecmp (view_name, views[j].name) == 0)
+ break;
+ }
+
+ xmlFree (view_name);
+ xmlXPathFreeObject (path_obj);
+
+ view_name = NULL;
+ path_obj = NULL;
+
+ if (j >= views_num)
+ return (0);
+
+ view = views + j;
+
+ DEBUG ("bind plugin: bind_xml_stats_handle_view: Found view `%s'.",
+ view->name);
+
+ if (view->qtypes != 0) /* {{{ */
+ {
+ char plugin_instance[DATA_MAX_NAME_LEN];
+ list_info_ptr_t list_info =
+ {
+ plugin_instance,
+ /* type = */ "dns_qtype_gauge"
+ };
+
+ ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-qtypes",
+ view->name);
+
+ bind_parse_generic_name_value (/* xpath = */ "rdtype",
+ /* callback = */ bind_xml_list_callback,
+ /* user_data = */ &list_info,
+ doc, path_ctx, current_time, DS_TYPE_COUNTER);
+ } /* }}} */
+
+ if (view->resolver_stats != 0) /* {{{ */
+ {
+ char plugin_instance[DATA_MAX_NAME_LEN];
+ translation_table_ptr_t table_ptr =
+ {
+ resstats_translation_table,
+ resstats_translation_table_length,
+ plugin_instance
+ };
+
+ ssnprintf (plugin_instance, sizeof (plugin_instance),
+ "%s-resolver_stats", view->name);
+
+ bind_parse_generic_name_value ("resstat",
+ /* callback = */ bind_xml_table_callback,
+ /* user_data = */ &table_ptr,
+ doc, path_ctx, current_time, DS_TYPE_COUNTER);
+ } /* }}} */
+
+ if (view->cacherrsets != 0) /* {{{ */
+ {
+ char plugin_instance[DATA_MAX_NAME_LEN];
+ list_info_ptr_t list_info =
+ {
+ plugin_instance,
+ /* type = */ "dns_qtype_gauge"
+ };
+
+ ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-cache_rr_sets",
+ view->name);
+
+ bind_parse_generic_name_value (/* xpath = */ "cache/rrset",
+ /* callback = */ bind_xml_list_callback,
+ /* user_data = */ &list_info,
+ doc, path_ctx, current_time, DS_TYPE_GAUGE);
+ } /* }}} */
+
+ if (view->zones_num > 0)
+ bind_xml_stats_search_zones (version, doc, path_ctx, node, view,
+ current_time);
+
+ return (0);
+} /* }}} int bind_xml_stats_handle_view */
+
+static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */
+ xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time)
+{
+ xmlXPathObject *view_nodes = NULL;
+ xmlXPathContext *view_path_context;
+ int i;
+
+ view_path_context = xmlXPathNewContext (doc);
+ if (view_path_context == NULL)
+ {
+ ERROR ("bind plugin: xmlXPathNewContext failed.");
+ 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);
+ }
+
+ for (i = 0; i < view_nodes->nodesetval->nodeNr; i++)
+ {
+ xmlNode *node;
+
+ node = view_nodes->nodesetval->nodeTab[i];
+ assert (node != NULL);
+
+ view_path_context->node = node;
+
+ bind_xml_stats_handle_view (version, doc, view_path_context, node,
+ current_time);
+ }
+
+ xmlXPathFreeObject (view_nodes);
+ xmlXPathFreeContext (view_path_context);
+ return (0);
+} /* }}} int bind_xml_stats_search_views */
+
+static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */