summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauri Leukkunen <lle@rahina.org>2007-11-19 02:50:50 +0200
committerLauri Leukkunen <lle@rahina.org>2007-11-19 23:54:37 +0200
commit9c9c2cf90c4cb92b4c163067f637bc8a18732150 (patch)
treec099516e92a4006586310ac5091f9ae01019c9de
parent0d237a39b06b91674fa26c308270018989542a77 (diff)
Restructure lua infra
Signed-off-by: Lauri Leukkunen <lle@rahina.org>
-rw-r--r--Makefile7
-rw-r--r--include/sb2.h17
-rw-r--r--lua_scripts/main.lua20
-rw-r--r--luaif/Makefile7
-rw-r--r--luaif/argvenvp.c47
-rw-r--r--luaif/luaif.c23
-rw-r--r--luaif/paths.c246
-rw-r--r--preload/Makefile2
-rw-r--r--preload/libsb2.h2
-rw-r--r--preload/sb_exec.c1
10 files changed, 346 insertions, 26 deletions
diff --git a/Makefile b/Makefile
index eddc2dc..c47345b 100644
--- a/Makefile
+++ b/Makefile
@@ -31,11 +31,14 @@ LLBUILD ?= $(SRCDIR)/llbuild
# targets variable will be filled by llbuild
targets =
-subdirs = mapping preload utils
+subdirs = luaif preload utils
-include config.mak
-CFLAGS += -O2 -g -Wall -W -I$(OBJDIR)/include -I$(SRCDIR)/include -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1
+CFLAGS += -O2 -g -Wall -W
+CFLAGS += -I$(OBJDIR)/include -I$(SRCDIR)/include
+CFLAGS += -I$(SRCDIR)/luaif/lua-5.1.2/src
+CFLAGS += -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1
CFLAGS += -DSCRATCHBOX_ROOT="$(prefix)"
CXXFLAGS =
diff --git a/include/sb2.h b/include/sb2.h
index 4cac62a..6543439 100644
--- a/include/sb2.h
+++ b/include/sb2.h
@@ -7,8 +7,23 @@
#ifndef __SB2_H
#define __SB2_H
-#include <syscall.h>
#include <stdio.h>
+#include <time.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+struct lua_instance {
+ lua_State *lua;
+ char *script_dir;
+ char *main_lua_script;
+ int mapping_disabled;
+};
+
+void sb2_lua_init(void);
+struct lua_instance *get_lua(void);
+char *sb_decolonize_path(const char *path);
int sb_next_execve(const char *filename, char *const argv [],
char *const envp[]);
diff --git a/lua_scripts/main.lua b/lua_scripts/main.lua
new file mode 100644
index 0000000..f017fca
--- /dev/null
+++ b/lua_scripts/main.lua
@@ -0,0 +1,20 @@
+-- Scratchbox2 Lua main file
+-- Copyright (C) 2006, 2007 Lauri Leukkunen
+-- Licensed under MIT license.
+
+
+function do_file(filename)
+ f, err = loadfile(filename)
+ if (f == nil) then
+ error("\nError while loading " .. filename .. ": \n"
+ .. err .. "\n")
+ else
+ f() -- execute the loaded chunk
+ end
+end
+
+lua_scripts = os.getenv("SBOX_LUA_SCRIPTS")
+
+do_file(lua_scripts .. "/mapping.lua")
+do_file(lua_scripts .. "/argvenvp.lua")
+
diff --git a/luaif/Makefile b/luaif/Makefile
index 95068f7..d0bf565 100644
--- a/luaif/Makefile
+++ b/luaif/Makefile
@@ -1,10 +1,9 @@
-LUASRC = mapping/lua-5.1.2/src
+LUASRC = luaif/lua-5.1.2/src
-objs := $(D)/luaif.o $(D)/sb_log.o $(D)/paths.o $(D)argvenvp.o
+objs := $(D)/luaif.o $(D)/sb_log.o $(D)/paths.o $(D)/argvenvp.o
luaif/libluaif.a: $(objs)
-luaif/libluaif.a: override CFLAGS := -O2 -g -fPIC -Wall -W \
- -I$(SRCDIR)/$(LUASRC) $(CFLAGS)
+luaif/libluaif.a: override CFLAGS := $(CFLAGS) -O2 -g -fPIC -Wall -W -I$(SRCDIR)/$(LUASRC)
luaif/libluaif.a: override LDFLAGS := $(LDFLAGS)
luaif/libluaif.a: override LIBS :=
diff --git a/luaif/argvenvp.c b/luaif/argvenvp.c
new file mode 100644
index 0000000..bcba120
--- /dev/null
+++ b/luaif/argvenvp.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2006,2007 Lauri Leukkunen <lle@rahina.org>
+ *
+ * Licensed under LGPL version 2.1, see top level LICENSE file for details.
+ */
+
+#include <stdlib.h>
+
+#include <sb2.h>
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+extern char *dummy;
+char *argvenvp_mode;
+
+int sb_argvenvp(const char *binary_name, const char *func_name,
+ char **argv, char **envp)
+{
+ struct lua_instance *luaif;
+
+ if (!dummy) sb2_lua_init();
+
+ luaif = get_lua();
+ if (!luaif) {
+ printf("Something's wrong with"
+ " the pthreads support.\n");
+ exit(1);
+ }
+
+ if (!(argvenvp_mode = getenv("SBOX_ARGVENVP_MODE"))) {
+ argvenvp_mode = "simple";
+ }
+
+ if (!argv || !envp) {
+ SB_LOG(SB_LOGLEVEL_ERROR,
+ "ERROR: sb_argvenvp: (argv || envp) == NULL");
+ return 1;
+ }
+
+ if (getenv("SBOX_DISABLE_ARGVENVP")) {
+ SB_LOG(SB_LOGLEVEL_DEBUG, "sb_argvenvp disabled(E):");
+ return 0;
+ }
+
+ return 0;
+}
diff --git a/luaif/luaif.c b/luaif/luaif.c
index 3e3a230..26f51b8 100644
--- a/luaif/luaif.c
+++ b/luaif/luaif.c
@@ -40,17 +40,9 @@
#define __set_errno(e) errno = e
-
void mapping_log_write(char *msg);
static int lua_bind_sb_functions(lua_State *l);
-struct lua_instance {
- lua_State *lua;
- char *script_dir;
- char *main_lua_script;
- int mapping_disabled;
-};
-
static pthread_key_t lua_key;
static pthread_once_t lua_key_once = PTHREAD_ONCE_INIT;
@@ -77,18 +69,17 @@ static void alloc_lua(void)
if (!tmp->script_dir) {
tmp->script_dir = "/scratchbox/lua_scripts";
} else {
- tmp->script_dir = strdup(m->script_dir);
+ tmp->script_dir = strdup(tmp->script_dir);
}
- tmp->main_lua_script = calloc(strlen(m->script_dir)
- + strlen("/main.lua") + 1, sizeof(char));
+ tmp->main_lua_script = calloc(strlen(tmp->script_dir)
+ + strlen("/main.lua") + 1, sizeof(char));
- strcpy(tmp->main_lua_script, tmp->script_dir);
- strcat(tmp->main_lua_script, "/main.lua");
+ strcpy(tmp->main_lua_script, tmp->script_dir);
+ strcat(tmp->main_lua_script, "/main.lua");
- SB_LOG(SB_LOGLEVEL_DEBUG, "script_dir: '%s'",
+ SB_LOG(SB_LOGLEVEL_DEBUG, "script_dir: '%s'",
tmp->script_dir);
- }
tmp->lua = luaL_newstate();
@@ -119,7 +110,7 @@ struct lua_instance *get_lua(void)
return (struct lua_instance *)pthread_getspecific(lua_key);
}
-static char *dummy = NULL;
+char *dummy = NULL;
void sb2_lua_init(void) __attribute((constructor));
void sb2_lua_init(void)
diff --git a/luaif/paths.c b/luaif/paths.c
new file mode 100644
index 0000000..6ca0239
--- /dev/null
+++ b/luaif/paths.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2006,2007 Lauri Leukkunen <lle@rahina.org>
+ *
+ * Licensed under LGPL version 2.1, see top level LICENSE file for details.
+ */
+
+#define _GNU_SOURCE
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#ifdef _GNU_SOURCE
+#undef _GNU_SOURCE
+#include <string.h>
+#include <libgen.h>
+#define _GNU_SOURCE
+#else
+#include <string.h>
+#include <libgen.h>
+#endif
+
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <assert.h>
+#include <pthread.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+
+#include <mapping.h>
+#include <sb2.h>
+
+#define enable_mapping(a) a->mapping_disabled--
+#define disable_mapping(a) a->mapping_disabled++
+
+extern char *dummy;
+
+struct path_entry {
+ struct path_entry *prev;
+ struct path_entry *next;
+ char name[PATH_MAX];
+};
+
+char *sb_decolonize_path(const char *path)
+{
+ char *cpath, *index, *start;
+ char cwd[PATH_MAX];
+ struct path_entry list;
+ struct path_entry *work;
+ struct path_entry *new;
+ char *buf = NULL;
+
+ if (!path) {
+ return NULL;
+ }
+
+ buf = malloc((PATH_MAX + 1) * sizeof(char));
+ memset(buf, '\0', PATH_MAX + 1);
+
+ list.next = NULL;
+ list.prev = NULL;
+ work = &list;
+
+ if (path[0] != '/') {
+ /* not an absolute path */
+ memset(cwd, '\0', PATH_MAX);
+ if (!getcwd(cwd, PATH_MAX)) {
+ perror("error getting current work dir\n");
+ return NULL;
+ }
+ unsigned int l = (strlen(cwd) + 1 + strlen(path) + 1);
+ cpath = malloc((strlen(cwd) + 1
+ + strlen(path) + 1) * sizeof(char));
+ if (!cpath)
+ abort();
+
+ memset(cpath, '\0', l);
+ strcpy(cpath, cwd);
+ strcat(cpath, "/");
+ strcat(cpath, path);
+ } else {
+ if (!(cpath = strdup(path)))
+ abort();
+ }
+
+ start = cpath + 1; /* ignore leading '/' */
+ while (1) {
+ unsigned int last = 0;
+
+ index = strstr(start, "/");
+ if (!index) {
+ last = 1;
+ } else {
+ *index = '\0';
+ }
+
+ if (index == start) {
+ goto proceed; /* skip over empty strings
+ resulting from // */
+ }
+
+ if (strcmp(start, "..") == 0) {
+ /* travel up one */
+ if (!work->prev)
+ goto proceed;
+ work = work->prev;
+ free(work->next);
+ work->next = NULL;
+ } else if (strcmp(start, ".") == 0) {
+ /* ignore */
+ goto proceed;
+ } else {
+ /* add an entry to our path_entry list */
+ if (!(new = malloc(sizeof(struct path_entry))))
+ abort();
+ memset(new->name, '\0', PATH_MAX);
+ new->prev = work;
+ work->next = new;
+ new->next = NULL;
+ strcpy(new->name, start);
+ work = new;
+ }
+
+proceed:
+ if (last)
+ break;
+ *index = '/';
+ start = index + 1;
+ }
+
+ work = list.next;
+ while (work) {
+ struct path_entry *tmp;
+ strcat(buf, "/");
+ strcat(buf, work->name);
+ tmp = work;
+ work = work->next;
+ free(tmp);
+ }
+ return buf;
+}
+
+char *scratchbox_path(const char *func_name, const char *path)
+{
+ char binary_name[PATH_MAX+1];
+ char *tmp;
+
+ memset(binary_name, '\0', PATH_MAX+1);
+ tmp = getenv("__SB2_BINARYNAME");
+ if (tmp) {
+ strcpy(binary_name, tmp);
+ } else {
+ strcpy(binary_name, "UNKNOWN");
+ }
+ return scratchbox_path2(binary_name, func_name, path);
+}
+
+
+/* make sure to use disable_mapping(m);
+ * to prevent recursive calls to this function
+ */
+char *scratchbox_path2(const char *binary_name,
+ const char *func_name,
+ const char *path)
+{
+ char work_dir[PATH_MAX + 1];
+ char *tmp = NULL, *decolon_path = NULL, *mapping_mode = NULL;
+ char pidlink[17]; /* /proc/2^8/exe */
+ struct lua_instance *luaif;
+
+ if (!dummy) sb2_lua_init();
+
+ luaif = get_lua();
+ if (!luaif) {
+ printf("Something's wrong with"
+ " the pthreads support.\n");
+ exit(1);
+ }
+
+ if (!(mapping_mode = getenv("SBOX_MAPMODE"))) {
+ mapping_mode = "simple";
+ }
+
+ if (!path) {
+ SB_LOG(SB_LOGLEVEL_ERROR,
+ "ERROR: scratchbox_path2: path==NULL [%s]", func_name);
+ return NULL;
+ }
+
+ if (getenv("SBOX_DISABLE_MAPPING")) {
+ SB_LOG(SB_LOGLEVEL_DEBUG, "disabled(E): %s '%s'",
+ func_name, path);
+ return strdup(path);
+ }
+ if (luaif->mapping_disabled) {
+ SB_LOG(SB_LOGLEVEL_DEBUG, "disabled(%d): %s '%s'",
+ luaif->mapping_disabled, func_name, path);
+ return strdup(path);
+ }
+
+ disable_mapping(luaif);
+ decolon_path = sb_decolonize_path(path);
+
+ memset(work_dir, '\0', PATH_MAX+1);
+ snprintf(pidlink, sizeof(pidlink), "/proc/%i/exe", getpid());
+ getcwd(work_dir, PATH_MAX);
+
+ lua_getfield(luaif->lua, LUA_GLOBALSINDEX, "sbox_translate_path");
+ lua_pushstring(luaif->lua, mapping_mode);
+ lua_pushstring(luaif->lua, binary_name);
+ lua_pushstring(luaif->lua, func_name);
+ lua_pushstring(luaif->lua, work_dir);
+ lua_pushstring(luaif->lua, decolon_path);
+ lua_call(luaif->lua, 5, 1); /* five arguments, one result */
+
+ tmp = (char *)lua_tostring(luaif->lua, -1);
+ if (tmp) {
+ tmp = strdup(tmp);
+ }
+
+ lua_pop(luaif->lua, 1);
+
+ enable_mapping(luaif);
+
+ if (strcmp(tmp, decolon_path) == 0) {
+ free(decolon_path);
+ free(tmp);
+ SB_LOG(SB_LOGLEVEL_INFO, "pass: %s '%s'",
+ func_name, path);
+ return strdup(path);
+ } else {
+ free(decolon_path);
+ SB_LOG(SB_LOGLEVEL_INFO, "mapped: %s '%s' -> '%s'",
+ func_name, path, tmp);
+ return tmp;
+ }
+}
+
diff --git a/preload/Makefile b/preload/Makefile
index c163df2..66a42c7 100644
--- a/preload/Makefile
+++ b/preload/Makefile
@@ -3,7 +3,7 @@ objs := wrappers.o libsb2.o sb_exec.o
PROTOTYPEWARNINGS=-Wmissing-prototypes -Wstrict-prototypes
$(D)/libsb2.so: $(call O,$(objs))
-$(D)/libsb2.so: mapping/libmapping.a mapping/liblua.a
+$(D)/libsb2.so: luaif/libluaif.a luaif/liblua.a
$(D)/libsb2.so: CFLAGS := $(CFLAGS) -fPIC -Wall -W \
$(PROTOTYPEWARNINGS)
$(D)/libsb2.so: LDFLAGS := $(LDFLAGS) -Wl,-soname=$(LIBSB2_SONAME) \
diff --git a/preload/libsb2.h b/preload/libsb2.h
index 1382241..5d09771 100644
--- a/preload/libsb2.h
+++ b/preload/libsb2.h
@@ -45,7 +45,7 @@
#include <sys/stat.h>
#include <sys/times.h>
#include <sys/utsname.h>
-#include <asm/unistd.h>
+//#include <asm/unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdarg.h>
diff --git a/preload/sb_exec.c b/preload/sb_exec.c
index 3b3c0d7..219c9b4 100644
--- a/preload/sb_exec.c
+++ b/preload/sb_exec.c
@@ -213,7 +213,6 @@ int run_qemu(char *qemu_bin, char *orig_file,char *file,
my_argv[i++] = qemu_bin;
my_argv[i++] = "-drop-ld-preload";
my_argv[i++] = "-L";
-
my_argv[i++] = "/";
my_argv[i++] = orig_file; /* we're passing the unmapped file
* here, it works because qemu will