+ rrd->rrd_value = temp;
+ cur_rrd_value = rrd->rrd_value
+ + (rrd->stat_head->ds_cnt * total_row_cnt);
+ memset(cur_rrd_value, '\0',
+ sizeof(rrd_value_t) * rrd->stat_head->ds_cnt);
+ total_row_cnt++;
+ cur_rra_def->row_cnt++;
+
+ status =
+ parse_tag_rra_database_row(doc, child, rrd, cur_rrd_value);
+ } /* if (xmlStrcmp (child->name, (const xmlChar *) "row") == 0) */
+ else {
+ rrd_set_error("parse_tag_rra_database: Unknown tag: %s",
+ child->name);
+ status = -1;
+ }
+
+ if (status != 0)
+ break;
+ } /* for (child = node->xmlChildrenNode) */
+
+ return (status);
+} /* int parse_tag_rra_database */
+
+/*
+ * Parse the <cdp_prep> block within an RRA definition
+ */
+static int parse_tag_rra_cdp_prep_ds_history(
+ xmlDoc * doc,
+ xmlNode * node,
+ cdp_prep_t *cdp_prep)
+{
+ /* Make `history_buffer' the same size as the scratch area, plus the
+ * terminating NULL byte. */
+ char history_buffer[sizeof(((cdp_prep_t *)0)->scratch) + 1];
+ char *history_ptr;
+ int status;
+ int i;
+
+ status = get_string_from_node(doc, node,
+ history_buffer, sizeof(history_buffer));
+ if (status != 0)
+ return (-1);
+
+ history_ptr = (char *) (&cdp_prep->scratch[0]);
+ for (i = 0; history_buffer[i] != '\0'; i++)
+ history_ptr[i] = (history_buffer[i] == '1') ? 1 : 0;
+
+ return (0);
+} /* int parse_tag_rra_cdp_prep_ds_history */
+
+static int parse_tag_rra_cdp_prep_ds(
+ xmlDoc * doc,
+ xmlNode * node,
+ rrd_t *rrd,
+ cdp_prep_t *cdp_prep)
+{
+ xmlNode *child;
+ int status;
+
+ memset(cdp_prep, '\0', sizeof(cdp_prep_t));
+
+ status = 0;
+ for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+ if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+ || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+ /* ignore */ ;
+ else if (xmlStrcmp(child->name, (const xmlChar *) "primary_value") ==
+ 0)
+ status =
+ get_double_from_node(doc, child,
+ &cdp_prep->scratch[CDP_primary_val].
+ u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "secondary_value")
+ == 0)
+ status =
+ get_double_from_node(doc, child,
+ &cdp_prep->scratch[CDP_secondary_val].
+ u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "intercept") == 0)
+ status = get_double_from_node(doc, child,
+ &cdp_prep->
+ scratch[CDP_hw_intercept].u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "last_intercept") ==
+ 0)
+ status =
+ get_double_from_node(doc, child,
+ &cdp_prep->
+ scratch[CDP_hw_last_intercept].u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "slope") == 0)
+ status = get_double_from_node(doc, child,
+ &cdp_prep->scratch[CDP_hw_slope].
+ u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "last_slope") == 0)
+ status = get_double_from_node(doc, child,
+ &cdp_prep->
+ scratch[CDP_hw_last_slope].u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "nan_count") == 0)
+ status = get_int_from_node(doc, child,
+ (int *) &cdp_prep->
+ scratch[CDP_null_count].u_cnt);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "last_nan_count") ==
+ 0)
+ status =
+ get_int_from_node(doc, child,
+ (int *) &cdp_prep->
+ scratch[CDP_last_null_count].u_cnt);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "seasonal") == 0)
+ status = get_double_from_node(doc, child,
+ &cdp_prep->scratch[CDP_hw_seasonal].
+ u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "last_seasonal") ==
+ 0)
+ status =
+ get_double_from_node(doc, child,
+ &cdp_prep->scratch[CDP_hw_last_seasonal].
+ u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "init_flag") == 0)
+ status = get_int_from_node(doc, child,
+ (int *) &cdp_prep->
+ scratch[CDP_init_seasonal].u_cnt);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "history") == 0)
+ status = parse_tag_rra_cdp_prep_ds_history(doc, child, cdp_prep);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0)
+ status = get_double_from_node(doc, child,
+ &cdp_prep->scratch[CDP_val].u_val);
+ else if (xmlStrcmp(child->name,
+ (const xmlChar *) "unknown_datapoints") == 0)
+ status = get_int_from_node(doc, child,
+ (int *) &cdp_prep->
+ scratch[CDP_unkn_pdp_cnt].u_cnt);
+ /*
+ * Compatibility code for 1.0.49
+ */
+ else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0) { /* {{{ */
+ unsigned int i = 0;
+ rra_def_t *rra_def = rrd->rra_def + (rrd->stat_head->rra_cnt - 1);
+
+ while (42) {
+ if (i >= ARRAY_LENGTH(cdp_prep->scratch)) {
+ status = -1;