118 lines
3.4 KiB
Plaintext
118 lines
3.4 KiB
Plaintext
--:Minify:--
|
|
-- chgrp: change group ownership
|
|
local name = syscall.getTask(syscall.getpid()).name
|
|
local cloptions = { R = false, help = false }
|
|
local args = {}
|
|
|
|
for _, v in ipairs({ ... }) do
|
|
if v:sub(1, 2) == "--" then
|
|
local opt = v:sub(3)
|
|
if cloptions[opt] == nil then
|
|
print(name .. ": unrecognized option '" .. v .. "'")
|
|
print("try '" .. name .. " --help' for more information.")
|
|
syscall.exit(1); return
|
|
end
|
|
cloptions[opt] = true
|
|
elseif v:sub(1, 1) == "-" then
|
|
for i = 2, #v do
|
|
local opt = v:sub(i, i)
|
|
if cloptions[opt] == nil then
|
|
print(name .. ": invalid option '-" .. opt .. "'")
|
|
print("try '" .. name .. " --help' for more information.")
|
|
syscall.exit(1); return
|
|
end
|
|
cloptions[opt] = true
|
|
end
|
|
else
|
|
table.insert(args, v)
|
|
end
|
|
end
|
|
|
|
if cloptions.help then
|
|
print("Usage: " .. name .. " [OPTION]... GROUP FILE...")
|
|
print("Change the group of each FILE to GROUP.")
|
|
print("GROUP may be a group name or numeric ID.")
|
|
print("")
|
|
print("Options:")
|
|
print(" -R operate on files and directories recursively")
|
|
print(" --help display this help and exit")
|
|
return
|
|
end
|
|
|
|
if #args < 2 then
|
|
print(name .. ": missing operand")
|
|
print("try '" .. name .. " --help' for more information.")
|
|
syscall.exit(1); return
|
|
end
|
|
|
|
local groupStr = args[1]
|
|
|
|
local function resolveGid(s)
|
|
local n = tonumber(s)
|
|
if n then return n end
|
|
local uid = syscall.getuidbyname and syscall.getuidbyname(s)
|
|
if uid then
|
|
local pwent = syscall.getpasswd(uid)
|
|
if pwent then return pwent.gid end
|
|
end
|
|
print(name .. ": invalid group: '" .. s .. "'")
|
|
syscall.exit(1)
|
|
end
|
|
|
|
local newGid = resolveGid(groupStr)
|
|
|
|
local function chgrpPath(path)
|
|
local stat = syscall.stat(path)
|
|
if not stat then
|
|
print(name .. ": cannot stat '" .. path .. "': no such file or directory")
|
|
return false
|
|
end
|
|
local ok, err = pcall(syscall.chown, path, stat.owner, newGid)
|
|
if not ok then
|
|
local msg = tostring(err)
|
|
if msg:find("EPERM") or msg:find("EACCES") then
|
|
msg = "operation not permitted (must be root)"
|
|
elseif msg:find("ENOENT") then
|
|
msg = "no such file or directory"
|
|
end
|
|
print(name .. ": cannot change group of '" .. path .. "': " .. msg)
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function chgrpRecursive(path)
|
|
if not chgrpPath(path) then return end
|
|
if syscall.type(path) == "directory" then
|
|
local ok, list = pcall(syscall.listdir, path)
|
|
if ok then
|
|
for _, entry in ipairs(list) do
|
|
local child = path
|
|
if child:sub(-1) ~= "/" then child = child .. "/" end
|
|
chgrpRecursive(child .. entry)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local cwd = syscall.getcwd()
|
|
local function absPath(p)
|
|
if p:sub(1,1) ~= "/" then p = cwd .. "/" .. p end
|
|
return p
|
|
end
|
|
|
|
local exitCode = 0
|
|
for i = 2, #args do
|
|
local path = absPath(args[i])
|
|
if not syscall.exists(path) then
|
|
print(name .. ": cannot access '" .. args[i] .. "': No such file or directory")
|
|
exitCode = 1
|
|
elseif cloptions.R then
|
|
chgrpRecursive(path)
|
|
else
|
|
if not chgrpPath(path) then exitCode = 1 end
|
|
end
|
|
end
|
|
|
|
syscall.exit(exitCode)
|