diff options
author | Steven Barth <steven@midlink.org> | 2008-05-28 15:28:13 +0000 |
---|---|---|
committer | Steven Barth <steven@midlink.org> | 2008-05-28 15:28:13 +0000 |
commit | 4365fbe2a373b73af5578d0ed6eddfb2ba9901ef (patch) | |
tree | cdc534c74a881b666012a92a645ff22c973a11a7 /libs/sgi-webuci/src/luci.c | |
parent | 776f9957d0376670e9d3e43677dbe3ba19ded193 (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.c | 216 |
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, +}; |