diff options
Diffstat (limited to 'tools/rrdui-cgi.c')
-rw-r--r-- | tools/rrdui-cgi.c | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/tools/rrdui-cgi.c b/tools/rrdui-cgi.c new file mode 100644 index 0000000..a2e7407 --- /dev/null +++ b/tools/rrdui-cgi.c @@ -0,0 +1,234 @@ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <err.h> +#include <unistd.h> + +static char* conf_directory = NULL; +static char* work_directory = NULL; + +typedef struct _graph +{ + const char* name; + char* title; + int width; + int height; + int interval; + char* category; + + struct _graph *next; +} +graph; + +static graph* allgraphs = NULL; + +/* ----------------------------------------------------------------------------- + * CONFIG PARSING + */ + +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(header, "poll") == 0) + { + if (strcmp(name, "interval") == 0) + gr->interval = atoi(value); + } +} + +int cfg_error(const char* filename, const char* errmsg, void* data) +{ + /* todo skip the rest of this file on error */ + warnx("%s", errmsg); + return 0; +} + +void +freegraphs () +{ + graph* l; + graph* t; + + for (l = allgraphs; l != NULL; ) + { + t = l->next; + free(l); + l = t; + } +} + +/* ----------------------------------------------------------------------------- + * METHODS + */ + +static void +listgraphs () +{ + graph* l; + + 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) + { + printf(" <graph name=\"%s\" category=\"%s\" title=\"%s\"", \ + l->name, l->category, l->title); + + 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 0 +static void +displaygraphs () +{ + char* name = NULL; + int width; + int height; + char* q; + char* query = NULL; + + 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") == ) + height = atoi(vl); + } + + } +} +#endif + +/* ----------------------------------------------------------------------------- + * MAIN + */ + +static void +usererror (const char* 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); +} + +static int +pathstarts (const char* path, const char* method) +{ + int len = strlen(method); + + if (strncmp(path, method, len) != 0) + return 0; + + if (path[len] == '/' || !path[len]) + return 1; + + return 0; +} + +int +main (int argc, char* argv[]) +{ + char* path; + + conf_directory = getenv("CONFDIR"); + work_directory = getenv("WORKDIR"); + + 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"); + + while (path && path[0] && + (isspace(path[0]) || path[0] == '/')) + path++; + + cfg_parse_dir(conf_directory, NULL); + + if (!path || !path[0] || pathstarts(path, "list")) + listgraphs(); + else if (pathstarts(path, "graph")) + printf("graph\n"); + else + usererror("Invalid request"); + + freegraphs(); + + return 0; +} |