made unified colors and stuff

This commit is contained in:
2026-03-19 08:33:47 -04:00
parent 4f9eebade2
commit 9b338328f0
40 changed files with 1218 additions and 1145 deletions

View File

@@ -0,0 +1,18 @@
--:Minify:--
return {
white=0xFFFFFF,
red=0xFF0000,
green=0x00FF00,
blue=0x0000FF,
cyan=0x00FFFF,
yellow=0xFFFF00,
purple=0xFF00FF,
black=0x000000,
gray=0x888888,
lightgrey=0xBBBBBB,
darkgrey=0x444444,
orange=0xFF8800,
mint=0x00FF88,
brown=0xa52a2a,
chocolate=0xd2691e
}

View File

@@ -0,0 +1,344 @@
--:Minify:--
local args={...}
local bootdrive=args[1]
local gpu=components:getFirst("gpu")
local screenTextBuffer=nil
local cursorX,cursorY=0,0
local screenSizeX,screenSizeY=128,25
if gpu then
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY)
for t,v in components:list() do
if t == "screen" then
gpu:assignBuffer(screenTextBuffer, v)
end
end
end
local function write(text)
cursorX, cursorY = screenTextBuffer:pasteText(cursorX, cursorY, "SCROLL_SPILL_CLEAR", text)
cursorY = cursorY + 1
cursorX = 0
if cursorY >= screenSizeY then
cursorY = screenSizeY-1
screenTextBuffer:newline()
end
end
local function displaySuperBadError(err)
gpu:freeAllBuffers()
screenTextBuffer=gpu:newBuffer(screenSizeX,screenSizeY)
for t,v in components:list() do
if t == "screen" then
gpu:assignBuffer(screenTextBuffer, v)
end
end
term.setBackgroundColor(0x1)
term.setTextColor(0x4)
term.clear()
term.setCursorPos(1, 1)
term.write("A critical error occurred while loading the system:")
term.setCursorPos(1, 3)
write(err)
while true do end
end
local ok, err = xpcall(function()
local apis = {}
local lua = {
coroutine = true,
debug = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = true,
getmetatable = true,
ipairs = true,
__inext = true,
load = true,
math = true,
next = true,
pairs = true,
pcall = true,
rawequal = true,
rawget = true,
rawlen = true,
rawset = true,
select = true,
setmetatable = true,
string = true,
table = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true,
_G = true
}
local debug = debug
for i, v in pairs(_G) do
if not lua[i] or lua[i] == nil then
apis[i] = v
_G[i] = nil
end
end
local function string_file(file)
local str = file:read()
local buf = {str or ""}
local pos = 1
local closed = false
local function content()
return table.concat(buf)
end
local function set_content(s)
buf = {s}
end
local function flush()
file.write(content())
end
local file = {}
function file:read(n)
assert(not closed, "file is closed")
local s = content()
local len = #s
if not n then
local out = s:sub(pos)
pos = len + 1
return out
end
local out = s:sub(pos, pos + n - 1)
pos = pos + #out
return out
end
function file:write(data)
assert(not closed, "file is closed")
local s = content()
local before = s:sub(1, pos - 1)
local after = s:sub(pos + #data)
set_content(before .. data .. after)
pos = pos + #data
return true
end
function file:seek(whence, offset)
assert(not closed, "file is closed")
local s = content()
local len = #s
whence = whence or "cur"
offset = offset or 0
if whence == "set" then
pos = offset + 1
elseif whence == "cur" then
pos = pos + offset
elseif whence == "end" then
pos = len + offset + 1
else
error("invalid whence")
end
if pos < 1 then pos = 1 end
if pos > len + 1 then pos = len + 1 end
return pos - 1
end
function file:close()
assert(not closed, "file is closed")
flush()
closed = true
end
function file:flush()
assert(not closed, "file is closed")
flush()
end
return file
end
local function getFile(path)
local file = bootdrive:open(path, "r")
if not file then
displaySuperBadError("Could not open file: " .. path)
end
local content = file:read()
return content
end
local Kernel = load(getFile("/boot/kernel.lua"),"@Kernel")
local initFs = load(getFile("/boot/ac/initdisks"),"@Init_disks")(apis)
local fs = load(getFile("/boot/initfs"), "@InitFs")()
if not Kernel then displaySuperBadError("Could not load kernel.") end
if not initFs then displaySuperBadError("Could not load initdisks.") end
if not fs then displaySuperBadError("Could not load initfs.") end
local computercomp=apis.components:getFirst("computer")
local uefi=apis.components:getFirst("uefi")
local computer = {
time = function() return apis.os.epoch("utc") end,
clock = function() return apis.os.clock() * 1000 end,
shutdown = apis.os.shutdown,
reboot = apis.os.reboot,
getMachineEvent = function()
return computercomp:getMachineEvent()
end,
getEEPROM = function() return uefi.data end,
setEEPROM = function(_, text)
uefi.data=text
end
}
local icolors = {
[0x1] = 1, -- #000000
[0x2] = 2, -- #FFFFFF
[0x4] = 3, -- #FF0000
[0x8] = 4, -- #00FF00
[0x10] = 5, -- #0000FF
[0x20] = 6, -- #00FFFF
[0x40] = 7, -- #FF00FF
[0x80] = 8, -- #FFFF00
[0x100] = 9, -- #FF6D00
[0x200] = 10, -- #6DFF55
[0x400] = 11, -- #24FFFF
[0x800] = 12, -- #924900
[0x1000] = 13, -- #6D6D55
[0x2000] = 14, -- #DBDBAA
[0x4000] = 15, -- #6D00FF
[0x8000] = 16 -- #B6FF00
}
local colors = {
0x0001, -- #000000
0x0002, -- #FFFFFF
0x0004, -- #FF0000
0x0008, -- #00FF00
0x0010, -- #0000FF
0x0020, -- #00FFFF
0x0040, -- #FF00FF
0x0080, -- #FFFF00
0x0100, -- #FF6D00
0x0200, -- #6DFF55
0x0400, -- #24FFFF
0x0800, -- #924900
0x1000, -- #6D6D55
0x2000, -- #DBDBAA
0x4000, -- #6D00FF
0x8000 -- #B6FF00
}
apis.term.setBackgroundColor(0x8000)
apis.term.setTextColor(0x1000)
apis.term.clear()
apis.term.setCursorPos(1, 1)
local kernelCoro = coroutine.create(function()
---@diagnostic disable-next-line: param-type-mismatch
local ok, err = xpcall(Kernel, debug.traceback, apis, initFs, "cct", "/sbin/init",
{
print = function(_, text) write(text .. "\n") end,
printInline = function(_, text) write(text) end,
clear = function()
apis.term.clear()
apis.term.setCursorPos(1, 1)
end,
setCursorPos = function(_, x, y)
apis.term.setCursorPos(x, y)
end,
getCursorPos = function() return apis.term.getCursorPos() end,
getSize = function() return apis.term.getSize() end,
setBackgroundColor = function(_, color)
apis.term.setBackgroundColor(colors[color])
end,
setTextColor = function(_, color)
apis.term.setTextColor(colors[color])
end,
getBackgroundColor = function()
return icolors[apis.term.getBackgroundColor()]
end,
getTextColor = function()
return icolors[apis.term.getTextColor()]
end
}, computer, fs, "$")
if not ok then displaySuperBadError(err) end
end)
function coroutine.resumeWithTimeout(co, timeout, ...)
local startTime = computer.time()
debug.sethook(co, function()
if computer.time() > startTime + timeout then
return coroutine.yield("timeout")
end
end, "", 1000)
local ret = {coroutine.resume(co, ...)}
if ret[1] and ret[2] == "timeout" then
return "timeout"
elseif ret[1] == false then
return "error", ret[2]
else
debug.sethook(co)
return "success", table.unpack(ret, 2)
end
end
write("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n")
while true do
local status, err = coroutine.resumeWithTimeout(kernelCoro, 50)
apis.os.queueEvent("NoSleep")
local exit = false
while not exit do
local event = {coroutine.yield()}
if event[1] == "key" then
queueEvent("keyPressed", 1, event[2])
if acekeys[event[2]] then
queueEvent("keyTyped", 1, acekeys[event[2]])
end
elseif event[1] == "char" then
queueEvent("keyTyped", 1, event[2])
elseif event[1] == "key_up" then
queueEvent("keyReleased", 1, event[2])
elseif event[1] == "disk" then
queueEvent("componentAdded", "disk")
elseif event[1] == "disk_eject" then
queueEvent("componentRemoved", "disk")
elseif event[1] == "modem_message" then
queueEvent("modem_message", table.unpack(event, 2))
elseif event[1] == "rednet_message" then
queueEvent("rednet_message", table.unpack(event, 2))
elseif event[1] == "http_success" then
queueEvent("http_success", table.unpack(event, 2))
elseif event[1] == "http_failure" then
queueEvent("http_failure", table.unpack(event, 2))
elseif event[1] == "NoSleep" then
exit = true
end
end
if status == "error" or coroutine.status(kernelCoro) == "dead" then
displaySuperBadError("Kernel error: " .. tostring(err))
coroutine.yield("key")
end
end
end, debug.traceback)
if not ok then displaySuperBadError("Fatal error during boot: " .. err) end
while true do coroutine.yield() end

View File

@@ -311,7 +311,7 @@ local fifo = kernel.newFifo()
kernel.processes.cctmond = function() kernel.processes.cctmond = function()
local timeout = false local timeout = false
while true do while true do
local event = {kernel.computer:getMachineEvent()} local event = {kernel.EFI:getMachineEvent()}
if event[1] then if event[1] then
local eventType = event[1] local eventType = event[1]

View File

@@ -1,4 +1,4 @@
-- :Minify:-- --:Minify:--
local BOOT_DRIVE_PATH = ({...})[1] or "/$" local BOOT_DRIVE_PATH = ({...})[1] or "/$"
---@diagnostic disable-next-line: undefined-global ---@diagnostic disable-next-line: undefined-global
local term = term local term = term
@@ -152,17 +152,99 @@ local ok, err = xpcall(function()
if not initFs then displaySuperBadError("Could not load initdisks.") end if not initFs then displaySuperBadError("Could not load initdisks.") end
if not fs then displaySuperBadError("Could not load initfs.") end if not fs then displaySuperBadError("Could not load initfs.") end
if not apis.fs.exists("/nvram.dat") then
local file = apis.fs.open("/nvram.dat", "w")
file.write("Hello, World!")
file.close()
end
local eventQueue = {} local eventQueue = {}
local function queueEvent(event, ...) local function queueEvent(event, ...)
table.insert(eventQueue, {event, ...}) table.insert(eventQueue, {event, ...})
end end
local computer = { local colors = {
time = function() return apis.os.epoch("utc") end, [0x000000]=0x0001,
clock = function() return apis.os.clock() * 1000 end, [0xFFFFFF]=0x0002,
shutdown = apis.os.shutdown, [0xFF0000]=0x0004,
reboot = apis.os.reboot, [0x00FF00]=0x0008,
[0x0000FF]=0x0010,
[0x00FFFF]=0x0020,
[0xFF00FF]=0x0040,
[0xFFFF00]=0x0080,
[0xFF6D00]=0x0100,
[0x6DFF55]=0x0200,
[0x24FFFF]=0x0400,
[0x924900]=0x0800,
[0x6D6D55]=0x1000,
[0xDBDBAA]=0x2000,
[0x6D00FF]=0x4000,
[0xB6FF00]=0x8000
}
local fg,bg=0x6D6D55,0x000000
local l1f,l1d,l2,ops={},{},{},0
local function findClosest(tbl, target)
local closest = nil
local smallestDiff = math.huge
for k, _ in pairs(tbl) do
local diff = math.abs(k - target)
if diff < smallestDiff then
smallestDiff = diff
closest = k
end
end
return closest
end
local function aprox(c24)
ops = ops + 1
if ops % 1024 == 0 then
l1d = {}
l1f = {}
end
if ops % 8192 == 0 then
l2 = {}
end
if l2[c24] ~= nil then
return l2[c24]
end
if l1d[c24] ~= nil then
l1f[c24] = l1f[c24] + 1
if l1f[c24] >= 16 then
l2[c24] = l1d[c24]
l1d[c24] = nil
l1f[c24] = nil
return l2[c24]
end
return l1d[c24]
end
local closestKey = findClosest(colors, c24)
if not closestKey then return nil end
local value = colors[closestKey]
l1d[c24] = value
l1f[c24] = 1
return value
end
local EFI = {
getEpochMs = function() return apis.os.epoch("utc") end,
getUptime = function() return apis.os.clock() * 1000 end,
date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end,
getMachineEvent = function() getMachineEvent = function()
if #eventQueue > 0 then if #eventQueue > 0 then
return table.unpack(table.remove(eventQueue, 1)) return table.unpack(table.remove(eventQueue, 1))
@@ -175,56 +257,10 @@ local ok, err = xpcall(function()
local h = apis.fs.open("/startup.lua", "w") local h = apis.fs.open("/startup.lua", "w")
h.write(text) h.write(text)
h.close() h.close()
end end,
} initfs=fs,
disks=initFs,
local icolors = { screenCtl={
[0x1] = 1, -- #000000
[0x2] = 2, -- #FFFFFF
[0x4] = 3, -- #FF0000
[0x8] = 4, -- #00FF00
[0x10] = 5, -- #0000FF
[0x20] = 6, -- #00FFFF
[0x40] = 7, -- #FF00FF
[0x80] = 8, -- #FFFF00
[0x100] = 9, -- #FF6D00
[0x200] = 10, -- #6DFF55
[0x400] = 11, -- #24FFFF
[0x800] = 12, -- #924900
[0x1000] = 13, -- #6D6D55
[0x2000] = 14, -- #DBDBAA
[0x4000] = 15, -- #6D00FF
[0x8000] = 16 -- #B6FF00
}
local colors = {
0x0001, -- #000000
0x0002, -- #FFFFFF
0x0004, -- #FF0000
0x0008, -- #00FF00
0x0010, -- #0000FF
0x0020, -- #00FFFF
0x0040, -- #FF00FF
0x0080, -- #FFFF00
0x0100, -- #FF6D00
0x0200, -- #6DFF55
0x0400, -- #24FFFF
0x0800, -- #924900
0x1000, -- #6D6D55
0x2000, -- #DBDBAA
0x4000, -- #6D00FF
0x8000 -- #B6FF00
}
apis.term.setBackgroundColor(0x8000)
apis.term.setTextColor(0x1000)
apis.term.clear()
apis.term.setCursorPos(1, 1)
local kernelCoro = coroutine.create(function()
---@diagnostic disable-next-line: param-type-mismatch
local ok, err = xpcall(Kernel, debug.traceback, apis, initFs, "cct", "/sbin/init",
{
print = function(_, text) write(text .. "\n") end, print = function(_, text) write(text .. "\n") end,
printInline = function(_, text) write(text) end, printInline = function(_, text) write(text) end,
clear = function() clear = function()
@@ -237,25 +273,51 @@ local ok, err = xpcall(function()
getCursorPos = function() return apis.term.getCursorPos() end, getCursorPos = function() return apis.term.getCursorPos() end,
getSize = function() return apis.term.getSize() end, getSize = function() return apis.term.getSize() end,
setBackgroundColor = function(_, color) setBackgroundColor = function(_, color)
apis.term.setBackgroundColor(colors[color]) apis.term.setBackgroundColor(aprox(color))
end, end,
setTextColor = function(_, color) setTextColor = function(_, color)
apis.term.setTextColor(colors[color]) apis.term.setTextColor(aprox(color))
end, end,
getBackgroundColor = function() getBackgroundColor = function()
return icolors[apis.term.getBackgroundColor()] return bg
end, end,
getTextColor = function() getTextColor = function()
return icolors[apis.term.getTextColor()] return fg
end end,
}, computer, fs, "$") enable=function() end,
if not ok then displaySuperBadError(err) end disable=function() end
},
architecture="cct",
getNvram = function() return getFile("/nvram.dat") end,
setNvram = function(_, text)
local h = apis.fs.open("/nvram.dat", "w")
h.write(text)
h.close()
end,
firmware=apis,
reboot=false
}
apis.term.setBackgroundColor(0x8000)
apis.term.setTextColor(0x1000)
apis.term.clear()
apis.term.setCursorPos(1, 1)
local kernelCoro = coroutine.create(function()
---@diagnostic disable-next-line: param-type-mismatch
local ok, err = xpcall(Kernel, debug.traceback, EFI)
if not ok and not EFI.reboot then displaySuperBadError(err) end
if err then
apis.os.reboot()
else
apis.os.shutdown()
end
end) end)
function coroutine.resumeWithTimeout(co, timeout, ...) function coroutine.resumeWithTimeout(co, timeout, ...)
local startTime = computer.time() local startTime = EFI.getEpochMs()
debug.sethook(co, function() debug.sethook(co, function()
if computer.time() > startTime + timeout then if EFI.getEpochMs() > startTime + timeout then
return coroutine.yield("timeout") return coroutine.yield("timeout")
end end
end, "", 1000) end, "", 1000)
@@ -304,11 +366,15 @@ local ok, err = xpcall(function()
end end
end end
if status == "error" or coroutine.status(kernelCoro) == "dead" then if status == "error" or coroutine.status(kernelCoro) == "dead" then
if EFI.reboot then
apis.os.reboot()
end
displaySuperBadError("Kernel error: " .. tostring(err)) displaySuperBadError("Kernel error: " .. tostring(err))
coroutine.yield("key") coroutine.yield("key")
end end
initFs:refresh()
end end
end, debug.traceback) end, debug.traceback)
if not ok then displaySuperBadError("Fatal error during boot: " .. err) end if not ok then displaySuperBadError("Fatal error during boot: " .. err) end
while true do coroutine.yield() end while true do coroutine.yield("key") end

View File

@@ -1,6 +1,6 @@
-- :Minify:-- --:Minify:--
local apis = ({...})[1] local apis = ({...})[1]
local BOOT_DRIVE_PATH = apis.BOOT_DRIVE_PATH or "/$" local BOOT_DRIVE_PATH = apis.BOOT_DRIVE_PATH
local fs = apis.fs local fs = apis.fs
local native = apis.peripheral local native = apis.peripheral
local peripheral = {} local peripheral = {}
@@ -241,11 +241,17 @@ internal["$"] = createDisk("$", BOOT_DRIVE_PATH, false, {
end end
}) })
local function refresh() internal["rom"] = createDisk("rom", "/rom", true, {
for id, _ in pairs(disks) do setLabel = function(label)
if not peripheral.getType(id) then disks[id] = nil end error("Device is read-only")
end,
getLabel = function()
return "cctrom"
end end
})
local function refresh()
disks={}
for _, disk in ipairs({peripheral.find("drive")}) do for _, disk in ipairs({peripheral.find("drive")}) do
if disk.isDiskPresent() then if disk.isDiskPresent() then
disks[tostring(disk.getDiskID())]=createDisk("cctdisk"..tostring(disk.getDiskID()), disk.getMountPath(), false, fs) disks[tostring(disk.getDiskID())]=createDisk("cctdisk"..tostring(disk.getDiskID()), disk.getMountPath(), false, fs)

View File

@@ -0,0 +1,152 @@
--:Minify:--
-- CCT driver peripheral helper
local kernel=...
kernel.cct={}
kernel.cct.peripheral={}
local peripheral=kernel.cct.peripheral
local apis = kernel.apis
local native = apis.peripheral
local sides = {"top", "bottom", "left", "right", "front", "back"}
function peripheral.getNames()
local results = {}
for n = 1, #sides do
local side = sides[n]
if native.isPresent(side) then
table.insert(results, side)
if native.hasType(side, "peripheral_hub") then
local remote = native.call(side, "getNamesRemote")
for _, name in ipairs(remote) do
table.insert(results, name)
end
end
end
end
return results
end
function peripheral.isPresent(name)
if native.isPresent(name) then
return true
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return true
end
end
return false
end
function peripheral.getType(peripheral)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.getType(peripheral)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "getTypeRemote", peripheral)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return table.unpack(mt.types)
end
end
function peripheral.hasType(peripheral, peripheral_type)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.hasType(peripheral, peripheral_type)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.types[peripheral_type] ~= nil
end
end
function peripheral.getMethods(name)
if native.isPresent(name) then
return native.getMethods(name)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "getMethodsRemote", name)
end
end
return nil
end
function peripheral.getName(peripheral)
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.name
end
function peripheral.call(name, method, ...)
if native.isPresent(name) then
return native.call(name, method, ...)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "callRemote", name, method, ...)
end
end
return nil
end
function peripheral.wrap(name)
local methods = peripheral.getMethods(name)
if not methods then
return nil
end
local types = { peripheral.getType(name) }
for i = 1, #types do types[types[i]] = true end
local result = setmetatable({}, {
__name = "peripheral",
name = name,
type = types[1],
types = types,
})
for _, method in ipairs(methods) do
result[method] = function(...)
return peripheral.call(name, method, ...)
end
end
return result
end
function peripheral.find(ty, filter)
local results = {}
for _, name in ipairs(peripheral.getNames()) do
if peripheral.hasType(name, ty) then
local wrapped = peripheral.wrap(name)
if filter == nil or filter(name, wrapped) then
table.insert(results, wrapped)
end
end
end
return table.unpack(results)
end

View File

@@ -1,192 +1,85 @@
--:Minify:-- --:Minify:--
local kernel = ... local kernel = ...
local apis = kernel.apis local peripheral=kernel.cct.peripheral
local native = apis.peripheral local keys=kernel.apis.keys
local sides = {"top", "bottom", "left", "right", "front", "back"}
local peripheral={}
function peripheral.getNames()
local results = {}
for n = 1, #sides do
local side = sides[n]
if native.isPresent(side) then
table.insert(results, side)
if native.hasType(side, "peripheral_hub") then
local remote = native.call(side, "getNamesRemote")
for _, name in ipairs(remote) do
table.insert(results, name)
end
end
end
end
return results
end
function peripheral.isPresent(name)
if native.isPresent(name) then
return true
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return true
end
end
return false
end
function peripheral.getType(peripheral)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.getType(peripheral)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "getTypeRemote", peripheral)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return table.unpack(mt.types)
end
end
function peripheral.hasType(peripheral, peripheral_type)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.hasType(peripheral, peripheral_type)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.types[peripheral_type] ~= nil
end
end
function peripheral.getMethods(name)
if native.isPresent(name) then
return native.getMethods(name)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "getMethodsRemote", name)
end
end
return nil
end
function peripheral.getName(peripheral)
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.name
end
function peripheral.call(name, method, ...)
if native.isPresent(name) then
return native.call(name, method, ...)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "callRemote", name, method, ...)
end
end
return nil
end
function peripheral.wrap(name)
local methods = peripheral.getMethods(name)
if not methods then
return nil
end
local types = { peripheral.getType(name) }
for i = 1, #types do types[types[i]] = true end
local result = setmetatable({}, {
__name = "peripheral",
name = name,
type = types[1],
types = types,
})
for _, method in ipairs(methods) do
result[method] = function(...)
return peripheral.call(name, method, ...)
end
end
return result
end
function peripheral.find(ty, filter)
local results = {}
for _, name in ipairs(peripheral.getNames()) do
if peripheral.hasType(name, ty) then
local wrapped = peripheral.wrap(name)
if filter == nil or filter(name, wrapped) then
table.insert(results, wrapped)
end
end
end
return table.unpack(results)
end
local icolors = {
[0x1] = 1, -- #000000
[0x2] = 2, -- #FFFFFF
[0x4] = 3, -- #FF0000
[0x8] = 4, -- #00FF00
[0x10] = 5, -- #0000FF
[0x20] = 6, -- #00FFFF
[0x40] = 7, -- #FF00FF
[0x80] = 8, -- #FFFF00
[0x100] = 9, -- #FF6D00
[0x200] = 10, -- #6DFF55
[0x400] = 11, -- #24FFFF
[0x800] = 12, -- #924900
[0x1000] = 13, -- #6D6D55
[0x2000] = 14, -- #DBDBAA
[0x4000] = 15, -- #6D00FF
[0x8000] = 16 -- #B6FF00
}
local colors = { local colors = {
0x0001, -- #000000 [0xFFFFFF]=0x0001,
0x0002, -- #FFFFFF [0xFF0000]=0x0002,
0x0004, -- #FF0000 [0x00FF00]=0x0004,
0x0008, -- #00FF00 [0x0000FF]=0x0008,
0x0010, -- #0000FF [0x00FFFF]=0x0010,
0x0020, -- #00FFFF [0xFF00FF]=0x0020,
0x0040, -- #FF00FF [0xFFFF00]=0x0040,
0x0080, -- #FFFF00 [0xFF6D00]=0x0080,
0x0100, -- #FF6D00 [0x6DFF55]=0x0100,
0x0200, -- #6DFF55 [0x24FFFF]=0x0200,
0x0400, -- #24FFFF [0x924900]=0x0400,
0x0800, -- #924900 [0x6D6D55]=0x0800,
0x1000, -- #6D6D55 [0xDBDBAA]=0x1000,
0x2000, -- #DBDBAA [0x6D00FF]=0x2000,
0x4000, -- #6D00FF [0xB6FF00]=0x4000,
0x8000 -- #B6FF00 [0x000000]=0x8000
} }
local fg,bg=0x6D6D55,0x000000
local l1f,l1d,l2,ops={},{},{},0
local function findClosest(tbl, target)
local closest = nil
local smallestDiff = math.huge
for k, _ in pairs(tbl) do
local diff = math.abs(k - target)
if diff < smallestDiff then
smallestDiff = diff
closest = k
end
end
return closest
end
local function aprox(c24)
ops = ops + 1
if ops % 1024 == 0 then
l1d = {}
l1f = {}
end
if ops % 8192 == 0 then
l2 = {}
end
if l2[c24] ~= nil then
return l2[c24]
end
if l1d[c24] ~= nil then
l1f[c24] = l1f[c24] + 1
if l1f[c24] >= 16 then
l2[c24] = l1d[c24]
l1d[c24] = nil
l1f[c24] = nil
return l2[c24]
end
return l1d[c24]
end
local closestKey = findClosest(colors, c24)
if not closestKey then return nil end
local value = colors[closestKey]
l1d[c24] = value
l1f[c24] = 1
return value
end
local function write(text, term) local function write(text, term)
local x, y = term.getCursorPos() local x, y = term.getCursorPos()
local w, h = term.getSize() local w, h = term.getSize()
@@ -244,18 +137,18 @@ local function serializeBool(bool)
end end
local function newtty(obj, id, ev) local function newtty(obj, id, ev)
obj.setPaletteColor(0x1, 0xFFFFFF) -- #000000 obj.setPaletteColor(0x1, 0xFFFFFF) -- #000000
obj.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF obj.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF
obj.setPaletteColor(0x4, 0x00FF00) -- #FF0000 obj.setPaletteColor(0x4, 0x00FF00) -- #FF0000
obj.setPaletteColor(0x8, 0x0000FF) -- #00FF00 obj.setPaletteColor(0x8, 0x0000FF) -- #00FF00
obj.setPaletteColor(0x10, 0x00FFFF) -- #0000FF obj.setPaletteColor(0x10, 0x00FFFF) -- #0000FF
obj.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF obj.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF
obj.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF obj.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF
obj.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00 obj.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00
obj.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00 obj.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00
obj.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55 obj.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55
obj.setPaletteColor(0x400, 0x924900) -- #24FFFF obj.setPaletteColor(0x400, 0x924900) -- #24FFFF
obj.setPaletteColor(0x800, 0x6D6D55) -- #924900 obj.setPaletteColor(0x800, 0x6D6D55) -- #924900
obj.setPaletteColor(0x1000, 0xDBDBAA) -- #6D6D55 obj.setPaletteColor(0x1000, 0xDBDBAA) -- #6D6D55
obj.setPaletteColor(0x2000, 0x6D00FF) -- #DBDBAA obj.setPaletteColor(0x2000, 0x6D00FF) -- #DBDBAA
obj.setPaletteColor(0x4000, 0xB6FF00) -- #6D00FF obj.setPaletteColor(0x4000, 0xB6FF00) -- #6D00FF
@@ -295,16 +188,18 @@ local function newtty(obj, id, ev)
return obj.setCursorPos(x,y) return obj.setCursorPos(x,y)
end, end,
sfgc=function(c) sfgc=function(c)
return obj.setTextColor(colors[c]) fg=c
return obj.setTextColor(aprox(c))
end, end,
sbgc=function(c) sbgc=function(c)
return obj.setBackgroundColor(colors[c]) bg=c
return obj.setBackgroundColor(aprox(c))
end, end,
gfgc=function() gfgc=function()
return icolors[obj.getTextColor()] return fg
end, end,
gbgc=function() gbgc=function()
return icolors[obj.getBackgroundColor()] return bg
end, end,
gctrl=function() gctrl=function()
return serializeBool(ctrl)..";"..serializeBool(alt) return serializeBool(ctrl)..";"..serializeBool(alt)
@@ -328,28 +223,28 @@ local fifo = kernel.newFifo()
kernel.processes.cctmond = function() kernel.processes.cctmond = function()
local timeout = false local timeout = false
while true do while true do
local event = {kernel.computer:getMachineEvent()} local event = {kernel.EFI:getMachineEvent()}
if event[1] then if event[1] then
local eventType = event[1] local eventType = event[1]
local charOrKey = event[3] local charOrKey = event[3]
local ctrlKeyMap = { local ctrlKeyMap = {
[apis.keys.a]=1, [apis.keys.b]=2, [apis.keys.c]=3, [keys.a]=1, [keys.b]=2, [keys.c]=3,
[apis.keys.d]=4, [apis.keys.e]=5, [apis.keys.f]=6, [keys.d]=4, [keys.e]=5, [keys.f]=6,
[apis.keys.g]=7, [apis.keys.h]=8, [apis.keys.i]=9, [keys.g]=7, [keys.h]=8, [keys.i]=9,
[apis.keys.j]=10, [apis.keys.k]=11, [apis.keys.l]=12, [keys.j]=10, [keys.k]=11, [keys.l]=12,
[apis.keys.m]=13, [apis.keys.n]=14, [apis.keys.o]=15, [keys.m]=13, [keys.n]=14, [keys.o]=15,
[apis.keys.p]=16, [apis.keys.q]=17, [apis.keys.r]=18, [keys.p]=16, [keys.q]=17, [keys.r]=18,
[apis.keys.s]=19, [apis.keys.t]=20, [apis.keys.u]=21, [keys.s]=19, [keys.t]=20, [keys.u]=21,
[apis.keys.v]=22, [apis.keys.w]=23, [apis.keys.x]=24, [keys.v]=22, [keys.w]=23, [keys.x]=24,
[apis.keys.y]=25, [apis.keys.z]=26, [keys.y]=25, [keys.z]=26,
} }
if eventType == "keyPressed" then if eventType == "keyPressed" then
if charOrKey == apis.keys.leftCtrl or charOrKey == apis.keys.rightCtrl then if charOrKey == keys.leftCtrl or charOrKey == keys.rightCtrl then
ctrl = true ctrl = true
elseif charOrKey == apis.keys.leftAlt or charOrKey == apis.keys.rightAlt then elseif charOrKey == keys.leftAlt or charOrKey == keys.rightAlt then
alt = true alt = true
end end
@@ -366,24 +261,24 @@ kernel.processes.cctmond = function()
end end
else else
local specialKeyMap = { local specialKeyMap = {
[apis.keys.up] = "", [keys.up] = "",
[apis.keys.down] = "", [keys.down] = "",
[apis.keys.right] = "", [keys.right] = "",
[apis.keys.left] = "", [keys.left] = "",
[apis.keys.home] = "", [keys.home] = "",
[apis.keys["end"]] = "", [keys["end"]] = "",
[apis.keys.pageUp] = "[5~", [keys.pageUp] = "[5~",
[apis.keys.pageDown] = "[6~", [keys.pageDown] = "[6~",
[apis.keys.delete] = "[3~", [keys.delete] = "[3~",
} }
local special = specialKeyMap[charOrKey] local special = specialKeyMap[charOrKey]
if special then fifo.push(special) end if special then fifo.push(special) end
end end
elseif eventType == "keyReleased" then elseif eventType == "keyReleased" then
if charOrKey == apis.keys.leftCtrl or charOrKey == apis.keys.rightCtrl then if charOrKey == keys.leftCtrl or charOrKey == keys.rightCtrl then
ctrl = false ctrl = false
elseif charOrKey == apis.keys.leftAlt or charOrKey == apis.keys.rightAlt then elseif charOrKey == keys.leftAlt or charOrKey == keys.rightAlt then
alt = false alt = false
end end
@@ -402,7 +297,7 @@ kernel.processes.cctmond = function()
end end
end end
newtty(apis.term, "1", fifo.pop) newtty(kernel.apis.term, "1", fifo.pop)
for i,v in ipairs({peripheral.find("monitor")}) do for i,v in ipairs({peripheral.find("monitor")}) do
v.setTextScale(.5) v.setTextScale(.5)

View File

@@ -1,26 +0,0 @@
local args={...}
local kernel=args[1]
local driver={}
driver.name="CCT Term Module"
driver.version="0.1.0"
driver.type="gpio"
driver.description="CCT redstone Module Kernel Module"
driver.arch="cct"
driver.author="HyperionOS Dev Team"
driver.license="MIT"
driver.api={}
function driver.load()
-- will
end
function driver.unload()
-- Nothing to unload
end
function driver.main()
-- Nothing to run
end
-- kernel.drivers.register(driver)

View File

@@ -0,0 +1,25 @@
--:Minify:--
local kernel=...
local rs=kernel.apis.rs
local sides = {top=1, bottom=2, left=3, right=4, front=5, back=6}
local function newGPIO(side)
return function(mode, data)
if mode=="w" then
if type(data)~="boolean" then error("data: expected bool") end
rs.setOutput(side, data)
elseif mode=="wa" then
if type(data)~="number" then error("data: expected bool") end
rs.setAnalogOutput(side, data)
elseif mode=="r" then
return rs.getInput(side)
elseif mode=="ra" then
return rs.getAnalogInput(side)
end
end
end
for side, alt in pairs(sides) do
local func=newGPIO(side)
kernel.gpio[side]=func
kernel.gpio[alt]=func
end

View File

@@ -1,11 +1,9 @@
--:Minify:-- --:Minify:--
local args = {...} local EFI=...
local apis = args[1] local screen=EFI.screenCtl
local disks = args[2] local ifs=EFI.initfs
local arch = args[3] local disks=EFI.disks
local screen = args[5] local arch=EFI.architecture
local computer = args[6]
local ifs = args[7]
local kernel = {} local kernel = {}
kernel.LOG_Text="" kernel.LOG_Text=""
kernel.version="HyperionOS V1.2.3" kernel.version="HyperionOS V1.2.3"
@@ -26,28 +24,31 @@ _G.sleep=nil
local windowsExp = false local windowsExp = false
function kernel.log(msg, level, c) function kernel.log(msg, level, c)
c=c or 12 c=c or 0x6D6D6D
kernel.LOG_Text = kernel.LOG_Text..string.format("%X",c-1).." "..tostring(computer:time()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n" kernel.LOG_Text = kernel.LOG_Text..tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n"
if kernel.status == "start" then if kernel.status == "start" then
screen:setTextColor(c) screen:setTextColor(c)
screen:print(tostring(computer:time()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg) screen:print(tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg)
elseif kernel.status == "term" then elseif kernel.status == "term" then
kernel.standbyTask=kernel.currentTask kernel.standbyTask=kernel.currentTask
kernel.currentTask=kernel.kernelTask kernel.currentTask=kernel.kernelTask
kernel.vfs.devctl(1,"sfgc",c) local file=kernel.vfs.open("/dev/console", "w")
kernel.vfs.write(1,tostring(computer:time()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n") kernel.vfs.devctl(file,"sfgc",c)
kernel.vfs.write(file,tostring(EFI:date()).." "..kernel.users[kernel.uid].." "..kernel.process.."["..tostring(level or "INFO").."]: "..msg.."\n")
kernel.vfs.close(file)
kernel.currentTask=kernel.standbyTask kernel.currentTask=kernel.standbyTask
end end
end end
function kernel.PANIC(msg) function kernel.PANIC(msg)
if kernel.status~="Panic" then if kernel.status~="Panic" then
kernel.log("PANIC: "..msg, "PANIC") kernel.log("PANIC: "..msg, "PANIC", 0xFF0000)
pcall(kernel["saveLog"]) pcall(kernel["saveLog"])
kernel.status="Panic" kernel.status="Panic"
kernel.reason=msg kernel.reason=msg
screen:setTextColor(2) screen:enable()
screen:setBackgroundColor(16) screen:setTextColor(0xFF0000)
screen:setBackgroundColor(0x000000)
screen:clear() screen:clear()
screen:setCursorPos(1,1) screen:setCursorPos(1,1)
screen:print(kernel.LOG_Text) screen:print(kernel.LOG_Text)
@@ -56,18 +57,19 @@ function kernel.PANIC(msg)
kernel.exitMain = true kernel.exitMain = true
end end
while true do while true do
local event={computer:getMachineEvent()} local event={EFI:getMachineEvent()}
if event[1]=="keyPressed" then if event[1]=="keyPressed" then
break break
end end
end end
computer:reboot() EFI.reboot=true
error("KERNEL PANIC")
end end
kernel.panic=kernel.PANIC kernel.panic=kernel.PANIC
if windowsExp then if windowsExp then
screen:setTextColor(1) screen:setTextColor(0xFFFFFF)
screen:setBackgroundColor(4) screen:setBackgroundColor(0x0000FF)
screen:clear() screen:clear()
local w,h = screen:getSize() local w,h = screen:getSize()
screen:setCursorPos(3,5) screen:setCursorPos(3,5)
@@ -113,7 +115,7 @@ local split = function(str, delim, maxResultCountOrNil)
end end
if not ifs.isFile("/boot/boot.cfg") then if not ifs.isFile("/boot/boot.cfg") then
kernel.log("First boot detected writing boot.cfg", "INFO", 3) kernel.log("First boot detected writing boot.cfg", "INFO", 0x00FF00)
ifs.writeAllText("/boot/boot.cfg",ifs.readAllText("/boot/safeboot.cfg")) ifs.writeAllText("/boot/boot.cfg",ifs.readAllText("/boot/safeboot.cfg"))
kernel.firstBoot=true kernel.firstBoot=true
end end
@@ -136,7 +138,7 @@ for i,v in ipairs(split(fstab,"\n")) do
local id="" local id=""
for i=3,#v do for i=3,#v do
if v:sub(i,i)==";" then if v:sub(i,i)==";" then
if i==3 then kernel.log("Invalid fstab line... Skipping.","WARN") skip = true break end if i==3 then kernel.log("Invalid fstab line... Skipping.","WARN", 0xFF8800) skip = true break end
id=v:sub(3,i-1) id=v:sub(3,i-1)
end end
end end
@@ -151,7 +153,13 @@ end
kernel.log("Disks initialized") kernel.log("Disks initialized")
function kernel.saveLog() function kernel.saveLog()
ifs.writeAllText("/var/log/syslog.log", kernel.LOG_Text) if kernel.status=="running" then
local file = kernel.vfs.open("/var/log/syslog.log", "w")
kernel.vfs.write(file, kernel.LOG_Text)
kernel.vfs.close(file)
else
ifs.writeAllText("/var/log/syslog.log", kernel.LOG_Text)
end
end end
function kernel.newFifo() function kernel.newFifo()
@@ -191,7 +199,7 @@ kernel.log("Gathering modules")
for _, i in ipairs(ifs.list("/lib/modules")) do for _, i in ipairs(ifs.list("/lib/modules")) do
local modlist = ifs.list("/lib/modules/"..i) local modlist = ifs.list("/lib/modules/"..i)
if not modlist then if not modlist then
kernel.log("WARNING: could not list /lib/modules/"..i.." (skipping)", "WARN", 8) kernel.log("WARNING: could not list /lib/modules/"..i.." (skipping)", "WARN", 0xFF8800)
else else
for _,v in ipairs(modlist) do for _,v in ipairs(modlist) do
local prior=tonumber(v:sub(1,2)) local prior=tonumber(v:sub(1,2))
@@ -203,8 +211,8 @@ for _, i in ipairs(ifs.list("/lib/modules")) do
end end
kernel.ifs=ifs kernel.ifs=ifs
kernel.apis=apis kernel.apis=EFI.firmware
kernel.computer=computer kernel.EFI=EFI
kernel.arch=arch kernel.arch=arch
kernel.initdisks=disks kernel.initdisks=disks
kernel.screen=screen kernel.screen=screen
@@ -233,16 +241,19 @@ kernel.kernelTask = {
kernel.currentTask = kernel.kernelTask kernel.currentTask = kernel.kernelTask
function kernel.shutdown() function kernel.shutdown()
kernel.computer:shutdown() kernel.exitMain=true
kernel.status="shutdown"
end end
function kernel.reboot() function kernel.reboot()
kernel.computer:reboot() kernel.exitMain=true
kernel.status="reboot"
end end
kernel.syscalls["time"]=function() return kernel.computer:time() end kernel.syscalls["time"]=function() return kernel.EFI:getEpochMs() end
kernel.syscalls["date"]=function() return kernel.EFI:date() end
kernel.syscalls["log"]=kernel.log kernel.syscalls["log"]=kernel.log
kernel.syscalls["getUptime"]=function() return kernel.computer:clock() end kernel.syscalls["getUptime"]=function() return kernel.EFI:getUptime() end
kernel.syscalls["getUsername"]=function(uid) return kernel.users[uid or kernel.uid] end kernel.syscalls["getUsername"]=function(uid) return kernel.users[uid or kernel.uid] end
kernel.syscalls["getHostname"]=function() return kernel.hostname end kernel.syscalls["getHostname"]=function() return kernel.hostname end
kernel.syscalls["getHost"]=function() return kernel.apis._HOST end kernel.syscalls["getHost"]=function() return kernel.apis._HOST end
@@ -256,17 +267,13 @@ kernel.syscalls["sysdump"]=function()
end end
return rv return rv
end end
kernel.syscalls["reboot"]=function() kernel.syscalls["reboot"]=kernel.reboot
kernel.computer:reboot() kernel.syscalls["shutdown"]=kernel.shutdown
end
kernel.syscalls["shutdown"]=function()
kernel.computer:reboot()
end
kernel.log("Running modules") kernel.log("Running modules")
for _,p in ipairs(modules) do for _,p in ipairs(modules) do
for _,v in ipairs(p) do for _,v in ipairs(p) do
if kernel.config.showModLoad then kernel.log("Loading module "..v, "DBUG", 5) end if kernel.config.showModLoad then kernel.log("Loading module "..v, "DBUG", 0x00FFFF) end
local code=ifs.readAllText(v) local code=ifs.readAllText(v)
if not code then if not code then
kernel.panic("Failed to read module "..v) kernel.panic("Failed to read module "..v)
@@ -275,15 +282,20 @@ for _,p in ipairs(modules) do
if not func then kernel.panic("ModuLoadErr: "..tostring(err)) end if not func then kernel.panic("ModuLoadErr: "..tostring(err)) end
local status, err = xpcall(func,debug.traceback, kernel) local status, err = xpcall(func,debug.traceback, kernel)
if not status then kernel.panic("ModuRunErr: "..tostring(err)) end if not status then kernel.panic("ModuRunErr: "..tostring(err)) end
if kernel.config.showModLoad then kernel.log("Loaded module "..v, "DBUG", 5) end if kernel.config.showModLoad then kernel.log("Loaded module "..v, "DBUG", 0x00FFFF) end
end end
end end
kernel.log("Kernel initialized successfully.") kernel.log("Kernel initialized successfully.")
kernel.saveLog() kernel.saveLog()
kernel.status="running" kernel.status="running"
screen:disable()
kernel.main() kernel.main()
kernel.panic("Exited main???")
if kernel.status=="panic" then if kernel.status=="panic" then
kernel.panic() kernel.panic(kernel.reason)
end
if kernel.status=="reboot" then
EFI.reboot=true
return true
end end
kernel.PANIC("Execution complete")

View File

@@ -7,5 +7,6 @@ return {
initPath = "/sbin/init", initPath = "/sbin/init",
maxOpenFiles = 128, maxOpenFiles = 128,
maxFilesPerTask = 16, maxFilesPerTask = 16,
preempt=true preempt=true,
logTaskExit=true
} }

View File

@@ -50,7 +50,7 @@ function proxy:type(path, mode)
if type(step[steps[#steps]]) == "table" then if type(step[steps[#steps]]) == "table" then
return "directory" return "directory"
end end
error("ENOENT") error(type(step[steps[#steps]]))
end end
function proxy:list(path) function proxy:list(path)
@@ -140,6 +140,68 @@ function data.zero(op, mode)
end end
end end
function data.eeprom(op, mode)
if op=="type" then
return "character device"
elseif op=="open" then
if mode=="r" then
local ptr,eeprom=1,kernel.EFI:getEEPROM()
return {
read=function(amount)
ptr=ptr+amount
return eeprom:sub(ptr-amount, ptr)
end
}
elseif mode=="w" then
if kernel.uid~=0 then error("EACCES") end
return {
write=function(data)
kernel.EFI:setEEPROM(data)
end
}
elseif mode=="a" then
if kernel.uid~=0 then error("EACCES") end
return {
write=function(data)
kernel.EFI:setEEPROM(kernel.EFI:getEEPROM()..data)
end
}
else error("EACCES")
end
end
end
function data.nvram(op, mode)
if op=="type" then
return "character device"
elseif op=="open" then
if mode=="r" then
local ptr,nvram=1,kernel.EFI:getNvram()
return {
read=function(amount)
ptr=ptr+amount
return nvram:sub(ptr-amount, ptr)
end
}
elseif mode=="w" then
if kernel.uid~=0 then error("EACCES") end
return {
write=function(data)
kernel.EFI:setNvram(data)
end
}
elseif mode=="a" then
if kernel.uid~=0 then error("EACCES") end
return {
write=function(data)
kernel.EFI:setNvram(kernel.EFI:getNvram()..data)
end
}
else error("EACCES")
end
end
end
data["disk"]={} data["disk"]={}
kernel.devfs={} kernel.devfs={}
kernel.devfs.data=data kernel.devfs.data=data

View File

@@ -258,7 +258,7 @@ function proxy:fileExists(path)
return ok return ok
end end
data.uptime=simpleFile(function()return tostring(kernel.computer:getUptime())end,function()error("EACCES")end) data.uptime=simpleFile(function()return tostring(kernel.EFI:getUptime())end,function()error("EACCES")end)
kernel.procfs={} kernel.procfs={}
kernel.procfs.data=data kernel.procfs.data=data
kernel.procfs.proxy=proxy kernel.procfs.proxy=proxy

View File

@@ -21,7 +21,7 @@ for _, line in ipairs(string.split(kernel.fstab, "\n")) do
end end
if not semicolon_pos or semicolon_pos == 3 then if not semicolon_pos or semicolon_pos == 3 then
kernel.log("Invalid fstab line: "..line.." ... Skipping.", "WARN", 8) kernel.log("Invalid fstab line: "..line.." ... Skipping.", "WARN", 0xFF8800)
else else
local id = line:sub(3, semicolon_pos - 1) local id = line:sub(3, semicolon_pos - 1)
local path = trim(line:sub(semicolon_pos + 1)) local path = trim(line:sub(semicolon_pos + 1))

View File

@@ -2,10 +2,7 @@
-- Supports: -- Supports:
-- AF_UNIX - local IPC via /var/run/*.sock paths -- AF_UNIX - local IPC via /var/run/*.sock paths
-- AF_INET - network sockets with three backends: -- AF_INET - network sockets with three backends:
-- rednet://0.0.B.C or rednet+PROTO://0.0.B.C -> CC rednet (computer B*256+C) -- Implemented by drivers but expect http:// and https://
-- modem://0.0.B.C -> raw CC modem frames
-- http://host/path or https://... -> HTTP via CC http API
-- A.B.C.D (dotted quad, non-zero A) -> HTTP
-- --
-- Socket lifecycle: -- Socket lifecycle:
-- fd = syscall.socket(domain, socktype) -- "unix"/"inet", "stream"/"dgram" -- fd = syscall.socket(domain, socktype) -- "unix"/"inet", "stream"/"dgram"
@@ -18,539 +15,9 @@
-- syscall.sockshutdown(fd) -- half-close send side -- syscall.sockshutdown(fd) -- half-close send side
-- -- normal vfs.close(fd) closes the socket -- -- normal vfs.close(fd) closes the socket
local kernel = ... local kernel=...
local socket={}
kernel.socket=socket
local sockets = {}
local unixSocks = {}
local nextSockId = 1
local function allocSockId()
local id = nextSockId
nextSockId = nextSockId + 1
return id
end
local function parseAddress(addr)
if not addr then error("EINVAL") end
if addr:sub(1,1) == "/" or addr:sub(1,5) == "unix:" then
local path = addr:sub(1,5) == "unix:" and addr:sub(6) or addr
return { backend="unix", path=path }
end
local rproto, raddr = addr:match("^rednet%+?([^:/]*)://(.+)$")
if raddr then
local a,b,c,d = raddr:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
if not a then error("EINVAL: bad rednet address " .. raddr) end
local compId = tonumber(c)*256 + tonumber(d)
return { backend="rednet", compId=compId,
protocol=(rproto ~= "" and rproto or "hyperion") }
end
local maddr = addr:match("^modem://(.+)$")
if maddr then
local a,b,c,d = maddr:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
if not a then error("EINVAL: bad modem address " .. maddr) end
local compId = tonumber(c)*256 + tonumber(d)
local port = tonumber(maddr:match(":(%d+)$")) or 0
return { backend="modem", compId=compId, port=port }
end
local scheme, rest = addr:match("^(https?)://(.+)$")
if scheme then
return { backend=scheme, url=addr }
end
local a,b,c,d = addr:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)")
if a and tonumber(a) ~= 0 then
return { backend="http", url="http://" .. addr }
end
error("EINVAL: unrecognised address format: " .. tostring(addr))
end
local rednetOpen = false
local function ensureRednet()
if rednetOpen then return end
local rn = kernel.apis and kernel.apis.rednet
if not rn then error("ENODEV: no rednet API available") end
local peripheral = kernel.apis.peripheral
if peripheral then
for _, name in ipairs(peripheral.getNames and peripheral.getNames() or {}) do
if peripheral.getType(name) == "modem" then
pcall(rn.open, name)
end
end
end
rednetOpen = true
end
local function getModem()
local peripheral = kernel.apis and kernel.apis.peripheral
if not peripheral then error("ENODEV") end
for _, name in ipairs(peripheral.getNames and peripheral.getNames() or {}) do
if peripheral.getType(name) == "modem" then
local m = peripheral.wrap(name)
if m then return m, name end
end
end
error("ENODEV: no modem peripheral found")
end
local function pumpEvents()
local ev = kernel.computer:getMachineEvent()
while ev do
if ev == "rednet_message" then
for _, sock in pairs(sockets) do
if sock.backend == "rednet" and sock.bound then
if sock.address.protocol == tostring(select(4, table.unpack({ev}))) or
sock.address.protocol == "hyperion" then
end
end
end
end
ev = kernel.computer:getMachineEvent()
end
end
local function pollEvent()
local results = table.pack(kernel.computer:getMachineEvent())
if results.n == 0 or results[1] == nil then return nil end
return results
end
local function dispatchEvent(ev)
if not ev then return end
local evtype = ev[1]
if evtype == "rednet_message" then
local senderId = ev[2]
local message = ev[3]
local protocol = ev[4] or "hyperion"
for _, sock in pairs(sockets) do
if sock.backend == "rednet" and (sock.listening or sock.connected) then
if sock.address and sock.address.protocol == protocol then
table.insert(sock.rxbuf, { from=senderId, data=message })
end
end
end
elseif evtype == "modem_message" then
local channel = ev[3]
local msg = ev[5]
local fromCh = ev[4]
for _, sock in pairs(sockets) do
if sock.backend == "modem" and sock.modemChannel == channel then
table.insert(sock.rxbuf, { from=fromCh, data=msg })
end
end
elseif evtype == "http_success" then
local url = ev[2]
local handle = ev[3]
for _, sock in pairs(sockets) do
if sock.backend == "http" or sock.backend == "https" then
if sock.pendingUrl == url then
local body = handle.readAll and handle.readAll() or ""
handle.close()
table.insert(sock.rxbuf, { data=body, done=true })
sock.pendingUrl = nil
sock.connected = true
end
end
end
elseif evtype == "http_failure" then
local url = ev[2]
local err = ev[3]
for _, sock in pairs(sockets) do
if (sock.backend == "http" or sock.backend == "https") and
sock.pendingUrl == url then
sock.error = err
sock.pendingUrl = nil
end
end
end
end
local function pumpAll()
local ev = pollEvent()
while ev do
dispatchEvent(ev)
ev = pollEvent()
end
end
local function newSocket(domain, socktype)
local sock = {
id = allocSockId(),
domain = domain, -- "unix" | "inet"
socktype = socktype, -- "stream" | "dgram"
backend = nil,
state = "idle", -- idle | bound | listening | connected | closed
rxbuf = {},
txbuf = {},
backlog = {},
address = nil,
peer = nil,
modemChannel = nil,
modem = nil,
pendingUrl = nil,
bound = false,
listening = false,
connected = false,
error = nil,
}
sockets[sock.id] = sock
return sock
end
local sockSend, sockClose
local function socketToFd(sock)
return {
isSocket = true,
sockId = sock.id,
mode = "rw",
meta = { etype=0, owner=0, group=0, perms=0x1FF, cmeta="" },
type = "socket",
refcount = 1,
handle = {
read = function(count)
pumpAll()
if #sock.rxbuf == 0 then return "" end
local item = table.remove(sock.rxbuf, 1)
local data = type(item) == "table" and (item.data or "") or tostring(item)
if count and #data > count then
table.insert(sock.rxbuf, 1, { data=data:sub(count+1), from=item.from })
data = data:sub(1, count)
end
return data
end,
write = function(data)
if sock.state == "closed" then error("EBADF") end
return sockSend(sock, data)
end,
close = function()
sockClose(sock)
end,
}
}
end
sockSend = function(sock, data)
if sock.backend == "unix" then
local peer = sock.peer
if not peer then error("ENOTCONN") end
table.insert(peer.rxbuf, { data=data })
return #data
elseif sock.backend == "rednet" then
ensureRednet()
local rn = kernel.apis.rednet
rn.send(sock.address.compId, data, sock.address.protocol)
return #data
elseif sock.backend == "modem" then
local modem = sock.modem
if not modem then error("ENOTCONN") end
modem.transmit(sock.address.port, sock.modemChannel or 0, data)
return #data
elseif sock.backend == "http" or sock.backend == "https" then
local http = kernel.apis and kernel.apis.http
if not http then error("ENODEV: no http API") end
local url = sock.address.url
local ok, err = pcall(http.request, url, data, {
["Content-Type"] = "application/octet-stream"
})
if not ok then error("ENETDOWN: " .. tostring(err)) end
sock.pendingUrl = url
return #data
end
error("EPROTONOSUPPORT")
end
sockClose = function(sock)
if sock.state == "closed" then return end
sock.state = "closed"
if sock.backend == "unix" then
if sock.peer then
sock.peer.peer = nil
sock.peer.state = "closed"
end
if sock.bound and sock.address and sock.address.path then
unixSocks[sock.address.path] = nil
end
elseif sock.backend == "modem" and sock.modem and sock.modemChannel then
pcall(sock.modem.close, sock.modemChannel)
elseif sock.backend == "rednet" then
end
sockets[sock.id] = nil
end
kernel.syscalls["socket"] = function(domain, socktype)
domain = domain or "inet"
socktype = socktype or "stream"
if domain ~= "unix" and domain ~= "inet" then error("EAFNOSUPPORT") end
if socktype ~= "stream" and socktype ~= "dgram" then error("EPROTOTYPE") end
local sock = newSocket(domain, socktype)
local fdobj = socketToFd(sock)
local fd = kernel.vfs.newfd(fdobj)
return fd
end
kernel.syscalls["bind"] = function(fd, address)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock then error("EBADF") end
if sock.bound then error("EINVAL") end
local parsed = parseAddress(address)
if parsed.backend == "unix" then
local existing = unixSocks[parsed.path]
if existing then
if existing.state == "closed" then
unixSocks[parsed.path] = nil
else
error("EADDRINUSE")
end
end
sock.backend = "unix"
sock.address = parsed
sock.bound = true
sock.state = "bound"
unixSocks[parsed.path] = sock
elseif parsed.backend == "rednet" then
ensureRednet()
sock.backend = "rednet"
sock.address = parsed
sock.bound = true
sock.state = "bound"
elseif parsed.backend == "modem" then
local modem, side = getModem()
sock.backend = "modem"
sock.address = parsed
sock.modem = modem
sock.modemChannel = parsed.port
sock.bound = true
sock.state = "bound"
modem.open(parsed.port)
else
error("EOPNOTSUPP: cannot bind to " .. parsed.backend .. " address")
end
end
kernel.syscalls["listen"] = function(fd, backlog)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock then error("EBADF") end
if not sock.bound then error("EDESTADDRREQ") end
sock.listening = true
sock.state = "listening"
sock.maxBacklog = backlog or 5
end
kernel.syscalls["accept"] = function(fd)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock then error("EBADF") end
if not sock.listening then error("EINVAL") end
local deadline = kernel.computer:time() + 30000
while #sock.backlog == 0 do
pumpAll()
if kernel.computer:time() > deadline then error("ETIMEDOUT") end
coroutine.yield()
end
local clientSock = table.remove(sock.backlog, 1)
local cfdobj = socketToFd(clientSock)
local newfd = kernel.vfs.newfd(cfdobj)
return newfd
end
kernel.syscalls["connect"] = function(fd, address)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock then error("EBADF") end
if sock.connected then error("EISCONN") end
local parsed = parseAddress(address)
sock.address = parsed
sock.backend = parsed.backend
if parsed.backend == "unix" then
local server = unixSocks[parsed.path]
if not server then error("ECONNREFUSED") end
if not server.listening then error("ECONNREFUSED") end
if #server.backlog >= (server.maxBacklog or 5) then error("ECONNREFUSED") end
local serverPeer = newSocket("unix", sock.socktype)
serverPeer.backend = "unix"
serverPeer.connected = true
serverPeer.state = "connected"
serverPeer.peer = sock
sock.peer = serverPeer
sock.connected = true
sock.state = "connected"
table.insert(server.backlog, serverPeer)
elseif parsed.backend == "rednet" then
ensureRednet()
sock.connected = true
sock.state = "connected"
elseif parsed.backend == "modem" then
local modem, side = getModem()
local replyChannel = math.random(1024, 65534)
sock.modem = modem
sock.modemChannel = replyChannel
sock.connected = true
sock.state = "connected"
modem.open(replyChannel)
elseif parsed.backend == "http" or parsed.backend == "https" then
sock.connected = true
sock.state = "connected"
else
error("EAFNOSUPPORT")
end
end
kernel.syscalls["send"] = function(fd, data)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock then error("EBADF") end
return sockSend(sock, data)
end
kernel.syscalls["recv"] = function(fd, maxlen, timeout_ms)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock then error("EBADF") end
local deadline = kernel.computer:time() + (timeout_ms or 10000)
while #sock.rxbuf == 0 do
pumpAll()
if #sock.rxbuf > 0 then break end
if sock.state == "closed" or sock.error then
if sock.error then error("ECONNRESET: " .. tostring(sock.error)) end
return ""
end
if kernel.computer:time() > deadline then return "" end
coroutine.yield()
end
local item = table.remove(sock.rxbuf, 1)
local data = type(item) == "table" and (item.data or "") or tostring(item)
if maxlen and #data > maxlen then
table.insert(sock.rxbuf, 1, { data=data:sub(maxlen+1), from=item and item.from })
data = data:sub(1, maxlen)
end
return data
end
kernel.syscalls["sockshutdown"] = function(fd)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if sock then sockClose(sock) end
end
kernel.syscalls["getpeername"] = function(fd)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock or not sock.connected then error("ENOTCONN") end
if sock.address then return sock.address end
return nil
end
kernel.syscalls["getsockname"] = function(fd)
local task = kernel.currentTask
local fdobj = task.fd[fd]
if not fdobj or not fdobj.isSocket then error("ENOTSOCK") end
local sock = sockets[fdobj.sockId]
if not sock then error("EBADF") end
return sock.address
end
kernel.syscalls["httpget"] = function(url, headers)
local http = kernel.apis and kernel.apis.http
if not http then error("ENODEV: no http API") end
local ok, err = pcall(http.request, url, nil, headers)
if not ok then error("ENETDOWN: " .. tostring(err)) end
local deadline = kernel.computer:time() + 15000
while true do
local ev = pollEvent()
if ev then
if ev[1] == "http_success" and ev[2] == url then
local handle = ev[3]
local body = handle.readAll and handle.readAll() or ""
handle.close()
return body
elseif ev[1] == "http_failure" and ev[2] == url then
error("ECONNREFUSED: " .. tostring(ev[3]))
else
dispatchEvent(ev)
end
end
if kernel.computer:time() > deadline then error("ETIMEDOUT") end
coroutine.yield()
end
end
kernel.syscalls["resolve"] = function(hostname)
if hostname:match("^%d+%.%d+%.%d+%.%d+$") then return hostname end
local a,b,c,d = hostname:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
if a and tonumber(a) == 0 and tonumber(b) == 0 then
return hostname
end
local http = kernel.apis and kernel.apis.http
if not http then error("ENODEV: no http API for DNS") end
local url = "https://cloudflare-dns.com/dns-query?name=" .. hostname .. "&type=A"
local body = kernel.syscalls["httpget"](url, {
["Accept"] = "application/dns-json"
})
local ip = body:match('"type":1[^}]*"data":"([%d%.]+)"')
if not ip then error("ENOENT: could not resolve " .. hostname) end
return ip
end
kernel.sockets = sockets
kernel.unixSockets = unixSocks
kernel.log("Loaded socket module") kernel.log("Loaded socket module")

View File

@@ -139,7 +139,7 @@ end
if not blake2s then error("Failed to load blake2s") end if not blake2s then error("Failed to load blake2s") end
if not kernel.vfs.exists("/etc/pam.d/secret") then if not kernel.vfs.exists("/etc/pam.d/secret") then
kernel.log("PAM SECRET REGENERATING PLEASE USE ROOT") kernel.log("PAM SECRET REGENERATING PLEASE USE ROOT", "WARN", 0xFF8800)
local key = "" local key = ""
for i = 1, 256 do key = key .. string.char(math.random(0, 255)) end for i = 1, 256 do key = key .. string.char(math.random(0, 255)) end
local handle = kernel.vfs.open("/etc/pam.d/secret", "w") local handle = kernel.vfs.open("/etc/pam.d/secret", "w")

View File

@@ -41,11 +41,11 @@ local function createTask(func, name, envars, args, tgid, real_uid, eff_uid)
if kernel.config.logTaskExit then if kernel.config.logTaskExit then
if not ok then if not ok then
kernel.log("Task " .. tostring(id) .. " exited with err: " .. tostring(err), "ERROR", 2) kernel.log("Task " .. tostring(id) .. " exited with err: " .. tostring(err), "ERROR", 0xFF0000)
elseif err then elseif err then
kernel.log("Task " .. tostring(id) .. " exited with code: " .. tostring(err), "INFO") kernel.log("Task " .. tostring(id) .. " exited with code: " .. tostring(err), "DBUG", 0x00FFFF)
else else
kernel.log("Task " .. tostring(id) .. " exited without code", "INFO") kernel.log("Task " .. tostring(id) .. " exited without code", "DBUG", 0x00FFFF)
end end
end end
@@ -110,7 +110,7 @@ function sys.execspawn(path, name, envars, args, tgid)
kernel.log( kernel.log(
"execspawn: suid exec '" .. path .. "execspawn: suid exec '" .. path ..
"' caller_uid=" .. tostring(real_uid) .. "' caller_uid=" .. tostring(real_uid) ..
" -> euid=" .. tostring(euid), "INFO" " -> euid=" .. tostring(euid)
) )
end end
@@ -136,9 +136,9 @@ function sys.exec(path, args, envars)
local ok, err = xpcall(func, debug.traceback, table.unpack(task.args)) local ok, err = xpcall(func, debug.traceback, table.unpack(task.args))
if kernel.config.logTaskExit then if kernel.config.logTaskExit then
if not ok then if not ok then
kernel.log("Task " .. tostring(task.pid) .. " exec '" .. path .. "' err: " .. tostring(err), "ERROR", 2) kernel.log("Task " .. tostring(task.pid) .. " exec '" .. path .. "' err: " .. tostring(err), "ERROR", 0xFF0000)
else else
kernel.log("Task " .. tostring(task.pid) .. " exec '" .. path .. "' exited: " .. tostring(err), "INFO") kernel.log("Task " .. tostring(task.pid) .. " exec '" .. path .. "' exited: " .. tostring(err), "DBUG", 0x00FFFF)
end end
end end
if type(err) == "number" then tasks[tostring(task.pid)].exit = err end if type(err) == "number" then tasks[tostring(task.pid)].exit = err end
@@ -155,7 +155,7 @@ end
function sys.sleep(s) function sys.sleep(s)
kernel.currentTask.status = "S" kernel.currentTask.status = "S"
kernel.currentTask.sleep = kernel.computer:time() + s * 1000 kernel.currentTask.sleep = kernel.EFI:getEpochMs() + s * 1000
coroutine.yield() coroutine.yield()
end end
@@ -260,9 +260,9 @@ function sys.exit(code)
local task = kernel.currentTask local task = kernel.currentTask
if kernel.config.logTaskExit then if kernel.config.logTaskExit then
if code then if code then
kernel.log("Task " .. tostring(task.pid) .. " exited with code: " .. tostring(code), "INFO") kernel.log("Task " .. tostring(task.pid) .. " exited with code: " .. tostring(code), "DBUG", 0x00FFFF)
else else
kernel.log("Task " .. tostring(task.pid) .. " exited without code", "INFO") kernel.log("Task " .. tostring(task.pid) .. " exited without code", "DBUG", 0x00FFFF)
end end
end end
tasks[tostring(task.pid)].status = "Z" tasks[tostring(task.pid)].status = "Z"
@@ -303,9 +303,9 @@ local function reapDeadTasks()
task.syscallReturn = nil task.syscallReturn = nil
task.sleep = nil task.sleep = nil
task.fd = nil task.fd = nil
task.reapTime = kernel.computer:time() + 30000 task.reapTime = kernel.EFI:getEpochMs() + 30000
elseif task.reapTime and kernel.computer:time() > task.reapTime elseif task.reapTime and kernel.EFI:getEpochMs() > task.reapTime
and task.status == "Z" then and task.status == "Z" then
for _, child in ipairs(task.children) do for _, child in ipairs(task.children) do
child.parent = tasks["1"] child.parent = tasks["1"]
@@ -343,7 +343,7 @@ function kernel.main()
local taskTimes = {} local taskTimes = {}
for pid, task in pairs(tasks) do for pid, task in pairs(tasks) do
if task.status == "S" and kernel.computer:time() >= task.sleep then if task.status == "S" and kernel.EFI:getEpochMs() >= task.sleep then
task.status = "R" task.status = "R"
task.sleep = 0 task.sleep = 0
end end
@@ -382,7 +382,7 @@ function kernel.main()
end end
if task.status == "R" then if task.status == "R" then
local startTime = kernel.computer:time() local startTime = kernel.EFI:getEpochMs()
local ret local ret
if kernel.config.preempt then if kernel.config.preempt then
@@ -391,7 +391,7 @@ function kernel.main()
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) } ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
end end
local elapsed = kernel.computer:time() - startTime local elapsed = kernel.EFI:getEpochMs() - startTime
task.lastTime = elapsed task.lastTime = elapsed
task.totalTime = (task.totalTime or 0) + elapsed task.totalTime = (task.totalTime or 0) + elapsed
task.numRuns = (task.numRuns or 0) + 1 task.numRuns = (task.numRuns or 0) + 1
@@ -403,7 +403,7 @@ function kernel.main()
if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end if elapsed >= Tmax then Tmax_hit = Tmax_hit + 1 end
if ret[1] == "error" or ret[1] == false then if ret[1] == "error" or ret[1] == false then
kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 2) kernel.log("processHandlerException: " .. tostring(ret[2]), "ERROR", 0xFF0000)
task.status = "Z" task.status = "Z"
task.exit = "processHandlerException: " .. tostring(ret[2]) task.exit = "processHandlerException: " .. tostring(ret[2])
@@ -418,9 +418,9 @@ function kernel.main()
local scname = ret[3] local scname = ret[3]
if kernel.syscalls[scname] then if kernel.syscalls[scname] then
if kernel.config.debugSyscalls then if kernel.config.debugSyscalls then
kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 5) kernel.log("Task " .. task.pid .. " syscall: " .. scname, "DBUG", 0x00FFFF)
for i = 4, #ret do for i = 4, #ret do
kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 5) kernel.log(" inval[" .. (i-3) .. "] = " .. tostring(ret[i]), "DBUG", 0x00FFFF)
end end
end end
@@ -428,12 +428,12 @@ function kernel.main()
if kernel.config.debugSyscalls then if kernel.config.debugSyscalls then
if not sysret[1] then if not sysret[1] then
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 2) kernel.log("Task " .. task.pid .. " syscall " .. scname .. " failed: " .. tostring(sysret[2]), "ERROR", 0xFF0000)
else else
kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 5) kernel.log("Task " .. task.pid .. " syscall " .. scname .. " ok, " .. (#sysret-1) .. " retvals", "DBUG", 0x00FFFF)
for i = 2, #sysret do for i = 2, #sysret do
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i]) local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 5) kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
end end
end end
end end

View File

@@ -9,8 +9,20 @@ sysc["gpio_write"]=function(pin, data)
end end
end end
sysc["gpio_writeAnalog"]=function(pin, data)
if kernel.gpio[pin] then
return kernel.gpio[pin]("wa", data)
end
end
sysc["gpio_read"]=function(pin) sysc["gpio_read"]=function(pin)
if kernel.gpio[pin] then if kernel.gpio[pin] then
return kernel.gpio[pin]("r") return kernel.gpio[pin]("r")
end end
end end
sysc["gpio_readAnalog"]=function(pin)
if kernel.gpio[pin] then
return kernel.gpio[pin]("ra")
end
end

View File

@@ -9,11 +9,13 @@ if not initOk then
end end
local handle = kernel.vfs.open(kernel.config.initPath, "r") local handle = kernel.vfs.open(kernel.config.initPath, "r")
if not handle then kernel.panic("Failed to open "..kernel.config.initPath) end
local data = kernel.vfs.read(handle, 1024 * 1024 * 4) local data = kernel.vfs.read(handle, 1024 * 1024 * 4)
if not handle then kernel.panic("Failed to read "..kernel.config.initPath) end
kernel.vfs.close(handle) kernel.vfs.close(handle)
local initFunc, err = load(data, "@sysinit", "t", kernel._U) local initFunc, err = load(data, "@sysinit", "t", kernel._U)
if not initFunc then error("Failed to load init system: " .. err) end if not initFunc then kernel.PANIC("Failed to load init system: " .. err) end
kernel.tasks["1"] = { kernel.tasks["1"] = {
coro = coroutine.create(function() coro = coroutine.create(function()

View File

@@ -4,6 +4,6 @@ local kernel = ...
kernel.processes.login = function() kernel.processes.login = function()
local ok, err = pcall(kernel.hpv.execspawn, "/bin/login", "login") local ok, err = pcall(kernel.hpv.execspawn, "/bin/login", "login")
if not ok then if not ok then
kernel.log("Failed to exec /bin/login: " .. tostring(err), "ERROR", 2) kernel.log("Failed to exec /bin/login: " .. tostring(err), "ERROR", 0xFF0000)
end end
end end

View File

@@ -1,88 +1,88 @@
--:Minify:-- --:Minify:--
local kernel = ... local kernel = ...
local P = kernel.vfs.P
local PERM = kernel.vfs.PERM
local RW_R_R = P.OWNER_R + P.OWNER_W + P.GROUP_R + P.WORLD_R
local RWX_RX_RX = P.OWNER_R + P.OWNER_W + P.OWNER_X
+ P.GROUP_R + P.GROUP_X
+ P.WORLD_R + P.WORLD_X
local RW_R__ = P.OWNER_R + P.OWNER_W + P.GROUP_R
local RW____ = P.OWNER_R + P.OWNER_W
local RWXRWXRWX = PERM.RWXRWXRWX
local SUID_755 = PERM.SUID_755
local META_VERSION = 0x02
local rootDisk = kernel.disks["$"]
local function makeEntry(name, etype, owner, group, perms, cmeta)
cmeta = cmeta or ""
local plo = perms % 256
local phi = math.floor(perms / 256) % 256
local olo = (owner or 0) % 256
local ohi = math.floor((owner or 0) / 256) % 256
local glo = (group or 0) % 256
local ghi = math.floor((group or 0) / 256) % 256
return string.char(#name) .. name
.. string.char(etype, olo, ohi, glo, ghi, plo, phi)
.. string.char(#cmeta) .. cmeta
end
local REG = 0x00
local function mergeMeta(dir, entries)
local diskDir = dir
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
local existing = {}
local rok, rf = pcall(function() return rootDisk:open(metaPath, "r") end)
if rok and rf then
local raw = rf.read(65535)
if rf.close then rf.close() end
existing = (kernel.vfs._parseMetafile and kernel.vfs._parseMetafile(raw)) or {}
end
for _, e in ipairs(entries) do
local name = e[1]
local etype = e[2] or REG
local owner = e[3] or 0
local group = e[4] or 0
local perms = e[5] or RWX_RX_RX
local cmeta = e[6] or ""
existing[name] = {
etype = etype,
owner = owner,
group = group,
perms = perms,
cmeta = cmeta,
}
end
local data = string.char(META_VERSION)
for name, m in pairs(existing) do
data = data .. makeEntry(
name,
m.etype or REG,
m.owner or 0,
m.group or 0,
m.perms or RWX_RX_RX,
m.cmeta or ""
)
end
local ok, err = pcall(function()
local f = rootDisk:open(metaPath, "w")
f.write(data)
f.close()
end)
if not ok then
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 8)
end
end
if kernel.firstBoot then if kernel.firstBoot then
local P = kernel.vfs.P
local PERM = kernel.vfs.PERM
local RW_R_R = P.OWNER_R + P.OWNER_W + P.GROUP_R + P.WORLD_R
local RWX_RX_RX = P.OWNER_R + P.OWNER_W + P.OWNER_X
+ P.GROUP_R + P.GROUP_X
+ P.WORLD_R + P.WORLD_X
local RW_R__ = P.OWNER_R + P.OWNER_W + P.GROUP_R
local RW____ = P.OWNER_R + P.OWNER_W
local RWXRWXRWX = PERM.RWXRWXRWX
local SUID_755 = PERM.SUID_755
local META_VERSION = 0x02
local rootDisk = kernel.disks["$"]
local function makeEntry(name, etype, owner, group, perms, cmeta)
cmeta = cmeta or ""
local plo = perms % 256
local phi = math.floor(perms / 256) % 256
local olo = (owner or 0) % 256
local ohi = math.floor((owner or 0) / 256) % 256
local glo = (group or 0) % 256
local ghi = math.floor((group or 0) / 256) % 256
return string.char(#name) .. name
.. string.char(etype, olo, ohi, glo, ghi, plo, phi)
.. string.char(#cmeta) .. cmeta
end
local REG = 0x00
local function mergeMeta(dir, entries)
local diskDir = dir
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
local existing = {}
local rok, rf = pcall(function() return rootDisk:open(metaPath, "r") end)
if rok and rf then
local raw = rf.read(65535)
if rf.close then rf.close() end
existing = (kernel.vfs._parseMetafile and kernel.vfs._parseMetafile(raw)) or {}
end
for _, e in ipairs(entries) do
local name = e[1]
local etype = e[2] or REG
local owner = e[3] or 0
local group = e[4] or 0
local perms = e[5] or RWX_RX_RX
local cmeta = e[6] or ""
existing[name] = {
etype = etype,
owner = owner,
group = group,
perms = perms,
cmeta = cmeta,
}
end
local data = string.char(META_VERSION)
for name, m in pairs(existing) do
data = data .. makeEntry(
name,
m.etype or REG,
m.owner or 0,
m.group or 0,
m.perms or RWX_RX_RX,
m.cmeta or ""
)
end
local ok, err = pcall(function()
local f = rootDisk:open(metaPath, "w")
f.write(data)
f.close()
end)
if not ok then
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 0xFF8800)
end
end
kernel.log("Seeding filesystem permissions...") kernel.log("Seeding filesystem permissions...")
mergeMeta("/", { mergeMeta("/", {

View File

@@ -261,16 +261,16 @@ local function render()
syscall.write(1, "\n") syscall.write(1, "\n")
end end
end end
syscall.devctl(1, "sfgc", 16) syscall.devctl(1, "sfgc", 0x000000)
syscall.devctl(1, "sbgc", 13) syscall.devctl(1, "sbgc", 0xDBDBDB)
local pct = math.floor(math.min(100, (scroll + pageSize) / totalLines * 100)) local pct = math.floor(math.min(100, (scroll + pageSize) / totalLines * 100))
local status = string.format(" help -- line %d/%d (%d%%) [up/down: scroll q: quit] ", local status = string.format(" help -- line %d/%d (%d%%) [up/down: scroll q: quit] ",
scroll + 1, totalLines, pct) scroll + 1, totalLines, pct)
if #status > screenW then status = status:sub(1, screenW) end if #status > screenW then status = status:sub(1, screenW) end
syscall.devctl(1, "spos", 1, screenH) syscall.devctl(1, "spos", 1, screenH)
syscall.write(1, status .. string.rep(" ", screenW - #status)) syscall.write(1, status .. string.rep(" ", screenW - #status))
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.devctl(1, "sbgc", 16) syscall.devctl(1, "sbgc", 0x000000)
dirty = false dirty = false
end end
@@ -281,7 +281,7 @@ if totalLines <= pageSize then
syscall.devctl(1, "sfgc", line[2]) syscall.devctl(1, "sfgc", line[2])
syscall.write(1, line[1] .. "\n") syscall.write(1, line[1] .. "\n")
end end
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
return return
end end
@@ -305,5 +305,5 @@ end
syscall.devctl(1, "clear") syscall.devctl(1, "clear")
syscall.devctl(1, "spos", 1, 1) syscall.devctl(1, "spos", 1, 1)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.devctl(1, "sbgc", 16) syscall.devctl(1, "sbgc", 0x000000)

View File

@@ -3,11 +3,11 @@
-- 1=white, 2=red, 3=green, 4=blue, 5=cyan, 6=magenta, 7=yellow -- 1=white, 2=red, 3=green, 4=blue, 5=cyan, 6=magenta, 7=yellow
-- 8=orange, 9=lime, 10=lightcyan, 11=brown, 12=darkgrey, 13=lightgrey, 14=purple, 15=chartreuse, 16=black -- 8=orange, 9=lime, 10=lightcyan, 11=brown, 12=darkgrey, 13=lightgrey, 14=purple, 15=chartreuse, 16=black
local C_LOGO = 5 -- cyan local C_LOGO = 0x00FFFF -- cyan
local C_WHITE = 1 -- white local C_WHITE = 0xFFFFFF -- white
local C_LABEL = 13 -- light grey (key names) local C_LABEL = 0xDBDBDB -- light grey (key names)
local C_SEP = 12 -- dark grey (---- separator) local C_SEP = 0x6D6D6D -- dark grey (---- separator)
local C_USER = 3 -- green (user@host) local C_USER = 0x00FF00 -- green (user@host)
local function c(col) syscall.devctl(1, "sfgc", col) end local function c(col) syscall.devctl(1, "sfgc", col) end

View File

@@ -8,7 +8,7 @@ local success, errorMsg = xpcall(function()
local fs = require("fs") local fs = require("fs")
syscall.devctl(1,"clear") syscall.devctl(1,"clear")
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFFFFFF)
syscall.devctl(1,"spos",1,1) syscall.devctl(1,"spos",1,1)
print("HyperionOS hysh Shell") print("HyperionOS hysh Shell")
@@ -26,8 +26,27 @@ else
end end
local oldWD = "" local oldWD = ""
local colors = {
0xFFFFFF,
0xFF0000,
0x00FF00,
0x0000FF,
0x00FFFF,
0xFF00FF,
0xFFFF00,
0xFF6D00,
0x6DFF55,
0x24FFFF,
0x924900,
0x6D6D55,
0xDBDBAA,
0x6D00FF,
0xB6FF00,
0x000000
}
for i = 1, 16 do for i = 1, 16 do
syscall.devctl(1,"sbgc",i); printInline(" ") syscall.devctl(1,"sbgc",colors[i]); printInline(" ")
end end
print("\n") print("\n")
@@ -221,7 +240,7 @@ end
builtinCmds.clear = function() builtinCmds.clear = function()
syscall.devctl(1,"clear") syscall.devctl(1,"clear")
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFFFFFF)
syscall.devctl(1,"spos",1,1) syscall.devctl(1,"spos",1,1)
end end
@@ -429,7 +448,7 @@ builtinCmds.head = function(...)
local multi = #files > 1 local multi = #files > 1
local function dohead(text, label) local function dohead(text, label)
if multi then if multi then
syscall.devctl(1,"sfgc",4); print("==> "..label.." <=="); syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0x0000FF); print("==> "..label.." <=="); syscall.devctl(1,"sfgc",0xFFFFFF)
end end
local count = 0 local count = 0
for line in (text.."\n"):gmatch("([^\n]*)\n") do for line in (text.."\n"):gmatch("([^\n]*)\n") do
@@ -468,7 +487,7 @@ builtinCmds.tail = function(...)
local multi = #files > 1 local multi = #files > 1
local function dotail(text, label) local function dotail(text, label)
if multi then if multi then
syscall.devctl(1,"sfgc",4); print("==> "..label.." <=="); syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0x0000FF); print("==> "..label.." <=="); syscall.devctl(1,"sfgc",0xFFFFFF)
end end
local lines = splitlines(text) local lines = splitlines(text)
local start = math.max(1, #lines - n + 1) local start = math.max(1, #lines - n + 1)
@@ -963,13 +982,13 @@ local function doTabComplete(input, cursorPos)
end end
local function getUserInput() local function getUserInput()
syscall.devctl(1,"sfgc",3) syscall.devctl(1,"sfgc",0x00FF00)
syscall.write(1, userhost) syscall.write(1, userhost)
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFFFFFF)
syscall.write(1, ":") syscall.write(1, ":")
syscall.devctl(1,"sfgc",10) syscall.devctl(1,"sfgc",0x24FFFF)
syscall.write(1, syscall.getcwd()) syscall.write(1, syscall.getcwd())
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFFFFFF)
syscall.write(1, "$ ") syscall.write(1, "$ ")
local curOffsetStr = syscall.devctl(1, "gpos") local curOffsetStr = syscall.devctl(1, "gpos")
local curOffsetX = tonumber(curOffsetStr:sub(1, curOffsetStr:find(";")-1)) local curOffsetX = tonumber(curOffsetStr:sub(1, curOffsetStr:find(";")-1))
@@ -1020,21 +1039,21 @@ local function getUserInput()
syscall.devctl(1,"spos",curOffsetX,curOffsetY) syscall.devctl(1,"spos",curOffsetX,curOffsetY)
syscall.write(1, string.sub(input, 1, cursorPos-1)) syscall.write(1, string.sub(input, 1, cursorPos-1))
if blinkState then if blinkState then
syscall.devctl(1,"sfgc",16); syscall.devctl(1,"sbgc",1) syscall.devctl(1,"sfgc",0x000000); syscall.devctl(1,"sbgc",0xFFFFFF)
end end
if cursorPos > #input then if cursorPos > #input then
syscall.write(1, " ") syscall.write(1, " ")
else else
syscall.write(1, string.sub(input, cursorPos, cursorPos)) syscall.write(1, string.sub(input, cursorPos, cursorPos))
end end
syscall.devctl(1,"sfgc",1); syscall.devctl(1,"sbgc",16) syscall.devctl(1,"sfgc",0xFFFFFF); syscall.devctl(1,"sbgc",0x000000)
local after = string.sub(input, cursorPos+1) local after = string.sub(input, cursorPos+1)
syscall.write(1, after) syscall.write(1, after)
local ghost = getGhostSuffix() local ghost = getGhostSuffix()
if #ghost > 0 then if #ghost > 0 then
syscall.devctl(1,"sfgc",14) syscall.devctl(1,"sfgc",0x6D00FF)
syscall.write(1, ghost) syscall.write(1, ghost)
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFFFFFF)
syscall.write(1, " ") syscall.write(1, " ")
else else
syscall.write(1, " ") syscall.write(1, " ")
@@ -1082,10 +1101,10 @@ local function getUserInput()
syscall.write(1, string.rep(" ", tw)) syscall.write(1, string.rep(" ", tw))
syscall.devctl(1,"spos",1,py) syscall.devctl(1,"spos",1,py)
end end
syscall.devctl(1,"sfgc",3); syscall.write(1, userhost) syscall.devctl(1,"sfgc",0x00FF00); syscall.write(1, userhost)
syscall.devctl(1,"sfgc",1); syscall.write(1, ":") syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, ":")
syscall.devctl(1,"sfgc",10); syscall.write(1, syscall.getcwd()) syscall.devctl(1,"sfgc",0x00FFFF); syscall.write(1, syscall.getcwd())
syscall.devctl(1,"sfgc",1); syscall.write(1, "$ ") syscall.devctl(1,"sfgc",0xFFFFFF); syscall.write(1, "$ ")
posStr = syscall.devctl(1, "gpos") posStr = syscall.devctl(1, "gpos")
sep = posStr:find(";") sep = posStr:find(";")
curOffsetX = tonumber(posStr:sub(1, sep-1)) curOffsetX = tonumber(posStr:sub(1, sep-1))
@@ -1098,7 +1117,7 @@ local function getUserInput()
cursorPos=cursorPos-1;dirty=true cursorPos=cursorPos-1;dirty=true
end end
elseif key=="\n" then elseif key=="\n" then
syscall.devctl(1,"sfgc",1);syscall.devctl(1,"sbgc",16) syscall.devctl(1,"sfgc",0xFFFFFF);syscall.devctl(1,"sbgc",0x000000)
syscall.devctl(1,"spos",curOffsetX,curOffsetY) syscall.devctl(1,"spos",curOffsetX,curOffsetY)
syscall.write(1, input.." \n") syscall.write(1, input.." \n")
return input return input
@@ -1114,7 +1133,7 @@ local function getUserInput()
end end
local function printError(progName, msg) local function printError(progName, msg)
syscall.devctl(1,"sfgc",2) syscall.devctl(1,"sfgc",0xFF0000)
local s = tostring(msg) local s = tostring(msg)
local line, rest = s:match("%]:(%d+): (.+)$") local line, rest = s:match("%]:(%d+): (.+)$")
if not line then line, rest = s:match(":(%d+): (.+)$") end if not line then line, rest = s:match(":(%d+): (.+)$") end
@@ -1123,7 +1142,7 @@ local function printError(progName, msg)
else else
print(progName..": "..s) print(progName..": "..s)
end end
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFFFFFF)
end end
local function runCommand(command) local function runCommand(command)
@@ -1171,7 +1190,7 @@ local function runCommand(command)
local xok, xerr = pcall(syscall.access, cmdPath, "x") local xok, xerr = pcall(syscall.access, cmdPath, "x")
if not xok then if not xok then
syscall.devctl(1,"sfgc",2); print(progName..": Permission denied"); syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFF0000); print(progName..": Permission denied"); syscall.devctl(1,"sfgc",0xFFFFFF)
return return
end end
@@ -1195,8 +1214,8 @@ local function runCommand(command)
if terminate then if terminate then
local ok2 = syscall.kill(proc) local ok2 = syscall.kill(proc)
if ok2 then if ok2 then
syscall.devctl(1,"sbgc",16); syscall.devctl(1,"sfgc",2) syscall.devctl(1,"sbgc",16); syscall.devctl(1,"sfgc",0xFF0000)
print("\nProgram Terminated."); syscall.devctl(1,"sfgc",1) print("\nProgram Terminated."); syscall.devctl(1,"sfgc",0xFFFFFF)
end end
terminate = false; break terminate = false; break
end end
@@ -1218,8 +1237,8 @@ end, debug.traceback)
if not success then if not success then
syscall.log("Error running shell: "..errorMsg, "ERROR") syscall.log("Error running shell: "..errorMsg, "ERROR")
syscall.devctl(1,"sfgc",2) syscall.devctl(1,"sfgc",0xFF0000)
syscall.devctl(1,"sbgc",16) syscall.devctl(1,"sbgc",0x000000)
print() print()
print("Error running shell: ") print("Error running shell: ")
print(errorMsg) print(errorMsg)

View File

@@ -37,9 +37,9 @@ local function firstBoot()
syscall.devctl(1, "clear") syscall.devctl(1, "clear")
syscall.devctl(1, "spos", 1, 1) syscall.devctl(1, "spos", 1, 1)
syscall.devctl(1, "sfgc", 3) syscall.devctl(1, "sfgc", 0x00FF00)
syscall.write(1, "HyperionOS First Boot Setup\n") syscall.write(1, "HyperionOS First Boot Setup\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.write(1, "No root password is set. Please create one now.\n\n") syscall.write(1, "No root password is set. Please create one now.\n\n")
while true do while true do
@@ -49,25 +49,25 @@ local function firstBoot()
local pw2 = readLine("*") local pw2 = readLine("*")
if pw1 ~= pw2 then if pw1 ~= pw2 then
syscall.devctl(1, "sfgc", 2) syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Passwords do not match. Try again.\n\n") syscall.write(1, "Passwords do not match. Try again.\n\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
elseif #pw1 < 6 then elseif #pw1 < 6 then
syscall.devctl(1, "sfgc", 2) syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Password too short (minimum 6 characters).\n\n") syscall.write(1, "Password too short (minimum 6 characters).\n\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
else else
local ok, err = syscall.setpassword(0, pw1) local ok, err = syscall.setpassword(0, pw1)
if ok then if ok then
syscall.devctl(1, "sfgc", 3) syscall.devctl(1, "sfgc", 0x00FF00)
syscall.write(1, "Root password set.\n\n") syscall.write(1, "Root password set.\n\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.5) sleep(0.5)
break break
else else
syscall.devctl(1, "sfgc", 2) syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Error: " .. tostring(err) .. "\n") syscall.write(1, "Error: " .. tostring(err) .. "\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
end end
end end
end end
@@ -112,8 +112,8 @@ end
local function doLogin() local function doLogin()
syscall.devctl(1, "clear") syscall.devctl(1, "clear")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.devctl(1, "sbgc", 16) syscall.devctl(1, "sbgc", 0x000000)
syscall.devctl(1, "spos", 1, 1) syscall.devctl(1, "spos", 1, 1)
local hostname = syscall.getHostname() or "hyperion" local hostname = syscall.getHostname() or "hyperion"
@@ -122,7 +122,7 @@ local function doLogin()
local attempts = 0 local attempts = 0
while attempts < MAX_ATTEMPTS do while attempts < MAX_ATTEMPTS do
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
syscall.write(1, "Username: ") syscall.write(1, "Username: ")
local username = readLine(nil) local username = readLine(nil)
@@ -140,9 +140,9 @@ local function doLogin()
local shell = (pwent and pwent.shell) or "/bin/hysh" local shell = (pwent and pwent.shell) or "/bin/hysh"
local homedir = (pwent and pwent.homedir) or "/" local homedir = (pwent and pwent.homedir) or "/"
syscall.devctl(1, "sfgc", 3) syscall.devctl(1, "sfgc", 0x00FF00)
syscall.write(1, "\nWelcome, " .. username .. "!\n") syscall.write(1, "\nWelcome, " .. username .. "!\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(0.3) sleep(0.3)
spawnShell(username, uid, shell, homedir) spawnShell(username, uid, shell, homedir)
@@ -150,16 +150,16 @@ local function doLogin()
else else
attempts = attempts + 1 attempts = attempts + 1
sleep(1) sleep(1)
syscall.devctl(1, "sfgc", 2) syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Login incorrect.\n\n") syscall.write(1, "Login incorrect.\n\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
end end
end end
end end
syscall.devctl(1, "sfgc", 2) syscall.devctl(1, "sfgc", 0xFF0000)
syscall.write(1, "Maximum login attempts exceeded.\n") syscall.write(1, "Maximum login attempts exceeded.\n")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
sleep(5) sleep(5)
end end

View File

@@ -110,9 +110,9 @@ if opts.x then
pcall(syscall.umount, tmpMnt) pcall(syscall.umount, tmpMnt)
pcall(syscall.lodetach, loopId) pcall(syscall.lodetach, loopId)
syscall.devctl(1, "sfgc", 10) syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": extracted "..count.." file(s) to "..destPath) print(name..": extracted "..count.." file(s) to "..destPath)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
return return
end end
@@ -150,8 +150,8 @@ local lineCount = 0
for _ in imgStr:gmatch("\n") do lineCount = lineCount + 1 end for _ in imgStr:gmatch("\n") do lineCount = lineCount + 1 end
local byteCount = #imgStr local byteCount = #imgStr
syscall.devctl(1, "sfgc", 10) syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": image written to "..imgPath) print(name..": image written to "..imgPath)
syscall.devctl(1, "sfgc", 14) syscall.devctl(1, "sfgc", 0x6D00FF)
print(string.format(" %d records, %d bytes", lineCount - 1, byteCount)) print(string.format(" %d records, %d bytes", lineCount - 1, byteCount))
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)

View File

@@ -60,18 +60,18 @@ if opts.l then
local info = devs[id] local info = devs[id]
local mode = (type(info) == "table" and info.mode) or "bind" local mode = (type(info) == "table" and info.mode) or "bind"
local path = (type(info) == "table" and info.path) or tostring(info) local path = (type(info) == "table" and info.path) or tostring(info)
local colour = mode == "image" and 5 or 4 local colour = mode == "image" and 0x00FFFF or 0x0000FF
syscall.devctl(1, "sfgc", 3) syscall.devctl(1, "sfgc", 0x00FF00)
printInline(string.format("%-10s", id)) printInline(string.format("%-10s", id))
syscall.devctl(1, "sfgc", colour) syscall.devctl(1, "sfgc", colour)
printInline(string.format("%-7s", "["..mode.."]")) printInline(string.format("%-7s", "["..mode.."]"))
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
print(" "..path) print(" "..path)
end end
if not any then if not any then
syscall.devctl(1, "sfgc", 14) syscall.devctl(1, "sfgc", 0x6D00FF)
print(name..": no loop devices attached") print(name..": no loop devices attached")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
end end
return return
end end
@@ -92,9 +92,9 @@ if opts.d then
end end
print(name..": "..msg); syscall.exit(1); return print(name..": "..msg); syscall.exit(1); return
end end
syscall.devctl(1, "sfgc", 10) syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": detached "..id) print(name..": detached "..id)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
return return
end end

View File

@@ -136,26 +136,26 @@ if cloptions.l then
printInline(tostring(mtime) .. " ") printInline(tostring(mtime) .. " ")
if isSym then if isSym then
syscall.devctl(1, "sfgc", 6) syscall.devctl(1, "sfgc", 0xFF00FF)
printInline(v) printInline(v)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
local ok, target = pcall(syscall.readlink, fullPath) local ok, target = pcall(syscall.readlink, fullPath)
if ok then if ok then
printInline(" -> ") printInline(" -> ")
local targetExists = pcall(syscall.stat, fullPath) local targetExists = pcall(syscall.stat, fullPath)
syscall.devctl(1, "sfgc", targetExists and 6 or 2) syscall.devctl(1, "sfgc", targetExists and 0xFF00FF or 0xFF0000)
printInline(target) printInline(target)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
end end
elseif isDir then elseif isDir then
syscall.devctl(1, "sfgc", 14) syscall.devctl(1, "sfgc", 0x6D00FF)
printInline(v) printInline(v)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
else else
local isExec = stat and stat.perms and (math.floor(stat.perms / (2^9)) % 2 == 1) local isExec = stat and stat.perms and (math.floor(stat.perms / (2^9)) % 2 == 1)
syscall.devctl(1, "sfgc", isExec and 3 or 1) syscall.devctl(1, "sfgc", isExec and 0x00FF00 or 0xFFFFFF)
printInline(v) printInline(v)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
end end
print("") print("")
end end
@@ -175,16 +175,16 @@ for i, v in ipairs(list) do
local isSym = stat and stat.etype == 0x01 local isSym = stat and stat.etype == 0x01
if isSym then if isSym then
syscall.devctl(1, "sfgc", 6) syscall.devctl(1, "sfgc", 0xFF00FF)
elseif isDir then elseif isDir then
syscall.devctl(1, "sfgc", 14) syscall.devctl(1, "sfgc", 0x6D00FF)
else else
local isExec = stat and stat.perms and (math.floor(stat.perms / (2^9)) % 2 == 1) local isExec = stat and stat.perms and (math.floor(stat.perms / (2^9)) % 2 == 1)
syscall.devctl(1, "sfgc", isExec and 3 or 1) syscall.devctl(1, "sfgc", isExec and 0x00FF00 or 0xFFFFFF)
end end
printInline(v) printInline(v)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
printInline((" "):rep(colWidth - #v)) printInline((" "):rep(colWidth - #v))
if i % numCols == 0 then print("") end if i % numCols == 0 then print("") end

View File

@@ -5,15 +5,15 @@ if not users or #users == 0 then
return return
end end
syscall.devctl(1,"sfgc",13) syscall.devctl(1,"sfgc",0xDBDBDB)
print(string.format("%-6s %-6s %-16s %-20s %s", "UID", "GID", "Username", "Home", "Shell")) print(string.format("%-6s %-6s %-16s %-20s %s", "UID", "GID", "Username", "Home", "Shell"))
print(string.rep("-", 65)) print(string.rep("-", 65))
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",0xFFFFFF)
for _, u in ipairs(users) do for _, u in ipairs(users) do
local lock_marker = u.locked and " [locked]" or "" local lock_marker = u.locked and " [locked]" or ""
if u.locked then syscall.devctl(1,"sfgc",2) end if u.locked then syscall.devctl(1,"sfgc",0xFF0000) end
print(string.format("%-6d %-6d %-16s %-20s %s%s", print(string.format("%-6d %-6d %-16s %-20s %s%s",
u.uid, u.gid, u.username, u.homedir, u.shell, lock_marker)) u.uid, u.gid, u.username, u.homedir, u.shell, lock_marker))
if u.locked then syscall.devctl(1,"sfgc",1) end if u.locked then syscall.devctl(1,"sfgc",0xFFFFFF) end
end end

View File

@@ -69,17 +69,17 @@ if #args == 0 and not opts.o then
end end
if next(loDevs) == nil then if next(loDevs) == nil then
syscall.devctl(1, "sfgc", 14) syscall.devctl(1, "sfgc", 0xFF00FF)
print("(no loop devices attached)") print("(no loop devices attached)")
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
return return
end end
for id, info in pairs(loDevs) do for id, info in pairs(loDevs) do
local colour = info.mode == "image" and 5 or 4 local colour = info.mode == "image" and 0x00FFFF or 0x0000FF
syscall.devctl(1, "sfgc", colour) syscall.devctl(1, "sfgc", colour)
printInline(info.mode.." "..id) printInline(info.mode.." "..id)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
print(" on "..info.path) print(" on "..info.path)
end end
return return
@@ -119,9 +119,9 @@ if opts.o and opts.o:lower() == "loop" then
print(name..": mount: "..msg); syscall.exit(1); return print(name..": mount: "..msg); syscall.exit(1); return
end end
syscall.devctl(1, "sfgc", 10) syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": "..loopId.." mounted at "..dest) print(name..": "..loopId.." mounted at "..dest)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
return return
end end
@@ -141,9 +141,9 @@ if #args == 2 then
print(name..": "..msg); syscall.exit(1); return print(name..": "..msg); syscall.exit(1); return
end end
syscall.devctl(1, "sfgc", 10) syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": "..loopId.." mounted at "..dest) print(name..": "..loopId.." mounted at "..dest)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
return return
end end

View File

@@ -1,6 +1,9 @@
--:Minify:-- --:Minify:--
local targetUser = ({ ... })[1] local targetUser = ({ ... })[1]
local currentUid = syscall.getuid() local currentUid = syscall.getuid()
if syscall.geteuid()~=0 then
syscall.exec("/bin/su", {...})
end
local targetUid local targetUid
if targetUser then if targetUser then
targetUid = syscall.getuidbyname(targetUser) targetUid = syscall.getuidbyname(targetUser)

View File

@@ -59,9 +59,9 @@ if opts.l then
end end
print(name..": "..msg); syscall.exit(1); return print(name..": "..msg); syscall.exit(1); return
end end
syscall.devctl(1, "sfgc", 10) syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": detached "..id) print(name..": detached "..id)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
return return
end end
@@ -95,17 +95,17 @@ if not ok then
print(name..": "..msg); syscall.exit(1); return print(name..": "..msg); syscall.exit(1); return
end end
syscall.devctl(1, "sfgc", 10) syscall.devctl(1, "sfgc", 0x00FFFF)
print(name..": unmounted "..mpt) print(name..": unmounted "..mpt)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
if loopIdToDetach then if loopIdToDetach then
for _, id in ipairs(loopIdToDetach) do for _, id in ipairs(loopIdToDetach) do
local dok = pcall(syscall.lodetach, id) local dok = pcall(syscall.lodetach, id)
if dok then if dok then
syscall.devctl(1, "sfgc", 14) syscall.devctl(1, "sfgc", 0xFF00FF)
print(name..": auto-detached "..id) print(name..": auto-detached "..id)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 0xFFFFFF)
end end
end end
end end

View File

@@ -1,14 +1,14 @@
--:Minify:-- --:Minify:--
local C_PROMPT = 7 local C_PROMPT = 0xFFFF00
local C_CONT = 13 local C_CONT = 0xDBDBDB
local C_OUT = 5 local C_OUT = 0x00FFFF
local C_ERR = 2 local C_ERR = 0xFF0000
local C_KEY = 3 local C_KEY = 0x00FF00
local C_STR = 9 local C_STR = 0x00FF88
local C_NUM = 10 local C_NUM = 0x24FFFF
local C_BOOL = 8 local C_BOOL = 0xFF6D00
local C_NIL = 12 local C_NIL = 0x6D6D6D
local C_TABLE = 13 local C_TABLE = 0xDBDBDB
local function c(col) syscall.devctl(1, "sfgc", col) end local function c(col) syscall.devctl(1, "sfgc", col) end
local function w(s) syscall.write(1, tostring(s)) end local function w(s) syscall.write(1, tostring(s)) end
@@ -250,9 +250,9 @@ local function getUserInput(prompt, history)
local function redraw() local function redraw()
syscall.devctl(1, "spos", ox, oy) syscall.devctl(1, "spos", ox, oy)
w(input:sub(1, cursor-1)) w(input:sub(1, cursor-1))
if blink then syscall.devctl(1,"sfgc",16); syscall.devctl(1,"sbgc",1) end if blink then syscall.devctl(1,"sfgc",0x000000); syscall.devctl(1,"sbgc",1) end
w(cursor > #input and " " or input:sub(cursor, cursor)) w(cursor > #input and " " or input:sub(cursor, cursor))
syscall.devctl(1,"sfgc",1); syscall.devctl(1,"sbgc",16) syscall.devctl(1,"sfgc",0xFFFFFF); syscall.devctl(1,"sbgc",16)
w(input:sub(cursor+1) .. " ") w(input:sub(cursor+1) .. " ")
dirty = false dirty = false
end end
@@ -284,7 +284,7 @@ local function getUserInput(prompt, history)
cursor = cursor - 1; dirty = true cursor = cursor - 1; dirty = true
end end
elseif key == "\n" then elseif key == "\n" then
syscall.devctl(1,"sfgc",1); syscall.devctl(1,"sbgc",16) syscall.devctl(1,"sfgc",0xFFFFFF); syscall.devctl(1,"sbgc",16)
syscall.devctl(1,"spos",ox,oy) syscall.devctl(1,"spos",ox,oy)
w(input .. " \n") w(input .. " \n")
return input return input

View File

@@ -135,16 +135,16 @@ local function pad(s, w)
end end
local function drawTop() local function drawTop()
tpos(1,1); tbg(4); tfg(16) tpos(1,1); tbg(0x0000FF); tfg(0x000000)
local left = " edit" .. (fname and (" - "..fname) or "") local left = " edit" .. (fname and (" - "..fname) or "")
if dirty then left = left .. " [+]" end if dirty then left = left .. " [+]" end
local right = tostring(cy)..","..tostring(cx).." " local right = tostring(cy)..","..tostring(cx).." "
twrite(pad(left..string.rep(" ", math.max(1, W-#left-#right))..right, W)) twrite(pad(left..string.rep(" ", math.max(1, W-#left-#right))..right, W))
tbg(16); tfg(1) tbg(0x000000); tfg(0xFFFFFF)
end end
local function drawBottom() local function drawBottom()
tpos(1, H); tbg(4); tfg(16) tpos(1, H); tbg(0x0000FF); tfg(0x000000)
if msg ~= "" then if msg ~= "" then
if msgErr then tbg(2) end if msgErr then tbg(2) end
twrite(pad(" "..msg, W)) twrite(pad(" "..msg, W))
@@ -152,7 +152,7 @@ local function drawBottom()
else else
twrite(pad(" ^W Save ^X Quit+Save ^P Quit ^K Cut ^U Paste ^F Find ^G Go", W)) twrite(pad(" ^W Save ^X Quit+Save ^P Quit ^K Cut ^U Paste ^F Find ^G Go", W))
end end
tbg(16); tfg(1) tbg(0x000000); tfg(0xFFFFFF)
end end
local function drawLines(map) local function drawLines(map)
@@ -177,29 +177,29 @@ local function drawLines(map)
local curCh = ci > #seg and " " or seg:sub(ci, ci) local curCh = ci > #seg and " " or seg:sub(ci, ci)
local after = seg:sub(ci+1) local after = seg:sub(ci+1)
tfg(1); tbg(16); twrite(before) tfg(0xFFFFFF); tbg(0x000000); twrite(before)
if blinkState then tfg(16); tbg(1) else tfg(1); tbg(16) end if blinkState then tfg(0x000000); tbg(0xFFFFFF) else tfg(0xFFFFFF); tbg(0x000000) end
twrite(curCh) twrite(curCh)
tfg(1); tbg(16); twrite(after) tfg(0xFFFFFF); tbg(0x000000); twrite(after)
local drawn = #before + 1 + #after local drawn = #before + 1 + #after
if drawn < W then twrite(string.rep(" ", W - drawn)) end if drawn < W then twrite(string.rep(" ", W - drawn)) end
else else
if li == sLine and sPat ~= "" and entry[2] == 1 then if li == sLine and sPat ~= "" and entry[2] == 1 then
local s, e = seg:find(sPat) local s, e = seg:find(sPat)
if s then if s then
tfg(1); tbg(16); twrite(seg:sub(1,s-1)) tfg(0xFFFFFF); tbg(0x000000); twrite(seg:sub(1,s-1))
tfg(16); tbg(3); twrite(seg:sub(s,e)) tfg(0x000000); tbg(0x00FF00); twrite(seg:sub(s,e))
tfg(1); tbg(16); twrite(seg:sub(e+1)) tfg(0xFFFFFF); tbg(0x000000); twrite(seg:sub(e+1))
twrite(string.rep(" ", W - #seg)) twrite(string.rep(" ", W - #seg))
else else
tfg(1); tbg(16); twrite(pad(seg, W)) tfg(0xFFFFFF); tbg(0x000000); twrite(pad(seg, W))
end end
else else
tfg(1); tbg(16); twrite(pad(seg, W)) tfg(0xFFFFFF); tbg(0x000000); twrite(pad(seg, W))
end end
end end
else else
tfg(13); tbg(16); twrite(pad("~", W)); tfg(1) tfg(0xDBDBDB); tbg(0x000000); twrite(pad("~", W)); tfg(0xFFFFFF)
end end
end end
end end
@@ -212,15 +212,15 @@ local function redraw()
drawLines(map) drawLines(map)
drawBottom() drawBottom()
tpos(1, H) tpos(1, H)
tbg(16); tfg(1) tbg(0x000000); tfg(0xFFFFFF)
end end
local function prompt(label, default) local function prompt(label, default)
local inp = default or "" local inp = default or ""
while true do while true do
tpos(1, H); tbg(3); tfg(16) tpos(1, H); tbg(0x00FF00); tfg(0x000000)
twrite(pad(" "..label..inp.." ", W)) twrite(pad(" "..label..inp.." ", W))
tbg(16); tfg(1) tbg(0x000000); tfg(0xFFFFFF)
local key = syscall.read(0) local key = syscall.read(0)
if not key or key == "" then sleep(0.02) if not key or key == "" then sleep(0.02)
elseif key == "" then return nil elseif key == "" then return nil
@@ -415,5 +415,5 @@ while running do
end end
end end
tclear(); tfg(1); tbg(16); tpos(1,1) tclear(); tfg(0xFFFFFF); tbg(0x000000); tpos(1,1)
print("edit: exited"..(fname and (" - "..fname) or "")) print("edit: exited"..(fname and (" - "..fname) or ""))

View File

@@ -1,15 +1,16 @@
--:Minify:-- --:Minify:--
local kernel=... local kernel=...
local fs=require("fs") local fs=require("fs")
kernel.log("Sysinit started...")
for i,v in pairs(kernel.processes) do for i,v in pairs(kernel.processes) do
kernel.log("Spawning kernel task "..i) kernel.log("Spawning kernel task "..i)
syscall.spawn(function() syscall.spawn(function()
local status, err = pcall(v) local status, err = pcall(v)
if not status then if not status then
kernel.log("Error executing kernel task '" .. i .. "': " .. err, "ERROR") kernel.log("Error executing kernel task '" .. i .. "': " .. err, "ERROR", 0xFF0000)
else else
kernel.log("Successfully executed kernel task: " .. i, "INFO") kernel.log("Successfully executed kernel task: " .. i)
end end
end, i) end, i)
end end
@@ -17,23 +18,24 @@ end
if not fs.exists("/bin/startup") then if not fs.exists("/bin/startup") then
fs.mkdir("/bin/startup") fs.mkdir("/bin/startup")
end end
local files = fs.list("/bin/startup") local files = fs.list("/bin/startup")
if not files then error("Failed to list /bin/startup") end if not files then error("Failed to list /bin/startup") end
for i,v in ipairs(files) do for i,v in ipairs(files) do
if v:sub(-4) == ".lua" then if v:sub(-4) == ".lua" then
local filepath = "/bin/startup/" .. v local filepath = "/bin/startup/" .. v
kernel.log("Executing startup script: " .. filepath, "INFO") kernel.log("Executing startup script: " .. filepath)
local startupFunc, err = load(fs.readAllText(filepath), "@" .. filepath) local startupFunc, err = load(fs.readAllText(filepath), "@" .. filepath)
if not startupFunc then if not startupFunc then
kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR") kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else else
syscall.spawn(function() syscall.spawn(function()
syscall.setuid(1) syscall.setuid(1)
local status, err = pcall(startupFunc) local status, err = pcall(startupFunc)
if not status then if not status then
kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR") kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
else else
kernel.log("Successfully executed startup script: " .. filepath, "INFO") kernel.log("Successfully executed startup script: " .. filepath)
end end
end, "startup:" .. v) end, "startup:" .. v)
end end

View File

@@ -74,7 +74,7 @@ def compress_lz4(data: bytes) -> bytes:
return lz4.frame.compress(data) return lz4.frame.compress(data)
def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool): def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool, arch:Union[str, None]):
print(f"Building from {src_root}") print(f"Building from {src_root}")
print(f"Output to {out_root}") print(f"Output to {out_root}")
print() print()
@@ -83,6 +83,10 @@ def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool):
if not pkg_dir.is_dir(): if not pkg_dir.is_dir():
continue continue
if pkg_dir.name[:18] == "Hyperion-firmware-":
if pkg_dir.name != f"Hyperion-firmware-{arch}":
continue
print(f"== Package: {pkg_dir.name} ==") print(f"== Package: {pkg_dir.name} ==")
for src in sorted(pkg_dir.rglob("*")): for src in sorted(pkg_dir.rglob("*")):
@@ -134,7 +138,7 @@ def run_build(minify: bool, micro: bool, include_test: bool, arch: Union[str, No
out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT out_root = BUILD_ROOT / "$" if arch else BUILD_ROOT
process_root(SRC_ROOT, out_root, minify, micro) process_root(SRC_ROOT, out_root, minify, micro, arch)
if include_test: if include_test:
process_root(TEST_ROOT, out_root, minify, micro) process_root(TEST_ROOT, out_root, minify, micro)

View File

@@ -144,9 +144,14 @@ syscall.dup=function(fd) end
--- Read GPIO pin --- Read GPIO pin
--- @param pin integer --- @param pin integer
--- @return number|nil --- @return boolean|nil
syscall.gpio_read=function(pin) end syscall.gpio_read=function(pin) end
--- Read GPIO pin analog
--- @param pin integer
--- @return number|nil
syscall.gpio_readAnalog=function(pin) end
--- Get SUID bit from fd --- Get SUID bit from fd
--- @param fd integer --- @param fd integer
--- @return boolean --- @return boolean
@@ -154,10 +159,14 @@ syscall.fget_suid=function(fd) end
--- Write GPIO pin --- Write GPIO pin
--- @param pin integer --- @param pin integer
--- @param data number --- @param data boolean
--- @return boolean
syscall.gpio_write=function(pin, data) end syscall.gpio_write=function(pin, data) end
--- Write GPIO pin analog
--- @param pin integer
--- @param data number
syscall.gpio_writeAnalog=function(pin, data) end
--- Set password for user --- Set password for user
--- @param uid integer --- @param uid integer
--- @param newPassword string --- @param newPassword string