summaryrefslogtreecommitdiff
path: root/lua_scripts
diff options
context:
space:
mode:
authorLauri Aarnio <Lauri.Aarnio@iki.fi>2008-10-23 17:27:55 +0300
committerLauri Leukkunen <lle@rahina.org>2008-10-23 19:18:01 +0300
commit0a44f98a97a22eb57ac34dea67623a2188038eda (patch)
tree23530e1eb51f5dab742443018eb14220c5b259d5 /lua_scripts
parentb779e037736239d3b8005506b898456c66c11a2a (diff)
Added path reversing logic; getcwd() etc now return backward-mapped results - i.e. getcwd(), realpath(), get_current_dir_name_gate() and getwd() now return the place where SB2 pretends to be, not the real path anymore - reverse mapping rules are created automatically when the session is created. However, there are still some situations where reverse mapping is disabled (see lua_scripts/create_reverse_rules.lua for details) - This also fixes a nasty bug with "mkdir -p" (which created directories to wrong locations in certain situations. "mkdir" witout "-p" was OK) - sb2-show: added new command "realcwd" - "devel" mapping mode: some paths were classified as virtual (virtual_path is a new attribute for rules: It disables reversing of that rule) - "simple" mapping mode: ~/.scratchbox2, .../share/scratchbox2 and /usr/bin/sb2-show were added to mapping rules - luaif.c: sb.decolonize_path() was disabled (It isn't anymore used from our Lua scripts, but I didn't
Diffstat (limited to 'lua_scripts')
-rw-r--r--lua_scripts/create_reverse_rules.lua255
-rw-r--r--lua_scripts/mapping.lua65
-rw-r--r--lua_scripts/pathmaps/devel/00_default.lua9
-rw-r--r--lua_scripts/pathmaps/simple/00_default.lua9
4 files changed, 332 insertions, 6 deletions
diff --git a/lua_scripts/create_reverse_rules.lua b/lua_scripts/create_reverse_rules.lua
new file mode 100644
index 0000000..ad9f758
--- /dev/null
+++ b/lua_scripts/create_reverse_rules.lua
@@ -0,0 +1,255 @@
+-- Copyright (c) 2008 Nokia Corporation.
+-- Author: Lauri T. Aarnio
+--
+-- Licensed under MIT license
+
+-- This script is executed once after a new SB2 session has been created,
+-- to create reversing rules for path mapping (see utils/sb2).
+-- This is still simple, and may not work in all cases: This script
+-- will shut down if problems are detected (then path reversing won't be
+-- available and SB2 works just as it did before this feature was implemented)
+--
+-- FIXME:
+-- 1. Rules with conditional actions are not reversed correctly. Basically,
+-- this script just gives up and marks the destinations with "use_orig_path".
+-- This should be fixed, even if it is not a problem with our current
+-- "official" mapping modes.
+--
+-- 2. Reverse rules won't be created if the forward rules use "func_name"
+-- conditions. It might be possible to fix that, but "func_names" certainly
+-- complicate sorting of the generated reversing rules.
+--
+-- 3. Rule chains with "next_chain" set to something else than 'nil'
+-- are not currently supported.
+
+allow_reversing = true -- default = create reverse rules.
+
+-- Order of reverse rules is not necessarily the same as order of forward rules
+function test_rev_rule_position(output_rules, d_path)
+ local n
+ for n=1,table.maxn(output_rules) do
+ local rule = output_rules[n]
+ if (rule.prefix and (rule.prefix ~= "") and
+ (isprefix(rule.prefix, d_path))) then
+ return n
+ end
+ -- "path" rules: (exact match)
+ if (rule.path == d_path) then
+ return n
+ end
+ end
+ return nil
+end
+
+function reverse_one_rule(output_rules, rule, n)
+ local new_rule = {}
+ new_rule.comments = {}
+
+ if rule.name then
+ new_rule.name = string.format(
+ "Rev: %s (%d)", rule.name, n)
+ else
+ new_rule.name = string.format(
+ "Rev: Rule %d", n)
+ end
+
+ local forward_path
+ if (rule.prefix) then
+ forward_path = rule.prefix
+ elseif (rule.path) then
+ forward_path = rule.path
+ else
+ forward_path = nil
+ new_rule.error = string.format(
+ "--ERROR: Rule '%s' does not contain 'prefix' or 'path'",
+ new_rule.name)
+ end
+
+ if (rule.func_name ~= nil) then
+ allow_reversing = false
+ end
+
+ local d_path
+ if (rule.use_orig_path) then
+ new_rule.use_orig_path = true
+ d_path = forward_path
+ elseif (rule.actions) then
+ -- FIXME: To be implemented. See the "TODO" list at top.
+ new_rule.use_orig_path = true
+ d_path = forward_path
+ elseif (rule.map_to) then
+ d_path = rule.map_to .. forward_path
+ new_rule.replace_by = forward_path
+ elseif (rule.replace_by) then
+ d_path = rule.replace_by
+ new_rule.replace_by = forward_path
+ else
+ new_rule.error = string.format(
+ "--ERROR: Rule '%s' does not contain any actions",
+ new_rule.name)
+ end
+
+ local idx
+ if (rule.prefix) then
+ new_rule.prefix = d_path
+ new_rule.orig_prefix = rule.prefix
+ idx = test_rev_rule_position(output_rules, d_path..":")
+ elseif (rule.path) then
+ new_rule.path = d_path
+ new_rule.orig_path = rule.path
+ idx = test_rev_rule_position(output_rules, d_path)
+ end
+
+ if (idx ~= nil) then
+ -- a conflict, must reorganize
+ table.insert(new_rule.comments, string.format(
+ "--NOTE: '%s' conflicts with '%s', reorganized",
+ new_rule.name, output_rules[idx].name))
+
+ local x_path = nil
+ if (output_rules[idx].prefix) then
+ x_path = output_rules[idx].prefix
+ elseif (output_rules[idx].path) then
+ x_path = output_rules[idx].path
+ end
+
+ table.insert(output_rules, idx, new_rule)
+
+ if x_path then
+ local idx2
+ idx2 = test_rev_rule_position(output_rules, x_path)
+
+ if idx2 ~= idx+1 then
+ table.insert(new_rule.comments, string.format(
+ "--NOTE: '%s' DOUBLE CONFLICT with '%s'",
+ new_rule.name, output_rules[idx].name))
+ end
+ end
+
+ else
+ -- no conflicts
+ table.insert(output_rules, new_rule)
+ end
+end
+
+function reverse_rules(input_rules)
+ local output_rules = {}
+ local n
+ for n=1,table.maxn(input_rules) do
+ local rule = input_rules[n]
+
+ if rule.virtual_path then
+ -- don't reverse virtual paths
+ print("-- virtual_path set, not reversing", n)
+ else
+ reverse_one_rule(output_rules, rule, n)
+ end
+
+ end
+ return(output_rules)
+end
+
+function print_rules(rules)
+ local n
+ for n=1,table.maxn(rules) do
+ local rule = rules[n]
+
+ print(string.format("\t{name=\"%s\",", rule.name))
+
+ local k
+ for k=1,table.maxn(rule.comments) do
+ print(rule.comments[k])
+ end
+
+ if (rule.orig_prefix) then
+ print("\t -- orig_prefix", rule.orig_prefix)
+ end
+ if (rule.orig_path) then
+ print("\t -- orig_path", rule.orig_path)
+ end
+
+ if (rule.prefix) then
+ print("\t prefix=\""..rule.prefix.."\",")
+ end
+ if (rule.path) then
+ print("\t path=\""..rule.path.."\",")
+ end
+
+ if (rule.use_orig_path) then
+ print("\t use_orig_path=true,")
+ end
+ -- FIXME: To be implemented. See the "TODO" list at top.
+ -- elseif (rule.actions) then
+ -- print("\t -- FIXME: handle 'actions'")
+ -- print(string.format(
+ -- "\t %s=\"%s\",\n\t use_orig_path=true},",
+ -- sel, fwd_target))
+ if (rule.map_to) then
+ print("\t map_to=\""..rule.map_to.."\",")
+ end
+ if (rule.replace_by) then
+ print("\t replace_by=\""..rule.replace_by.."\",")
+ end
+ if (rule.error) then
+ print("\t -- ",rule.error)
+ allow_reversing = false
+ end
+ print("\t},")
+ end
+end
+
+function process_chains(chains_table)
+ local n
+
+ for n=1,table.maxn(chains_table) do
+ if chains_table[n].noentry then
+ print("-- ========== ",n)
+ print("-- noentry")
+ else
+ print(string.format("-- ======= Chain %d =======",n))
+ print(string.format("reverse_chain_%d = {",n))
+
+ if chains_table[n].next_chain then
+ -- FIXME: Handle next_chain!!!
+ print(" -- NOTE: next_chain is not nil,")
+ print(" -- can't create reversing rules")
+ allow_reversing = false
+ else
+ print(" next_chain=nil,")
+ end
+
+ if chains_table[n].binary then
+ print(string.format(" binary=\"%s\",",
+ chains_table[n].binary,"\n"))
+ else
+ print(" binary=nil,")
+ end
+
+ local rev_rules = reverse_rules(chains_table[n].rules)
+ if (allow_reversing) then
+ print(" rules={")
+ print_rules(rev_rules)
+ print(" }")
+ end
+ print("}")
+ end
+ end
+
+ if (allow_reversing) then
+ print("reverse_chains = {")
+ for n=1,table.maxn(chains_table) do
+ if chains_table[n].noentry then
+ print(string.format(" -- %d = noentry",n))
+ else
+ print(string.format(" reverse_chain_%d,",n))
+ end
+ end
+ print("}")
+ else
+ print("-- Failed to create reverse rules.")
+ print("reverse_chains = nil")
+ end
+end
+
+process_chains(active_mode_mapping_rule_chains)
+
diff --git a/lua_scripts/mapping.lua b/lua_scripts/mapping.lua
index f42aee9..1e4adde 100644
--- a/lua_scripts/mapping.lua
+++ b/lua_scripts/mapping.lua
@@ -133,6 +133,21 @@ active_mode_exec_policy_chains = {}
load_and_check_rules()
+-- load reverse mapping rules, if those have been created
+-- (the file does not exist during the very first round here)
+reverse_chains = nil
+if (sb.path_exists(session_dir .. "/rev_rules.lua")) then
+ sb.log("debug", "Loading reverse rules")
+ do_file(session_dir .. "/rev_rules.lua")
+end
+if (debug_messages_enabled) then
+ if reverse_chains ~= nil then
+ sb.log("debug", "Loaded reverse rules")
+ else
+ sb.log("debug", "No reverse rules")
+ end
+end
+
function sbox_execute_replace_rule(path, replacement, rule)
local ret = nil
@@ -283,11 +298,20 @@ function find_rule(chain, func, full_path)
or string.match(func, wrk.rules[i].func_name))) then
-- "prefix" rules:
-- compare prefix (only if a non-zero prefix)
+ local rulename
+ if (debug_messages_enabled) then
+ rulename = wrk.rules[i].name
+ if rulename == nil then
+ rulename = string.format("#%d",i)
+ end
+ end
if (wrk.rules[i].prefix and
(wrk.rules[i].prefix ~= "") and
(isprefix(wrk.rules[i].prefix, full_path))) then
if (debug_messages_enabled) then
- sb.log("noise", string.format("selected prefix rule %d (%s)", i, wrk.rules[i].prefix))
+ sb.log("noise", string.format(
+ "selected prefix rule '%s' (%s)",
+ rulename, wrk.rules[i].prefix))
end
min_path_len = string.len(wrk.rules[i].prefix)
return wrk.rules[i], min_path_len
@@ -295,7 +319,9 @@ function find_rule(chain, func, full_path)
-- "path" rules: (exact match)
if (wrk.rules[i].path == full_path) then
if (debug_messages_enabled) then
- sb.log("noise", string.format("selected path rule %d (%s)", i, wrk.rules[i].path))
+ sb.log("noise", string.format(
+ "selected path rule '%s' (%s)",
+ rulename, wrk.rules[i].path))
end
min_path_len = string.len(wrk.rules[i].path)
return wrk.rules[i], min_path_len
@@ -427,3 +453,38 @@ function sb_find_exec_policy(binaryname, mapped_file)
return 0, nil
end
+-- sbox_reverse_path is called from libsb2.so
+-- returns "orig_path"
+function sbox_reverse_path(binary_name, func_name, full_path)
+ -- loop through the chains, first match is used
+ local min_path_len = 0
+ local rule = nil
+ local chain = nil
+
+ if (reverse_chains ~= nil) then
+ chain = find_chain(reverse_chains, binary_name)
+ end
+ if (chain == nil) then
+ -- reverse mapping is an optional feature,
+ -- so it isn't really an error if the rule
+ -- can't be found.
+ sb.log("info", string.format("Unable to find REVERSE chain for: %s(%s)",
+ func_name, full_path))
+
+ return nil
+ end
+
+ rule, min_path_len = find_rule(chain, func_name, full_path)
+ if (not rule) then
+ -- not even a default rule found
+ sb.log("info", string.format("Unable to find REVERSE rule for: %s(%s)", func_name, full_path))
+ return nil
+ end
+
+ local rule2, exec_policy2, orig_path, ro2
+ rule2, exec_policy2, orig_path, ro2 = sbox_translate_path(rule,
+ binary_name, func_name, full_path)
+
+ return orig_path
+end
+
diff --git a/lua_scripts/pathmaps/devel/00_default.lua b/lua_scripts/pathmaps/devel/00_default.lua
index b38a451..a0febd5 100644
--- a/lua_scripts/pathmaps/devel/00_default.lua
+++ b/lua_scripts/pathmaps/devel/00_default.lua
@@ -337,28 +337,29 @@ simple_chain = {
-- 98. Scratchbox 1 emulation rules
-- (some packages have hard-coded paths to the SB1 enviroment;
-- replace those by the correct locations in our environment)
+ -- (these are marked "virtual"; these won't be reversed)
-- "libtool" for arm
{prefix = "/scratchbox/compilers/cs2005q3.2-glibc2.5-arm/arch_tools/share/libtool",
replace_by = sb2_share_dir .. "/libtool",
log_level = "warning",
- readonly = true},
+ readonly = true, virtual_path = true},
-- "libtool" for i386
{prefix = "/scratchbox/compilers/cs2005q3.2-glibc-i386/arch_tools/share",
replace_by = tools .. "/usr/share",
log_level = "warning",
- readonly = true},
+ readonly = true, virtual_path = true},
{prefix = "/scratchbox/tools/bin",
replace_by = tools .. "/usr/bin",
log_level = "warning",
- readonly = true},
+ readonly = true, virtual_path = true},
{prefix = "/scratchbox/tools/autotools/automake-1.7/share/automake-1.7",
replace_by = tools .. "/usr/share/automake-1.7",
log_level = "warning",
- readonly = true},
+ readonly = true, virtual_path = true},
-- otherwise, don't map /scratchbox, some people still
-- keep their projects there.
diff --git a/lua_scripts/pathmaps/simple/00_default.lua b/lua_scripts/pathmaps/simple/00_default.lua
index 44311c0..d1534ff 100644
--- a/lua_scripts/pathmaps/simple/00_default.lua
+++ b/lua_scripts/pathmaps/simple/00_default.lua
@@ -30,6 +30,15 @@ simple_chain = {
replace_by = sbox_dir.."/share/scratchbox2/scripts",
readonly = true},
+ {prefix = sbox_user_home_dir .. "/.scratchbox2",
+ use_orig_path = true},
+
+ {prefix = sbox_dir .. "/share/scratchbox2",
+ use_orig_path = true},
+
+ {path = "/usr/bin/sb2-show",
+ use_orig_path = true, readonly = true},
+
-- -----------------------------------------------
-- 99. Other rules.
{prefix = "/lib", map_to = target_root},