summaryrefslogtreecommitdiff
path: root/tools/rrdui-cgi.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/rrdui-cgi.c')
-rw-r--r--tools/rrdui-cgi.c234
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;
+}