--:Minify:-- 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]... OWNER[:GROUP] FILE...") print(" " .. name .. " [OPTION]... :GROUP FILE...") print("Change the owner and/or group of each FILE.") print("OWNER and GROUP may be names or numeric IDs.") 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 spec = args[1] local ownerStr, groupStr if spec:sub(1,1) == ":" then groupStr = spec:sub(2) else local colon = spec:find(":", 1, true) if colon then ownerStr = spec:sub(1, colon - 1) groupStr = spec:sub(colon + 1) if groupStr == "" then groupStr = nil end else ownerStr = spec end end local function resolveUid(s) if not s or s == "" then return nil end local n = tonumber(s) if n then return n end local uid = syscall.getuidbyname and syscall.getuidbyname(s) if uid then return uid end print(name .. ": invalid user: '" .. s .. "'") syscall.exit(1) end local function resolveGid(s) if not s or s == "" then return nil end 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 newUid = resolveUid(ownerStr) local newGid = resolveGid(groupStr) if newUid == nil and newGid == nil then print(name .. ": no owner or group specified") syscall.exit(1); return end local function chownPath(path) local stat = syscall.stat(path) if not stat then print(name .. ": cannot stat '" .. path .. "': no such file or directory") return false end local uid = newUid ~= nil and newUid or stat.owner local gid = newGid ~= nil and newGid or stat.group local ok, err = pcall(syscall.chown, path, uid, gid) 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 owner of '" .. path .. "': " .. msg) return false end return true end local function chownRecursive(path) if not chownPath(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 chownRecursive(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 chownRecursive(path) else if not chownPath(path) then exitCode = 1 end end end syscall.exit(exitCode)