3 * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
4 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2
8 * as published by the Free Software Foundation
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 #include <boa-plugin.h>
24 #define LUAMAIN "luci.lua"
26 static lua_State *L = NULL;
28 extern int luci_parse_header (lua_State *L);
30 static lua_State *luci_context_init(struct httpd_plugin *p)
36 Lnew = luaL_newstate();
42 path = malloc(strlen(p->dir) + sizeof(LUAMAIN) + 2);
44 strcat(path, "/" LUAMAIN);
46 ret = luaL_dofile(Lnew, path);
48 lua_getfield(Lnew, LUA_GLOBALSINDEX, "luci-plugin");
50 if (!lua_istable(Lnew, -1)) {
55 lua_getfield(Lnew, -1, "init");
56 if (!lua_isfunction(Lnew, -1))
59 lua_pushstring(Lnew, p->dir);
60 ret = lua_pcall(Lnew, 1, 0, 0);
70 fprintf(stderr, "Error: ");
72 const char *s = lua_tostring(Lnew, -1);
75 fprintf(stderr, "%s\n", s);
78 fprintf(stderr, "Out of memory!\n");
83 static int luci_init(struct httpd_plugin *p)
85 L = luci_context_init(p);
89 static void pushvar(char *name, char *val)
94 lua_pushstring(L, val);
95 lua_setfield(L, -2, name);
98 static int luci_pcall(lua_State *L, char *func, int narg)
102 ret = lua_pcall(L, narg, narg, 0);
104 const char *s = lua_tostring(L, -1);
106 fprintf(stderr, "Error running %s: %s\n", func, s);
112 ret = lua_isnumber(L, -1);
116 ret = lua_tonumber(L, -1);
123 static int luci_prepare_req(struct httpd_plugin *p, struct http_context *ctx)
128 lua_getglobal(L, "luci-plugin");
129 lua_getfield(L, -1, "reload");
130 if (lua_isboolean(L, -1))
131 reload = lua_toboolean(L, -1);
136 L = luci_context_init(p);
137 lua_getglobal(L, "luci-plugin");
140 lua_getfield(L, -1, "prepare_req");
142 ret = lua_isfunction(L, -1);
146 lua_pushstring(L, ctx->uri);
148 ret = luci_pcall(L, "prepare_req", 1);
155 static int luci_handle_req(struct httpd_plugin *p, struct http_context *ctx)
159 lua_newtable(L); /* new table for the http context */
161 /* convert http_context data structure to lua table */
162 #define PUSH(x) pushvar(#x, ctx->x)
163 PUSH(request_method);
168 lua_pushinteger(L, ctx->remote_port);
169 lua_setfield(L, -2, "remote_port");
171 PUSH(content_length);
175 if (!strncmp(ctx->uri, p->prefix, strlen(p->prefix)))
176 pushvar("uri", ctx->uri + strlen(p->prefix));
178 pushvar("uri", ctx->uri);
181 /* make sure the global 'luci' table is prepared */
182 lua_getglobal(L, "luci-plugin");
183 if (!lua_istable(L, -1))
186 lua_getfield(L, -1, "init_req");
187 if (!lua_isfunction(L, -1)) {
191 lua_pushvalue(L, -3);
192 luci_pcall(L, "init_req", 1);
195 /* storage space for cgi variables */
197 lua_pushvalue(L, -1); /* copy for setfield */
198 lua_setfield(L, -3, "vars");
200 lua_pushvalue(L, -3); /* the http context table */
203 * make luci_parse_header a closure
204 * argument 1: the luci.vars table
205 * argument 2: the http context table
207 lua_pushcclosure(L, luci_parse_header, 2);
208 ret = luci_pcall(L, "parse_header", 0);
210 lua_getfield(L, -1, "handle_req");
211 ret = lua_isfunction(L, -1);
215 lua_pushvalue(L, -3);
216 ret = luci_pcall(L, "handle_req", 1);
218 /* pop the luci and http context tables */
224 static void luci_unload(struct httpd_plugin *p)
233 .prepare_req = luci_prepare_req,
234 .handle_req = luci_handle_req,