+ rrd->pdp_prep = temp;
+ cur_pdp_prep = rrd->pdp_prep + rrd->stat_head->ds_cnt;
+ memset(cur_pdp_prep, '\0', sizeof(pdp_prep_t));
+ } /* }}} */
+
+ /* All allocations successful, let's increment the number of DSes. */
+ rrd->stat_head->ds_cnt++;
+
+ 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 *) "name") == 0)
+ status = get_string_from_node(doc, child,
+ cur_ds_def->ds_nam,
+ sizeof(cur_ds_def->ds_nam));
+ else if (xmlStrcmp(child->name, (const xmlChar *) "type") == 0)
+ status = parse_tag_ds_type(doc, child, cur_ds_def);
+ else if (xmlStrcmp(child->name,
+ (const xmlChar *) "minimal_heartbeat") == 0)
+ status = get_int_from_node(doc, child,
+ (int *) &cur_ds_def->par[DS_mrhb_cnt].
+ u_cnt);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "min") == 0)
+ status = get_double_from_node(doc, child,
+ &cur_ds_def->par[DS_min_val].u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "max") == 0)
+ status = get_double_from_node(doc, child,
+ &cur_ds_def->par[DS_max_val].u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "cdef") == 0)
+ status = parse_tag_ds_cdef(doc, child, rrd);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "last_ds") == 0)
+ status = get_string_from_node(doc, child,
+ cur_pdp_prep->last_ds,
+ sizeof(cur_pdp_prep->last_ds));
+ else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0)
+ status = get_double_from_node(doc, child,
+ &cur_pdp_prep->scratch[PDP_val].
+ u_val);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "unknown_sec") == 0)
+ status = get_int_from_node(doc, child,
+ (int *) &cur_pdp_prep->
+ scratch[PDP_unkn_sec_cnt].u_cnt);
+ else {
+ rrd_set_error("parse_tag_ds: Unknown tag: %s", child->name);
+ status = -1;
+ }
+
+ if (status != 0)
+ break;
+ }
+
+ return (status);
+} /* int parse_tag_ds */
+
+/*
+ * Parse root nodes
+ */
+static int parse_tag_rrd(
+ xmlDoc * doc,
+ xmlNode * node,
+ rrd_t *rrd)
+{
+ xmlNode *child;
+ int status;
+
+ 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 *) "version") == 0)
+ status = get_string_from_node(doc, child,
+ rrd->stat_head->version,
+ sizeof(rrd->stat_head->version));
+ else if (xmlStrcmp(child->name, (const xmlChar *) "step") == 0)
+ status = get_int_from_node(doc, child,
+ (int *) &rrd->stat_head->pdp_step);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "lastupdate") == 0)
+ status = get_int_from_node(doc, child,
+ (int *) &rrd->live_head->last_up);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "ds") == 0)
+ status = parse_tag_ds(doc, child, rrd);
+ else if (xmlStrcmp(child->name, (const xmlChar *) "rra") == 0)
+ status = parse_tag_rra(doc, child, rrd);
+ else {
+ rrd_set_error("parse_tag_rrd: Unknown tag: %s", child->name);
+ status = -1;
+ }
+
+ if (status != 0)
+ break;
+ }
+
+ return (status);
+} /* int parse_tag_rrd */
+
+static rrd_t *parse_file(
+ const char *filename)
+{
+ xmlDoc *doc;
+ xmlNode *cur;
+ int status;
+
+ rrd_t *rrd;
+
+ doc = xmlParseFile(filename);
+ if (doc == NULL) {
+ rrd_set_error("Document not parsed successfully.");
+ return (NULL);
+ }
+
+ cur = xmlDocGetRootElement(doc);
+ if (cur == NULL) {
+ rrd_set_error("Document is empty.");
+ xmlFreeDoc(doc);
+ return (NULL);
+ }
+
+ if (xmlStrcmp(cur->name, (const xmlChar *) "rrd") != 0) {
+ rrd_set_error
+ ("Document of the wrong type, root node is not \"rrd\".");
+ xmlFreeDoc(doc);
+ return (NULL);
+ }
+
+ rrd = (rrd_t *) malloc(sizeof(rrd_t));
+ if (rrd == NULL) {
+ rrd_set_error("parse_file: malloc failed.");
+ xmlFreeDoc(doc);
+ return (NULL);
+ }
+ memset(rrd, '\0', sizeof(rrd_t));
+
+ rrd->stat_head = (stat_head_t *) malloc(sizeof(stat_head_t));
+ if (rrd->stat_head == NULL) {
+ rrd_set_error("parse_tag_rrd: malloc failed.");
+ xmlFreeDoc(doc);
+ free(rrd);
+ return (NULL);
+ }
+ memset(rrd->stat_head, '\0', sizeof(stat_head_t));
+
+ strncpy(rrd->stat_head->cookie, "RRD", sizeof(rrd->stat_head->cookie));
+ rrd->stat_head->float_cookie = FLOAT_COOKIE;
+
+ rrd->live_head = (live_head_t *) malloc(sizeof(live_head_t));
+ if (rrd->live_head == NULL) {
+ rrd_set_error("parse_tag_rrd: malloc failed.");
+ xmlFreeDoc(doc);
+ free(rrd->stat_head);
+ free(rrd);
+ return (NULL);
+ }
+ memset(rrd->live_head, '\0', sizeof(live_head_t));
+
+ status = parse_tag_rrd(doc, cur, rrd);
+
+ xmlFreeDoc(doc);
+ if (status != 0) {
+ rrd_free(rrd);
+ rrd = NULL;