diff options
author | Lauri Leukkunen <lle@rahina.org> | 2007-11-19 02:50:50 +0200 |
---|---|---|
committer | Lauri Leukkunen <lle@rahina.org> | 2007-11-19 23:54:37 +0200 |
commit | 9c9c2cf90c4cb92b4c163067f637bc8a18732150 (patch) | |
tree | c099516e92a4006586310ac5091f9ae01019c9de | |
parent | 0d237a39b06b91674fa26c308270018989542a77 (diff) |
Restructure lua infra
Signed-off-by: Lauri Leukkunen <lle@rahina.org>
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | include/sb2.h | 17 | ||||
-rw-r--r-- | lua_scripts/main.lua | 20 | ||||
-rw-r--r-- | luaif/Makefile | 7 | ||||
-rw-r--r-- | luaif/argvenvp.c | 47 | ||||
-rw-r--r-- | luaif/luaif.c | 23 | ||||
-rw-r--r-- | luaif/paths.c | 246 | ||||
-rw-r--r-- | preload/Makefile | 2 | ||||
-rw-r--r-- | preload/libsb2.h | 2 | ||||
-rw-r--r-- | preload/sb_exec.c | 1 |
10 files changed, 346 insertions, 26 deletions
@@ -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 |