From c9708d8eabf178f2fdea371a024045355ff00505 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Sun, 24 Jun 2018 19:23:31 -0300 Subject: fs: add LuaPosix-version of set_permissions This implemention the ugly side-effect of "exposing" some Unix-specific utility functions to the public API, so they can be shared by `luarocks.fs.lua` and `luarocks.fs.unix.tools`. I named those functions `_unix_*` (with a Python-style `_` at the beginning) to clarify that they should not be used publicly. --- src/luarocks/fs/lua.lua | 46 ++++++++++++++++++++++++++++------ src/luarocks/fs/unix.lua | 40 +++++++++++++++++++++++++++++ src/luarocks/fs/unix/tools.lua | 57 +++++++++++------------------------------- 3 files changed, 92 insertions(+), 51 deletions(-) diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index 37e1bffc..b5232a52 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua @@ -788,16 +788,46 @@ local octal_to_rwx = { ["7"] = "rwx", } -function fs_lua.chmod(file, mode) - -- LuaPosix (as of 5.1.15) does not support octal notation... - if mode:sub(1,1) == "0" then - local new_mode = {} - for c in mode:sub(-3):gmatch(".") do - table.insert(new_mode, octal_to_rwx[c]) +do + local umask_cache + function fs_lua._unix_umask() + if umask_cache then + return umask_cache + end + -- LuaPosix (as of 34.0.4) only returns the umask as rwx + local rwx = posix.umask() + local oct = 0 + for i = 1, 9 do + if rwx:sub(10 - i, 10 - i) == "-" then + oct = oct + 2^i + end end - mode = table.concat(new_mode) + umask_cache = ("%03o"):format(oct) + return umask_cache + end +end + +function fs_lua.set_permissions(filename, mode, scope) + local perms + if mode == "read" and scope == "user" then + perms = fs._unix_moderate_permissions("600") + elseif mode == "exec" and scope == "user" then + perms = fs._unix_moderate_permissions("700") + elseif mode == "read" and scope == "all" then + perms = fs._unix_moderate_permissions("644") + elseif mode == "exec" and scope == "all" then + perms = fs._unix_moderate_permissions("755") + else + return false, "Invalid permission " .. mode .. " for " .. scope + end + + -- LuaPosix (as of 5.1.15) does not support octal notation... + local new_perms = {} + for c in perms:sub(-3):gmatch(".") do + table.insert(new_perms, octal_to_rwx[c]) end - local err = posix.chmod(file, mode) + perms = table.concat(new_perms) + local err = posix.chmod(filename, perms) return err == 0 end diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua index dbe48cca..4ca68ce5 100644 --- a/src/luarocks/fs/unix.lua +++ b/src/luarocks/fs/unix.lua @@ -165,4 +165,44 @@ function unix.export_cmd(var, val) return ("export %s='%s'"):format(var, val) end +--- Moderate the given permissions based on the local umask +-- @param perms string: permissions to moderate +-- @return string: the moderated permissions +function unix._unix_moderate_permissions(perms) + local octal_to_rwx = { + ["0"] = "---", + ["1"] = "--x", + ["2"] = "-w-", + ["3"] = "-wx", + ["4"] = "r--", + ["5"] = "r-x", + ["6"] = "rw-", + ["7"] = "rwx", + } + local rwx_to_octal = {} + for octal, rwx in pairs(octal_to_rwx) do + rwx_to_octal[rwx] = octal + end + + local umask = fs._unix_umask() + + local moderated_perms = "" + for i = 1, 3 do + local p_rwx = octal_to_rwx[perms:sub(i, i)] + local u_rwx = octal_to_rwx[umask:sub(i, i)] + local new_perm = "" + for j = 1, 3 do + local p_val = p_rwx:sub(j, j) + local u_val = u_rwx:sub(j, j) + if p_val == u_val then + new_perm = new_perm .. "-" + else + new_perm = new_perm .. p_val + end + end + moderated_perms = moderated_perms .. rwx_to_octal[new_perm] + end + return moderated_perms +end + return unix diff --git a/src/luarocks/fs/unix/tools.lua b/src/luarocks/fs/unix/tools.lua index 06098399..e0b0d22a 100644 --- a/src/luarocks/fs/unix/tools.lua +++ b/src/luarocks/fs/unix/tools.lua @@ -160,47 +160,18 @@ function tools.is_file(file) return fs.execute(vars.TEST, "-f", file) end ---- Moderate the given permissions based on the local umask --- @param perms string: permissions to moderate --- @return string: the moderated permissions -local function moderate_permissions(perms) - local octal_to_rwx = { - ["0"] = "---", - ["1"] = "--x", - ["2"] = "-w-", - ["3"] = "-wx", - ["4"] = "r--", - ["5"] = "r-x", - ["6"] = "rw-", - ["7"] = "rwx", - } - local rwx_to_octal = {} - for octal, rwx in pairs(octal_to_rwx) do - rwx_to_octal[rwx] = octal - end - - local fd = assert(io.popen("umask")) - local umask = assert(fd:read("*a")) - umask = umask:gsub("\n", "") - umask = umask:sub(2, 4) - - local moderated_perms = "" - for i = 1, 3 do - local p_rwx = octal_to_rwx[perms:sub(i, i)] - local u_rwx = octal_to_rwx[umask:sub(i, i)] - local new_perm = "" - for j = 1, 3 do - local p_val = p_rwx:sub(j, j) - local u_val = u_rwx:sub(j, j) - if p_val == u_val then - new_perm = new_perm .. "-" - else - new_perm = new_perm .. p_val - end +do + local umask_cache + function tools._unix_umask() + if umask_cache then + return umask_cache end - moderated_perms = moderated_perms .. rwx_to_octal[new_perm] + local fd = assert(io.popen("umask")) + local umask = assert(fd:read("*a")) + umask = umask:gsub("\n", "") + umask_cache = umask:sub(2, 4) + return umask_cache end - return moderated_perms end --- Set permissions for file or directory @@ -214,13 +185,13 @@ function tools.set_permissions(filename, mode, scope) local perms if mode == "read" and scope == "user" then - perms = moderate_permissions("600") + perms = fs._unix_moderate_permissions("600") elseif mode == "exec" and scope == "user" then - perms = moderate_permissions("700") + perms = fs._unix_moderate_permissions("700") elseif mode == "read" and scope == "all" then - perms = moderate_permissions("644") + perms = fs._unix_moderate_permissions("644") elseif mode == "exec" and scope == "all" then - perms = moderate_permissions("755") + perms = fs._unix_moderate_permissions("755") else return false, "Invalid permission " .. mode .. " for " .. scope end -- cgit v1.2.3-55-g6feb