summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2006-08-05 23:09:03 +0000
committerStef Walter <stef@memberwebs.com>2006-08-05 23:09:03 +0000
commit1e9eba6d717ed3132db6b6c232e9d78e0f452568 (patch)
treeb01c5bffd4999a5eb02410b59be1c9dc6698175a
parent8f2e6fc5fe651d67e419b69749a29223866fcb10 (diff)
Finish the C implementation of rrdui-cgi
* Add color support See #77 * Add variable substitutions for environment
-rw-r--r--common/compat.c11
-rw-r--r--common/config-parser.c16
-rw-r--r--tools/rrdui-cgi.c848
3 files changed, 533 insertions, 342 deletions
diff --git a/common/compat.c b/common/compat.c
index c6138d0..50a2be7 100644
--- a/common/compat.c
+++ b/common/compat.c
@@ -136,15 +136,8 @@ strtob(const char* str)
size_t
strlcpy(char *dst, const char *src, size_t len)
{
- size_t ret = strlen(dst);
-
- while (len > 1) {
- *dst++ = *src++;
- len--;
- }
- if (len > 0)
- *dst = '\0';
- return (ret);
+ *dst = 0;
+ return strlcat(dst, src, len);
}
#endif /* HAVE_STRLCPY */
diff --git a/common/config-parser.c b/common/config-parser.c
index 36c8ba9..c096104 100644
--- a/common/config-parser.c
+++ b/common/config-parser.c
@@ -66,10 +66,10 @@ static char*
read_config_file(const char** configfile, void* data)
{
char* config = NULL;
- char* newfilename;
+ char* newfilename;
FILE* f = NULL;
long len;
- int flen;
+ int flen;
ASSERT(configfile);
@@ -87,7 +87,7 @@ read_config_file(const char** configfile, void* data)
return NULL;
}
- flen = strlen(*configfile);
+ flen = strlen(*configfile);
if((config = (char*)malloc(len + 4 + flen)) == NULL)
{
errmsg(*configfile, data, "out of memory");
@@ -110,9 +110,9 @@ read_config_file(const char** configfile, void* data)
/* Remove nasty dos line endings */
strcln(config, '\r');
- /* Persistent allocation for filename */
- newfilename = config + len + 2;
- strcpy(newfilename, *configfile);
+ /* Persistent allocation for filename */
+ newfilename = config + len + 2;
+ strcpy(newfilename, *configfile);
*configfile = newfilename;
return config;
@@ -171,7 +171,7 @@ cfg_parse_file(const char* filename, void* data, char** memory)
/* No continuation hand off value if necessary */
if(name && value)
{
- if(cfg_value(filename, header, name, value, data) == -1)
+ if(cfg_value(filename, header, name, strtrim(value), data) == -1)
goto finally;
}
@@ -212,7 +212,7 @@ cfg_parse_file(const char* filename, void* data, char** memory)
t++;
name = strtrim(p);
- value = strtrim(t);
+ value = t;
}
if(name && value)
diff --git a/tools/rrdui-cgi.c b/tools/rrdui-cgi.c
index ad755a4..f5f526e 100644
--- a/tools/rrdui-cgi.c
+++ b/tools/rrdui-cgi.c
@@ -5,6 +5,7 @@
#define _GNU_SOURCE
+#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -14,24 +15,68 @@
#include <errno.h>
#include <time.h>
#include <rrd.h>
+#include <assert.h>
-#include "../common/config-parser.h"
+#ifndef ASSERT
+#define ASSERT assert
+#endif
+
+#include "common/compat.h"
+#include "common/config-parser.h"
static char* conf_directory = NULL;
static char* work_directory = NULL;
+#define MAX_COLORS 30
+static char* all_colors[MAX_COLORS] =
+{
+ "#336699",
+ "#99CCFF",
+ "#999933",
+ "#666699",
+ "#CC9933",
+ "#006666",
+ "#3399FF",
+ "#993300",
+ "#CCCC99",
+ "#666666",
+ "#FFCC66",
+ "#6699CC",
+ "#663366",
+ "#9999CC",
+ "#CCCCCC",
+ "#669999",
+ "#CCCC66",
+ "#CC6600",
+ "#9999FF",
+ "#0066CC",
+ "#99CCCC",
+ "#999999",
+ "#FFCC00",
+ "#009999",
+ "#99CC33",
+ "#FF9900",
+ "#999966",
+ "#66CCCC",
+ "#339966",
+ "#CCCC33",
+};
+
+#define VARIABLE_CHARS "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+
typedef struct _graph
{
- const char* name;
- char* title;
- int width;
- int height;
- int interval;
- char* category;
- const char** options;
- const char** commands;
-
- struct _graph *next;
+ char rrd[MAXPATHLEN];
+ const char* name;
+ char* title;
+ int width;
+ int height;
+ int interval;
+ char* category;
+ const char** options;
+ const char** commands;
+
+ struct _graph *next;
}
graph;
@@ -42,20 +87,20 @@ static graph* allgraphs = NULL;
*/
static void
-usererror (const char* msg)
+user_error (const char* msg)
{
- printf("Content-Type: text/plain\n\n");
- printf("%s\n", msg);
+ printf("Content-Type: text/plain\n\n");
+ printf("%s\n", msg);
- /* Custom error so webserver doesn't think it's a server error */
- exit(0);
+ /* Custom error so webserver doesn't think it's a server error */
+ exit(0);
}
/* -----------------------------------------------------------------------------
* CONFIG PARSING
*/
-/* *argv should be freed with free() after use */
+/* *argvp should be freed with free() after use */
int
parse_argv(const char* s, const char*** argvp)
{
@@ -85,11 +130,11 @@ parse_argv(const char* s, const char*** argvp)
argv[argc] = buf;
for (src = s; r == 0 && *src; src++) {
- if (quote == *src) {
- quote = '\0';
- } else if (quote != '\0') {
+ if (quote != '\0') {
+ if (quote == *src)
+ quote = '\0';
if (*src == '\\') {
- src++;
+ *buf++ = *src++;
if (!*src) {
r = -1; errno = EINVAL;
continue;
@@ -114,16 +159,16 @@ parse_argv(const char* s, const char*** argvp)
}
} else {
switch (*src) {
- case '"':
- case '\'':
- quote = *src;
- break;
case '\\':
- src++;
+ *buf++ = *src++;
if (!*src) {
r = -1; errno = EINVAL;
continue;
}
+ case '"':
+ case '\'':
+ quote = *src;
+ /* Fall through */
default:
*buf++ = *src;
break;
@@ -131,152 +176,164 @@ parse_argv(const char* s, const char*** argvp)
}
}
- /* Reallocate the whole thing as one block of memory */
+ /* Reallocate the whole thing as one block of memory */
if (r == 0) {
if (strlen(argv[argc]))
argc++;
- nb = (argc + 1) * sizeof(*argv);
-
- for (i = 0; i < argc; i++) {
- if (argv[i] != NULL)
- nb += strlen(argv[i]) + 1;
- }
-
- dst = malloc (nb);
- if (dst == NULL) {
- free(argv);
- errno = ENOMEM;
- return -1;
- }
-
- argv2 = (void *) dst;
- dst += (argc + 1) * sizeof(*argv);
-
- for (i = 0; i < argc; i++) {
- if (argv[i] == NULL)
- continue;
- argv2[i] = dst;
- dst += strlen(strcpy(dst, argv[i])) + 1;
- }
- argv2[argc] = NULL;
-
- if (argvp) {
- *argvp = argv2;
- } else {
- free(argv2);
- argv2 = NULL;
- }
-
- r = 0;
+ nb = (argc + 1) * sizeof(*argv);
+
+ for (i = 0; i < argc; i++) {
+ if (argv[i] != NULL)
+ nb += strlen(argv[i]) + 1;
+ }
+
+ dst = malloc (nb);
+ if (dst == NULL) {
+ free(argv);
+ errno = ENOMEM;
+ return -1;
+ }
+
+ argv2 = (void *) dst;
+ dst += (argc + 1) * sizeof(*argv);
+
+ for (i = 0; i < argc; i++) {
+ if (argv[i] == NULL)
+ continue;
+ argv2[i] = dst;
+ dst += strlen(strcpy(dst, argv[i])) + 1;
+ }
+ argv2[argc] = NULL;
+
+ if (argvp) {
+ *argvp = argv2;
+ } else {
+ free(argv2);
+ argv2 = NULL;
+ }
+
+ r = 0;
}
free(argv);
return r;
}
-int cfg_value(const char* filename, const char* header, const char* name,
- char* value, void* data)
+/* Called for each value in the config files */
+int
+cfg_value(const char* filename, const char* header, const char* name,
+ char* value, void* data)
{
- static graph* gr = NULL;
-
- /* called like this after ever file */
- if (!header)
- {
- /* add to the list */
- gr->next = allgraphs;
- allgraphs = gr;
-
- gr = NULL;
- return 0;
- }
-
- if (gr == NULL)
- {
- gr = calloc(1, sizeof(graph));
- if (!gr)
- err(1, "Out of memory");
- gr->name = filename;
- gr->category = "";
- }
-
- if (strcmp(header, "general") == 0)
- {
- if (strcmp(name, "title") == 0)
- gr->title = value;
- else if (strcmp(name, "category") == 0)
- gr->category = value;
- }
- else if (strcmp(header, "graph") == 0)
- {
- if (strcmp(name, "height") == 0)
- gr->height = atoi(value);
- else if (strcmp(name, "width") == 0)
- gr->width = atoi(value);
- else if (strcmp(name, "options") == 0)
- {
- if (parse_argv(value, &gr->options) != 0)
- errx(2, "Invalid 'options' option");
- }
- else if (strcmp(name, "commands") == 0)
- {
- if (parse_argv(value, &gr->commands) != 0)
- errx(2, "Invalid 'commands' option");
- }
- }
- else if (strcmp(header, "poll") == 0)
- {
- if (strcmp(name, "interval") == 0)
- gr->interval = atoi(value);
- }
-
- return 0;
+ static graph* gr = NULL;
+
+ /* called like this after ever file */
+ if (!header)
+ {
+ /* add to the list */
+ gr->next = allgraphs;
+ allgraphs = gr;
+
+ gr = NULL;
+ return 0;
+ }
+
+ if (gr == NULL)
+ {
+ gr = calloc(1, sizeof(graph));
+ if (!gr)
+ err(1, "Out of memory");
+ gr->name = filename;
+ gr->category = "";
+
+ /* The default RRD path */
+ strlcpy(gr->rrd, work_directory, sizeof(gr->rrd));
+ strlcat(gr->rrd, "/", sizeof(gr->rrd));
+ strlcat(gr->rrd, filename, sizeof(gr->rrd));
+ strlcat(gr->rrd, ".rrd", sizeof(gr->rrd));
+ }
+
+ if (strcmp(header, "general") == 0)
+ {
+ if (strcmp(name, "title") == 0)
+ gr->title = value;
+ else if (strcmp(name, "category") == 0)
+ gr->category = value;
+ else if (strcmp(name, "rrd") == 0)
+ strlcpy(gr->rrd, value, sizeof(gr->rrd));
+ }
+ else if (strcmp(header, "graph") == 0)
+ {
+ if (strcmp(name, "height") == 0)
+ gr->height = atoi(value);
+ else if (strcmp(name, "width") == 0)
+ gr->width = atoi(value);
+ else if (strcmp(name, "options") == 0)
+ {
+ if (parse_argv(value, &gr->options) != 0)
+ errx (2, "Invalid 'options' option");
+ }
+ else if (strcmp(name, "commands") == 0)
+ {
+ if (parse_argv(value, &gr->commands) != 0)
+ errx (2, "Invalid 'commands' option");
+ }
+ }
+ else if (strcmp(header, "poll") == 0)
+ {
+ if (strcmp(name, "interval") == 0)
+ gr->interval = atoi(value);
+ }
+
+ return 0;
}
-int cfg_error(const char* filename, const char* errmsg, void* data)
+/* Called for each error in the config files */
+int
+cfg_error(const char* filename, const char* errmsg, void* data)
{
- /* todo skip the rest of this file on error */
+ /* TODO: skip the rest of this file on error */
warnx("%s", errmsg);
return 0;
}
-void
-freegraphs ()
+static void
+free_graphs ()
{
- graph* l;
- graph* t;
-
- for (l = allgraphs; l != NULL; )
- {
- t = l->next;
- if (l->options)
- free(l->options);
- if (l->commands)
- free(l->commands);
-
- free(l);
- l = t;
- }
+ graph* l;
+ graph* t;
+
+ for (l = allgraphs; l != NULL; )
+ {
+ t = l->next;
+ if (l->options)
+ free(l->options);
+ if (l->commands)
+ free(l->commands);
+
+ free(l);
+ l = t;
+ }
}
-graph*
-findgraphs (char* name)
+static graph*
+find_graphs (char* name)
{
- graph* l;
+ graph* l;
- if (!name)
- return NULL;
+ if (!name)
+ return NULL;
- for (l = allgraphs; l != NULL; l = l->next)
- {
- if (!l->commands)
- continue;
+ for (l = allgraphs; l != NULL; l = l->next)
+ {
+ if (!l->commands)
+ continue;
- if (strcmp(l->name, name) == 0)
- return l;
- }
+ if (strcmp(l->name, name) == 0)
+ return l;
+ }
- return NULL;
+ return NULL;
}
/* -----------------------------------------------------------------------------
@@ -284,168 +341,309 @@ findgraphs (char* name)
*/
static void
-listgraphs ()
+list_graphs ()
{
- graph* l;
+ graph* l;
- printf("Content-Type: text/xml\n\n");
- printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- printf("<data>\n");
+ printf("Content-Type: text/xml\n\n");
+ printf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ printf("<data>\n");
- for (l = allgraphs; l != NULL; l = l->next)
- {
- if (!l->commands)
- continue;
+ for (l = allgraphs; l != NULL; l = l->next)
+ {
+ if (!l->commands)
+ continue;
- printf(" <graph name=\"%s\" category=\"%s\" title=\"%s\"", \
- l->name, l->category, l->title);
+ printf(" <graph name=\"%s\" category=\"%s\" title=\"%s\"", \
+ l->name, l->category, l->title);
- if (l->width)
- printf(" width=\"%d\"", l->width);
+ if (l->width)
+ printf(" width=\"%d\"", l->width);
+ if (l->height)
+ printf(" height=\"%d\"", l->height);
+ if (l->interval)
+ printf(" interval=\"%d\"", l->interval);
+
+ printf(" />\n");
+ }
+ printf("</data>\n");
+}
- if (l->height)
- printf(" height=\"%d\"", l->height);
+static void
+add_text(char** result, char** pos, char** end, const char* text, int len)
+{
+ ASSERT(*result <= *pos);
+ ASSERT(*pos <= *end);
+ ASSERT(text);
+
+ if(!len || !text)
+ return;
+
+ if(len == -1)
+ len = strlen(text);
+
+ /* Need more memory allocated */
+ while(len >= *end - *pos)
+ {
+ int o = *end - *result;
+ int p = *pos - *result;
+ int x = o ? o * 2 : 128;
+
+ *result = realloc(*result, x);
+ if(!*result)
+ err(1, "out of memory");
+
+ memset(*result + o, 0, x);
+ *end = *result + x;
+ *pos = *result + p;
+ }
- if (l->interval)
- printf(" interval=\"%d\"", l->interval);
+ /* Copy the nastiness in */
+ memcpy(*pos, text, len);
+ *pos += len;
- printf(" />\n");
- }
- printf("</data>\n");
+ ASSERT(*pos <= *end);
}
-static int
-runrrd(int argc, const char** argv)
+static void
+add_time(char** result, char** pos, char** end, time_t time)
{
- int x, y;
- double min, max;
- char** text;
+ char buf[128];
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H\\:%M", localtime(&time));
+ buf[sizeof(buf) - 1] = 0;
+ add_text(result, pos, end, buf, -1);
+}
- optind = 0;
- opterr = 0;
+static char*
+substitute_variables(graph* gr, time_t start, time_t end, const char* src)
+{
+ char* result = NULL;
+ char* bound = NULL;
+ char* p = NULL;
+ const char* next;
+ char* name;
+ int len, color;
+
+ while(*src)
+ {
+ /* Next variable */
+ next = strpbrk(src, "$\\");
+ if(!next)
+ next = src + strlen(src);
+
+ /* Copy all the text until that point */
+ add_text(&result, &p, &bound, src, next - src);
+ src = next;
+
+ if(!*src)
+ break;
+
+ /* Handled escaped characters */
+ if(*src == '\\')
+ {
+ add_text(&result, &p, &bound, src + 1, 1);
+ src += 2;
+ continue;
+ }
+
+ /* We found a variable parse it out */
+ if(*(++src) == '{')
+ {
+ ++src;
+ next = strchr(src, '}');
+
+ /* Invalid variables are empty */
+ if(!next)
+ break;
+
+ len = next - src;
+ next++;
+ }
+ else
+ {
+ /* A variable without braces */
+ next = src + strspn(src, VARIABLE_CHARS);
+ len = next - src;
+ }
+
+ name = calloc(len + 1, 1);
+ if(!name)
+ err(1, "out of memory");
+ memcpy(name, src, len);
+
+ /* Put in the variable text */
+ if(strcmp(name, "START") == 0)
+ add_time(&result, &p, &bound, start);
+
+ else if(strcmp(name, "END") == 0)
+ add_time(&result, &p, &bound, end);
+
+ else if(strcmp(name, "RRD") == 0)
+ add_text(&result, &p, &bound, gr->rrd, -1);
- return rrd_graph(argc, (char**)argv, &text, &x, &y, stdout, &min, &max);
+ else if(strncmp(name, "COLOR", 5) == 0)
+ {
+ color = atoi(src + 5);
+ if(color > 0 && color < MAX_COLORS)
+ add_text(&result, &p, &bound, all_colors[color], -1);
+ }
+
+ /* Pull other environment variables from outside */
+ else
+ add_text(&result, &p, &bound, getenv(name), -1);
+
+ free(name);
+ src = next;
+ }
+
+ return result;
+}
+
+static int
+run_rrd(int argc, const char** argv)
+{
+ int x, y;
+ double min, max;
+ char** text;
+
+ optind = 0;
+ opterr = 0;
+
+//#ifdef TEST
+ {
+ int i;
+ for(i = 0; i < argc; i++)
+ fprintf(stderr, "%s\n", argv[i]);
+ }
+//#endif
+
+ return rrd_graph(argc, (char**)argv, &text, &x, &y, stdout, &min, &max);
}
static void
-displaygraphs ()
+display_graphs ()
{
- #define MAX_SIZE 1024
- const char* args[MAX_SIZE];
- int numargs = 0;
- char* allocs[MAX_SIZE];
- int numalloc = 0;
- char* name = NULL;
- int width, height, start, end;
- char* t;
- const char** k;
- char* q;
- char *nm, *vl;
- char* query = NULL;
- graph* gr = NULL;
- int r;
- int i;
-
- width = height = start = end = 0;
- memset(args, 0, sizeof(args));
-
- args[numargs++] = "graph";
- args[numargs++] = "-";
- args[numargs++] = "--imgformat=PNG";
- args[numargs++] = "--rigid";
-
- q = getenv("QUERY_STRING");
-
- if (q)
- {
- query = q = strdup(q);
- while (q[0] && (q[0] == '?' || isspace(q[0])))
- q++;
-
- while (q && q[0])
- {
- nm = strsep(&q, "&");
- vl = strchr(nm, '=');
- if (!vl)
- continue;
- vl[0] = 0;
- vl++;
-
- if (strcmp(nm, "name") == 0)
- name = vl;
- else if (strcmp(nm, "width") == 0)
- width = atoi(vl);
- else if (strcmp(nm, "height") == 0)
- height = atoi(vl);
- else if (strcmp(nm, "start") == 0)
- start = atoi(vl);
- else if (strcmp(nm, "end") == 0)
- end = atoi(vl);
- else if (strcmp(nm, "color") == 0)
- {
- args[numargs++] = "--color";
- t = strchr(vl, ':');
- if (t != NULL)
- *t = '#';
- args[numargs++] = vl;
- }
- }
- }
-
- gr = findgraphs(name);
- if (gr == NULL)
- usererror("Invalid graph");
-
- if (width || gr->width)
- {
- asprintf(&t, "--width=%d", width ? width : gr->width);
-
- args[numargs++] = allocs[numalloc++] = t;
- }
-
- if (height || gr->height)
- {
- asprintf(&t, "--height=%d", height ? height : gr->height);
-
- args[numargs++] = allocs[numalloc++] = t;
- }
-
- if (!end)
- end = (int)time(NULL);
-
- asprintf(&t, "--end=%d", end);
- args[numargs++] = allocs[numalloc++] = t;
-
- if (!start)
- start = 86400;
-
- asprintf(&t, "--start=%d", start);
- args[numargs++] = allocs[numalloc++] = t;
-
- asprintf(&t, "--title=%s", gr->title);
- args[numargs++] = allocs[numalloc++] = t;
-
- if (gr->options)
- {
- for (k = gr->options; *k != NULL; k++)
- args[numargs++] = *k;
- }
-
- for (k = gr->commands; *k != NULL; k++)
- args[numargs++] = *k;
-
- printf("Content-Type: image/png\n\n");
-
-/* for (i = 0; i < numargs; i++)
- fprintf(stderr, "%s\n", args[i]);*/
-
- rrd_clear_error();
- r = runrrd(numargs, args);
- if (r != 0)
- errx(2, "could't create graph: %s", rrd_get_error());
-
- for (i = 0; i < numalloc; i++)
- free(allocs[i]);
+ #define MAX_SIZE 1024
+ const char* args[MAX_SIZE];
+ int numargs = 0;
+ char* allocs[MAX_SIZE];
+ int numalloc = 0;
+ char* name = NULL;
+ int width, height, start, end;
+ char* t;
+ const char** k;
+ char* q;
+ char *nm, *vl;
+ char* query = NULL;
+ graph* gr = NULL;
+ int r;
+ int i;
+
+ width = height = start = end = 0;
+ memset(args, 0, sizeof(args));
+
+ /* Arguments that are always present */
+ args[numargs++] = "graph";
+ args[numargs++] = "-";
+ args[numargs++] = "--imgformat=PNG";
+ args[numargs++] = "--rigid";
+
+ /* Dig out the arguments from the query string */
+ q = getenv("QUERY_STRING");
+ if (q)
+ {
+ query = q = strdup(q);
+ while (q[0] && (q[0] == '?' || isspace(q[0])))
+ q++;
+
+ while (q && q[0])
+ {
+ nm = strsep(&q, "&");
+ vl = strchr(nm, '=');
+ if (!vl)
+ continue;
+ vl[0] = 0;
+ vl++;
+
+ if (strcmp(nm, "name") == 0)
+ name = vl;
+ else if (strcmp(nm, "width") == 0)
+ width = atoi(vl);
+ else if (strcmp(nm, "height") == 0)
+ height = atoi(vl);
+ else if (strcmp(nm, "start") == 0)
+ start = atoi(vl);
+ else if (strcmp(nm, "end") == 0)
+ end = atoi(vl);
+ else if (strcmp(nm, "color") == 0)
+ {
+ args[numargs++] = "--color";
+ t = strchr(vl, ':');
+ if (t != NULL)
+ *t = '#';
+ args[numargs++] = vl;
+ }
+ }
+ }
+
+ gr = find_graphs(name);
+ if (gr == NULL)
+ user_error("Invalid graph");
+
+ if (width || gr->width)
+ {
+ /* Substitute values from the graph where not specified */
+ asprintf(&t, "--width=%d", width ? width : gr->width);
+ args[numargs++] = allocs[numalloc++] = t;
+ }
+
+ if (height || gr->height)
+ {
+ /* Substitute values from the graph where not specified */
+ asprintf(&t, "--height=%d", height ? height : gr->height);
+ args[numargs++] = allocs[numalloc++] = t;
+ }
+
+ /* Figure out the start / end times */
+ if (!end)
+ end = (int)time(NULL);
+
+ asprintf(&t, "--end=%d", end);
+ args[numargs++] = allocs[numalloc++] = t;
+
+ if (!start)
+ start = end - 86400;
+
+ asprintf(&t, "--start=%d", start);
+ args[numargs++] = allocs[numalloc++] = t;
+
+ asprintf(&t, "--title=%s", gr->title);
+ args[numargs++] = allocs[numalloc++] = t;
+
+ /* Add in any other specified options */
+ if (gr->options)
+ {
+ for (k = gr->options; *k != NULL; k++)
+ args[numargs++] = *k;
+ }
+
+ /* And then the graph commands */
+ for (k = gr->commands; *k != NULL; k++)
+ {
+ args[numargs++] = allocs[numalloc++] =
+ substitute_variables(gr, start, end, *k);
+ }
+
+ /* Now make it happen */
+ printf("Content-Type: image/png\n\n");
+
+ rrd_clear_error();
+ r = run_rrd(numargs, args);
+ if (r != 0)
+ errx(2, "could't create graph: %s", rrd_get_error());
+
+ for (i = 0; i < numalloc; i++)
+ free(allocs[i]);
}
/* -----------------------------------------------------------------------------
@@ -453,54 +651,54 @@ displaygraphs ()
*/
static int
-pathstarts (const char* path, const char* method)
+path_starts (const char* path, const char* method)
{
- int len = strlen(method);
+ int len = strlen(method);
- if (strncmp(path, method, len) != 0)
- return 0;
+ if (strncmp(path, method, len) != 0)
+ return 0;
- if (path[len] == '/' || !path[len])
- return 1;
+ if (path[len] == '/' || !path[len])
+ return 1;
- return 0;
+ return 0;
}
int
-main (int argc, char* argv[])
+main(int argc, char* argv[])
{
- char* path;
-
- conf_directory = getenv("CONFDIR");
- work_directory = getenv("WORKDIR");
+ char* path;
- if (!conf_directory || !work_directory)
- errx(2, "not setup properly. CONFDIR and WORKDIR env variables must be set");
+ conf_directory = getenv("CONFDIR");
+ work_directory = getenv("WORKDIR");
- /*
- * We always have this as our current directory.
- * It helps when constructing graphs and the like
- */
- if (chdir(work_directory) < 0)
- err(1, "Couldn't change to work directory: %s", work_directory);
+ if (!conf_directory || !work_directory)
+ errx(2, "not setup properly. CONFDIR and WORKDIR env variables must be set");
+ /*
+ * We always have this as our current directory.
+ * It helps when constructing graphs and the like
+ */
+ if (chdir(work_directory) < 0)
+ err(1, "Couldn't change to work directory: %s", work_directory);
- path = getenv("PATH_INFO");
+ /* Load up all the configuration files */
+ cfg_parse_dir(conf_directory, NULL);
- while (path && path[0] &&
- (isspace(path[0]) || path[0] == '/'))
- path++;
+ path = getenv("PATH_INFO");
- cfg_parse_dir(conf_directory, NULL);
+ while (path && path[0] &&
+ (isspace(path[0]) || path[0] == '/'))
+ path++;
- if (!path || !path[0] || pathstarts(path, "list"))
- listgraphs();
- else if (pathstarts(path, "graph"))
- displaygraphs();
- else
- usererror("Invalid request");
+ /* See what kind of request we're talking about */
+ if (!path || !path[0] || path_starts(path, "list"))
+ list_graphs();
+ else if (path_starts(path, "graph"))
+ display_graphs();
+ else
+ user_error("Invalid request");
- freegraphs();
-
- return 0;
+ free_graphs();
+ return 0;
}