summaryrefslogtreecommitdiffhomepage
path: root/libs/sgi-webuci/src/luci.c
diff options
context:
space:
mode:
authorSteven Barth <steven@midlink.org>2008-05-28 15:28:13 +0000
committerSteven Barth <steven@midlink.org>2008-05-28 15:28:13 +0000
commit4365fbe2a373b73af5578d0ed6eddfb2ba9901ef (patch)
treecdc534c74a881b666012a92a645ff22c973a11a7 /libs/sgi-webuci/src/luci.c
parent776f9957d0376670e9d3e43677dbe3ba19ded193 (diff)
Squashed commit of the following:
commit d45d1757d24d8214f730af1a3401dd2bef4a434f Author: Steven <steven@cyrus.homeunix.org> Date: Wed May 28 17:23:27 2008 +0200 * libs/core: Removed dummymode checks in sys * libs/sgi-webuci: Fixes commit b870e8d345bc8912fd8ab61d463b9d68b924a6f4 Author: Felix Fietkau <nbd@openwrt.org> Date: Wed May 28 15:40:10 2008 +0200 fix path to theme commit e3732926bd98db4cc38de6eb8018cd4e55176699 Author: Felix Fietkau <nbd@openwrt.org> Date: Wed May 28 14:56:03 2008 +0200 set the proper path to the config in dummy mode commit a75aecf46f037c98bd6e49b9e48adb735d76d150 Author: Felix Fietkau <nbd@openwrt.org> Date: Wed May 28 14:50:42 2008 +0200 add some dummy mode support commit 12bb39ef606bca6b403cc982213a6597b76dc1b3 Author: Felix Fietkau <nbd@openwrt.org> Date: Wed May 28 14:41:56 2008 +0200 normalize paths commit 7aaad1103fd2bdc75aca158baa6ef191f9a961c6 Author: Felix Fietkau <nbd@openwrt.org> Date: Wed May 28 14:27:26 2008 +0200 add missing require statement commit 5766274bd2511b00c42b474aeeeb3efaca6ded9b Author: Felix Fietkau <nbd@openwrt.org> Date: Wed May 28 14:19:54 2008 +0200 add optional luaposix package (patched for darwin support) commit 9e257a76d03722fc0ce8312aa9952641b21424bd Author: Felix Fietkau <nbd@openwrt.org> Date: Tue May 27 20:21:59 2008 +0200 add missing files, more integration for the boa plugin, fix path to lua modules commit dacc1a98ec946975fcb19f87076dfa7db865fca6 Author: Felix Fietkau <nbd@openwrt.org> Date: Tue May 27 19:42:37 2008 +0200 use "compile" instead of "source" and rename the old version of compile to "compile-all" commit eb14777c4fee1eb5740aba1e5603e481320da7b1 Author: Felix Fietkau <nbd@openwrt.org> Date: Tue May 27 19:41:59 2008 +0200 more boa integration commit df0afb965bf0a987b653e9d0acadf3151179a596 Author: Felix Fietkau <nbd@openwrt.org> Date: Tue May 27 18:33:42 2008 +0200 build boa and the webuci.so plugin along with sgi-webuci commit 878161dabf32066631103d199e2cbaf3f5a7fb07 Author: Felix Fietkau <nbd@openwrt.org> Date: Tue May 27 18:03:16 2008 +0200 add .gitignore
Diffstat (limited to 'libs/sgi-webuci/src/luci.c')
-rw-r--r--libs/sgi-webuci/src/luci.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/libs/sgi-webuci/src/luci.c b/libs/sgi-webuci/src/luci.c
new file mode 100644
index 0000000000..d65fc20b6d
--- /dev/null
+++ b/libs/sgi-webuci/src/luci.c
@@ -0,0 +1,216 @@
+/*
+ * luci
+ * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <boa-plugin.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#define LUAMAIN "luci.lua"
+
+static lua_State *L = NULL;
+
+extern int luci_parse_header (lua_State *L);
+
+static int luci_init(struct httpd_plugin *p)
+{
+ char *path = NULL;
+ int ret = 0;
+
+ L = luaL_newstate();
+ if (!L)
+ goto error;
+
+ luaL_openlibs(L);
+
+ path = malloc(strlen(p->dir) + sizeof(LUAMAIN) + 2);
+ strcpy(path, p->dir);
+ strcat(path, "/" LUAMAIN);
+
+ ret = luaL_dofile(L, path);
+
+ lua_getfield(L, LUA_GLOBALSINDEX, "luci-plugin");
+ do {
+ if (!lua_istable(L, -1)) {
+ ret = 1;
+ break;
+ }
+
+ lua_getfield(L, -1, "init");
+ if (!lua_isfunction(L, -1))
+ break;
+
+ lua_pushstring(L, p->dir);
+ ret = lua_pcall(L, 1, 0, 0);
+ } while (0);
+ free(path);
+
+ if (ret != 0)
+ goto error;
+
+ return 1;
+
+error:
+ fprintf(stderr, "Error: ");
+ if (L) {
+ const char *s = lua_tostring(L, -1);
+ if (!s)
+ s = "unknown error";
+ fprintf(stderr, "%s\n", s);
+ lua_close(L);
+ } else {
+ fprintf(stderr, "Out of memory!\n");
+ }
+ return 0;
+}
+
+static void pushvar(char *name, char *val)
+{
+ if (!val)
+ return;
+
+ lua_pushstring(L, val);
+ lua_setfield(L, -2, name);
+}
+
+static int luci_pcall(lua_State *L, char *func, int narg)
+{
+ int ret;
+
+ ret = lua_pcall(L, narg, narg, 0);
+ if (ret) {
+ const char *s = lua_tostring(L, -1);
+ if (s)
+ fprintf(stderr, "Error running %s: %s\n", func, s);
+ return ret;
+ }
+ if (!narg)
+ return ret;
+
+ ret = lua_isnumber(L, -1);
+ if (!ret)
+ goto done;
+
+ ret = lua_tonumber(L, -1);
+
+done:
+ lua_pop(L, 1);
+ return ret;
+}
+
+static int luci_prepare_req(struct httpd_plugin *p, struct http_context *ctx)
+{
+ int ret;
+
+ lua_getglobal(L, "luci-plugin");
+ lua_getfield(L, -1, "prepare_req");
+
+ ret = lua_isfunction(L, -1);
+ if (!ret)
+ goto done;
+
+ lua_pushstring(L, ctx->uri);
+
+ ret = luci_pcall(L, "prepare_req", 1);
+
+done:
+ lua_pop(L, 1);
+ return ret;
+}
+
+static int luci_handle_req(struct httpd_plugin *p, struct http_context *ctx)
+{
+ int ret;
+
+ lua_newtable(L); /* new table for the http context */
+
+ /* convert http_context data structure to lua table */
+#define PUSH(x) pushvar(#x, ctx->x)
+ PUSH(request_method);
+ PUSH(server_addr);
+ PUSH(server_proto);
+ PUSH(query_string);
+ PUSH(remote_addr);
+ lua_pushinteger(L, ctx->remote_port);
+ lua_setfield(L, -2, "remote_port");
+ PUSH(content_type);
+ PUSH(content_length);
+ PUSH(http_accept);
+#undef PUSH
+
+ if (!strncmp(ctx->uri, p->prefix, strlen(p->prefix)))
+ pushvar("uri", ctx->uri + strlen(p->prefix));
+ else
+ pushvar("uri", ctx->uri);
+
+
+ /* make sure the global 'luci' table is prepared */
+ lua_getglobal(L, "luci-plugin");
+ if (!lua_istable(L, -1))
+ return 0;
+
+ lua_getfield(L, -1, "init_req");
+ if (!lua_isfunction(L, -1)) {
+ /* ignore error */
+ lua_pop(L, 1);
+ } else {
+ lua_pushvalue(L, -3);
+ luci_pcall(L, "init_req", 1);
+ }
+
+ /* storage space for cgi variables */
+ lua_newtable(L);
+ lua_pushvalue(L, -1); /* copy for setfield */
+ lua_setfield(L, -3, "vars");
+
+ lua_pushvalue(L, -3); /* the http context table */
+
+ /*
+ * make luci_parse_header a closure
+ * argument 1: the luci.vars table
+ * argument 2: the http context table
+ */
+ lua_pushcclosure(L, luci_parse_header, 2);
+ ret = luci_pcall(L, "parse_header", 0);
+
+ lua_getfield(L, -1, "handle_req");
+ ret = lua_isfunction(L, -1);
+ if (!ret)
+ goto done;
+
+ lua_pushvalue(L, -3);
+ ret = luci_pcall(L, "handle_req", 1);
+
+ /* pop the luci and http context tables */
+done:
+ lua_pop(L, 2);
+ return ret;
+}
+
+static void luci_unload(struct httpd_plugin *p)
+{
+ lua_close(L);
+}
+
+HTTPD_PLUGIN {
+ .prefix = "/luci/",
+ .init = luci_init,
+ .done = luci_unload,
+ .prepare_req = luci_prepare_req,
+ .handle_req = luci_handle_req,
+};