From: Anton Hillebrand Date: Thu, 11 May 2017 10:02:47 +0000 (+0200) Subject: Moved parse_mode code from c to lua. X-Git-Tag: e2factory-2.3.17p0~8 X-Git-Url: https://git.e2factory.org/?a=commitdiff_plain;h=5169fed9a4e977ce144c091df23b577467ae7b6e;p=e2factory.git Moved parse_mode code from c to lua. Signed-off-by: Anton Hillebrand --- diff --git a/generic/e2lib.lua b/generic/e2lib.lua index 6b7a5bd..c76f083 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -2047,14 +2047,125 @@ end -- @return Numeric mode or false on error. -- @return Error object on failure. function e2lib.parse_mode(modestring) - local rc, errstring = le2lib.parse_mode(modestring) + --- check for with octal numbers + if tonumber(modestring) ~= nil then + if string.len(modestring) == 3 then + local out = 0 + local index = 0 + for mode in string.gmatch(modestring, "%S") do + if tonumber(mode) > 7 then + return false, err.new("cannot parse mode string '%s': mode is a number between 0 and 7", tostring(modestring)) + end + out = out + tonumber(mode) * 8^(2 - index) + index = index + 1 + end + return out + else + return false, err.new("cannot parse mode string '%s': octal string is exactly 3 characters long", tostring(modestring)) + end + end - if not rc then - return false, err.new("cannot parse mode string '%s': %s", modestring, - errstring) + --- VARIABLE SETUP + local perm = { -- w r x + user = {w = 0, r = 0, x = 0}, -- u + group = {w = 0, r = 0, x = 0}, -- g + other = {w = 0, r = 0, x = 0}, -- o + } + local class_name = {} + local func + local operator = "" + + --- state functions + -- state function for permissions + local function permissions(char) + if char == "X" then + char = "x" -- cast special Executable to normal executable for calculation reasons + end + if char == "," then + return "reset" + elseif char ~= "w" and char ~= "r" and char ~= "x" then + return false, err.new("cannot parse mode string '%s': unknown permission mode: %s", modestring, char) + end + + for ow in pairs(class_name) do + if operator == "+" then + perm[ow][char] = 1 + elseif operator == "-" then + perm[ow][char] = 0 + elseif operator == "=" then + perm[ow][char] = 1 + else + return false, err.new("cannot parse mode string '%s': unknown operator in permission evaluation: %s", modestring, char) + end + end end - return rc + -- state function for operators + local function op(char) + if char == "=" or char == "-" or char == "+" then + func = permissions + operator = char + if char == "=" then + -- nulling the given classs. + -- If we do this, we only need to set the given modes to 1 later + for ow in pairs(class_name) do + for p in pairs(perm[ow]) do + perm[ow][p] = 0 + end + end + end + else + return false, err.new("cannot parse mode string '%s': unknown operator: %s", modestring, char) + end + end + + -- state function for class + local function class(char) + if char == "u" then + class_name["user"] = 1 + elseif char == "g" then + class_name["group"] = 1 + elseif char == "o" then + class_name["other"] = 1 + elseif char == "a" then + class_name["user"] = 1 + class_name["group"] = 1 + class_name["other"] = 1 + else + -- calculate size of user_name table + local table_size = 0 + for _ in pairs(class_name) do + table_size = table_size + 1 + end + if table_size == 0 then -- if no entry is in user_name, string is invalid + return false, err.new("cannot parse mode string '%s': no valid class given", modestring) + end + return op(char) -- pass char to actual current state, which is 'operator' + end + end + func = class + + --- evaluting the string + for c in string.gmatch(modestring, "%S") do + local re, re_err + re, re_err = func(c) -- the func(c) call does the most magic here + if re ~= nil then + if re == "reset" then + class_name = {} + operator = "" + func = class + end + if (not re) and re_err then + return false, re_err + end + end + end + + -- calculate classs permissions as decimals + local out_other = perm["other"]["r"] * 4 + perm["other"]["w"] * 2 + perm["other"]["x"] + local out_group = (perm["group"]["r"] * 4 + perm["group"]["w"] * 2 + perm["group"]["x"]) * 8 + local out_user = (perm["user"]["r"] * 4 + perm["user"]["w"] * 2 + perm["user"]["x"]) * 64 + return out_user + out_group + out_other end --- Create a single directory.