re-fix #243 checking for '\0' made the whole check pointless. Now it should actually...
[rrdtool.git] / src / rrd_update.c
index fa50929..8efd493 100644 (file)
@@ -1,6 +1,5 @@
-
 /*****************************************************************************
- * RRDtool 1.3.2  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.4.2  Copyright by Tobi Oetiker, 1997-2009
  *                Copyright by Florian Forster, 2008
  *****************************************************************************
  * rrd_update.c  RRD Update Function
@@ -283,7 +282,7 @@ static int write_changes_to_disk(
  * normalize time as returned by gettimeofday. usec part must
  * be always >= 0
  */
-static inline void normalize_time(
+static void normalize_time(
     struct timeval *t)
 {
     if (t->tv_usec < 0) {
@@ -296,7 +295,7 @@ static inline void normalize_time(
  * Sets current_time and current_time_usec based on the current time.
  * current_time_usec is set to 0 if the version number is 1 or 2.
  */
-static inline void initialize_time(
+static void initialize_time(
     time_t *current_time,
     unsigned long *current_time_usec,
     int version)
@@ -906,12 +905,16 @@ static int parse_ds(
             if (i < tmpl_cnt) {
                 updvals[tmpl_idx[i++]] = p + 1;
             }
+            else {
+                rrd_set_error("found extra data on update argument: %s",p+1);
+                return -1;
+            }                
         }
     }
 
     if (i != tmpl_cnt) {
         rrd_set_error("expected %lu data source readings (got %lu) from %s",
-                      tmpl_cnt - 1, i, input);
+                      tmpl_cnt - 1, i - 1, input);
         return -1;
     }
 
@@ -965,8 +968,19 @@ static int get_time_from_reading(
         *current_time_usec = tmp_time.tv_usec;
     } else {
         old_locale = setlocale(LC_NUMERIC, "C");
+        errno = 0;
         tmp = strtod(updvals[0], 0);
+        if (errno > 0) {
+            rrd_set_error("converting '%s' to float: %s",
+                updvals[0], rrd_strerror(errno));
+            return -1;
+        };
         setlocale(LC_NUMERIC, old_locale);
+        if (tmp < 0.0){
+            gettimeofday(&tmp_time, 0);
+            tmp = (double)tmp_time.tv_sec + (double)tmp_time.tv_usec * 1e-6f + tmp;
+        }
+
         *current_time = floor(tmp);
         *current_time_usec = (long) ((tmp - (double) *current_time) * 1e6f);
     }
@@ -1029,10 +1043,19 @@ static int update_pdp_prep(
             switch (dst_idx) {
             case DST_COUNTER:
             case DST_DERIVE:
-                for (ii = 0; updvals[ds_idx + 1][ii] != '\0'; ii++) {
-                    if ((updvals[ds_idx + 1][ii] < '0'
-                         || updvals[ds_idx + 1][ii] > '9')
-                        && (ii != 0 && updvals[ds_idx + 1][ii] != '-')) {
+                if ( (   updvals[ds_idx + 1][0] < '0'
+                      || updvals[ds_idx + 1][0] > '9' )
+                     && updvals[ds_idx + 1][0] != '-'
+                     && updvals[ds_idx + 1][0] != 'U'
+                   ) {
+                    rrd_set_error("not a simple integer: '%s'",
+                                  updvals[ds_idx + 1]);
+                    return -1;
+                }
+                for (ii = 1; updvals[ds_idx + 1][ii] != '\0'; ii++) {
+                    if (    updvals[ds_idx + 1][ii] < '0'
+                         || updvals[ds_idx + 1][ii] > '9'
+                       ) {
                         rrd_set_error("not a simple integer: '%s'",
                                       updvals[ds_idx + 1]);
                         return -1;
@@ -1061,12 +1084,12 @@ static int update_pdp_prep(
                 old_locale = setlocale(LC_NUMERIC, "C");
                 errno = 0;
                 pdp_new[ds_idx] = strtod(updvals[ds_idx + 1], &endptr);
-                setlocale(LC_NUMERIC, old_locale);
                 if (errno > 0) {
                     rrd_set_error("converting '%s' to float: %s",
                                   updvals[ds_idx + 1], rrd_strerror(errno));
                     return -1;
                 };
+                setlocale(LC_NUMERIC, old_locale);
                 if (endptr[0] != '\0') {
                     rrd_set_error
                         ("conversion of '%s' to float not complete: tail '%s'",
@@ -1076,16 +1099,16 @@ static int update_pdp_prep(
                 rate = pdp_new[ds_idx] / interval;
                 break;
             case DST_GAUGE:
-                errno = 0;
                 old_locale = setlocale(LC_NUMERIC, "C");
+                errno = 0;
                 pdp_new[ds_idx] =
                     strtod(updvals[ds_idx + 1], &endptr) * interval;
-                setlocale(LC_NUMERIC, old_locale);
                 if (errno) {
                     rrd_set_error("converting '%s' to float: %s",
                                   updvals[ds_idx + 1], rrd_strerror(errno));
                     return -1;
                 };
+                setlocale(LC_NUMERIC, old_locale);
                 if (endptr[0] != '\0') {
                     rrd_set_error
                         ("conversion of '%s' to float not complete: tail '%s'",
@@ -1891,7 +1914,7 @@ static int write_to_rras(
                  scratch_idx = CDP_secondary_val,
                  step_subtract = 2) {
 
-            off_t rra_pos_new;
+            size_t rra_pos_new;
 #ifdef DEBUG
             fprintf(stderr, "  -- RRA Preseek %ld\n", rrd_file->pos);
 #endif
@@ -1904,7 +1927,7 @@ static int write_to_rras(
               + ds_cnt * rra_ptr->cur_row * sizeof(rrd_value_t);
 
             /* re-seek if the position is wrong or we wrapped around */
-            if (rra_pos_new != rrd_file->pos) {
+            if ((size_t)rra_pos_new != rrd_file->pos) {
                 if (rrd_seek(rrd_file, rra_pos_new, SEEK_SET) != 0) {
                     rrd_set_error("seek error in rrd");
                     return -1;
@@ -1967,12 +1990,14 @@ static int write_RRA_row(
             /* append info to the return hash */
             *pcdp_summary = rrd_info_push(*pcdp_summary,
                                           sprintf_alloc
-                                          ("[%lli]RRA[%s][%lu]DS[%s]", rra_time,
+                                          ("[%lli]RRA[%s][%lu]DS[%s]", 
+                                           (long long)rra_time,
                                            rrd->rra_def[rra_idx].cf_nam,
                                            rrd->rra_def[rra_idx].pdp_cnt,
                                            rrd->ds_def[ds_idx].ds_nam),
-                                          RD_I_VAL, iv);
+                                           RD_I_VAL, iv);
         }
+        errno = 0;
         if (rrd_write(rrd_file,
                       &(rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].
                         u_val), sizeof(rrd_value_t)) != sizeof(rrd_value_t)) {