--: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 .. "'")
