Remove INTLLIBS from librazor_la_LIBADD.
This partially reverts 611c84a3f4b4538a65d186050608c17adbf17770.
It's not clear what motivated the initial inclusion of INTLLIBS
here since the net effect is only seen in librazor.la and not
in razor.pc and librazor.la is not normally packaged. Certainly
neither the static nor the dynamic versions of librazor currently
use libintl. At best this would cause the linker to search a
static libintl for undefined symbols without finding any; at worse
it causes a static build of plover using librazor.la to fail if
no static version of libintl is installed.
2 * Copyright (C) 2009 J. Ali Harlow <ali@juiblex.co.uk>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <sys/types.h>
32 #include "razor-internal.h"
36 #define ARG_FLAG_OPT 0x1
37 #define ARG_FLAG_BYPASS 0x2
39 #define ARG(flags, swtch, index, type) \
40 ((flags) << 26 | (swtch) << 21 | \
42 #define ARG_FLAGS(arg) ((unsigned)(arg) >> 26)
43 #define ARG_SWTCH(arg) ((unsigned)(arg) >> 21 & 0x1F)
44 #define ARG_INDEX(arg) ((unsigned)(arg) >> 16 & 0x1F)
45 #define ARG_TYPE(arg) ((unsigned)(arg) & 0xFFFF)
48 #define ARG_STRING(n) ARG(0, 0, n, LUA_TSTRING)
49 #define ARG_OPT_STRING(n) ARG(ARG_FLAG_OPT, 0, n, LUA_TSTRING)
50 #define ARG_BYP_STRING(n, s) ARG(ARG_FLAG_BYPASS, s, n, LUA_TSTRING)
55 unsigned args[MAX_ARGS];
58 static struct razor_proxy proxy[] = {
59 { NULL, "dofile", LUA_TNONE, { ARG_STRING(1) } },
60 { NULL, "loadfile", LUA_TNONE, { ARG_OPT_STRING(1) } },
61 { "io", "input", LUA_TNONE, { ARG_OPT_STRING(1) } },
62 { "io", "output", LUA_TNONE, { ARG_OPT_STRING(1) } },
63 { "io", "lines", LUA_TNONE, { ARG_OPT_STRING(1) } },
64 { "io", "open", LUA_TNONE, { ARG_STRING(1) } },
65 { "io", "popen", LUA_TNONE, { ARG_STRING(1) } },
67 * Note: We do not proxy os.execute
68 * We can't do it properly (there is no way to distinguish filenames
69 * in arguments from any other strings) so it's better not to try.
70 * Scripts that attempt to be portable should use posix.exec[p]
72 { "os", "remove", LUA_TNONE, { ARG_STRING(1) } },
73 { "os", "rename", LUA_TNONE, { ARG_STRING(1), ARG_STRING(2) } },
75 * Note: We do not proxy os.tmpname
76 * It should never be used. scripts should use io.tmpfile instead
77 * if the rather limited functionality it provides suffices. The
78 * proper solution is to implement posix.mkstemp
80 { "posix", "access", LUA_TNONE, { ARG_STRING(1) } },
81 { "posix", "chdir", LUA_TNONE, { ARG_STRING(1) } },
82 { "posix", "chmod", LUA_TNONE, { ARG_STRING(1) } },
83 { "posix", "chown", LUA_TNONE, { ARG_STRING(1) } },
84 { "posix", "dir", LUA_TNONE, { ARG_OPT_STRING(1) } },
85 { "posix", "exec", LUA_TNONE, { ARG_STRING(1) } },
86 { "posix", "execp", LUA_TNONE, { ARG_STRING(1) } },
87 { "posix", "files", LUA_TNONE, { ARG_OPT_STRING(1) } },
88 { "posix", "getcwd", LUA_TSTRING, { ARG_NONE } },
89 { "posix", "glob", LUA_TTABLE, { ARG_STRING(1) } },
90 { "posix", "link", LUA_TNONE, { ARG_BYP_STRING(1, 3), ARG_STRING(2) } },
91 { "posix", "mkdir", LUA_TNONE, { ARG_STRING(1) } },
92 { "posix", "mkfifo", LUA_TNONE, { ARG_STRING(1) } },
93 { "posix", "pathconf", LUA_TNONE, { ARG_STRING(1) } },
94 { "posix", "readlink", LUA_TNONE, { ARG_STRING(1) } },
95 { "posix", "rmdir", LUA_TNONE, { ARG_STRING(1) } },
96 { "posix", "stat", LUA_TNONE, { ARG_STRING(1) } },
97 { "posix", "unlink", LUA_TNONE, { ARG_STRING(1) } },
98 { "posix", "utime", LUA_TNONE, { ARG_STRING(1) } },
101 static lua_CFunction execp_handler;
105 lua_CFunction handler[ARRAY_SIZE(proxy)];
108 static void *alloc_lua(void *user_data, void *ptr, size_t osize, size_t nsize)
114 return realloc(ptr, nsize);
117 static int proxy_execp(lua_State *L)
119 int r, n, err, got_eacces = 0;
120 char *file = strdup(luaL_checkstring(L, 1));
122 const char *s, *e, *path;
123 struct razor_lua *rl;
125 if (*file == '\0' || strchr(file, '/')) {
126 r = execp_handler(L);
131 (void)lua_getallocf(L, (void **)&rl);
133 path = getenv("PATH");
135 path = ":/bin:/usr/bin";
143 n = strlen(rl->root);
144 exe = malloc(n + (e - s) + 1 + strlen(file) + 1);
145 memcpy(exe, rl->root, n);
146 memcpy(exe + n, s, e - s);
149 strcpy(exe + n, file);
151 exe = malloc((e - s) + 1 + strlen(file) + 1);
152 memcpy(exe, s, e - s);
155 strcpy(exe + n, file);
157 /* Ensure exe contains a slash to avoid PATH search */
158 exe = malloc(2 + strlen(file) + 1);
161 strcpy(exe + 2, file);
163 lua_pushstring(L, exe);
167 r = execp_handler(L);
169 err = lua_tointeger(L, -1);
183 lua_pop(L, lua_gettop(L) - n);
200 lua_pushfstring(L, "%s: %s", file, strerror(err));
201 lua_pushinteger(L, err);
207 static int real2fake(lua_State *L, struct razor_lua *rl, int indx)
212 indx += lua_gettop(L) + 1;
214 if (lua_type(L, indx) == LUA_TSTRING) {
215 path = lua_tostring(L, indx);
216 if (path && !strncmp(path, rl->root, strlen(rl->root)) &&
217 (path[strlen(rl->root)] == '/' || !path[strlen(rl->root)])) {
218 lua_pushstring(L, path + strlen(rl->root));
219 lua_replace(L, indx);
227 static int proxy_handler(lua_State *L)
232 struct razor_lua *rl;
233 int method = lua_tointeger(L, lua_upvalueindex(1));
234 struct razor_proxy *rp = proxy + method;
236 (void)lua_getallocf(L, (void **)&rl);
238 for(i = 0; i < MAX_ARGS; i++) {
242 switch (ARG_TYPE(arg)) {
244 if (ARG_FLAGS(arg) & ARG_FLAG_BYPASS)
245 cond = !lua_toboolean(L, ARG_SWTCH(arg));
248 if (ARG_FLAGS(arg) & ARG_FLAG_OPT) {
249 if (lua_isstring(L, ARG_INDEX(arg)))
250 path = lua_tostring(L, ARG_INDEX(arg));
254 path = luaL_checkstring(L, ARG_INDEX(arg));
255 if (cond && path && *path == '/') {
256 lua_pushfstring(L, "%s%s", rl->root, path);
257 lua_replace(L, ARG_INDEX(arg));
261 lua_pushfstring(L, "razor proxy: Unhandled type (%d)",
267 retval = rl->handler[method](L);
269 if (rp->result != LUA_TNONE && !lua_isnil(L, 1)) {
270 switch (rp->result) {
274 real2fake(L, rl, -1);
278 while (lua_next(L, -2)) {
279 if (real2fake(L, rl, -1)) {
280 i = lua_tonumber(L, -2);
281 lua_rawseti(L, -3, i);
287 lua_pushfstring(L, "razor proxy: Unhandled type (%d)",
296 struct razor_lua_loader {
301 static struct razor_preload {
303 struct hashtable modules;
304 struct array name_pool;
305 struct array loaders;
306 } razor_preload = {0};
308 RAZOR_EXPORT void razor_set_lua_loader(const char *modname, void (*loader)())
311 struct razor_lua_loader *ploader, *end;
313 if (!razor_preload.init) {
314 razor_preload.init = 1;
315 array_init(&razor_preload.name_pool);
316 array_init(&razor_preload.loaders);
317 hashtable_init(&razor_preload.modules,
318 &razor_preload.name_pool);
321 name = hashtable_tokenize(&razor_preload.modules, modname);
323 end = razor_preload.loaders.data + razor_preload.loaders.size;
324 for(ploader = razor_preload.loaders.data; ploader < end; ploader++)
325 if (ploader->name == name) {
326 ploader->func = loader;
330 ploader = array_add(&razor_preload.loaders, sizeof(*ploader));
331 ploader->name = name;
332 ploader->func = loader;
335 RAZOR_EXPORT void (*razor_get_lua_loader(const char *modname))()
338 struct razor_lua_loader *ploader, *end;
340 if (!razor_preload.init)
343 name = hashtable_lookup(&razor_preload.modules, modname);
345 end = razor_preload.loaders.data + razor_preload.loaders.size;
346 for(ploader = razor_preload.loaders.data; ploader < end; ploader++)
347 if (ploader->name == name)
348 return ploader->func;
353 static void razor_lua_preload(lua_State *L)
355 struct razor_lua_loader *ploader, *end;
357 if (!razor_preload.init)
360 lua_getfield(L, LUA_GLOBALSINDEX, "package");
361 lua_getfield(L, -1, "preload");
364 end = razor_preload.loaders.data + razor_preload.loaders.size;
365 for(ploader = razor_preload.loaders.data; ploader < end; ploader++) {
366 lua_pushcfunction(L, ploader->func);
368 razor_preload.name_pool.data + ploader->name);
374 int run_lua_script(const char *root, const char *name, const char *body,
375 ssize_t len, int arg1)
381 if (root && strcmp(root, "/"))
386 L = lua_newstate(alloc_lua, &rl);
388 razor_lua_preload(L);
389 lua_getglobal(L, "require");
390 lua_pushstring(L, "posix");
391 if (lua_pcall(L, 1, 1, 0)) {
392 fprintf(stderr, "lua posix: %s\n", lua_tostring(L, -1));
399 for(i = 0; i < ARRAY_SIZE(proxy); i++) {
400 if (proxy[i].table) {
401 lua_getglobal(L, proxy[i].table);
404 n = LUA_GLOBALSINDEX;
405 lua_getfield(L, n, proxy[i].name);
406 rl.handler[i] = lua_tocfunction(L, -1);
409 if (proxy[i].table &&
410 !strcmp(proxy[i].table, "posix") &&
411 !strcmp(proxy[i].name, "execp")) {
412 execp_handler = rl.handler[i];
413 rl.handler[i] = proxy_execp;
415 lua_pushinteger(L, i);
416 lua_pushcclosure(L, proxy_handler, 1);
417 lua_pushvalue(L, -2);
419 lua_setfield(L, n, proxy[i].name);
429 if (luaL_loadbuffer(L, body, len, name)) {
430 fprintf(stderr, "failed to load lua script\n");
436 lua_pushvalue(L, LUA_GLOBALSINDEX);
437 lua_pushliteral(L, "arg");
438 lua_pushvalue(L, -3);
441 lua_pushliteral(L, "<lua>");
442 lua_rawseti(L, -2, 1);
444 lua_pushinteger(L, arg1);
445 lua_rawseti(L, -2, 2);
449 if (lua_pcall(L, 0, 0, 0)) {
450 fprintf(stderr, "lua script failed: %s\n", lua_tostring(L, -1));