index d571ea7cc2f3dc4018f1f22f816683d6ec4a8070..3bdd809c670000aedf08dfe0184170e090f8f67f 100644 (file)
--- a/program/src/rrd_create.c
+++ b/program/src/rrd_create.c
/*****************************************************************************
- * RRDtool 1.2rc4 Copyright by Tobi Oetiker, 1997-2005
+ * RRDtool 1.2.30 Copyright by Tobi Oetiker, 1997-2009
*****************************************************************************
* rrd_create.c creates new rrds
*****************************************************************************/
+#include <stdlib.h>
+#include <time.h>
+
#include "rrd_tool.h"
#include "rrd_rpncalc.h"
#include "rrd_hw.h"
#include "rrd_is_thread_safe.h"
-unsigned long FnvHash(char *str);
+unsigned long FnvHash(const char *str);
int create_hw_contingent_rras(rrd_t *rrd, unsigned short period, unsigned long hashed_name);
-void parseGENERIC_DS(char *def,rrd_t *rrd, int ds_idx);
+void parseGENERIC_DS(const char *def,rrd_t *rrd, int ds_idx);
+long int rra_random_row(rra_def_t *);
int
rrd_create(int argc, char **argv)
char *parsetime_error = NULL;
long long_tmp;
int rc;
+ optind = 0; opterr = 0; /* initialize getopt */
while (1){
static struct option long_options[] =
return(-1);
}
}
-
+ if (optind == argc) {
+ rrd_set_error("what is the name of the rrd file you want to create?");
+ return -1;
+ }
rc = rrd_create_r(argv[optind],
pdp_step, last_up,
- argc - optind - 1, argv + optind + 1);
+ argc - optind - 1, (const char **)(argv + optind + 1));
return rc;
}
/* #define DEBUG */
int
-rrd_create_r(char *filename,
+rrd_create_r(const char *filename,
unsigned long pdp_step, time_t last_up,
- int argc, char **argv)
+ int argc, const char **argv)
{
rrd_t rrd;
long i;
int offset;
char *token;
+ char dummychar1[2], dummychar2[2];
unsigned short token_idx, error_flag, period=0;
unsigned long hashed_name;
}
memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
/* extract the name and type */
- if (sscanf(&argv[i][3],
- DS_NAM_FMT ":" DST_FMT ":%n",
- rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
- rrd.ds_def[rrd.stat_head->ds_cnt].dst,&offset) == 2)
- {
- /* check for duplicate datasource names */
- for(ii=0;ii<rrd.stat_head->ds_cnt;ii++)
- if(strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
- rrd.ds_def[ii].ds_nam) == 0){
- rrd_set_error("Duplicate DS name: %s",rrd.ds_def[ii].ds_nam);
- }
- } else {
- rrd_set_error("invalid DS format");
+ switch (sscanf(&argv[i][3],
+ DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n",
+ rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
+ dummychar1,
+ rrd.ds_def[rrd.stat_head->ds_cnt].dst,
+ dummychar2,
+ &offset)) {
+ case 0:
+ case 1: rrd_set_error("Invalid DS name"); break;
+ case 2:
+ case 3: rrd_set_error("Invalid DS type"); break;
+ case 4: /* (%n may or may not be counted) */
+ case 5: /* check for duplicate datasource names */
+ for (ii=0;ii<rrd.stat_head->ds_cnt;ii++)
+ if(strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
+ rrd.ds_def[ii].ds_nam) == 0)
+ rrd_set_error("Duplicate DS name: %s",
+ rrd.ds_def[ii].ds_nam);
+ /* DS_type may be valid or not. Checked later */
+ break;
+ default: rrd_set_error("invalid DS format");
+ }
+ if (rrd_test_error()) {
+ rrd_free(&rrd);
+ return -1;
}
/* parse the remainder of the arguments */
return -1;
}
rrd.stat_head -> ds_cnt++;
- } else if (strncmp(argv[i],"RRA:",3)==0){
+ } else if (strncmp(argv[i],"RRA:",4)==0){
+ char *argvcopy;
char *tokptr;
size_t old_size = sizeof(rra_def_t)*(rrd.stat_head->rra_cnt);
if((rrd.rra_def = rrd_realloc(rrd.rra_def,
return(-1);
}
memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0, sizeof(rra_def_t));
-
- token = strtok_r(&argv[i][4],":", &tokptr);
+
+ argvcopy = strdup(argv[i]);
+ token = strtok_r(&argvcopy[4],":", &tokptr);
token_idx = error_flag = 0;
while (token != NULL)
{
break;
default:
rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt = atoi(token);
+ if (atoi(token) < 1)
+ rrd_set_error("Invalid step: must be >= 1");
break;
}
break;
if (rrd_test_error())
{
/* all errors are unrecoverable */
+ free(argvcopy);
rrd_free(&rrd);
return (-1);
}
token = strtok_r(NULL,":", &tokptr);
token_idx++;
} /* end while */
+ free(argvcopy);
#ifdef DEBUG
fprintf(stderr,"Creating RRA CF: %s, dep idx %lu, current idx %lu\n",
rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam,
return rrd_create_fn(filename, &rrd);
}
-void parseGENERIC_DS(char *def,rrd_t *rrd, int ds_idx)
+void parseGENERIC_DS(const char *def,rrd_t *rrd, int ds_idx)
{
char minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE];
/*
@@ -526,7 +553,7 @@ create_hw_contingent_rras(rrd_t *rrd, unsigned short period, unsigned long hashe
/* create and empty rrd file according to the specs given */
int
-rrd_create_fn(char *file_name, rrd_t *rrd)
+rrd_create_fn(const char *file_name, rrd_t *rrd)
{
unsigned long i,ii;
FILE *rrd_file;
if ((rrd_file = fopen(file_name,"wb")) == NULL ) {
rrd_set_error("creating '%s': %s",file_name, rrd_strerror(errno));
- free(rrd->stat_head);
- free(rrd->ds_def);
- free(rrd->rra_def);
+ rrd_free(rrd);
return(-1);
}
* the pointer a priori. */
for (i=0; i < rrd->stat_head->rra_cnt; i++)
{
- rrd->rra_ptr->cur_row = rrd->rra_def[i].row_cnt - 1;
+ rrd->rra_ptr->cur_row = rra_random_row(&rrd->rra_def[i]);
fwrite( rrd->rra_ptr, sizeof(rra_ptr_t),1,rrd_file);
}
rrd_free(rrd);
return (0);
}
+
+static int rand_init = 0;
+
+long int
+rra_random_row(rra_def_t *rra)
+{
+ if (!rand_init)
+ {
+ srandom((unsigned int)time(NULL) + (unsigned int)getpid());
+ rand_init++;
+ }
+
+ return random() % rra->row_cnt;
+}