1
1
/*****************************************************************************
2
* RRDtool 1.3.8 Copyright by Tobi Oetiker, 1997-2009
3
* This file: Copyright 2008 Florian octo Forster
4
* Distributed under the GPL
5
*****************************************************************************
6
* rrd_restore.c Contains logic to parse XML input and create an RRD file
7
*****************************************************************************
8
* $Id: rrd_restore.c 1801 2009-05-19 13:45:05Z oetiker $
2
* RRDtool 1.4.3 Copyright by Tobi Oetiker, 1997-2010
3
*****************************************************************************
4
* rrd_restore.c Contains logic to parse XML input and create an RRD file
6
* Copyright (C) 2008 Florian octo Forster (original libxml2 code)
7
* Copyright (C) 2008,2009 Tobias Oetiker
8
*****************************************************************************
9
* $Id: rrd_restore.c 2042 2010-03-22 16:05:55Z oetiker $
9
10
*************************************************************************** */
12
* This program is free software; you can redistribute it and / or modify it
13
* under the terms of the GNU General Public License as published by the Free
14
* Software Foundation; either version 2 of the License, or (t your option)
17
* This program is distributed in the hope that it will be useful, but WITHOUT
18
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22
* You should have received a copy of the GNU General Public License along
23
* with this program; if not, write to the Free Software Foundation, Inc.,
24
* 51 Franklin St, Fifth Floor, Boston, MA 02110 - 1301 USA
27
* Florian octo Forster <octo at verplant.org>
13
#include "rrd_rpncalc.h"
30
16
#include <stdlib.h>
32
17
#include <string.h>
18
#include <libxml/parser.h>
19
#include <libxml/xmlreader.h>
23
# include <unistd.h> /* for off_t */
25
typedef size_t ssize_t;
36
#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
30
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
39
32
# define open _open
40
33
# define close _close
45
#include <libxml/parser.h>
47
#include "rrd_rpncalc.h"
48
37
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof ((a)[0]))
49
39
static int opt_range_check = 0;
50
40
static int opt_force_overwrite = 0;
55
static int get_string_from_node(
65
temp0 = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
67
rrd_set_error("get_string_from_node: xmlNodeListGetString failed.");
71
begin_ptr = (char *) temp0;
72
while ((begin_ptr[0] != 0) && (isspace(begin_ptr[0])))
75
if (begin_ptr[0] == 0) {
82
while ((end_ptr[0] != 0) && (!isspace(end_ptr[0])))
86
strncpy(buffer, begin_ptr, buffer_size);
87
buffer[buffer_size - 1] = 0;
92
} /* int get_string_from_node */
94
static int get_long_from_node(
103
str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
104
if (str_ptr == NULL) {
105
rrd_set_error("get_long_from_node: xmlNodeListGetString failed.");
110
temp = strtol(str_ptr, &end_ptr, 0);
113
if (str_ptr == end_ptr) {
114
rrd_set_error("get_long_from_node: Cannot parse buffer as long: %s",
122
} /* int get_long_from_node */
124
static int get_ulong_from_node(
46
/* skip all but tags. complain if we do not get the right tag */
47
/* dept -1 causes depth to be ignored */
48
static xmlChar* get_xml_element (
49
xmlTextReaderPtr reader
52
while(xmlTextReaderRead(reader)){
55
type = xmlTextReaderNodeType(reader);
56
if (type == XML_READER_TYPE_TEXT){
58
value = xmlTextReaderValue(reader);
59
rrd_set_error("line %d: expected element but found text '%s'",
60
xmlTextReaderGetParserLineNumber(reader),value);
64
/* skip all other non-elements */
65
if (type != XML_READER_TYPE_ELEMENT && type != XML_READER_TYPE_END_ELEMENT)
68
name = xmlTextReaderName(reader);
69
if (type == XML_READER_TYPE_END_ELEMENT){
72
temp = (xmlChar*)sprintf_alloc("/%s",name);
73
temp2 = xmlStrdup(temp);
78
/* all seems well, return the happy news */
81
rrd_set_error("the xml ended while we were looking for an element");
83
} /* get_xml_element */
85
static void local_rrd_free (rrd_t *rrd)
99
static int expect_element (
100
xmlTextReaderPtr reader,
104
name = get_xml_element(reader);
107
if (xmlStrcasecmp(name,(xmlChar *)exp_name) != 0){
108
rrd_set_error("line %d: expected <%s> element but found <%s>",
109
xmlTextReaderGetParserLineNumber(reader),name,exp_name);
115
} /* expect_element */
117
static int expect_element_end (
118
xmlTextReaderPtr reader,
122
/* maybe we are already on the end element ... lets see */
123
if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT){
126
temp = xmlTextReaderName(reader);
127
temp2 = (xmlChar*)sprintf_alloc("/%s", temp);
128
name = xmlStrdup(temp2);
132
name = get_xml_element(reader);
137
if (xmlStrcasecmp(name+1,(xmlChar *)exp_name) != 0 || name[0] != '/'){
138
rrd_set_error("line %d: expected </%s> end element but found <%s>",
139
xmlTextReaderGetParserLineNumber(reader),exp_name,name);
145
} /* expect_element_end */
148
static xmlChar* get_xml_text (
149
xmlTextReaderPtr reader
152
while(xmlTextReaderRead(reader)){
158
type = xmlTextReaderNodeType(reader);
159
if (type == XML_READER_TYPE_ELEMENT){
161
name = xmlTextReaderName(reader);
162
rrd_set_error("line %d: expected a value but found a <%s> element",
163
xmlTextReaderGetParserLineNumber(reader),
169
/* trying to read text from <a></a> we end up here
170
lets return an empty string insead. This is a tad optimistic
171
since we do not check if it is actually </a> and not </b>
172
we got, but first we do not know if we expect </a> and second
173
we the whole implementation is on the optimistic side. */
174
if (type == XML_READER_TYPE_END_ELEMENT){
175
return xmlStrdup(BAD_CAST "");
178
/* skip all other non-text */
179
if (type != XML_READER_TYPE_TEXT)
182
text = xmlTextReaderValue(reader);
185
while ((begin_ptr[0] != 0) && (isspace(begin_ptr[0])))
187
if (begin_ptr[0] == 0) {
189
return xmlStrdup(BAD_CAST "");
192
while ((end_ptr[0] != 0) && (!isspace(end_ptr[0])))
196
ret = xmlStrdup(begin_ptr);
200
rrd_set_error("file ended while looking for text");
205
static int get_xml_string(
206
xmlTextReaderPtr reader,
211
str = get_xml_text(reader);
213
strncpy(value,(char *)str,max_len);
222
static int get_xml_time_t(
223
xmlTextReaderPtr reader,
228
if ((text = get_xml_text(reader)) != NULL){
230
#ifdef TIME_T_IS_32BIT
231
temp = strtol((char *)text,NULL, 0);
233
#ifdef TIME_T_IS_64BIT
234
temp = strtoll((char *)text,NULL, 0);
236
if (sizeof(time_t) == 4){
237
temp = strtol((char *)text,NULL, 0);
239
temp = strtoll((char *)text,NULL, 0);
244
rrd_set_error("ling %d: get_xml_time_t from '%s' %s",
245
xmlTextReaderGetParserLineNumber(reader),
246
text,rrd_strerror(errno));
255
} /* get_xml_time_t */
257
static int get_xml_ulong(
258
xmlTextReaderPtr reader,
127
259
unsigned long *value)
133
str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
134
if (str_ptr == NULL) {
135
rrd_set_error("get_ulong_from_node: xmlNodeListGetString failed.");
140
temp = strtoul(str_ptr, &end_ptr, 0);
143
if (str_ptr == end_ptr) {
144
rrd_set_error("get_ulong_from_node: Cannot parse buffer as unsigned long: %s",
152
} /* int get_ulong_from_node */
154
static int get_double_from_node(
264
if ((text = get_xml_text(reader)) != NULL){
266
temp = strtoul((char *)text,NULL, 0);
268
rrd_set_error("ling %d: get_xml_ulong from '%s' %s",
269
xmlTextReaderGetParserLineNumber(reader),
270
text,rrd_strerror(errno));
279
} /* get_xml_ulong */
281
static int get_xml_double(
282
xmlTextReaderPtr reader,
163
str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
164
if (str_ptr == NULL) {
165
rrd_set_error("get_double_from_node: xmlNodeListGetString failed.");
169
if (strstr(str_ptr, "NaN") != NULL)
288
if ((text = get_xml_text(reader))!= NULL){
289
if (xmlStrcasestr(text,(xmlChar *)"nan")){
294
else if (xmlStrcasestr(text,(xmlChar *)"-inf")){
299
else if (xmlStrcasestr(text,(xmlChar *)"+inf")
300
|| xmlStrcasestr(text,(xmlChar *)"inf")){
306
temp = strtod((char *)text,NULL);
308
rrd_set_error("ling %d: get_xml_double from '%s' %s",
309
xmlTextReaderGetParserLineNumber(reader),
310
text,rrd_strerror(errno));
177
temp = strtod(str_ptr, &end_ptr);
180
if (str_ptr == end_ptr) {
182
("get_double_from_node: Cannot parse buffer as double: %s",
190
} /* int get_double_from_node */
319
} /* get_xml_double */
192
322
static int value_check_range(
193
323
rrd_value_t *rrd_value,
207
337
*rrd_value = DNAN;
210
} /* int value_check_range */
340
} /* int value_check_range */
213
343
* Parse the <database> block within an RRA definition
215
346
static int parse_tag_rra_database_row(
347
xmlTextReaderPtr reader,
219
349
rrd_value_t *rrd_value)
221
351
unsigned int values_count = 0;
226
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
227
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
228
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
230
else if (xmlStrcmp(child->name, (const xmlChar *) "v") == 0) {
231
if (values_count < rrd->stat_head->ds_cnt) {
233
get_double_from_node(doc, child,
234
rrd_value + values_count);
236
value_check_range(rrd_value + values_count,
237
rrd->ds_def + values_count);
242
rrd_set_error("parse_tag_rra_database_row: Unknown tag: %s",
355
for (values_count = 0;values_count < rrd->stat_head->ds_cnt;values_count++){
356
if (expect_element(reader,"v") == 0){
357
status = get_xml_double(reader,rrd_value + values_count);
359
value_check_range(rrd_value + values_count,
360
rrd->ds_def + values_count);
365
if (expect_element(reader,"/v") == -1){
249
} /* for (child = node->xmlChildrenNode) */
251
if (values_count != rrd->stat_head->ds_cnt) {
252
rrd_set_error("parse_tag_rra_database_row: Row has %u values "
253
"and RRD has %lu data sources.",
254
values_count, rrd->stat_head->ds_cnt);
259
370
} /* int parse_tag_rra_database_row */
261
372
static int parse_tag_rra_database(
373
xmlTextReaderPtr reader,
266
376
rra_def_t *cur_rra_def;
267
377
unsigned int total_row_cnt;
272
382
total_row_cnt = 0;
273
383
for (i = 0; i < (((int) rrd->stat_head->rra_cnt) - 1); i++)
323
437
* Parse the <cdp_prep> block within an RRA definition
325
439
static int parse_tag_rra_cdp_prep_ds_history(
440
xmlTextReaderPtr reader,
328
441
cdp_prep_t *cdp_prep)
330
443
/* Make `history_buffer' the same size as the scratch area, plus the
331
444
* terminating NULL byte. */
332
char history_buffer[sizeof(((cdp_prep_t *)0)->scratch) + 1];
333
446
char *history_ptr;
337
status = get_string_from_node(doc, node,
338
history_buffer, sizeof(history_buffer));
342
history_ptr = (char *) (&cdp_prep->scratch[0]);
343
for (i = 0; history_buffer[i] != '\0'; i++)
344
history_ptr[i] = (history_buffer[i] == '1') ? 1 : 0;
347
} /* int parse_tag_rra_cdp_prep_ds_history */
448
if ((history = get_xml_text(reader)) != NULL){
449
history_ptr = (char *) (&cdp_prep->scratch[0]);
450
for (i = 0; history[i] != '\0'; i++)
451
history_ptr[i] = (history[i] == '1') ? 1 : 0;
456
} /* int parse_tag_rra_cdp_prep_ds_history */
349
458
static int parse_tag_rra_cdp_prep_ds(
459
xmlTextReaderPtr reader,
353
461
cdp_prep_t *cdp_prep)
358
465
memset(cdp_prep, '\0', sizeof(cdp_prep_t));
361
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
362
if (atoi(rrd->stat_head->version) == 1) {
363
cdp_prep->scratch[CDP_primary_val].u_val = 0.0;
364
cdp_prep->scratch[CDP_secondary_val].u_val = 0.0;
366
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
367
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
369
else if (xmlStrcmp(child->name, (const xmlChar *) "primary_value") ==
372
get_double_from_node(doc, child,
373
&cdp_prep->scratch[CDP_primary_val].
375
else if (xmlStrcmp(child->name, (const xmlChar *) "secondary_value")
378
get_double_from_node(doc, child,
379
&cdp_prep->scratch[CDP_secondary_val].
381
else if (xmlStrcmp(child->name, (const xmlChar *) "intercept") == 0)
382
status = get_double_from_node(doc, child,
469
if (atoi(rrd->stat_head->version) == 1) {
470
cdp_prep->scratch[CDP_primary_val].u_val = 0.0;
471
cdp_prep->scratch[CDP_secondary_val].u_val = 0.0;
474
while ((element = get_xml_element(reader)) != NULL){
475
if (xmlStrcasecmp(element, (const xmlChar *) "primary_value") == 0)
477
get_xml_double(reader,&cdp_prep->scratch[CDP_primary_val].u_val);
478
else if (xmlStrcasecmp(element, (const xmlChar *) "secondary_value") == 0)
480
get_xml_double(reader,&cdp_prep->scratch[CDP_secondary_val].u_val);
481
else if (xmlStrcasecmp(element, (const xmlChar *) "intercept") == 0)
482
status = get_xml_double(reader,
384
484
scratch[CDP_hw_intercept].u_val);
385
else if (xmlStrcmp(child->name, (const xmlChar *) "last_intercept") ==
485
else if (xmlStrcasecmp(element, (const xmlChar *) "last_intercept") ==
388
get_double_from_node(doc, child,
488
get_xml_double(reader,
390
490
scratch[CDP_hw_last_intercept].u_val);
391
else if (xmlStrcmp(child->name, (const xmlChar *) "slope") == 0)
392
status = get_double_from_node(doc, child,
393
&cdp_prep->scratch[CDP_hw_slope].
395
else if (xmlStrcmp(child->name, (const xmlChar *) "last_slope") == 0)
396
status = get_double_from_node(doc, child,
398
scratch[CDP_hw_last_slope].u_val);
399
else if (xmlStrcmp(child->name, (const xmlChar *) "nan_count") == 0)
400
status = get_ulong_from_node(doc, child,
402
scratch[CDP_null_count].u_cnt);
403
else if (xmlStrcmp(child->name, (const xmlChar *) "last_nan_count") ==
406
get_ulong_from_node(doc, child,
491
else if (xmlStrcasecmp(element, (const xmlChar *) "slope") == 0)
492
status = get_xml_double(reader,
493
&cdp_prep->scratch[CDP_hw_slope].
495
else if (xmlStrcasecmp(element, (const xmlChar *) "last_slope") == 0)
496
status = get_xml_double(reader,
498
scratch[CDP_hw_last_slope].u_val);
499
else if (xmlStrcasecmp(element, (const xmlChar *) "nan_count") == 0)
500
status = get_xml_ulong(reader,
408
scratch[CDP_last_null_count].u_cnt);
409
else if (xmlStrcmp(child->name, (const xmlChar *) "seasonal") == 0)
410
status = get_double_from_node(doc, child,
411
&cdp_prep->scratch[CDP_hw_seasonal].
413
else if (xmlStrcmp(child->name, (const xmlChar *) "last_seasonal") ==
416
get_double_from_node(doc, child,
502
scratch[CDP_null_count].u_cnt);
503
else if (xmlStrcasecmp(element, (const xmlChar *) "last_nan_count") ==
506
get_xml_ulong(reader,
508
scratch[CDP_last_null_count].u_cnt);
509
else if (xmlStrcasecmp(element, (const xmlChar *) "seasonal") == 0)
510
status = get_xml_double(reader,
511
&cdp_prep->scratch[CDP_hw_seasonal].
513
else if (xmlStrcasecmp(element, (const xmlChar *) "last_seasonal") ==
516
get_xml_double(reader,
417
517
&cdp_prep->scratch[CDP_hw_last_seasonal].
419
else if (xmlStrcmp(child->name, (const xmlChar *) "init_flag") == 0)
420
status = get_ulong_from_node(doc, child,
519
else if (xmlStrcasecmp(element, (const xmlChar *) "init_flag") == 0)
520
status = get_xml_ulong(reader,
422
522
scratch[CDP_init_seasonal].u_cnt);
423
else if (xmlStrcmp(child->name, (const xmlChar *) "history") == 0)
424
status = parse_tag_rra_cdp_prep_ds_history(doc, child, cdp_prep);
425
else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0)
426
status = get_double_from_node(doc, child,
427
&cdp_prep->scratch[CDP_val].u_val);
428
else if (xmlStrcmp(child->name,
523
else if (xmlStrcasecmp(element, (const xmlChar *) "history") == 0)
524
status = parse_tag_rra_cdp_prep_ds_history(reader, cdp_prep);
525
else if (xmlStrcasecmp(element, (const xmlChar *) "value") == 0)
526
status = get_xml_double(reader,
527
&cdp_prep->scratch[CDP_val].u_val);
528
else if (xmlStrcasecmp(element,
429
529
(const xmlChar *) "unknown_datapoints") == 0)
430
status = get_ulong_from_node(doc, child,
530
status = get_xml_ulong(reader,
432
532
scratch[CDP_unkn_pdp_cnt].u_cnt);
533
else if (xmlStrcasecmp(element,
534
(const xmlChar *) "/ds") == 0){
434
539
rrd_set_error("parse_tag_rra_cdp_prep: Unknown tag: %s",
549
status = expect_element_end(reader,(char *)element);
444
555
} /* int parse_tag_rra_cdp_prep_ds */
446
557
static int parse_tag_rra_cdp_prep(
558
xmlTextReaderPtr reader,
450
560
cdp_prep_t *cdp_prep)
455
unsigned int ds_count = 0;
564
unsigned int ds_count;
458
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
459
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
460
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
462
else if (xmlStrcmp(child->name, (const xmlChar *) "ds") == 0) {
463
if (ds_count >= rrd->stat_head->ds_cnt)
466
status = parse_tag_rra_cdp_prep_ds(doc, child, rrd,
467
cdp_prep + ds_count);
567
for ( ds_count = 0; ds_count < rrd->stat_head->ds_cnt;ds_count++){
568
if (expect_element(reader,"ds") == 0) {
569
status = parse_tag_rra_cdp_prep_ds(reader, rrd,
570
cdp_prep + ds_count);
471
rrd_set_error("parse_tag_rra_cdp_prep: Unknown tag: %s",
480
if (ds_count != rrd->stat_head->ds_cnt) {
481
rrd_set_error("parse_tag_rra_cdp_prep: There are %i data sources in "
482
"the RRD file, but %i in this cdp_prep block!",
483
(int) rrd->stat_head->ds_cnt, ds_count);
579
status = expect_element(reader,"/cdp_prep");
488
581
} /* int parse_tag_rra_cdp_prep */
491
584
* Parse the <params> block within an RRA definition
493
586
static int parse_tag_rra_params(
587
xmlTextReaderPtr reader,
496
588
rra_def_t *rra_def)
502
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
503
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
504
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
594
while ((element = get_xml_element(reader)) != NULL){
507
596
* Parameters for CF_HWPREDICT
509
else if (xmlStrcmp(child->name, (const xmlChar *) "hw_alpha") == 0)
510
status = get_double_from_node(doc, child,
598
if (xmlStrcasecmp(element, (const xmlChar *) "hw_alpha") == 0)
599
status = get_xml_double(reader,
511
600
&rra_def->par[RRA_hw_alpha].u_val);
512
else if (xmlStrcmp(child->name, (const xmlChar *) "hw_beta") == 0)
513
status = get_double_from_node(doc, child,
601
else if (xmlStrcasecmp(element, (const xmlChar *) "hw_beta") == 0)
602
status = get_xml_double(reader,
514
603
&rra_def->par[RRA_hw_beta].u_val);
515
else if (xmlStrcmp(child->name,
604
else if (xmlStrcasecmp(element,
516
605
(const xmlChar *) "dependent_rra_idx") == 0)
517
status = get_ulong_from_node(doc, child,
606
status = get_xml_ulong(reader,
519
608
par[RRA_dependent_rra_idx].u_cnt);
521
610
* Parameters for CF_SEASONAL and CF_DEVSEASONAL
523
else if (xmlStrcmp(child->name, (const xmlChar *) "seasonal_gamma") ==
612
else if (xmlStrcasecmp(element, (const xmlChar *) "seasonal_gamma") ==
526
get_double_from_node(doc, child,
615
get_xml_double(reader,
527
616
&rra_def->par[RRA_seasonal_gamma].u_val);
529
(child->name, (const xmlChar *) "seasonal_smooth_idx") == 0)
617
else if (xmlStrcasecmp
618
(element, (const xmlChar *) "seasonal_smooth_idx") == 0)
531
get_ulong_from_node(doc, child,
620
get_xml_ulong(reader,
533
622
par[RRA_seasonal_smooth_idx].u_cnt);
534
else if (xmlStrcmp(child->name, (const xmlChar *) "smoothing_window")
623
else if (xmlStrcasecmp(element, (const xmlChar *) "smoothing_window")
537
get_double_from_node(doc, child,
626
get_xml_double(reader,
539
628
par[RRA_seasonal_smoothing_window].
543
632
* Parameters for CF_FAILURES
545
else if (xmlStrcmp(child->name, (const xmlChar *) "delta_pos") == 0)
546
status = get_double_from_node(doc, child,
634
else if (xmlStrcasecmp(element, (const xmlChar *) "delta_pos") == 0)
635
status = get_xml_double(reader,
547
636
&rra_def->par[RRA_delta_pos].u_val);
548
else if (xmlStrcmp(child->name, (const xmlChar *) "delta_neg") == 0)
549
status = get_double_from_node(doc, child,
637
else if (xmlStrcasecmp(element, (const xmlChar *) "delta_neg") == 0)
638
status = get_xml_double(reader,
550
639
&rra_def->par[RRA_delta_neg].u_val);
551
else if (xmlStrcmp(child->name, (const xmlChar *) "window_len") == 0)
552
status = get_ulong_from_node(doc, child,
640
else if (xmlStrcasecmp(element, (const xmlChar *) "window_len") == 0)
641
status = get_xml_ulong(reader,
553
642
&rra_def->par[RRA_window_len].
555
else if (xmlStrcmp(child->name, (const xmlChar *) "failure_threshold")
644
else if (xmlStrcasecmp(element, (const xmlChar *) "failure_threshold")
558
get_ulong_from_node(doc, child,
647
get_xml_ulong(reader,
560
649
par[RRA_failure_threshold].u_cnt);
562
651
* Parameters for CF_AVERAGE, CF_MAXIMUM, CF_MINIMUM, and CF_LAST
564
else if (xmlStrcmp(child->name, (const xmlChar *) "xff") == 0)
565
status = get_double_from_node(doc, child,
653
else if (xmlStrcasecmp(element, (const xmlChar *) "xff") == 0)
654
status = get_xml_double(reader,
566
655
&rra_def->par[RRA_cdp_xff_val].
569
658
* Compatibility code for 1.0.49
571
else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0) { /* {{{ */
660
else if (xmlStrcasecmp(element, (const xmlChar *) "value") == 0) { /* {{{ */
572
661
unsigned int i = 0;
575
if (i >= ARRAY_LENGTH(rra_def->par)) {
663
for (i=0;i<ARRAY_LENGTH(rra_def->par);i++){
580
664
if ((i == RRA_dependent_rra_idx)
581
665
|| (i == RRA_seasonal_smooth_idx)
582
666
|| (i == RRA_failure_threshold))
583
status = get_ulong_from_node(doc, child,
667
status = get_xml_ulong(reader,
584
668
&rra_def->par[i].
587
status = get_double_from_node(doc, child,
671
status = get_xml_double(reader,
588
672
&rra_def->par[i].u_val);
593
/* When this loops exits (sucessfully) `child' points to the last
594
* `value' tag in the list. */
595
if ((child->next == NULL)
596
|| (xmlStrcmp(child->name, (const xmlChar *) "value") !=
676
if ( i-1 < ARRAY_LENGTH(rra_def->par)){
677
status = expect_element(reader,"/value");
679
status = expect_element(reader,"value");
687
else if (xmlStrcasecmp(element,(const xmlChar *) "/params") == 0){
605
rrd_set_error("parse_tag_rra_params: Unknown tag: %s",
692
rrd_set_error("line %d: parse_tag_rra_params: Unknown tag: %s",
693
xmlTextReaderGetParserLineNumber(reader),element);
696
status = expect_element_end(reader,(char *)element);
615
702
} /* int parse_tag_rra_params */
705
790
rrd->stat_head->rra_cnt++;
708
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
709
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
710
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
712
else if (xmlStrcmp(child->name, (const xmlChar *) "cf") == 0)
713
status = parse_tag_rra_cf(doc, child, cur_rra_def);
714
else if (xmlStrcmp(child->name, (const xmlChar *) "pdp_per_row") == 0)
715
status = get_ulong_from_node(doc, child,
793
while ((element = get_xml_element(reader)) != NULL){
794
if (xmlStrcasecmp(element, (const xmlChar *) "cf") == 0)
795
status = parse_tag_rra_cf(reader, cur_rra_def);
796
else if (xmlStrcasecmp(element, (const xmlChar *) "pdp_per_row") == 0)
797
status = get_xml_ulong(reader,
716
798
&cur_rra_def->pdp_cnt);
717
799
else if (atoi(rrd->stat_head->version) == 1
718
&& xmlStrcmp(child->name, (const xmlChar *) "xff") == 0)
719
status = get_double_from_node(doc, child,
800
&& xmlStrcasecmp(element, (const xmlChar *) "xff") == 0)
801
status = get_xml_double(reader,
720
802
(double *) &cur_rra_def->
721
803
par[RRA_cdp_xff_val].u_val);
722
804
else if (atoi(rrd->stat_head->version) >= 2
723
&& xmlStrcmp(child->name, (const xmlChar *) "params") == 0)
724
status = parse_tag_rra_params(doc, child, cur_rra_def);
725
else if (xmlStrcmp(child->name, (const xmlChar *) "cdp_prep") == 0)
726
status = parse_tag_rra_cdp_prep(doc, child, rrd, cur_cdp_prep);
727
else if (xmlStrcmp(child->name, (const xmlChar *) "database") == 0)
728
status = parse_tag_rra_database(doc, child, rrd);
730
rrd_set_error("parse_tag_rra: Unknown tag: %s", child->name);
805
&& xmlStrcasecmp(element, (const xmlChar *) "params") == 0){
807
status = parse_tag_rra_params(reader, cur_rra_def);
813
else if (xmlStrcasecmp(element, (const xmlChar *) "cdp_prep") == 0){
815
status = parse_tag_rra_cdp_prep(reader, rrd, cur_cdp_prep);
821
else if (xmlStrcasecmp(element, (const xmlChar *) "database") == 0){
823
status = parse_tag_rra_database(reader, rrd);
829
else if (xmlStrcasecmp(element,(const xmlChar *) "/rra") == 0){
834
rrd_set_error("line %d: parse_tag_rra: Unknown tag: %s",
835
xmlTextReaderGetParserLineNumber(reader), element);
842
status = expect_element_end(reader,(char *)element);
738
848
/* Set the RRA pointer to a random location */
740
cur_rra_ptr->cur_row = rand() % cur_rra_def->row_cnt;
742
cur_rra_ptr->cur_row = random() % cur_rra_def->row_cnt;
849
cur_rra_ptr->cur_row = rrd_random() % cur_rra_def->row_cnt;
746
852
} /* int parse_tag_rra */
847
953
rrd->stat_head->ds_cnt++;
850
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
851
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
852
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
854
else if (xmlStrcmp(child->name, (const xmlChar *) "name") == 0)
855
status = get_string_from_node(doc, child,
857
sizeof(cur_ds_def->ds_nam));
858
else if (xmlStrcmp(child->name, (const xmlChar *) "type") == 0)
859
status = parse_tag_ds_type(doc, child, cur_ds_def);
860
else if (xmlStrcmp(child->name,
956
while ((element = get_xml_element(reader)) != NULL){
957
if (xmlStrcasecmp(element, (const xmlChar *) "name") == 0){
958
status = get_xml_string(reader,cur_ds_def->ds_nam,sizeof(cur_ds_def->ds_nam));
960
else if (xmlStrcasecmp(element, (const xmlChar *) "type") == 0)
961
status = parse_tag_ds_type(reader, cur_ds_def);
962
else if (xmlStrcasecmp(element,
861
963
(const xmlChar *) "minimal_heartbeat") == 0)
862
status = get_ulong_from_node(doc, child,
964
status = get_xml_ulong(reader,
863
965
&cur_ds_def->par[DS_mrhb_cnt].
865
else if (xmlStrcmp(child->name, (const xmlChar *) "min") == 0)
866
status = get_double_from_node(doc, child,
967
else if (xmlStrcasecmp(element, (const xmlChar *) "min") == 0)
968
status = get_xml_double(reader,
867
969
&cur_ds_def->par[DS_min_val].u_val);
868
else if (xmlStrcmp(child->name, (const xmlChar *) "max") == 0)
869
status = get_double_from_node(doc, child,
970
else if (xmlStrcasecmp(element, (const xmlChar *) "max") == 0)
971
status = get_xml_double(reader,
870
972
&cur_ds_def->par[DS_max_val].u_val);
871
else if (xmlStrcmp(child->name, (const xmlChar *) "cdef") == 0)
872
status = parse_tag_ds_cdef(doc, child, rrd);
873
else if (xmlStrcmp(child->name, (const xmlChar *) "last_ds") == 0)
874
status = get_string_from_node(doc, child,
973
else if (xmlStrcasecmp(element, (const xmlChar *) "cdef") == 0)
974
status = parse_tag_ds_cdef(reader, rrd);
975
else if (xmlStrcasecmp(element, (const xmlChar *) "last_ds") == 0)
976
status = get_xml_string(reader,
875
977
cur_pdp_prep->last_ds,
876
978
sizeof(cur_pdp_prep->last_ds));
877
else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0)
878
status = get_double_from_node(doc, child,
979
else if (xmlStrcasecmp(element, (const xmlChar *) "value") == 0)
980
status = get_xml_double(reader,
879
981
&cur_pdp_prep->scratch[PDP_val].
881
else if (xmlStrcmp(child->name, (const xmlChar *) "unknown_sec") == 0)
882
status = get_ulong_from_node(doc, child,
983
else if (xmlStrcasecmp(element, (const xmlChar *) "unknown_sec") == 0)
984
status = get_xml_ulong(reader,
884
986
scratch[PDP_unkn_sec_cnt].u_cnt);
987
else if (xmlStrcasecmp(element, (const xmlChar *) "/ds") == 0) {
886
rrd_set_error("parse_tag_ds: Unknown tag: %s", child->name);
992
rrd_set_error("parse_tag_ds: Unknown tag: %s", element);
999
status = expect_element_end(reader,(char *)element);
890
1001
if (status != 0)
894
1005
return (status);
895
1006
} /* int parse_tag_ds */
898
1009
* Parse root nodes
900
1011
static int parse_tag_rrd(
1012
xmlTextReaderPtr reader,
909
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
910
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
911
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
913
else if (xmlStrcmp(child->name, (const xmlChar *) "version") == 0)
914
status = get_string_from_node(doc, child,
1019
while ((element = get_xml_element(reader)) != NULL ){
1020
if (xmlStrcasecmp(element, (const xmlChar *) "version") == 0)
1021
status = get_xml_string(reader,
915
1022
rrd->stat_head->version,
916
1023
sizeof(rrd->stat_head->version));
917
else if (xmlStrcmp(child->name, (const xmlChar *) "step") == 0)
918
status = get_ulong_from_node(doc, child,
1024
else if (xmlStrcasecmp(element, (const xmlChar *) "step") == 0)
1025
status = get_xml_ulong(reader,
919
1026
&rrd->stat_head->pdp_step);
920
else if (xmlStrcmp(child->name, (const xmlChar *) "lastupdate") == 0)
921
status = get_long_from_node(doc, child,
922
&rrd->live_head->last_up);
923
else if (xmlStrcmp(child->name, (const xmlChar *) "ds") == 0)
924
status = parse_tag_ds(doc, child, rrd);
925
else if (xmlStrcmp(child->name, (const xmlChar *) "rra") == 0)
926
status = parse_tag_rra(doc, child, rrd);
1027
else if (xmlStrcasecmp(element, (const xmlChar *) "lastupdate") == 0) {
1028
status = get_xml_time_t(reader, &rrd->live_head->last_up);
1030
else if (xmlStrcasecmp(element, (const xmlChar *) "ds") == 0){
1032
status = parse_tag_ds(reader, rrd);
1033
/* as we come back the </ds> tag is already gone */
1039
else if (xmlStrcasecmp(element, (const xmlChar *) "rra") == 0){
1041
status = parse_tag_rra(reader, rrd);
1047
else if (xmlStrcasecmp(element, (const xmlChar *) "/rrd") == 0) {
928
rrd_set_error("parse_tag_rrd: Unknown tag: %s", child->name);
1052
rrd_set_error("parse_tag_rrd: Unknown tag: %s", element);
1060
status = expect_element_end(reader,(char *)element);
932
1062
if (status != 0)
936
1065
return (status);
937
1066
} /* int parse_tag_rrd */
939
1068
static rrd_t *parse_file(
940
1069
const char *filename)
1071
xmlTextReaderPtr reader;
948
doc = xmlParseFile(filename);
950
rrd_set_error("Document not parsed successfully.");
954
cur = xmlDocGetRootElement(doc);
956
rrd_set_error("Document is empty.");
961
if (xmlStrcmp(cur->name, (const xmlChar *) "rrd") != 0) {
963
("Document of the wrong type, root node is not \"rrd\".");
1076
reader = xmlNewTextReaderFilename(filename);
1077
if (reader == NULL) {
1078
rrd_set_error("Could not create xml reader for: %s",filename);
1082
if (expect_element(reader,"rrd") != 0) {
1083
xmlFreeTextReader(reader);
968
1087
rrd = (rrd_t *) malloc(sizeof(rrd_t));
969
1088
if (rrd == NULL) {
970
1089
rrd_set_error("parse_file: malloc failed.");
1090
xmlFreeTextReader(reader);
974
1093
memset(rrd, '\0', sizeof(rrd_t));