added rrd filename to illegal update message -- he at uninett.no
[rrdtool.git] / src / rrd_create.c
index a8f6a29..2cc8557 100644 (file)
@@ -1,9 +1,11 @@
 /*****************************************************************************
- * RRDtool 1.2.99907080300  Copyright by Tobi Oetiker, 1997-2007
+ * RRDtool 1.3.0  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_create.c  creates new rrds
  *****************************************************************************/
 
+#include <stdlib.h>
+#include <time.h>
 #include <locale.h>
 
 #include "rrd_tool.h"
@@ -22,6 +24,8 @@ 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,
@@ -36,7 +40,7 @@ int rrd_create(
     int       opt;
     time_t    last_up = time(NULL) - 10;
     unsigned long pdp_step = 300;
-    struct rrd_time_value last_up_tv;
+    rrd_time_value_t last_up_tv;
     char     *parsetime_error = NULL;
     long      long_tmp;
     int       rc;
@@ -52,7 +56,7 @@ int rrd_create(
 
         switch (opt) {
         case 'b':
-            if ((parsetime_error = parsetime(optarg, &last_up_tv))) {
+            if ((parsetime_error = rrd_parsetime(optarg, &last_up_tv))) {
                 rrd_set_error("start time: %s", parsetime_error);
                 return (-1);
             }
@@ -228,6 +232,7 @@ int rrd_create_r(
             char     *argvcopy;
             char     *tokptr;
             size_t    old_size = sizeof(rra_def_t) * (rrd.stat_head->rra_cnt);
+            int       row_cnt;
 
             if ((rrd.rra_def = rrd_realloc(rrd.rra_def,
                                            old_size + sizeof(rra_def_t))) ==
@@ -308,8 +313,10 @@ int rrd_create_r(
                     case CF_SEASONAL:
                     case CF_DEVPREDICT:
                     case CF_FAILURES:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt =
-                            atoi(token);
+                        row_cnt = atoi(token);
+                        if (row_cnt <= 0)
+                            rrd_set_error("Invalid row count: %i", row_cnt);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = row_cnt;
                         break;
                     default:
                         rrd.rra_def[rrd.stat_head->rra_cnt].
@@ -412,8 +419,10 @@ int rrd_create_r(
                             ("Unexpected extra argument for consolidation function DEVPREDICT");
                         break;
                     default:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt =
-                            atoi(token);
+                        row_cnt = atoi(token);
+                        if (row_cnt <= 0)
+                            rrd_set_error("Invalid row count: %i", row_cnt);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = row_cnt;
                         break;
                     }
                     break;
@@ -671,8 +680,12 @@ int rrd_create_fn(
     int       unkn_cnt;
     rrd_file_t *rrd_file_dn;
     rrd_t     rrd_dn;
+    unsigned flags = O_WRONLY | O_CREAT | O_TRUNC;
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+    flags |= O_BINARY;
+#endif
 
-    if ((rrd_file = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
+    if ((rrd_file = open(file_name, flags, 0666)) < 0) {
         rrd_set_error("creating '%s': %s", file_name, rrd_strerror(errno));
         free(rrd->stat_head);
         free(rrd->live_head);
@@ -690,13 +703,13 @@ int rrd_create_fn(
 
     if ((rrd->pdp_prep = calloc(1, sizeof(pdp_prep_t))) == NULL) {
         rrd_set_error("allocating pdp_prep");
-        free(rrd->stat_head);       
-        free(rrd->live_head);       
+        free(rrd->stat_head);
+        free(rrd->live_head);
         close(rrd_file);
         return (-1);
     }
 
-    strcpy(rrd->pdp_prep->last_ds, "UNKN");
+    strcpy(rrd->pdp_prep->last_ds, "U");
 
     rrd->pdp_prep->scratch[PDP_val].u_val = 0.0;
     rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt =
@@ -707,8 +720,8 @@ int rrd_create_fn(
 
     if ((rrd->cdp_prep = calloc(1, sizeof(cdp_prep_t))) == NULL) {
         rrd_set_error("allocating cdp_prep");
-        free(rrd->stat_head);       
-        free(rrd->live_head);       
+        free(rrd->stat_head);
+        free(rrd->live_head);
         close(rrd_file);
         return (-1);
     }
@@ -755,8 +768,8 @@ int rrd_create_fn(
 
     if ((rrd->rra_ptr = calloc(1, sizeof(rra_ptr_t))) == NULL) {
         rrd_set_error("allocating rra_ptr");
-        free(rrd->stat_head);       
-        free(rrd->live_head);       
+        free(rrd->stat_head);
+        free(rrd->live_head);
         close(rrd_file);
         return (-1);
     }
@@ -766,15 +779,15 @@ int rrd_create_fn(
      * would occur for cur_row = 1 because rrd_update increments
      * 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]);
         write(rrd_file, rrd->rra_ptr, sizeof(rra_ptr_t));
     }
 
     /* write the empty data area */
     if ((unknown = (rrd_value_t *) malloc(512 * sizeof(rrd_value_t))) == NULL) {
         rrd_set_error("allocating unknown");
-        free(rrd->stat_head);       
-        free(rrd->live_head);       
+        free(rrd->stat_head);
+        free(rrd->live_head);
         close(rrd_file);
         return (-1);
     }
@@ -792,8 +805,8 @@ int rrd_create_fn(
     }
     free(unknown);
     fdatasync(rrd_file);
-    free(rrd->stat_head);       
-    free(rrd->live_head);       
+    free(rrd->stat_head);
+    free(rrd->live_head);
     if (close(rrd_file) == -1) {
         rrd_set_error("creating rrd: %s", rrd_strerror(errno));
         return -1;
@@ -805,3 +818,16 @@ int rrd_create_fn(
     rrd_close(rrd_file_dn);
     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;
+}