Code

fix for segfault in rrd_cgi: caused by freeing a invalid address when printing an...
[rrdtool.git] / src / rrd_cgi.c
index 17a6b16b97f64919957f0221cbcc6ce9b3fee094..9f0a0bd879afe822e28e9ec759a782955a597bda 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.11  Copyright by Tobi Oetiker, 1997-2005
+ * RRDtool 1.2.29  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_cgi.c  RRD Web Page Generator
  *****************************************************************************/
@@ -61,6 +61,9 @@ char* includefile(long, const char **);
 /* for how long is the output of the cgi valid ? */
 char* rrdgoodfor(long, const char **);
 
+/* return rrdcgi version string */ 
+char* rrdgetinternal(long, const char **);
+
 char* rrdstrip(char *buf);
 char* scanargs(char *line, int *argc, char ***args);
 
@@ -284,6 +287,7 @@ rrd_expand_vars(char* buffer)
                 parse(&buffer, i, "<RRD::TIME::LAST", printtimelast);
                 parse(&buffer, i, "<RRD::TIME::NOW", printtimenow);
                 parse(&buffer, i, "<RRD::TIME::STRFTIME", printstrftime);
+               parse(&buffer, i, "<RRD::INTERNAL", rrdgetinternal);
        }
        return buffer;
 }
@@ -301,6 +305,7 @@ static void calfree (void){
     if (calcpr) {
            free(calcpr);
     }
+    calcpr=NULL;
   }
 }
 
@@ -409,6 +414,7 @@ int main(int argc, char *argv[]) {
                parse(&buffer, i, "<RRD::TIME::LAST", printtimelast);
                parse(&buffer, i, "<RRD::TIME::NOW", printtimenow);
                parse(&buffer, i, "<RRD::TIME::STRFTIME", printstrftime);
+               parse(&buffer, i, "<RRD::INTERNAL", rrdgetinternal);
        }
 
        if (!filter) {
@@ -506,11 +512,7 @@ char* rrdgetenv(long argc, const char **args) {
        if (envvar) {
                return stralloc(envvar);
        } else {
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
-               _snprintf(buf, sizeof(buf), "[ERROR:_getenv_'%s'_failed", args[0]);
-#else
                 snprintf(buf, sizeof(buf), "[ERROR:_getenv_'%s'_failed", args[0]);
-#endif         
                 return stralloc(buf);
        }
 }
@@ -526,11 +528,7 @@ char* rrdgetvar(long argc, const char **args) {
        if (value) {
                return stralloc(value);
        } else {
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
-               _snprintf(buf, sizeof(buf), "[ERROR:_getvar_'%s'_failed", args[0]);
-#else
                 snprintf(buf, sizeof(buf), "[ERROR:_getvar_'%s'_failed", args[0]);
-#endif
                return stralloc(buf);
        }
 }
@@ -549,6 +547,20 @@ char* rrdgoodfor(long argc, const char **args){
   return stralloc("");
 }
 
+char* rrdgetinternal(long argc, const char **args){
+  if (argc == 1) {
+    if( strcasecmp( args[0], "VERSION") == 0) {
+      return stralloc(PACKAGE_VERSION);
+    } else if( strcasecmp( args[0], "COMPILETIME") == 0) {
+      return stralloc(__DATE__ " " __TIME__);
+    } else {
+      return stralloc("[ERROR: internal unknown argument]");
+    }
+  } else {
+    return stralloc("[ERROR: internal expected 1 argument]");
+  }
+}
+
 /* Format start or end times using strftime.  We always need both the
  * start and end times, because, either might be relative to the other.
  * */
@@ -563,7 +575,7 @@ char* printstrftime(long argc, const char **args){
        /* Make sure that we were given the right number of args */
        if( argc != 4) {
                rrd_set_error( "wrong number of args %d", argc);
-               return (char *) -1;
+               return stralloc("");
        }
 
        /* Init start and end time */
@@ -573,14 +585,14 @@ char* printstrftime(long argc, const char **args){
        /* Parse the start and end times we were given */
        if( (parsetime_error = parsetime( args[1], &start_tv))) {
                rrd_set_error( "start time: %s", parsetime_error);
-               return (char *) -1;
+               return stralloc("");
        }
        if( (parsetime_error = parsetime( args[2], &end_tv))) {
                rrd_set_error( "end time: %s", parsetime_error);
-               return (char *) -1;
+               return stralloc("");
        }
        if( proc_start_end( &start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
-               return (char *) -1;
+               return stralloc("");
        }
 
        /* Do we do the start or end */
@@ -592,7 +604,7 @@ char* printstrftime(long argc, const char **args){
        }
        else {
                rrd_set_error( "start/end not found in '%s'", args[0]);
-               return (char *) -1;
+               return stralloc("");
        }
 
        /* now format it */
@@ -601,7 +613,7 @@ char* printstrftime(long argc, const char **args){
        }
        else {
                rrd_set_error( "strftime failed");
-               return (char *) -1;
+               return stralloc("");
        }
 }
 
@@ -767,7 +779,6 @@ char* drawgraph(long argc, const char **args){
       char *err = malloc((strlen(rrd_get_error())+DS_NAM_SIZE)*sizeof(char));
       sprintf(err, "[ERROR: %s]",rrd_get_error());
       rrd_clear_error();
-      calfree();
       return err;
     }
   }
@@ -1276,7 +1287,7 @@ s_var **rrdcgiReadVariables(void)
        if (i<numargs) {
 
            /* try to find out if there's already such a variable */
-           for (k=0; k<i && (strncmp (result[k]->name,cp, esp-cp) || !(strlen (result[k]->name) == esp-cp)); k++);
+           for (k=0; k<i && (strncmp (result[k]->name,cp, esp-cp) || !(strlen (result[k]->name) == (size_t)(esp-cp))); k++);
 
            if (k == i) {       /* No such variable yet */
                if ((result[i] = (s_var *)malloc(sizeof(s_var))) == NULL)