diff --git a/src/rrd_restore.c b/src/rrd_restore.c
index f8086afc88cb9742665d8a8df29dc986a17f830e..ef524b2ed9fc663b296bc49e6346f4ff6da79045 100644 (file)
--- a/src/rrd_restore.c
+++ b/src/rrd_restore.c
/*****************************************************************************
- * RRDtool 1.3rc2 Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3.8 Copyright by Tobi Oetiker, 1997-2009
* This file: Copyright 2008 Florian octo Forster
* Distributed under the GPL
*****************************************************************************
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#include <unistd.h>
#include <fcntl.h>
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+
+#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#include <math.h>
# include <io.h>
# define open _open
# define close _close
+#else
+# include <unistd.h>
#endif
+
#include <libxml/parser.h>
#include "rrd_tool.h"
#include "rrd_rpncalc.h"
return (0);
} /* int get_string_from_node */
-static int get_int_from_node(
+static int get_long_from_node(
xmlDoc * doc,
xmlNode * node,
- int *value)
+ long *value)
{
- int temp;
+ long temp;
char *str_ptr;
char *end_ptr;
str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (str_ptr == NULL) {
- rrd_set_error("get_int_from_node: xmlNodeListGetString failed.");
+ rrd_set_error("get_long_from_node: xmlNodeListGetString failed.");
return (-1);
}
xmlFree(str_ptr);
if (str_ptr == end_ptr) {
- rrd_set_error("get_int_from_node: Cannot parse buffer as int: %s",
+ rrd_set_error("get_long_from_node: Cannot parse buffer as long: %s",
+ str_ptr);
+ return (-1);
+ }
+
+ *value = temp;
+
+ return (0);
+} /* int get_long_from_node */
+
+static int get_ulong_from_node(
+ xmlDoc * doc,
+ xmlNode * node,
+ unsigned long *value)
+{
+ unsigned long temp;
+ char *str_ptr;
+ char *end_ptr;
+
+ str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (str_ptr == NULL) {
+ rrd_set_error("get_ulong_from_node: xmlNodeListGetString failed.");
+ return (-1);
+ }
+
+ end_ptr = NULL;
+ temp = strtoul(str_ptr, &end_ptr, 0);
+ xmlFree(str_ptr);
+
+ if (str_ptr == end_ptr) {
+ rrd_set_error("get_ulong_from_node: Cannot parse buffer as unsigned long: %s",
str_ptr);
return (-1);
}
*value = temp;
return (0);
-} /* int get_int_from_node */
+} /* int get_ulong_from_node */
+
+static int get_long_long_from_node(
+ xmlDoc * doc,
+ xmlNode * node,
+ long long *value)
+{
+ long long temp;
+ char *str_ptr;
+ char *end_ptr;
+
+ str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+ if (str_ptr == NULL) {
+ rrd_set_error("get_ulong_from_node: xmlNodeListGetString failed.");
+ return (-1);
+ }
+
+ end_ptr = NULL;
+ temp = strtoll(str_ptr, &end_ptr, 0);
+ xmlFree(str_ptr);
+
+ if (str_ptr == end_ptr) {
+ rrd_set_error("get_long_long_from_node: Cannot parse buffer as unsigned long long: %s",
+ str_ptr);
+ return (-1);
+ }
+
+ *value = temp;
+
+ return (0);
+} /* int get_ulong_from_node */
static int get_double_from_node(
xmlDoc * doc,
return (-1);
}
+ if (strstr(str_ptr, "NaN") != NULL)
+ {
+ *value = DNAN;
+ xmlFree(str_ptr);
+ return 0;
+ }
+
end_ptr = NULL;
temp = strtod(str_ptr, &end_ptr);
xmlFree(str_ptr);
if (((!isnan(min)) && (*rrd_value < min))
|| ((!isnan(max)) && (*rrd_value > max)))
- *rrd_value = NAN;
+ *rrd_value = DNAN;
return (0);
} /* int value_check_range */
status = 0;
for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+ if (atoi(rrd->stat_head->version) == 1) {
+ cdp_prep->scratch[CDP_primary_val].u_val = 0.0;
+ cdp_prep->scratch[CDP_secondary_val].u_val = 0.0;
+ }
if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
|| (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
/* ignore */ ;
&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->
+ status = get_ulong_from_node(doc, child,
+ &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->
+ get_ulong_from_node(doc, child,
+ &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_last_seasonal].
u_val);
else if (xmlStrcmp(child->name, (const xmlChar *) "init_flag") == 0)
- status = get_int_from_node(doc, child,
- (int *) &cdp_prep->
+ status = get_ulong_from_node(doc, child,
+ &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);
&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->
+ status = get_ulong_from_node(doc, child,
+ &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;
- break;
- }
-
- if ((cf_conv(rra_def->cf_nam) == CF_FAILURES)
- || (i == CDP_unkn_pdp_cnt)
- || (i == CDP_null_count)
- || (i == CDP_last_null_count))
- status = get_int_from_node(doc, child,
- (int *) &cdp_prep->scratch[i].
- u_cnt);
- else
- status = get_double_from_node(doc, child,
- &cdp_prep->scratch[i].
- u_val);
-
- if (status != 0)
- break;
-
- /* When this loops exits (sucessfully) `child' points to the last
- * `value' tag in the list. */
- if ((child->next == NULL)
- || (xmlStrcmp(child->name, (const xmlChar *) "value") !=
- 0))
- break;
-
- child = child->next;
- i++;
- }
- } /* }}} */
else {
rrd_set_error("parse_tag_rra_cdp_prep: Unknown tag: %s",
child->name);
&rra_def->par[RRA_hw_beta].u_val);
else if (xmlStrcmp(child->name,
(const xmlChar *) "dependent_rra_idx") == 0)
- status = get_int_from_node(doc, child,
- (int *) &rra_def->
+ status = get_ulong_from_node(doc, child,
+ &rra_def->
par[RRA_dependent_rra_idx].u_cnt);
/*
* Parameters for CF_SEASONAL and CF_DEVSEASONAL
else if (xmlStrcmp
(child->name, (const xmlChar *) "seasonal_smooth_idx") == 0)
status =
- get_int_from_node(doc, child,
- (int *) &rra_def->
+ get_ulong_from_node(doc, child,
+ &rra_def->
par[RRA_seasonal_smooth_idx].u_cnt);
else if (xmlStrcmp(child->name, (const xmlChar *) "smoothing_window")
== 0)
status = get_double_from_node(doc, child,
&rra_def->par[RRA_delta_neg].u_val);
else if (xmlStrcmp(child->name, (const xmlChar *) "window_len") == 0)
- status = get_int_from_node(doc, child,
- (int *) &rra_def->par[RRA_window_len].
+ status = get_ulong_from_node(doc, child,
+ &rra_def->par[RRA_window_len].
u_cnt);
else if (xmlStrcmp(child->name, (const xmlChar *) "failure_threshold")
== 0)
status =
- get_int_from_node(doc, child,
- (int *) &rra_def->
+ get_ulong_from_node(doc, child,
+ &rra_def->
par[RRA_failure_threshold].u_cnt);
/*
* Parameters for CF_AVERAGE, CF_MAXIMUM, CF_MINIMUM, and CF_LAST
if ((i == RRA_dependent_rra_idx)
|| (i == RRA_seasonal_smooth_idx)
|| (i == RRA_failure_threshold))
- status = get_int_from_node(doc, child,
- (int *) &rra_def->par[i].
+ status = get_ulong_from_node(doc, child,
+ &rra_def->par[i].
u_cnt);
else
status = get_double_from_node(doc, child,
else if (xmlStrcmp(child->name, (const xmlChar *) "cf") == 0)
status = parse_tag_rra_cf(doc, child, cur_rra_def);
else if (xmlStrcmp(child->name, (const xmlChar *) "pdp_per_row") == 0)
- status = get_int_from_node(doc, child,
- (int *) &cur_rra_def->pdp_cnt);
- else if (xmlStrcmp(child->name, (const xmlChar *) "params") == 0)
+ status = get_ulong_from_node(doc, child,
+ &cur_rra_def->pdp_cnt);
+ else if (atoi(rrd->stat_head->version) == 1
+ && xmlStrcmp(child->name, (const xmlChar *) "xff") == 0)
+ status = get_double_from_node(doc, child,
+ (double *) &cur_rra_def->
+ par[RRA_cdp_xff_val].u_val);
+ else if (atoi(rrd->stat_head->version) >= 2
+ && xmlStrcmp(child->name, (const xmlChar *) "params") == 0)
status = parse_tag_rra_params(doc, child, cur_rra_def);
else if (xmlStrcmp(child->name, (const xmlChar *) "cdp_prep") == 0)
status = parse_tag_rra_cdp_prep(doc, child, rrd, cur_cdp_prep);
break;
}
- /* Set the RRA pointer to the last value in the archive */
- cur_rra_ptr->cur_row = cur_rra_def->row_cnt - 1;
+ /* Set the RRA pointer to a random location */
+#ifdef WIN32
+ cur_rra_ptr->cur_row = rand() % cur_rra_def->row_cnt;
+#else
+ cur_rra_ptr->cur_row = random() % cur_rra_def->row_cnt;
+#endif
return (status);
} /* int parse_tag_rra */
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].
+ status = get_ulong_from_node(doc, child,
+ &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_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->
+ status = get_ulong_from_node(doc, child,
+ &cur_pdp_prep->
scratch[PDP_unkn_sec_cnt].u_cnt);
else {
rrd_set_error("parse_tag_ds: Unknown tag: %s", child->name);
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);
+ status = get_ulong_from_node(doc, child,
+ &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);
+ if (sizeof(time_t) == sizeof(long)) {
+ status = get_long_from_node(doc, child, (long *)&rrd->live_head->last_up);
+ }
+ else if (sizeof(time_t) == sizeof(long long)) {
+ status = get_long_long_from_node(doc, child, (long long *)&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)
{
FILE *fh;
unsigned int i;
- unsigned int value_count;
+ unsigned int rra_offset;
if (strcmp("-", file_name) == 0)
fh = stdout;
return (-1);
}
}
-
+ if (atoi(rrd->stat_head->version) < 3) {
+ /* we output 3 or higher */
+ strcpy(rrd->stat_head->version, "0003");
+ }
fwrite(rrd->stat_head, sizeof(stat_head_t), 1, fh);
fwrite(rrd->ds_def, sizeof(ds_def_t), rrd->stat_head->ds_cnt, fh);
fwrite(rrd->rra_def, sizeof(rra_def_t), rrd->stat_head->rra_cnt, fh);
fwrite(rrd->rra_ptr, sizeof(rra_ptr_t), rrd->stat_head->rra_cnt, fh);
/* calculate the number of rrd_values to dump */
- value_count = 0;
- for (i = 0; i < rrd->stat_head->rra_cnt; i++)
- value_count += (rrd->rra_def[i].row_cnt * rrd->stat_head->ds_cnt);
+ rra_offset = 0;
+ for (i = 0; i < rrd->stat_head->rra_cnt; i++) {
+ unsigned long num_rows = rrd->rra_def[i].row_cnt;
+ unsigned long cur_row = rrd->rra_ptr[i].cur_row;
+ unsigned long ds_cnt = rrd->stat_head->ds_cnt;
+
+ fwrite(rrd->rrd_value +
+ (rra_offset + num_rows - 1 - cur_row) * ds_cnt,
+ sizeof(rrd_value_t), (cur_row + 1) * ds_cnt, fh);
- fwrite(rrd->rrd_value, sizeof(rrd_value_t), value_count, fh);
+ fwrite(rrd->rrd_value + rra_offset * ds_cnt,
+ sizeof(rrd_value_t), (num_rows - 1 - cur_row) * ds_cnt, fh);
+
+ rra_offset += num_rows;
+ }
/* lets see if we had an error */
if (ferror(fh)) {
{
rrd_t *rrd;
+#ifdef WIN32
+ srand((unsigned int) time(NULL));
+#else
+ srandom((unsigned int) time(NULL) + (unsigned int) getpid());
+#endif
/* init rrd clean */
optind = 0;
opterr = 0; /* initialize getopt */