diff --git a/program/src/rrd_cgi.c b/program/src/rrd_cgi.c
index 5e66095cfaae1b0d2091cd9deb1801a9cf395d8c..a0c9b3b27d4f86d7e6f118da303024c004b6a08f 100644 (file)
--- a/program/src/rrd_cgi.c
+++ b/program/src/rrd_cgi.c
/*****************************************************************************
- * RRDtool 1.2.99907080300 Copyright by Tobi Oetiker, 1997-2007
+ * RRDtool 1.4.3 Copyright by Tobi Oetiker, 1997-2010
*****************************************************************************
* rrd_cgi.c RRD Web Page Generator
*****************************************************************************/
#include <stdlib.h>
#endif
+#ifdef WIN32
+ #define strcasecmp stricmp
+ #define strcasencmp strnicmp
+#endif
+
#define MEMBLK 1024
/*#define DEBUG_PARSER
#define DEBUG_VARS*/
if (calcpr) {
free(calcpr);
}
+ calcpr = NULL;
}
}
char *stralloc(
const char *str)
{
- char *nstr;
-
if (!str) {
return NULL;
}
- nstr = malloc((strlen(str) + 1));
- strcpy(nstr, str);
- return (nstr);
+ return strdup(str);
+}
+
+static int readfile(
+ const char *file_name,
+ char **buffer,
+ int skipfirst)
+{
+ long writecnt = 0, totalcnt = MEMBLK;
+ long offset = 0;
+ FILE *input = NULL;
+ char c;
+
+ if ((strcmp("-", file_name) == 0)) {
+ input = stdin;
+ } else {
+ if ((input = fopen(file_name, "rb")) == NULL) {
+ rrd_set_error("opening '%s': %s", file_name, rrd_strerror(errno));
+ return (-1);
+ }
+ }
+ if (skipfirst) {
+ do {
+ c = getc(input);
+ offset++;
+ } while (c != '\n' && !feof(input));
+ }
+ if (strcmp("-", file_name)) {
+ fseek(input, 0, SEEK_END);
+ /* have extra space for detecting EOF without realloc */
+ totalcnt = (ftell(input) + 1) / sizeof(char) - offset;
+ if (totalcnt < MEMBLK)
+ totalcnt = MEMBLK; /* sanitize */
+ fseek(input, offset * sizeof(char), SEEK_SET);
+ }
+ if (((*buffer) = (char *) malloc((totalcnt + 4) * sizeof(char))) == NULL) {
+ perror("Allocate Buffer:");
+ exit(1);
+ };
+ do {
+ writecnt +=
+ fread((*buffer) + writecnt, 1,
+ (totalcnt - writecnt) * sizeof(char), input);
+ if (writecnt >= totalcnt) {
+ totalcnt += MEMBLK;
+ if (((*buffer) =
+ rrd_realloc((*buffer),
+ (totalcnt + 4) * sizeof(char))) == NULL) {
+ perror("Realloc Buffer:");
+ exit(1);
+ };
+ }
+ } while (!feof(input));
+ (*buffer)[writecnt] = '\0';
+ if (strcmp("-", file_name) != 0) {
+ fclose(input);
+ };
+ return writecnt;
}
int main(
const char **args)
{
if (argc >= 2) {
- char *xyz = malloc((strlen(args[0]) + strlen(args[1]) + 2));
+ const size_t len = strlen(args[0]) + strlen(args[1]) + 2;
+ char *xyz = malloc(len);
if (xyz == NULL) {
return stralloc("[ERROR: allocating setenv buffer]");
};
- sprintf(xyz, "%s=%s", args[0], args[1]);
+ snprintf(xyz, len, "%s=%s", args[0], args[1]);
if (putenv(xyz) == -1) {
free(xyz);
return stralloc("[ERROR: failed to do putenv]");
long argc,
const char **args)
{
- struct rrd_time_value start_tv, end_tv;
+ rrd_time_value_t start_tv, end_tv;
char *parsetime_error = NULL;
char formatted[MAX_STRFTIME_SIZE];
struct tm *the_tm;
}
/* Init start and end time */
- parsetime("end-24h", &start_tv);
- parsetime("now", &end_tv);
+ rrd_parsetime("end-24h", &start_tv);
+ rrd_parsetime("now", &end_tv);
/* Parse the start and end times we were given */
- if ((parsetime_error = parsetime(args[1], &start_tv))) {
+ if ((parsetime_error = rrd_parsetime(args[1], &start_tv))) {
rrd_set_error("start time: %s", parsetime_error);
return stralloc("");
}
- if ((parsetime_error = parsetime(args[2], &end_tv))) {
+ if ((parsetime_error = rrd_parsetime(args[2], &end_tv))) {
rrd_set_error("end time: %s", parsetime_error);
return stralloc("");
}
- if (proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
+ if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
return stralloc("");
}
readfile(filename, &buffer, 0);
if (rrd_test_error()) {
- char *err = malloc((strlen(rrd_get_error()) + DS_NAM_SIZE));
+ const size_t len = strlen(rrd_get_error()) + DS_NAM_SIZE;
+ char *err = malloc(len);
- sprintf(err, "[ERROR: %s]", rrd_get_error());
+ snprintf(err, len, "[ERROR: %s]", rrd_get_error());
rrd_clear_error();
return err;
} else {
return stralloc(calcpr[0]);
} else {
if (rrd_test_error()) {
- char *err =
- malloc((strlen(rrd_get_error()) +
- DS_NAM_SIZE) * sizeof(char));
- sprintf(err, "[ERROR: %s]", rrd_get_error());
+ const size_t len = strlen(rrd_get_error()) + DS_NAM_SIZE;
+ char *err = malloc(len);
+ snprintf(err, len, "[ERROR: %s]", rrd_get_error());
rrd_clear_error();
- calfree();
return err;
}
}
if (buf == NULL) {
return stralloc("[ERROR: allocating strftime buffer]");
};
- last = rrd_last(argc + 1, (char **) args - 1);
+ /* not raising argc in step with args - 1 since the last argument
+ will be used below for strftime */
+
+ last = rrd_last(argc, (char **) args - 1);
if (rrd_test_error()) {
- char *err =
- malloc((strlen(rrd_get_error()) +
- DS_NAM_SIZE) * sizeof(char));
- sprintf(err, "[ERROR: %s]", rrd_get_error());
+ const size_t len = strlen(rrd_get_error()) + DS_NAM_SIZE;
+ char *err = malloc(len);
+ snprintf(err, len, "[ERROR: %s]", rrd_get_error());
rrd_clear_error();
return err;
}
strftime(buf, 254, args[1], &tm_last);
return buf;
}
- if (argc < 2) {
- return stralloc("[ERROR: too few arguments for RRD::TIME::LAST]");
- }
- return stralloc("[ERROR: not enough arguments for RRD::TIME::LAST]");
+ return stralloc("[ERROR: expected <RRD::TIME::LAST file.rrd strftime-format>]");
}
char *printtimenow(
int curarg_contains_rrd_directives;
/* local array of arguments while parsing */
- int argc = 0;
+ int argc = 1;
char **argv;
#ifdef DEBUG_PARSER
if (!argv) {
return NULL;
}
+ argv[0] = "rrdcgi";
/* skip leading blanks */
while (isspace((int) *line)) {
argv[argc - 1] = rrd_expand_vars(stralloc(argv[argc - 1]));
}
#ifdef DEBUG_PARSER
- if (argc > 0) {
+ if (argc > 1) {
int n;
printf("<-- arguments found [%d]\n", argc);
#endif
/* update caller's notion of the argument array and it's size */
- *arguments = argv;
- *argument_count = argc;
+
+ /* note this is a bit of a hack since the rrd_cgi code used to just put
+ its arguments into a normal array starting at 0 ... since the rrd_*
+ commands expect and argc/argv array we used to just shift everything
+ by -1 ... this in turn exploded when a rrd_* function tried to print
+ argv[0] ... hence we are now doing everything in argv style but hand
+ over seemingly the old array ... but doing argv-1 will actually end
+ up in a 'good' place now. */
+
+ *arguments = argv+1;
+ *argument_count = argc-1;
if (Quote) {
return NULL;
if (end) {
/* got arguments, call function for 'tag' with arguments */
val = func(argc, (const char **) args);
- free(args);
+ free(args-1);
} else {
- /* unable to parse arguments, undo 0-termination by scanargs */
- for (; argc > 0; argc--) {
- *((args[argc - 1]) - 1) = ' ';
- }
-
/* next call, try parsing at current offset +1 */
end = (*buf) + i + 1;
s_var **result;
int i, k, len;
char tmp[101];
+ size_t tmplen;
cp = getenv("REQUEST_METHOD");
ip = getenv("CONTENT_LENGTH");
length = atoi(ip);
if ((line = (char *) malloc(length + 2)) == NULL)
return NULL;
- fgets(line, length + 1, stdin);
+ if (fgets(line, length + 1, stdin) == NULL)
+ return NULL;
} else
return NULL;
} else if (cp && !strcmp(cp, "GET")) {
esp = getenv("QUERY_STRING");
if (esp && strlen(esp)) {
- if ((line = (char *) malloc(strlen(esp) + 2)) == NULL)
+ if ((line = strdup(esp)) == NULL)
return NULL;
- sprintf(line, "%s", esp);
} else
return NULL;
} else {
printf("(offline mode: enter name=value pairs on standard input)\n");
memset(tmp, 0, sizeof(tmp));
while ((cp = fgets(tmp, 100, stdin)) != NULL) {
- if (strlen(tmp)) {
- if (tmp[strlen(tmp) - 1] == '\n')
- tmp[strlen(tmp) - 1] = '&';
- if (length) {
- length += strlen(tmp);
- len = (length + 1) * sizeof(char);
+ if ((tmplen = strlen(tmp)) != 0) {
+ if (tmp[tmplen - 1] == '\n')
+ tmp[tmplen - 1] = '&';
+ length += tmplen;
+ len = (length + 1) * sizeof(char);
+ if ((unsigned) length > tmplen) {
if ((line = (char *) realloc(line, len)) == NULL)
return NULL;
- strcat(line, tmp);
+ strncat(line, tmp, tmplen);
} else {
- length = strlen(tmp);
- len = (length + 1) * sizeof(char);
- if ((line = (char *) malloc(len)) == NULL)
+ if ((line = strdup(tmp)) == NULL)
return NULL;
- memset(line, 0, len);
- strcpy(line, tmp);
}
}
memset(tmp, 0, sizeof(tmp));
i++;
} else { /* There is already such a name, suppose a mutiple field */
cp = ++esp;
- len =
- (strlen(result[k]->value) + (ip - esp) +
- 2) * sizeof(char);
- if ((sptr = (char *) malloc(len)) == NULL)
+ len = strlen(result[k]->value) + (ip - esp) + 2;
+ if ((sptr = (char *) calloc(len, sizeof(char))) == NULL)
return NULL;
- memset(sptr, 0, len);
- sprintf(sptr, "%s\n", result[k]->value);
- strncat(sptr, cp, ip - esp);
+ snprintf(sptr, len, "%s\n%s", result[k]->value, cp);
free(result[k]->value);
result[k]->value = rrdcgiDecodeString(sptr);
}