Ensure that response_read() always calls fflush() or fclose().
[rrdtool.git] / src / rrd_create.c
index 3b57c9f..707e601 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.3.2  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.4.3  Copyright by Tobi Oetiker, 1997-2010
  *****************************************************************************
  * rrd_create.c  creates new rrds
  *****************************************************************************/
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
 #include "rrd_hw.h"
+#include "rrd_client.h"
 
 #include "rrd_is_thread_safe.h"
+static int opt_no_overwrite = 0;
+
+#ifdef WIN32
+# include <process.h>
+#endif
 
 unsigned long FnvHash(
     const char *str);
@@ -28,6 +34,12 @@ void      parseGENERIC_DS(
 static void rrd_free2(
     rrd_t *rrd);        /* our onwn copy, immmune to mmap */
 
+void rrd_create_set_no_overwrite( 
+    int opt ) 
+{
+       opt_no_overwrite = (opt?1:0);
+}
+
 int rrd_create(
     int argc,
     char **argv)
@@ -35,6 +47,8 @@ int rrd_create(
     struct option long_options[] = {
         {"start", required_argument, 0, 'b'},
         {"step", required_argument, 0, 's'},
+        {"daemon", required_argument, 0, 'd'},
+        {"no-overwrite", no_argument, 0, 'O'},
         {0, 0, 0, 0}
     };
     int       option_index = 0;
@@ -45,17 +59,29 @@ int rrd_create(
     char     *parsetime_error = NULL;
     long      long_tmp;
     int       rc;
+    char * opt_daemon = NULL;
 
     optind = 0;
     opterr = 0;         /* initialize getopt */
 
     while (1) {
-        opt = getopt_long(argc, argv, "b:s:", long_options, &option_index);
+        opt = getopt_long(argc, argv, "Ob:s:d:", long_options, &option_index);
 
         if (opt == EOF)
             break;
 
         switch (opt) {
+        case 'd':
+            if (opt_daemon != NULL)
+                    free (opt_daemon);
+            opt_daemon = strdup (optarg);
+            if (opt_daemon == NULL)
+            {
+                rrd_set_error ("strdup failed.");
+                return (-1);
+            }
+            break;
+
         case 'b':
             if ((parsetime_error = rrd_parsetime(optarg, &last_up_tv))) {
                 rrd_set_error("start time: %s", parsetime_error);
@@ -86,6 +112,10 @@ int rrd_create(
             pdp_step = long_tmp;
             break;
 
+        case 'O':
+            opt_no_overwrite = 1;
+           break;
+
         case '?':
             if (optopt != 0)
                 rrd_set_error("unknown option '%c'", optopt);
@@ -98,9 +128,17 @@ int rrd_create(
         rrd_set_error("need name of an rrd file to create");
         return -1;
     }
+
+    rrdc_connect (opt_daemon);
+    if (rrdc_is_connected (opt_daemon)) {
+        rc = rrdc_create (argv[optind],
+                      pdp_step, last_up, opt_no_overwrite,
+                      argc - optind - 1, (const char **) (argv + optind + 1));
+       } else {
     rc = rrd_create_r(argv[optind],
                       pdp_step, last_up,
                       argc - optind - 1, (const char **) (argv + optind + 1));
+       }
 
     return rc;
 }
@@ -121,17 +159,20 @@ int rrd_create_r(
     unsigned short token_idx, error_flag, period = 0;
     unsigned long hashed_name;
 
+    /* clear any previous errors */
+    rrd_clear_error();
+
     /* init rrd clean */
     rrd_init(&rrd);
     /* static header */
-    if ((rrd.stat_head = calloc(1, sizeof(stat_head_t))) == NULL) {
+    if ((rrd.stat_head = (stat_head_t*)calloc(1, sizeof(stat_head_t))) == NULL) {
         rrd_set_error("allocating rrd.stat_head");
         rrd_free2(&rrd);
         return (-1);
     }
 
     /* live header */
-    if ((rrd.live_head = calloc(1, sizeof(live_head_t))) == NULL) {
+    if ((rrd.live_head = (live_head_t*)calloc(1, sizeof(live_head_t))) == NULL) {
         rrd_set_error("allocating rrd.live_head");
         rrd_free2(&rrd);
         return (-1);
@@ -162,7 +203,7 @@ int rrd_create_r(
         if (strncmp(argv[i], "DS:", 3) == 0) {
             size_t    old_size = sizeof(ds_def_t) * (rrd.stat_head->ds_cnt);
 
-            if ((rrd.ds_def = rrd_realloc(rrd.ds_def,
+            if ((rrd.ds_def = (ds_def_t*)rrd_realloc(rrd.ds_def,
                                           old_size + sizeof(ds_def_t))) ==
                 NULL) {
                 rrd_set_error("allocating rrd.ds_def");
@@ -179,11 +220,11 @@ int rrd_create_r(
                            dummychar2, &offset)) {
             case 0:
             case 1:
-                rrd_set_error("Invalid DS name");
+                rrd_set_error("Invalid DS name in [%s]",&argv[i][3]);
                 break;
             case 2:
             case 3:
-                rrd_set_error("Invalid DS type");
+                rrd_set_error("Invalid DS type in [%s]",&argv[i][3]);
                 break;
             case 4:    /* (%n may or may not be counted) */
             case 5:    /* check for duplicate datasource names */
@@ -227,11 +268,11 @@ int rrd_create_r(
             rrd.stat_head->ds_cnt++;
         } else if (strncmp(argv[i], "RRA:", 4) == 0) {
             char     *argvcopy;
-            char     *tokptr;
+            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,
+            if ((rrd.rra_def = (rra_def_t*)rrd_realloc(rrd.rra_def,
                                            old_size + sizeof(rra_def_t))) ==
                 NULL) {
                 rrd_set_error("allocating rrd.rra_def");
@@ -561,7 +602,8 @@ void parseGENERIC_DS(
        &(rrd -> ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
        minstr,maxstr);
      */
-    old_locale = setlocale(LC_NUMERIC, "C");
+    old_locale = setlocale(LC_NUMERIC, NULL);
+    setlocale(LC_NUMERIC, "C");
     if (sscanf(def, "%lu:%18[^:]:%18[^:]",
                &(rrd->ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
                minstr, maxstr) == 3) {
@@ -606,7 +648,7 @@ int create_hw_contingent_rras(
     (rrd->stat_head->rra_cnt)++;
     /* allocate the memory for the 4 contingent RRAs */
     old_size = sizeof(rra_def_t) * (rrd->stat_head->rra_cnt);
-    if ((rrd->rra_def = rrd_realloc(rrd->rra_def,
+    if ((rrd->rra_def = (rra_def_t*)rrd_realloc(rrd->rra_def,
                                     old_size + 4 * sizeof(rra_def_t))) ==
         NULL) {
         rrd_free2(rrd);
@@ -675,6 +717,14 @@ int rrd_create_fn(
     rrd_t     rrd_dn;
     unsigned  rrd_flags = RRD_READWRITE | RRD_CREAT;
 
+    if (opt_no_overwrite) {
+      rrd_flags |= RRD_EXCL ;
+    }
+
+    unkn_cnt = 0;
+    for (i = 0; i < rrd->stat_head->rra_cnt; i++)
+        unkn_cnt += rrd->stat_head->ds_cnt * rrd->rra_def[i].row_cnt;
+
     if ((rrd_file_dn = rrd_open(file_name, rrd, rrd_flags)) == NULL) {
         rrd_set_error("creating '%s': %s", file_name, rrd_strerror(errno));
         rrd_free2(rrd);
@@ -690,7 +740,7 @@ int rrd_create_fn(
 
     rrd_write(rrd_file_dn, rrd->live_head, sizeof(live_head_t));
 
-    if ((rrd->pdp_prep = calloc(1, sizeof(pdp_prep_t))) == NULL) {
+    if ((rrd->pdp_prep = (pdp_prep_t*)calloc(1, sizeof(pdp_prep_t))) == NULL) {
         rrd_set_error("allocating pdp_prep");
         rrd_free2(rrd);
         rrd_close(rrd_file_dn);
@@ -706,7 +756,7 @@ int rrd_create_fn(
     for (i = 0; i < rrd->stat_head->ds_cnt; i++)
         rrd_write(rrd_file_dn, rrd->pdp_prep, sizeof(pdp_prep_t));
 
-    if ((rrd->cdp_prep = calloc(1, sizeof(cdp_prep_t))) == NULL) {
+    if ((rrd->cdp_prep = (cdp_prep_t*)calloc(1, sizeof(cdp_prep_t))) == NULL) {
         rrd_set_error("allocating cdp_prep");
         rrd_free2(rrd);
         rrd_close(rrd_file_dn);
@@ -753,7 +803,7 @@ int rrd_create_fn(
     /* now, we must make sure that the rest of the rrd
        struct is properly initialized */
 
-    if ((rrd->rra_ptr = calloc(1, sizeof(rra_ptr_t))) == NULL) {
+    if ((rrd->rra_ptr = (rra_ptr_t*)calloc(1, sizeof(rra_ptr_t))) == NULL) {
         rrd_set_error("allocating rra_ptr");
         rrd_free2(rrd);
         rrd_close(rrd_file_dn);
@@ -779,10 +829,6 @@ int rrd_create_fn(
     for (i = 0; i < 512; ++i)
         unknown[i] = DNAN;
 
-    unkn_cnt = 0;
-    for (i = 0; i < rrd->stat_head->rra_cnt; i++)
-        unkn_cnt += rrd->stat_head->ds_cnt * rrd->rra_def[i].row_cnt;
-
     while (unkn_cnt > 0) {
         if(rrd_write(rrd_file_dn, unknown, sizeof(rrd_value_t) * min(unkn_cnt, 512)) < 0)
         {
@@ -799,6 +845,7 @@ int rrd_create_fn(
         return -1;
     }
     /* flush all we don't need out of the cache */
+    rrd_init(&rrd_dn);
     if((rrd_file_dn = rrd_open(file_name, &rrd_dn, RRD_READONLY)) != NULL)
     {
         rrd_dontneed(rrd_file_dn, &rrd_dn);