added seperate input and working on http / sockets

This commit is contained in:
2026-05-27 17:01:26 -04:00
parent 59e09a5995
commit f7b64c11b7
43 changed files with 5035 additions and 533 deletions
+169
View File
@@ -0,0 +1,169 @@
--:Minify:--
syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
syscall.open("/dev/tty/1", "w") --stdout (fd 1)
syscall.open("/dev/null", "w") --stderr (fd 2)
local MAX_ATTEMPTS = 3
local function readLine(mask)
local input = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then
syscall.write(1, "\n")
return input
elseif ch == "\b" then
if #input > 0 then
input = input:sub(1, -2)
syscall.write(1, "\b \b")
end
else
input = input .. ch
syscall.write(1, mask or ch)
end
end
end
local function firstBoot()
local shadow = ""
local _fd, _fderr = pcall(function()
local fd = syscall.open("/etc/shadow", "r")
shadow = syscall.read(fd, 65535) or ""
syscall.close(fd)
end)
if shadow:match("%S") then return end
syscall.devctl(1, "clear")
syscall.devctl(1, "spos", 1, 1)
syscall.devctl(1, "sfgc", 0x00FF00)
syscall.write(1, "HyperionOS First Boot Setup\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.write(1, "No root password is set. Please create one now.\n\n")
while true do
syscall.write(1, "New root password: ")
local pw1 = readLine("*")
syscall.write(1, "Confirm password: ")
local pw2 = readLine("*")
if pw1 ~= pw2 then
syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Passwords do not match. Try again.\n\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
elseif #pw1 < 6 then
syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Password too short (minimum 6 characters).\n\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
else
local ok, err = syscall.setpassword(0, pw1)
if ok then
syscall.devctl(1, "sfgc", 0x00FF00)
syscall.write(1, "Root password set.\n\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.5)
break
else
syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Error: " .. tostring(err) .. "\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
end
end
end
end
local function spawnShell(username, uid, shell, homedir)
local existsOk, existsErr = pcall(syscall.exists, shell)
if not existsOk or not existsErr then
syscall.write(1, "login: shell not found: " .. shell .. "\n")
sleep(2)
return false
end
local accessOk, accessErr = pcall(syscall.access, shell, "rx")
syscall.setEnviron("HOME", homedir)
syscall.setEnviron("USER", username)
syscall.setEnviron("SHELL", shell)
syscall.setEnviron("PATH", "/bin/")
local setuidOk, setuidErr = pcall(syscall.setuid, uid)
if not setuidOk then
syscall.write(1, "login: setuid failed: " .. tostring(setuidErr) .. "\n")
sleep(2)
return false
end
local chdirOk, chdirErr = pcall(syscall.chdir, homedir)
if not chdirOk then
pcall(syscall.chdir, "/")
end
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell")
if not ok then
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
sleep(2)
return false
end
syscall.exit(0)
end
local function doLogin()
syscall.devctl(1, "clear")
syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.devctl(1, "sbgc", 0x000000)
syscall.devctl(1, "spos", 1, 1)
local hostname = syscall.getHostname() or "hyperion"
syscall.write(1, "HyperionOS\n")
syscall.write(1, hostname .. " login\n\n")
local attempts = 0
while attempts < MAX_ATTEMPTS do
syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.write(1, "Username: ")
local username = readLine(nil)
if username ~= "" then
syscall.write(1, "Password: ")
local password = readLine("*")
local uid = syscall.getuidbyname(username)
local ok, err = syscall.login(uid, password)
if ok then
local uid = syscall.getuid()
local pwent = syscall.getpasswd(uid)
local shell = (pwent and pwent.shell) or "/bin/hysh"
local homedir = (pwent and pwent.homedir) or "/"
syscall.devctl(1, "sfgc", 0x00FF00)
syscall.write(1, "\nWelcome, " .. username .. "!\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3)
spawnShell(username, uid, shell, homedir)
return -- back to login prompt
else
attempts = attempts + 1
sleep(1)
syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Login incorrect.\n\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
end
end
end
syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Maximum login attempts exceeded.\n")
syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(5)
end
firstBoot()
while true do
doLogin()
end
+19
View File
@@ -0,0 +1,19 @@
--:Minify:--
local users = syscall.listusers()
if not users or #users == 0 then
print("No users found.")
return
end
syscall.devctl(1,"sfgc",0xDBDBDB)
print(string.format("%-6s %-6s %-16s %-20s %s", "UID", "GID", "Username", "Home", "Shell"))
print(string.rep("-", 65))
syscall.devctl(1,"sfgc",0xFFFFFF)
for _, u in ipairs(users) do
local lock_marker = u.locked and " [locked]" or ""
if u.locked then syscall.devctl(1,"sfgc",0xFF0000) end
print(string.format("%-6d %-6d %-16s %-20s %s%s",
u.uid, u.gid, u.username, u.homedir, u.shell, lock_marker))
if u.locked then syscall.devctl(1,"sfgc",0xFFFFFF) end
end
+152
View File
@@ -0,0 +1,152 @@
--:Minify:--
-- Usage:
-- mount list all current mounts
-- mount <id> <mountpoint> mount loop device id at mountpoint
-- mount -o loop <src> <dest> attach <src> as loop device and mount at <dest>
-- mount --help
local name = syscall.getTask(syscall.getpid()).name
local args, opts = {}, { help=false, o=nil }
local i = 1
local rawArgs = {...}
while i <= #rawArgs do
local v = rawArgs[i]
if v:sub(1,2) == "--" then
local o = v:sub(3)
if o == "help" then opts.help = true
else print(name..": unrecognised option '"..v.."'")
print("try '"..name.." --help' for more information.")
syscall.exit(1); return end
elseif v == "-o" then
i = i + 1
opts.o = rawArgs[i]
elseif v:sub(1,1) == "-" then
local rest = v:sub(2)
if rest:sub(1,1) == "o" then
if #rest > 1 then opts.o = rest:sub(2)
else i = i + 1; opts.o = rawArgs[i] end
else
print(name..": invalid option '"..v.."'")
print("try '"..name.." --help' for more information.")
syscall.exit(1); return
end
else
table.insert(args, v)
end
i = i + 1
end
if opts.help then
print("Usage: "..name)
print(" "..name.." <id> <mountpoint>")
print(" "..name.." -o loop <source> <mountpoint>")
print("")
print("Mount a loop device or filesystem.")
print("")
print(" (no args) list all active mount points")
print(" <id> <mountpoint> mount an already-attached loop device")
print(" -o loop <src> <dest> attach src as loop device and mount at dest")
print(" src can be a directory (bind) or .hfs image")
print("")
print("Requires root for all operations except listing.")
return
end
if #args == 0 and not opts.o then
local ok, mounts = pcall(syscall.mounts or function()
error("ENOSYS")
end)
local loDevs = {}
local lok, ld = pcall(syscall.lolist)
if lok then
for id, info in pairs(ld) do
local path = (type(info)=="table" and info.path) or tostring(info)
local mode = (type(info)=="table" and info.mode) or "bind"
loDevs[id] = { path=path, mode=mode }
end
end
if next(loDevs) == nil then
syscall.devctl(1, "sfgc", 0xFF00FF)
print("(no loop devices attached)")
syscall.devctl(1, "sfgc", 0xFFFFFF)
return
end
for id, info in pairs(loDevs) do
local colour = info.mode == "image" and 0x00FFFF or 0x0000FF
syscall.devctl(1, "sfgc", colour)
printInline(info.mode.." "..id)
syscall.devctl(1, "sfgc", 0xFFFFFF)
print(" on "..info.path)
end
return
end
if opts.o and opts.o:lower() == "loop" then
if #args < 2 then
print(name..": -o loop requires <source> and <mountpoint>")
print("try '"..name.." --help' for more information.")
syscall.exit(1); return
end
local src = args[1]
local dest = args[2]
if src:sub(1,1) ~= "/" then src = syscall.getcwd().."/"..src end
if dest:sub(1,1) ~= "/" then dest = syscall.getcwd().."/"..dest end
local ok, loopId = pcall(syscall.losetup, src)
if not ok then
local msg = tostring(loopId)
if msg:find("EPERM") then msg = "Permission denied"
elseif msg:find("EINVAL") then msg = "'"..args[1].."': not a directory or .hfs image"
elseif msg:find("EIO") then msg = "'"..args[1].."': I/O error reading image"
end
print(name..": losetup: "..msg); syscall.exit(1); return
end
local ok2, merr = pcall(syscall.mount, dest, loopId)
if not ok2 then
pcall(syscall.lodetach, loopId)
local msg = tostring(merr)
if msg:find("EPERM") then msg = "Permission denied"
elseif msg:find("EBUSY") then msg = "'"..dest.."' is already a mount point"
elseif msg:find("ENODEV") then msg = "loop device not found (internal error)"
end
print(name..": mount: "..msg); syscall.exit(1); return
end
syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": "..loopId.." mounted at "..dest)
syscall.devctl(1, "sfgc", 0xFFFFFF)
return
end
if #args == 2 then
local loopId = args[1]
local dest = args[2]
if dest:sub(1,1) ~= "/" then dest = syscall.getcwd().."/"..dest end
local ok, err = pcall(syscall.mount, dest, loopId)
if not ok then
local msg = tostring(err)
if msg:find("EPERM") then msg = "Permission denied"
elseif msg:find("ENODEV") then msg = "'"..loopId.."': no such device - use losetup first"
elseif msg:find("EBUSY") then msg = "'"..dest.."' is already a mount point"
elseif msg:find("EINVAL") then msg = "invalid arguments"
end
print(name..": "..msg); syscall.exit(1); return
end
syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": "..loopId.." mounted at "..dest)
syscall.devctl(1, "sfgc", 0xFFFFFF)
return
end
print(name..": wrong number of arguments")
print("try '"..name.." --help' for more information.")
syscall.exit(1)
+80
View File
@@ -0,0 +1,80 @@
--:Minify:--
-- passwd: change a user's password
-- Usage: passwd [username] (default: current user)
local args = {...}
local targetName = args[1]
local currentUid = syscall.getuid()
local targetUid
if targetName then
targetUid = syscall.getuid()
if not targetUid then
print("passwd: user '" .. targetName .. "' does not exist")
syscall.exit(1); return
end
-- Only root can change another user's password
if currentUid ~= 0 and targetUid ~= currentUid then
print("passwd: permission denied")
syscall.exit(1); return
end
else
targetUid = currentUid
targetName = syscall.getUsername(currentUid) or tostring(currentUid)
end
-- Non-root must verify their current password first
if currentUid ~= 0 then
printInline("Current password: ")
local cur = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then syscall.write(1,"\n"); break
elseif ch == "\b" then
if #cur > 0 then cur=cur:sub(1,-2); syscall.write(1,"\b \b") end
else cur=cur..ch; syscall.write(1,"*") end
end
local ok, err = syscall.login(targetUid, cur)
if not ok then
sleep(1)
print("passwd: authentication failure")
syscall.exit(1); return
end
end
printInline("New password: ")
local pw1 = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then syscall.write(1,"\n"); break
elseif ch == "\b" then
if #pw1 > 0 then pw1=pw1:sub(1,-2); syscall.write(1,"\b \b") end
else pw1=pw1..ch; syscall.write(1,"*") end
end
printInline("Confirm password: ")
local pw2 = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then syscall.write(1,"\n"); break
elseif ch == "\b" then
if #pw2 > 0 then pw2=pw2:sub(1,-2); syscall.write(1,"\b \b") end
else pw2=pw2..ch; syscall.write(1,"*") end
end
if pw1 ~= pw2 then
print("passwd: passwords do not match")
syscall.exit(1); return
end
local ok, err = syscall.setpassword(targetUid, pw1)
if not ok then
print("passwd: " .. tostring(err))
syscall.exit(1); return
end
print("passwd: password updated for '" .. targetName .. "'")
+65
View File
@@ -0,0 +1,65 @@
--:Minify:--
local targetUser = ({ ... })[1]
local currentUid = syscall.getuid()
if syscall.geteuid()~=0 then
syscall.exec("/bin/su", {...})
end
local targetUid
if targetUser then
targetUid = syscall.getuidbyname(targetUser)
else
targetUid = 0
end
if not targetUid then
print("su: user '" .. targetUser .. "' does not exist")
syscall.exit(1)
return
end
if currentUid ~= 0 then
printInline("Password: ")
local pw = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then
syscall.write(1, "\n")
break
elseif ch == "\b" then
if #pw > 0 then pw = pw:sub(1, -2); syscall.write(1, "\b \b") end
else
pw = pw .. ch; syscall.write(1, "*")
end
end
local ok, err = syscall.login(targetUid, pw)
if not ok then
sleep(1)
print("su: Authentication failure")
syscall.exit(1)
return
end
else
syscall.setuid(targetUid)
end
local pwent = syscall.getpasswd(targetUid)
local shell = (pwent and pwent.shell) or "/bin/hysh"
local homedir = (pwent and pwent.homedir) or "/"
local username= (pwent and pwent.username)or "Unknown"
local ok_cd, err_cd = pcall(syscall.chdir, homedir)
if not ok_cd then
homedir = "/"
syscall.chdir(homedir)
end
syscall.setEnviron("HOME", homedir)
syscall.setEnviron("USER", username)
syscall.setEnviron("SHELL", shell)
local ok, err = pcall(syscall.exec, shell)
if not ok then
print("su: cannot exec shell '" .. shell .. "': " .. tostring(err))
syscall.exit(1)
end
+110
View File
@@ -0,0 +1,110 @@
--:Minify:--
local fs = require("fs")
local cmdArgs = {...}
local targetUser = "root"
local i = 1
if cmdArgs[i] == "-u" then
i = i + 1
local uarg = cmdArgs[i] or "root"
local numUid = tonumber(uarg)
if numUid then
local pwent = syscall.getpasswd(numUid)
targetUser = (pwent and pwent.username) or uarg
else
targetUser = uarg
end
i = i + 1
end
local cmd = cmdArgs[i]
if not cmd or cmd == "" then
print("usage: sudo [-u user] <command> [args...]")
syscall.exit(1)
return
end
local restArgs = {}
for j = i + 1, #cmdArgs do restArgs[#restArgs + 1] = cmdArgs[j] end
local currentUid = syscall.getuid()
local currentUser = syscall.getUsername(currentUid) or tostring(currentUid)
local targetUid = syscall.getuidbyname(targetUser)
if not targetUid then
print("sudo: user '" .. targetUser .. "' does not exist")
syscall.exit(1)
return
end
if currentUid ~= 0 then
printInline("[sudo] password for root: ")
local pw = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then
syscall.write(1, "\n")
break
elseif ch == "\b" then
if #pw > 0 then pw = pw:sub(1, -2); syscall.write(1, "\b \b") end
else
pw = pw .. ch
syscall.write(1, "*")
end
end
local ok, err = syscall.login(0, pw)
if not ok then
sleep(1)
print("sudo: Authentication failure")
syscall.exit(1)
return
end
if targetUid ~= currentUid then
syscall.setuid(targetUid)
end
else
if targetUid ~= currentUid then
syscall.setuid(targetUid)
end
end
local cmdPath = ""
if cmd:find("/") then
if fs.exists(cmd) then cmdPath = cmd end
else
local paths = string.split(syscall.getEnviron("PATH") or "/bin/", ":")
for _, p in ipairs(paths) do
local full = p .. cmd
if fs.exists(full) then cmdPath = full; break end
end
end
if cmdPath == "" then
print("sudo: command not found: " .. cmd)
syscall.exit(1)
return
end
local text = fs.readAllText(cmdPath)
local program, loadErr = load(text, "@" .. cmdPath)
if not program then
print("sudo: cannot load " .. cmd .. ": " .. tostring(loadErr))
syscall.exit(1)
return
end
local pwent = syscall.getpasswd(targetUid)
if pwent and pwent.homedir then
syscall.setEnviron("HOME", pwent.homedir)
end
syscall.setEnviron("USER", targetUser)
local ok, err = xpcall(program, debug.traceback, table.unpack(restArgs))
if not ok then
print("sudo: " .. cmd .. ": " .. tostring(err))
syscall.exit(1)
end
+111
View File
@@ -0,0 +1,111 @@
--:Minify:--
-- Usage:
-- umount <mountpoint> unmount; auto-detach loop device if one is found
-- umount -l <id> detach loop device without unmounting (force)
-- umount --no-detach <mpt> unmount but leave loop device attached
-- umount --help
local name = syscall.getTask(syscall.getpid()).name
local args, opts = {}, { l=false, ["no-detach"]=false, help=false }
for _, v in ipairs({...}) do
if v:sub(1,2) == "--" then
local o = v:sub(3)
if opts[o] ~= nil then opts[o] = true
else print(name..": unrecognised option '"..v.."'")
print("try '"..name.." --help' for more information.")
syscall.exit(1); return end
elseif v:sub(1,1) == "-" then
for i = 2, #v do
local c = v:sub(i,i)
if opts[c] ~= nil then opts[c] = true
else print(name..": invalid option '-"..c.."'")
print("try '"..name.." --help' for more information.")
syscall.exit(1); return end
end
else
table.insert(args, v)
end
end
if opts.help then
print("Usage: "..name.." <mountpoint>")
print(" "..name.." --no-detach <mountpoint>")
print(" "..name.." -l <loopid>")
print("")
print("Unmount a filesystem mounted at <mountpoint>.")
print("")
print(" <mountpoint> unmount and auto-detach any loop device")
print(" --no-detach unmount but keep the loop device attached")
print(" -l <loopid> forcibly detach a loop device (no unmount)")
print("")
print("Requires root.")
return
end
if opts.l then
if #args < 1 then
print(name..": -l requires a loop device id")
print("try '"..name.." --help' for more information.")
syscall.exit(1); return
end
local id = args[1]
local ok, err = pcall(syscall.lodetach, id)
if not ok then
local msg = tostring(err)
if msg:find("EPERM") then msg = "Permission denied"
elseif msg:find("ENXIO") then msg = "no such loop device '"..id.."'"
elseif msg:find("EBUSY") then msg = "'"..id.."' is still mounted - unmount first or omit -l"
end
print(name..": "..msg); syscall.exit(1); return
end
syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": detached "..id)
syscall.devctl(1, "sfgc", 0xFFFFFF)
return
end
if #args < 1 then
print(name..": missing mount point operand")
print("try '"..name.." --help' for more information.")
syscall.exit(1); return
end
local mpt = args[1]
if mpt:sub(1,1) ~= "/" then mpt = syscall.getcwd().."/"..mpt end
local loopIdToDetach = nil
if not opts["no-detach"] then
local lok, devs = pcall(syscall.lolist)
if lok then
loopIdToDetach = {}
for id in pairs(devs) do
loopIdToDetach[#loopIdToDetach + 1] = id
end
end
end
local ok, err = pcall(syscall.umount, mpt)
if not ok then
local msg = tostring(err)
if msg:find("EPERM") then msg = "Permission denied"
elseif msg:find("EINVAL") then msg = "'"..args[1].."' is not a mount point"
elseif msg:find("EBUSY") then msg = "'"..args[1].."' is busy - close open files first"
end
print(name..": "..msg); syscall.exit(1); return
end
syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": unmounted "..mpt)
syscall.devctl(1, "sfgc", 0xFFFFFF)
if loopIdToDetach then
for _, id in ipairs(loopIdToDetach) do
local dok = pcall(syscall.lodetach, id)
if dok then
syscall.devctl(1, "sfgc", 0xFF00FF)
print(name..": auto-detached "..id)
syscall.devctl(1, "sfgc", 0xFFFFFF)
end
end
end
+67
View File
@@ -0,0 +1,67 @@
--:Minify:--
local args = {...}
local i = 1
local opt = { createHome = true }
while i <= #args do
local a = args[i]
if a == "-p" then i=i+1; opt.password = args[i]
elseif a == "-g" then i=i+1; opt.gid = tonumber(args[i])
elseif a == "-d" then i=i+1; opt.homedir = args[i]
elseif a == "-s" then i=i+1; opt.shell = args[i]
elseif a == "-M" then opt.createHome = false
elseif a:sub(1,1) ~= "-" then opt.username = a
else print("useradd: unknown option: " .. a); return end
i = i + 1
end
if not opt.username then
print("Usage: useradd [-p password] [-g gid] [-d homedir] [-s shell] [-M] <username>")
syscall.exit(1); return
end
local password = opt.password
if not password then
printInline("New password: ")
password = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then syscall.write(1,"\n"); break
elseif ch == "\b" then
if #password > 0 then password=password:sub(1,-2); syscall.write(1,"\b \b") end
else password=password..ch; syscall.write(1,"*") end
end
printInline("Confirm password: ")
local pw2 = ""
while true do
local ch = syscall.read(0)
if not ch or ch == "" then
elseif ch == "\n" then syscall.write(1,"\n"); break
elseif ch == "\b" then
if #pw2 > 0 then pw2=pw2:sub(1,-2); syscall.write(1,"\b \b") end
else pw2=pw2..ch; syscall.write(1,"*") end
end
if password ~= pw2 then
print("useradd: passwords do not match")
syscall.exit(1); return
end
end
local uid, err = syscall.newuser(
opt.username, password, opt.gid, opt.homedir, opt.shell or "/bin/hysh"
)
if not uid then
print("useradd: " .. tostring(err))
syscall.exit(1); return
end
if opt.createHome then
local home = opt.homedir or ("/home/" .. opt.username)
local ok, e = pcall(syscall.mkdir, home)
if not ok then
print("useradd: warning: could not create home " .. home .. ": " .. tostring(e))
end
end
print("useradd: created user '" .. opt.username .. "' with uid=" .. tostring(uid))
+49
View File
@@ -0,0 +1,49 @@
--:Minify:--
local args = {...}
local removeHome = false
local username = nil
for _, a in ipairs(args) do
if a == "-r" then removeHome = true
elseif a:sub(1,1) ~= "-" then username = a
else print("userdel: unknown option: " .. a); syscall.exit(1); return end
end
if not username then
print("Usage: userdel [-r] <username>")
syscall.exit(1); return
end
local uid = syscall.getuid(username)
if not uid then
print("userdel: user '" .. username .. "' does not exist")
syscall.exit(1); return
end
local pwent = syscall.getpasswd(uid)
local ok, err = syscall.deleteuser(uid)
if not ok then
print("userdel: " .. tostring(err))
syscall.exit(1); return
end
if removeHome and pwent and pwent.homedir then
local fs = require("fs")
local ok2, err2 = pcall(function()
local function rmdir(path)
for _, f in ipairs(fs.list(path) or {}) do
local full = path .. "/" .. f
if fs.isDir(full) then rmdir(full)
else syscall.remove(full) end
end
syscall.remove(path)
end
if fs.exists(pwent.homedir) then rmdir(pwent.homedir) end
end)
if not ok2 then
print("userdel: warning: could not remove home: " .. tostring(err2))
end
end
print("userdel: deleted user '" .. username .. "'")
+49
View File
@@ -0,0 +1,49 @@
--:Minify:--
local args = {...}
local i = 1
local opt = {}
while i <= #args do
local a = args[i]
if a == "-l" then i=i+1; opt.newname = args[i]
elseif a == "-p" then i=i+1; opt.password = args[i]
elseif a == "-g" then i=i+1; opt.gid = tonumber(args[i])
elseif a == "-d" then i=i+1; opt.homedir = args[i]
elseif a == "-s" then i=i+1; opt.shell = args[i]
elseif a == "-L" then opt.lock = true
elseif a == "-U" then opt.unlock = true
elseif a:sub(1,1) ~= "-" then opt.username = a
else print("usermod: unknown option: " .. a); syscall.exit(1); return end
i = i + 1
end
if not opt.username then
print("Usage: usermod [-l newname] [-p password] [-g gid] [-d homedir] [-s shell] [-L] [-U] <username>")
syscall.exit(1); return
end
if opt.lock and opt.unlock then
print("usermod: -L and -U are mutually exclusive")
syscall.exit(1); return
end
local uid = syscall.getuid(opt.username)
if not uid then
print("usermod: user '" .. opt.username .. "' does not exist")
syscall.exit(1); return
end
local function apply(fn, ...)
local ok, err = fn(...)
if not ok then print("usermod: " .. tostring(err)); syscall.exit(1) end
end
if opt.newname then apply(syscall.setusername, uid, opt.newname) end
if opt.password then apply(syscall.setpassword, uid, opt.password) end
if opt.gid then apply(syscall.setgid, uid, opt.gid) end
if opt.homedir then apply(syscall.sethomedir, uid, opt.homedir) end
if opt.shell then apply(syscall.setshell, uid, opt.shell) end
if opt.lock then apply(syscall.lockuser, uid) end
if opt.unlock then apply(syscall.unlockuser, uid) end
print("usermod: updated user '" .. opt.username .. "'")