e
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
local object = {}
|
local object = {}
|
||||||
local file = fs.open("/bios.lua", "r")
|
local file = fs.open("/computers/0/bios.lua", "r")
|
||||||
local bios = file.readAll()
|
local bios = file.readAll()
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
local object = {}
|
local object = {}
|
||||||
local file = fs.open("/nvram.dat", "r")
|
local file = fs.open("/computers/0/nvram.dat", "r")
|
||||||
local nvram = string.split(file.readAll(), "\n")
|
local nvram = string.split(file.readAll(), "\n")
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
137
AceVM/components/disks.lua
Normal file
137
AceVM/components/disks.lua
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
local fss = {}
|
||||||
|
local object = {}
|
||||||
|
local uObject = {}
|
||||||
|
|
||||||
|
local function getFs(self)
|
||||||
|
return fss[tostring(self.__UDATA_id)]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function normalize(path)
|
||||||
|
if path:sub(1,1)=="/" then
|
||||||
|
path=path:sub(2)
|
||||||
|
end
|
||||||
|
return path
|
||||||
|
end
|
||||||
|
|
||||||
|
function object:open(path)
|
||||||
|
path=normalize(path)
|
||||||
|
local f = getFs(self)
|
||||||
|
return {
|
||||||
|
read=function()
|
||||||
|
local file = fs.open(f..path, "r")
|
||||||
|
local text = file.readAll()
|
||||||
|
file.close()
|
||||||
|
return text
|
||||||
|
end,
|
||||||
|
write=function(text)
|
||||||
|
local file = fs.open(f..path, "w")
|
||||||
|
file.write(text)
|
||||||
|
file.close()
|
||||||
|
end,
|
||||||
|
append=function(text)
|
||||||
|
local file = fs.open(f..path, "a")
|
||||||
|
file.write(text)
|
||||||
|
file.close()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function object:list(path)
|
||||||
|
path=normalize(path)
|
||||||
|
local f = getFs(self)
|
||||||
|
return fs.list(f..path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function object:fileExists(path)
|
||||||
|
path=normalize(path)
|
||||||
|
local f = getFs(self)
|
||||||
|
return fs.exists(f..path) and not fs.isDir(f..path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function object:directoryExists(path)
|
||||||
|
path=normalize(path)
|
||||||
|
local f = getFs(self)
|
||||||
|
return fs.exists(f..path) and fs.isDir(f..path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function object:makeDirectory(path)
|
||||||
|
path=normalize(path)
|
||||||
|
local f = getFs(self)
|
||||||
|
fs.makeDir(f..path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function object:delete(path)
|
||||||
|
path=normalize(path)
|
||||||
|
local f = getFs(self)
|
||||||
|
fs.delete(f..path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function object:getSize(path)
|
||||||
|
path=normalize(path)
|
||||||
|
local f = getFs(self)
|
||||||
|
return fs.getSize(f..path)
|
||||||
|
end
|
||||||
|
|
||||||
|
function uObject:readBytes(start, length)
|
||||||
|
local f = getFs(self)
|
||||||
|
local file=fs.open(f, "r")
|
||||||
|
local data=fs.readAll()
|
||||||
|
file.close()
|
||||||
|
return data:sub(start, start+length)
|
||||||
|
end
|
||||||
|
|
||||||
|
function uObject:writeBytes(start, dat)
|
||||||
|
local f = getFs(self)
|
||||||
|
local file=fs.open(f, "r")
|
||||||
|
local data=fs.readAll()
|
||||||
|
file.close()
|
||||||
|
return data:sub(1, start)..dat..data:sub(start+#dat, #data)
|
||||||
|
end
|
||||||
|
|
||||||
|
function uObject:getSize()
|
||||||
|
local f = getFs(self)
|
||||||
|
local file=fs.open(f, "r")
|
||||||
|
local data=fs.readAll()
|
||||||
|
file.close()
|
||||||
|
return #data
|
||||||
|
end
|
||||||
|
|
||||||
|
local function findDisks(tble)
|
||||||
|
for i,v in ipairs(tble) do
|
||||||
|
if fs.exists("/disks/"..tostring(v).."h") then
|
||||||
|
local obj = deepcopy(object)
|
||||||
|
obj.__UDATA_id=v
|
||||||
|
obj.id="disk_"..tostring(v)
|
||||||
|
obj.type="hdd"
|
||||||
|
newComponent("disk", obj)
|
||||||
|
fss[tostring(v)]="/disks/"..tostring(v).."h/"
|
||||||
|
elseif fs.exists("/disks/"..tostring(v).."f") then
|
||||||
|
local obj = deepcopy(object)
|
||||||
|
obj.__UDATA_id=v
|
||||||
|
obj.id="disk_"..tostring(v)
|
||||||
|
obj.type="fdd"
|
||||||
|
newComponent("disk", obj)
|
||||||
|
fss[tostring(v)]="/disks/"..tostring(v).."f/"
|
||||||
|
elseif fs.exists("/disks/"..tostring(v).."u") then
|
||||||
|
local obj = deepcopy(uObject)
|
||||||
|
obj.__UDATA_id=v
|
||||||
|
obj.id="disk_"..tostring(v)
|
||||||
|
obj.type="udd"
|
||||||
|
newComponent("disk", obj)
|
||||||
|
fss[tostring(v)]="/disks/"..tostring(v).."u"
|
||||||
|
else
|
||||||
|
fs.makeDir("/disks/"..tostring(v).."f/")
|
||||||
|
local obj = deepcopy(object)
|
||||||
|
obj.__UDATA_id=v
|
||||||
|
obj.id="disk_"..tostring(v)
|
||||||
|
obj.type="fdd"
|
||||||
|
newComponent("disk", obj)
|
||||||
|
fss[tostring(v)]="/disks/"..tostring(v).."f/"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = fs.open("/computers/0/computer.ltable", "r")
|
||||||
|
local config = load("return "..file.readAll())()
|
||||||
|
file.close()
|
||||||
|
findDisks(config.disks)
|
||||||
28
AceVM/components/internet.lua
Normal file
28
AceVM/components/internet.lua
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
local internet = {}
|
||||||
|
|
||||||
|
local function wrap_request(_url, ...)
|
||||||
|
local ok, err = http.request(...)
|
||||||
|
if ok then
|
||||||
|
while true do
|
||||||
|
local event, param1, param2, param3 = coroutine.yield()
|
||||||
|
if event == "http_success" and param1 == _url then
|
||||||
|
return param2
|
||||||
|
elseif event == "http_failure" and param1 == _url then
|
||||||
|
return nil, param2, param3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil, err
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get(_url)
|
||||||
|
if type(_url) ~= "string" then
|
||||||
|
error("URL must be a string")
|
||||||
|
end
|
||||||
|
|
||||||
|
return wrap_request(_url, _url)
|
||||||
|
end
|
||||||
|
|
||||||
|
function internet.get(url) return get(url).readAll() end
|
||||||
|
|
||||||
|
newComponent("internet", internet)
|
||||||
88
AceVM/components/screen.lua
Normal file
88
AceVM/components/screen.lua
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
local screen = {}
|
||||||
|
|
||||||
|
local function write(sText)
|
||||||
|
local w, h = term.getSize()
|
||||||
|
local x, y = term.getCursorPos()
|
||||||
|
|
||||||
|
local nLinesPrinted = 0
|
||||||
|
local function newLine()
|
||||||
|
if y + 1 <= h then
|
||||||
|
term.setCursorPos(1, y + 1)
|
||||||
|
else
|
||||||
|
term.setCursorPos(1, h)
|
||||||
|
term.scroll(1)
|
||||||
|
end
|
||||||
|
x, y = term.getCursorPos()
|
||||||
|
nLinesPrinted = nLinesPrinted + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
sText = tostring(sText)
|
||||||
|
while #sText > 0 do
|
||||||
|
local whitespace = string.match(sText, "^[ \t]+")
|
||||||
|
if whitespace then
|
||||||
|
term.write(whitespace)
|
||||||
|
x, y = term.getCursorPos()
|
||||||
|
sText = string.sub(sText, #whitespace + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local newline = string.match(sText, "^\n")
|
||||||
|
if newline then
|
||||||
|
newLine()
|
||||||
|
sText = string.sub(sText, 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
local text = string.match(sText, "^[^ \t\n]+")
|
||||||
|
if text then
|
||||||
|
sText = string.sub(sText, #text + 1)
|
||||||
|
if #text > w then
|
||||||
|
while #text > 0 do
|
||||||
|
if x > w then
|
||||||
|
newLine()
|
||||||
|
end
|
||||||
|
term.write(text)
|
||||||
|
text = string.sub(text, w - x + 2)
|
||||||
|
x, y = term.getCursorPos()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if x + #text - 1 > w then
|
||||||
|
newLine()
|
||||||
|
end
|
||||||
|
term.write(text)
|
||||||
|
x, y = term.getCursorPos()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nLinesPrinted
|
||||||
|
end
|
||||||
|
|
||||||
|
function screen.print(...)
|
||||||
|
local nLinesPrinted = 0
|
||||||
|
local nLimit = select("#", ...)
|
||||||
|
for n = 1, nLimit do
|
||||||
|
local s = tostring(select(n, ...))
|
||||||
|
if n < nLimit then
|
||||||
|
s = s .. "\t"
|
||||||
|
end
|
||||||
|
nLinesPrinted = nLinesPrinted + write(s)
|
||||||
|
end
|
||||||
|
nLinesPrinted = nLinesPrinted + write("\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
function screen.printInline(...)
|
||||||
|
local nLinesPrinted = 0
|
||||||
|
local nLimit = select("#", ...)
|
||||||
|
for n = 1, nLimit do
|
||||||
|
local s = tostring(select(n, ...))
|
||||||
|
nLinesPrinted = nLinesPrinted + write(s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function screen.clear()
|
||||||
|
term.clear()
|
||||||
|
end
|
||||||
|
|
||||||
|
screen.id = "screen_1"
|
||||||
|
screen.__UDATA_ID = 1
|
||||||
|
|
||||||
|
newComponent("screen", screen)
|
||||||
@@ -1,6 +1,26 @@
|
|||||||
_VG = _G
|
local function deepcopy(orig, copies)
|
||||||
_VG._G=_VG
|
copies = copies or {}
|
||||||
|
|
||||||
|
if type(orig) ~= 'table' then
|
||||||
|
return orig
|
||||||
|
elseif copies[orig] then
|
||||||
|
return copies[orig]
|
||||||
|
end
|
||||||
|
|
||||||
|
local copy = {}
|
||||||
|
copies[orig] = copy
|
||||||
|
|
||||||
|
for k, v in next, orig, nil do
|
||||||
|
local copied_key = deepcopy(k, copies)
|
||||||
|
local copied_val = deepcopy(v, copies)
|
||||||
|
copy[copied_key] = copied_val
|
||||||
|
end
|
||||||
|
|
||||||
|
return copy
|
||||||
|
end
|
||||||
|
local _VG = deepcopy(_G)
|
||||||
|
_VG._G=_VG
|
||||||
|
_G.deepcopy=deepcopy
|
||||||
function string.split(str, delim, maxResultCountOrNil)
|
function string.split(str, delim, maxResultCountOrNil)
|
||||||
assert(#delim == 1, "only delim len 1 supported for now")
|
assert(#delim == 1, "only delim len 1 supported for now")
|
||||||
maxResultCountOrNil = (maxResultCountOrNil or 0)-1
|
maxResultCountOrNil = (maxResultCountOrNil or 0)-1
|
||||||
@@ -68,20 +88,15 @@ function _VG.component.getFirst(type)
|
|||||||
return object.object
|
return object.object
|
||||||
end
|
end
|
||||||
|
|
||||||
for i,v in ipairs(fs.list("/aceVM/components/")) do
|
for i,v in ipairs(fs.list("/AceVM/components/")) do
|
||||||
load("/aceVM/components/"..v)()
|
local file = fs.open("/AceVM/components/"..v, "r")
|
||||||
|
local code = file.readAll()
|
||||||
|
file.close()
|
||||||
|
load(code)()
|
||||||
end
|
end
|
||||||
|
|
||||||
local file=fs.open("/bios.lua","r")
|
local file=fs.open("/computers/0/bios.lua","r")
|
||||||
local bios=file.readAll()
|
local bios=file.readAll()
|
||||||
file.close()
|
file.close()
|
||||||
file=nil
|
file=nil
|
||||||
BIOS_CORO=coroutine.create(load(bios,"bios",nil,_VG))
|
load(bios,"@bios",nil,_VG)()
|
||||||
debug.sethook(BIOS_CORO,coroutine.yield, "l", 50)
|
|
||||||
bios=nil
|
|
||||||
while true do
|
|
||||||
coroutine.resume(BIOS_CORO)
|
|
||||||
for i,v in ipairs(INTERNAL_RUNTIME_FUNCTIONS) do
|
|
||||||
pcall(v)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
local object={}
|
|
||||||
|
|
||||||
local function findDisks()
|
|
||||||
for i,v in ipairs(fs.list("/")) do
|
|
||||||
if v:sub(1,4)=="disk" then
|
|
||||||
if v == "disk" then
|
|
||||||
createDisk(v, "0")
|
|
||||||
else
|
|
||||||
createDisk(v, v:sub(5,5))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function createDisk()
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
newComponent("disk")
|
|
||||||
addRuntimeFunction(findDisks)
|
|
||||||
198
computers/0/bios.lua
Normal file
198
computers/0/bios.lua
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
local disks={}
|
||||||
|
|
||||||
|
for i,v in component.list() do
|
||||||
|
if v.type == "udd" then
|
||||||
|
v.writeBytes(0,"Hello, World!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
--[[
|
||||||
|
local computer = component.getFirst("computer")
|
||||||
|
local screen=component.getFirst("screen")
|
||||||
|
if not screen then
|
||||||
|
local function e(...)end
|
||||||
|
screen = {
|
||||||
|
print=e,
|
||||||
|
printInline=e,
|
||||||
|
clear=e
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok,err = xpcall(function()
|
||||||
|
-- Init components
|
||||||
|
_G._DEVELOPMENT=true
|
||||||
|
_G.component=component
|
||||||
|
|
||||||
|
local printed=""
|
||||||
|
local print=function(text)
|
||||||
|
printed=printed..text.."\n"
|
||||||
|
screen.print(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get CFG
|
||||||
|
local biosCfg = {}
|
||||||
|
local i=1
|
||||||
|
while i<=256 do
|
||||||
|
biosCfg[i]=computer.getData(i) or ""
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
-- Difine functions
|
||||||
|
local function copy(tabl)
|
||||||
|
local out = {}
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
local t=type(v)
|
||||||
|
if t=="table" then
|
||||||
|
if i == "_G" then
|
||||||
|
out._G=out
|
||||||
|
else
|
||||||
|
out[i]=copy(v)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
out[i]=v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local function save(table)
|
||||||
|
while i<=256 do
|
||||||
|
computer.setData(i, table[i] or nil)
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function hasKey(tabl, query)
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
if i==query then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Start boot seq
|
||||||
|
local disks={}
|
||||||
|
for i,v in component.list() do
|
||||||
|
if i=="disk" then
|
||||||
|
disks[v.id]=v
|
||||||
|
if v.type=="udd" then
|
||||||
|
v:writeBytes(0, "HDS") -- "HDS"
|
||||||
|
local tmp = v:readBytes(0,512) -- Just to make sure it writes the data
|
||||||
|
print(tmp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local idx = 1
|
||||||
|
local bootOption=1
|
||||||
|
while true do
|
||||||
|
if biosCfg[idx]=="$EOF" then break end
|
||||||
|
print("Atempting boot option "..tostring(bootOption).." labled \""..biosCfg[idx].."\".")
|
||||||
|
bootOption=bootOption+1
|
||||||
|
local drive={}
|
||||||
|
idx=idx+1
|
||||||
|
if not hasKey(disks,biosCfg[idx]) then
|
||||||
|
print("└─ Drive not found.")
|
||||||
|
print(" ")
|
||||||
|
idx=idx+3
|
||||||
|
goto invalid_boot
|
||||||
|
else
|
||||||
|
drive=disks[biosCfg[idx] ]
|
||||||
|
print("├─ Drive found with id of \""..drive.id.."\"")
|
||||||
|
end
|
||||||
|
idx=idx+1
|
||||||
|
local path
|
||||||
|
local code
|
||||||
|
if drive.type=="udd" then
|
||||||
|
print("├─ Drive is Unmanaged, looking for MBR...")
|
||||||
|
sleep(0.02)
|
||||||
|
print("├─ Reading MBR...")
|
||||||
|
local tmp = drive.readBytes(0,512)
|
||||||
|
print("├─ MBR found, compiling bootloader...")
|
||||||
|
code = table.concat(tmp)
|
||||||
|
else
|
||||||
|
if not drive:fileExists(biosCfg[idx]) then
|
||||||
|
print("└─ Path not found.")
|
||||||
|
print(" ")
|
||||||
|
idx=idx+2
|
||||||
|
goto invalid_boot
|
||||||
|
else
|
||||||
|
print("├─ Kernel exists at path \""..biosCfg[idx].."\"")
|
||||||
|
path=biosCfg[idx]
|
||||||
|
end
|
||||||
|
code = drive:open(path).read()
|
||||||
|
end
|
||||||
|
idx=idx+1
|
||||||
|
local _VG=copy(_G)
|
||||||
|
print("├─ Created virtual ENV.")
|
||||||
|
local _,func = pcall(load,code,drive.id.." | "..path,nil,_VG)
|
||||||
|
if not func then
|
||||||
|
print("└─ Compilation failure.")
|
||||||
|
print(" ")
|
||||||
|
idx=idx+1
|
||||||
|
goto invalid_boot
|
||||||
|
else
|
||||||
|
print("├─ Executing.")
|
||||||
|
end
|
||||||
|
local cmd=biosCfg[idx] or ""
|
||||||
|
idx=idx+1
|
||||||
|
local biosData = {}
|
||||||
|
biosData.bootDrive=drive
|
||||||
|
biosData.term=screen
|
||||||
|
screen.clear()
|
||||||
|
local ok, err = xpcall(func, debug.traceback, biosData, cmd)
|
||||||
|
screen.clear()
|
||||||
|
screen.print(printed)
|
||||||
|
if not ok then
|
||||||
|
print("└─ OS exited with error: "..err)
|
||||||
|
print(" ")
|
||||||
|
else
|
||||||
|
print("└─ OS exited.")
|
||||||
|
print(" ")
|
||||||
|
end
|
||||||
|
screen.print("Press enter to continue...")
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == "keyTyped" then
|
||||||
|
if event[3] == "\n" then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sleep(0.02)
|
||||||
|
end
|
||||||
|
::invalid_boot::
|
||||||
|
end
|
||||||
|
computer.beep(400,0.4)
|
||||||
|
print("No boot options available")
|
||||||
|
screen.print("Press enter to continue...")
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == "keyTyped" then
|
||||||
|
if event[3] == "\n" then
|
||||||
|
computer.shutdown()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sleep(0.02)
|
||||||
|
end
|
||||||
|
end, debug.traceback)
|
||||||
|
if not ok then
|
||||||
|
screen.clear()
|
||||||
|
screen.print("BIOS PANIC: "..err)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
sleep(0.02)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
sleep(0.02)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
sleep(0.02)
|
||||||
|
screen.print("Press enter to continue...")
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == "keyTyped" then
|
||||||
|
if event[3] == "\n" then
|
||||||
|
computer.shutdown()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
sleep(0.02)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
]]
|
||||||
3
computers/0/computer.ltable
Normal file
3
computers/0/computer.ltable
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
disks={1, 56}
|
||||||
|
}
|
||||||
250
computers/0/nvram.dat
Normal file
250
computers/0/nvram.dat
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
HyperionOS
|
||||||
|
disk_1
|
||||||
|
/boot/hyprkrnl.sys
|
||||||
|
|
||||||
|
$EOF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
local screen = component.getFirst("screen")
|
|
||||||
screen.print("hello")
|
|
||||||
component.getFirst("computer").reboot()
|
|
||||||
2
disks/1h/bin_/beep
Normal file
2
disks/1h/bin_/beep
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local computer=component.getFirst("computer")
|
||||||
|
computer.beep(800, 0.2, 1)
|
||||||
2
disks/1h/bin_/clear
Normal file
2
disks/1h/bin_/clear
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local term=component.getFirst("screen")
|
||||||
|
term.clear()
|
||||||
17
disks/1h/bin_/debug
Normal file
17
disks/1h/bin_/debug
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
local args={...}
|
||||||
|
local term=component.getFirst("screen")
|
||||||
|
local hpv=require("hypervisor")
|
||||||
|
local fs=require("filesystem")
|
||||||
|
if not (fs.exists("/bin/"..args[1]) and (not fs.isDir("/bin/"..args[1]))) then error("not a file") end
|
||||||
|
local handle = hpv.createProcessFromFile("/bin/"..args[1], args[1], table.unpack(args, 2))
|
||||||
|
local pid=handle.getID()
|
||||||
|
local debugger=hpv.attachDebugger(handle)
|
||||||
|
debugger.addEvent("threadReturn", function(...)
|
||||||
|
term.print("threadReturn", ...)
|
||||||
|
end)
|
||||||
|
debugger.addEvent("threadError", function(...)
|
||||||
|
term.print("threadError", ...)
|
||||||
|
end)
|
||||||
|
while hpv.isrunning(pid) do
|
||||||
|
sleep(0.5)
|
||||||
|
end
|
||||||
24
disks/1h/bin_/neofetch
Normal file
24
disks/1h/bin_/neofetch
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
local term=component.getFirst("screen")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | root@hyperion ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ------------- ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | OS: Hyperion AC ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | Host: $Computer_id ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | Kernel: Hyprkrnl 1.0.0 ")
|
||||||
|
term.print("⠀⢷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡞⠀ | Uptime: 2:00 ")
|
||||||
|
term.print("⠀⠈⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⠁⠀ | Packages: 204 ")
|
||||||
|
term.print("⠀⠀⠘⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⠃⠀⠀ | Shell: DoomieShell ")
|
||||||
|
term.print("⠀⠀⠀⢹⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⡏⠀⠀⠀ | Resolution: $monitor_size ")
|
||||||
|
term.print("⠀⠀⠀⠀⢻⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⡟⠀⠀⠀⠀ | DE: ComputeX ")
|
||||||
|
term.print("⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀ | WM: HWMS ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⡿⠋⠁⠀⠀⠀⠀⠀ | WM Theme: Standard dark ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣦⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⣠⣿⣿⣿⣿⡿⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀ | Theme: Standard dark ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⢠⣀⠀⠀⠈⠛⢿⣿⣿⣷⣄⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⣠⣾⣿⣿⡿⠛⠁⠀⠀⣀⡄⠀⠀⠀⠀⠀⠀⠀ | Icons: Standard ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⣶⣤⣀⠀⠈⠛⢿⣿⠀⠀⣿⣿⣿⣿⣿⣿⠀⠀⣿⡿⠛⠁⠀⣀⣤⣶⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀ | Terminal: Goterm ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣶⡄⢸⣿⠀⠀⠸⣿⣿⣿⣿⡏⠀⠀⣿⡇⢠⣶⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⠿⠿⠿⠟⠛⠃⢸⣿⠀⠀⠀⠹⣿⣿⡟⠀⠀⠀⣿⡇⠘⠛⠻⠿⠿⠿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⡄⢸⣿⡀⠀⠀⠀⢻⡿⠁⠀⠀⢀⣿⡇⢠⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⠇⠘⢿⣿⣦⡀⠀⠀⠁⠀⢀⣴⣿⡿⠃⠸⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡿⠋⠀⠀⠀⠀⠙⣿⣿⣦⡀⢀⣴⣿⡿⠋⠀⠀⠀⠈⠙⠿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
|
term.print("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | ")
|
||||||
13
disks/1h/bin_/pge
Normal file
13
disks/1h/bin_/pge
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
local function func(tble,space)
|
||||||
|
space=space or ""
|
||||||
|
for i,v in pairs(tble) do
|
||||||
|
print(space..tostring(i).." | "..tostring(v))
|
||||||
|
if type(v) == "table" then
|
||||||
|
if i=="_G" then else
|
||||||
|
func(v,space.." ")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
func(_G)
|
||||||
2
disks/1h/bin_/reboot
Normal file
2
disks/1h/bin_/reboot
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local computer=component.getFirst("computer")
|
||||||
|
computer.reboot()
|
||||||
52
disks/1h/bin_/shell
Normal file
52
disks/1h/bin_/shell
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
local stringBuffer=""
|
||||||
|
local hpv = require("hypervisor")
|
||||||
|
local fs = require("filesystem")
|
||||||
|
local term=component.getFirst("screen")
|
||||||
|
local captureInput=true
|
||||||
|
local exit=false
|
||||||
|
local function printPrefix()
|
||||||
|
term.printInline("root@testharness:/& ")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function tokenize(str)
|
||||||
|
return string.split(str, " ")
|
||||||
|
end
|
||||||
|
|
||||||
|
hpv.addEvent("keyTyped",function(...)
|
||||||
|
if not captureInput then return end
|
||||||
|
local char=({...})[1]
|
||||||
|
if char == "\n" then
|
||||||
|
captureInput=false
|
||||||
|
term.print("")
|
||||||
|
elseif char == "\b" then
|
||||||
|
if #stringBuffer > 0 then
|
||||||
|
stringBuffer=stringBuffer:sub(1,#stringBuffer-1)
|
||||||
|
term.printInline(char)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
stringBuffer=stringBuffer..char
|
||||||
|
term.printInline(char)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
printPrefix()
|
||||||
|
while not exit do
|
||||||
|
while captureInput do
|
||||||
|
sleep(1)
|
||||||
|
end
|
||||||
|
local token = tokenize(stringBuffer)
|
||||||
|
if token[1] == "exit" then
|
||||||
|
exit=true
|
||||||
|
elseif fs.exists("/bin/"..token[1]) and (not fs.isDir("/bin/"..token[1])) then
|
||||||
|
local handle = hpv.createProcessFromFile("/bin/"..token[1], token[1], table.unpack(token, 2))
|
||||||
|
local pid=handle.getID()
|
||||||
|
while hpv.isrunning(pid) do
|
||||||
|
sleep(0.5)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
term.print("Command not recognized")
|
||||||
|
end
|
||||||
|
stringBuffer=""
|
||||||
|
printPrefix()
|
||||||
|
captureInput=true
|
||||||
|
end
|
||||||
2
disks/1h/bin_/t
Normal file
2
disks/1h/bin_/t
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local print=component.getFirst("screen").print
|
||||||
|
print("test")
|
||||||
23
disks/1h/bin_/top
Normal file
23
disks/1h/bin_/top
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
local hpv=require("hypervisor")
|
||||||
|
local term=component.getFirst("screen")
|
||||||
|
|
||||||
|
term.clear()
|
||||||
|
local function m(str, m)
|
||||||
|
if #str>m then
|
||||||
|
return str:sub(1,m-1).."- "
|
||||||
|
else
|
||||||
|
while #str~=m do
|
||||||
|
str=str.." "
|
||||||
|
end
|
||||||
|
return str.." "
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i in hpv.listProc() do
|
||||||
|
term.print(m(i.name, 15)..m(i.status, 7)..m(i.pid, 4))
|
||||||
|
for _,v in ipairs(i.threads) do
|
||||||
|
if v.name~="main" then
|
||||||
|
term.print(" "..m(v.name, 12)..m(v.status, 7))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
19
disks/1h/bin_/unitest
Normal file
19
disks/1h/bin_/unitest
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
local errors={}
|
||||||
|
local function tables_equal(t1, t2)
|
||||||
|
if #t1 ~= #t2 then return false end
|
||||||
|
for i = 1, #t1 do
|
||||||
|
if t1[i] ~= t2[i] then return false end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function run_test(name, test_func)
|
||||||
|
local status, err = pcall(test_func)
|
||||||
|
if status then
|
||||||
|
print("[PASS] " .. name)
|
||||||
|
else
|
||||||
|
print("[FAIL] " .. name .. ": " .. err)
|
||||||
|
errors[name]=err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
215
disks/1h/boot/Hyprkrnl.sys
Normal file
215
disks/1h/boot/Hyprkrnl.sys
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
local function rand()
|
||||||
|
if math.random(0,1)==0 then return true else return false end
|
||||||
|
end
|
||||||
|
function coroutine.resumeWithTimeout(CORO, TIME, ...)
|
||||||
|
return rand(), coroutine.resume(CORO, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
-- Get boot arguments
|
||||||
|
local bootArgs=({...})[1]
|
||||||
|
local bootDrive=bootArgs.bootDrive
|
||||||
|
local LOG_TEXT=""
|
||||||
|
local log={}
|
||||||
|
local term
|
||||||
|
local bootData=load("return "..(bootDrive:open("var/log/kernel/bootData").read() or "{}"))()
|
||||||
|
local computer=component.getFirst("computer")
|
||||||
|
local startup=true
|
||||||
|
local osleep=sleep
|
||||||
|
local oldYield=coroutine.yield
|
||||||
|
|
||||||
|
function coroutine.yield(...)
|
||||||
|
if not startup then
|
||||||
|
if coroutine.isyieldable(coroutine.running()) then
|
||||||
|
oldYield(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Find terminal(s)
|
||||||
|
local terminals={}
|
||||||
|
for i,v in component.list() do
|
||||||
|
if i == "screen" then
|
||||||
|
terminals[#terminals+1] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
term={
|
||||||
|
print=function(...)
|
||||||
|
for _,v in ipairs(terminals) do
|
||||||
|
v.print(...)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
printInline=function(...)
|
||||||
|
for _,v in ipairs(terminals) do
|
||||||
|
v.printInline(...)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
clear=function(...)
|
||||||
|
for _,v in ipairs(terminals) do
|
||||||
|
v.clear(...)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
term.print("Welcome to Hyperion OS")
|
||||||
|
-- Difine logging lib
|
||||||
|
local function getPName(func)
|
||||||
|
if type(func) == "function" then
|
||||||
|
getPName=func
|
||||||
|
end
|
||||||
|
return "Hyprkrnl"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.log(text)
|
||||||
|
if startup then term.print("[ OK ] "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.."[ OK ] "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.error(text)
|
||||||
|
if startup then term.print("[FAILED] "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.."[FAILED] "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.warn(text)
|
||||||
|
if startup then term.print("[ WARN ] "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.."[ WARN ] "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.raw(text)
|
||||||
|
if startup then term.print(" "..getPName()..": "..text) end
|
||||||
|
LOG_TEXT=LOG_TEXT.." "..getPName()..": "..text.."\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function log.get()
|
||||||
|
return LOG_TEXT
|
||||||
|
end
|
||||||
|
|
||||||
|
local function t2t(table)
|
||||||
|
local output = "{"
|
||||||
|
for i,v in pairs(table) do
|
||||||
|
local coma=true
|
||||||
|
if type(i) == "string" then
|
||||||
|
output=output.."[\""..i.."\"]="
|
||||||
|
end
|
||||||
|
if type(v) == "table" then
|
||||||
|
if v == table then
|
||||||
|
output=string.sub(output,1,#output-(#i+1))
|
||||||
|
coma=false
|
||||||
|
else
|
||||||
|
output=output..t2t(v)
|
||||||
|
end
|
||||||
|
elseif type(v) == "string" then
|
||||||
|
output=output.."[=["..v.."]=]"
|
||||||
|
elseif type(v) == "number" then
|
||||||
|
output=output..tostring(v)
|
||||||
|
elseif type(v) == "function" then
|
||||||
|
output=string.sub(output,1,#output-(#i+1))
|
||||||
|
coma=false
|
||||||
|
end
|
||||||
|
if coma then
|
||||||
|
output=output..","
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #table>0 or string.sub(output,#output,#output) == "," then
|
||||||
|
output=string.sub(output,1,#output-1)
|
||||||
|
end
|
||||||
|
output=output.."}"
|
||||||
|
return output
|
||||||
|
end
|
||||||
|
|
||||||
|
-- My favorite function
|
||||||
|
local function PANIC(err,lvl)
|
||||||
|
term.clear()
|
||||||
|
term.print(LOG_TEXT)
|
||||||
|
term.printInline("KERNEL PANIC: "..err)
|
||||||
|
computer.beep(800,0.2)
|
||||||
|
osleep(0.02)
|
||||||
|
if err==bootData.prevError then
|
||||||
|
bootData.errorCount=bootData.errorCount+1
|
||||||
|
else
|
||||||
|
bootData.prevError=err
|
||||||
|
bootData.errorCount=0
|
||||||
|
end
|
||||||
|
bootDrive:open("var/log/kernel/bootData").write(t2t(bootData))
|
||||||
|
if bootData.errorCount < 4 then
|
||||||
|
term.print("")
|
||||||
|
term.print("Atempting reboot...")
|
||||||
|
osleep(0.5)
|
||||||
|
computer.reboot()
|
||||||
|
elseif bootData.errorCount > 3 then
|
||||||
|
term.print("")
|
||||||
|
term.print("boot determined to be unrecoverable...")
|
||||||
|
osleep(0.5)
|
||||||
|
computer.shutdown()
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function runAsKernel(path, args)
|
||||||
|
local ok,err,extra = pcall(load(bootDrive:open(path):read()), args)
|
||||||
|
if not ok then
|
||||||
|
PANIC(path.." failed to load/execute err:\n"..(err or ""))
|
||||||
|
end
|
||||||
|
return err,extra
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add libray modifications+
|
||||||
|
for _,v in ipairs(bootDrive:list("/sys/kernel/glib")) do
|
||||||
|
log.raw("running "..v)
|
||||||
|
runAsKernel("/sys/kernel/glib/"..v)
|
||||||
|
log.log("Loaded "..v)
|
||||||
|
end
|
||||||
|
log.log("Finished loading global librarys")
|
||||||
|
local sudoMaster={}
|
||||||
|
local auth=runAsKernel("sys/kernel/userManager.sys",{masterKey=sudoMaster,bootDrive=bootDrive})
|
||||||
|
log.log("Created UE Manager")
|
||||||
|
local fs=runAsKernel("sys/kernel/filesystem.sys",{bootDrive=bootDrive,auth=auth})
|
||||||
|
log.log("Initailized filesystem")
|
||||||
|
local io=runAsKernel("sys/kernel/ioManager.sys",{masterKey=sudoMaster})
|
||||||
|
log.log("Started ioManager")
|
||||||
|
local packages={filesystem=fs, auth=auth, logging=log, term=term}
|
||||||
|
local req=runAsKernel("sys/modules/require",{filesystem=fs,logging=log, preload=packages})
|
||||||
|
log.log("Loaded require")
|
||||||
|
local setRequire
|
||||||
|
local requ=req.makeRequire("lib/?;lib/?/init;sys/modules/?;sys/modules/?/init",packages)
|
||||||
|
_G.require, setRequire = requ.require, requ.load
|
||||||
|
setRequire("require",req)
|
||||||
|
log.log("Initailized require")
|
||||||
|
|
||||||
|
local code=fs.open("sys/kernel/hypervisor.sys","xe", _G)
|
||||||
|
|
||||||
|
if not code then
|
||||||
|
PANIC("System failed to load")
|
||||||
|
end
|
||||||
|
local ok, system=pcall(code, {masterKey=sudoMaster, setRequire=setRequire, pname=getPName})
|
||||||
|
if not ok then
|
||||||
|
PANIC("Hypervisor failed to execute ERR:\n"..hypervisor)
|
||||||
|
end
|
||||||
|
log.log("Loaded hypervisor")
|
||||||
|
log.raw("Making kernel process")
|
||||||
|
|
||||||
|
hypervisor(function()
|
||||||
|
local hpv=require("hypervisor")
|
||||||
|
local thread=require("thread")
|
||||||
|
log.log("Created kernel process")
|
||||||
|
hpv.createProcessFromFile("sys/os/init.lua", "systemd")
|
||||||
|
thread.create(function()
|
||||||
|
while true do
|
||||||
|
local event = {computer.getMachineEvent()}
|
||||||
|
if event[1] == nil then
|
||||||
|
coroutine.yield()
|
||||||
|
else
|
||||||
|
hpv.triggerEvent("all", event[1], table.unpack(event,2))
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, "eventHandler")
|
||||||
|
|
||||||
|
while true do
|
||||||
|
coroutine.yield()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
term.print("Goodbye :)")
|
||||||
0
disks/1h/etc/ast-ip/config.ini
Normal file
0
disks/1h/etc/ast-ip/config.ini
Normal file
0
disks/1h/etc/fstab
Normal file
0
disks/1h/etc/fstab
Normal file
2
disks/1h/etc/group
Normal file
2
disks/1h/etc/group
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
root:0:root
|
||||||
|
sudo:1:root
|
||||||
1
disks/1h/etc/passwd
Normal file
1
disks/1h/etc/passwd
Normal file
@@ -0,0 +1 @@
|
|||||||
|
root:x:0:0::/root:/bin/pshell
|
||||||
1
disks/1h/etc/shadow
Normal file
1
disks/1h/etc/shadow
Normal file
@@ -0,0 +1 @@
|
|||||||
|
root:$5$9a7f8e2b4cd01ac18d7cbb4da74f5c1e$53326d6a24ef6a050b5ef88dbbe5906d4afbcf191725f9750e44a818ab22bd62:0
|
||||||
2
disks/1h/etc/spm/repos
Normal file
2
disks/1h/etc/spm/repos
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
https://git.astronand.dev/Hyperion-OS/packages/raw/branch/main/spm/
|
||||||
|
https://git.astronand.dev/Hyperion-OS/packages/raw/branch/main/ac/
|
||||||
1
disks/1h/etc/sudoers
Normal file
1
disks/1h/etc/sudoers
Normal file
@@ -0,0 +1 @@
|
|||||||
|
root
|
||||||
0
disks/1h/etc/sysinit/system/graphical.target
Normal file
0
disks/1h/etc/sysinit/system/graphical.target
Normal file
0
disks/1h/etc/sysinit/system/halt.target
Normal file
0
disks/1h/etc/sysinit/system/halt.target
Normal file
0
disks/1h/etc/sysinit/system/multi-user.target
Normal file
0
disks/1h/etc/sysinit/system/multi-user.target
Normal file
5
disks/1h/etc/sysinit/system/poweroff.target
Normal file
5
disks/1h/etc/sysinit/system/poweroff.target
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Shutdown of system
|
||||||
|
Conflicts=reboot.target halt.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
0
disks/1h/etc/sysinit/system/reboot.target
Normal file
0
disks/1h/etc/sysinit/system/reboot.target
Normal file
111
disks/1h/lib/config/ini
Normal file
111
disks/1h/lib/config/ini
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local ini = {}
|
||||||
|
local fs=require("filesystem")
|
||||||
|
|
||||||
|
local function trim(s)
|
||||||
|
local i, j = 1, #s
|
||||||
|
while i <= j and (s:sub(i,i) == " " or s:sub(i,i) == "\t") do
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
while j >= i and (s:sub(j,j) == " " or s:sub(j,j) == "\t") do
|
||||||
|
j = j - 1
|
||||||
|
end
|
||||||
|
return s:sub(i, j)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function parse(list)
|
||||||
|
local lines=function ()
|
||||||
|
local i=0
|
||||||
|
return function()
|
||||||
|
i=i+1
|
||||||
|
return list[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local data = {}
|
||||||
|
local section = data
|
||||||
|
for line in lines() do
|
||||||
|
line = trim(line)
|
||||||
|
|
||||||
|
if line ~= "" and line:sub(1,1) ~= ";" and line:sub(1,1) ~= "#" then
|
||||||
|
if line:sub(1,1) == "[" and line:sub(-1) == "]" then
|
||||||
|
local secName = trim(line:sub(2, -2))
|
||||||
|
if secName ~= "" then
|
||||||
|
data[secName] = data[secName] or {}
|
||||||
|
section = data[secName]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local eq
|
||||||
|
for i = 1, #line do
|
||||||
|
if line:sub(i,i) == "=" then
|
||||||
|
eq = i
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if eq then
|
||||||
|
local key = trim(line:sub(1, eq-1))
|
||||||
|
local value = trim(line:sub(eq+1))
|
||||||
|
|
||||||
|
local lower = value:lower()
|
||||||
|
if tonumber(value) then
|
||||||
|
value = tonumber(value)
|
||||||
|
elseif lower == "true" then
|
||||||
|
value = true
|
||||||
|
elseif lower == "false" then
|
||||||
|
value = false
|
||||||
|
end
|
||||||
|
section[key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.read(path)
|
||||||
|
local file, err = fs.open(path, "r")
|
||||||
|
if not file then return nil, err end
|
||||||
|
local list={}
|
||||||
|
for i in file.lines() do
|
||||||
|
list[#list+1] = i
|
||||||
|
end
|
||||||
|
file.close()
|
||||||
|
return parse(list)
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.get(text)
|
||||||
|
return parse(string.split(text, "\n"))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function write(data)
|
||||||
|
local text=""
|
||||||
|
for k,v in pairs(data) do
|
||||||
|
if type(v) ~= "table" then
|
||||||
|
text=text..k .. " = " .. tostring(v) .. "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for sec, tbl in pairs(data) do
|
||||||
|
if type(tbl) == "table" then
|
||||||
|
text=text.."\n[" .. sec .. "]\n"
|
||||||
|
for k,v in pairs(tbl) do
|
||||||
|
text=text..k .. " = " .. tostring(v) .. "\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.write(path, data)
|
||||||
|
local file=fs.open(path, "w")
|
||||||
|
file.write(write(data))
|
||||||
|
file.close()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function ini.make(data)
|
||||||
|
return write(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
return ini
|
||||||
193
disks/1h/lib/crypto/sha256
Normal file
193
disks/1h/lib/crypto/sha256
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
-- From http://pastebin.com/gsFrNjbt linked from http://www.computercraft.info/forums2/index.php?/topic/8169-sha-256-in-pure-lua/
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Adaptation of the Secure Hashing Algorithm (SHA-244/256)
|
||||||
|
-- Found Here: http://lua-users.org/wiki/SecureHashAlgorithm
|
||||||
|
--
|
||||||
|
-- Using an adapted version of the bit library
|
||||||
|
-- Found Here: https://bitbucket.org/Boolsheet/bslf/src/1ee664885805/bit.lua
|
||||||
|
--
|
||||||
|
|
||||||
|
local MOD = 2^32
|
||||||
|
local MODM = MOD-1
|
||||||
|
|
||||||
|
local function memoize(f)
|
||||||
|
local mt = {}
|
||||||
|
local t = setmetatable({}, mt)
|
||||||
|
function mt:__index(k)
|
||||||
|
local v = f(k)
|
||||||
|
t[k] = v
|
||||||
|
return v
|
||||||
|
end
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_bitop_uncached(t, m)
|
||||||
|
local function bitop(a, b)
|
||||||
|
local res,p = 0,1
|
||||||
|
while a ~= 0 and b ~= 0 do
|
||||||
|
local am, bm = a % m, b % m
|
||||||
|
res = res + t[am][bm] * p
|
||||||
|
a = (a - am) / m
|
||||||
|
b = (b - bm) / m
|
||||||
|
p = p*m
|
||||||
|
end
|
||||||
|
res = res + (a + b) * p
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
return bitop
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_bitop(t)
|
||||||
|
local op1 = make_bitop_uncached(t,2^1)
|
||||||
|
local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)
|
||||||
|
return make_bitop_uncached(op2, 2 ^ (t.n or 1))
|
||||||
|
end
|
||||||
|
|
||||||
|
local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
|
||||||
|
|
||||||
|
local function bxor(a, b, c, ...)
|
||||||
|
local z = nil
|
||||||
|
if b then
|
||||||
|
a = a % MOD
|
||||||
|
b = b % MOD
|
||||||
|
z = bxor1(a, b)
|
||||||
|
if c then z = bxor(z, c, ...) end
|
||||||
|
return z
|
||||||
|
elseif a then return a % MOD
|
||||||
|
else return 0 end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function band(a, b, c, ...)
|
||||||
|
local z
|
||||||
|
if b then
|
||||||
|
a = a % MOD
|
||||||
|
b = b % MOD
|
||||||
|
z = ((a + b) - bxor1(a,b)) / 2
|
||||||
|
if c then z = bit32_band(z, c, ...) end
|
||||||
|
return z
|
||||||
|
elseif a then return a % MOD
|
||||||
|
else return MODM end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function bnot(x) return (-1 - x) % MOD end
|
||||||
|
|
||||||
|
local function rshift1(a, disp)
|
||||||
|
if disp < 0 then return lshift(a,-disp) end
|
||||||
|
return math.floor(a % 2 ^ 32 / 2 ^ disp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rshift(x, disp)
|
||||||
|
if disp > 31 or disp < -31 then return 0 end
|
||||||
|
return rshift1(x % MOD, disp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function lshift(a, disp)
|
||||||
|
if disp < 0 then return rshift(a,-disp) end
|
||||||
|
return (a * 2 ^ disp) % 2 ^ 32
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rrotate(x, disp)
|
||||||
|
x = x % MOD
|
||||||
|
disp = disp % 32
|
||||||
|
local low = band(x, 2 ^ disp - 1)
|
||||||
|
return rshift(x, disp) + lshift(low, 32 - disp)
|
||||||
|
end
|
||||||
|
|
||||||
|
local k = {
|
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
|
||||||
|
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||||
|
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
|
||||||
|
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
|
||||||
|
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||||
|
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
|
||||||
|
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
|
||||||
|
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||||
|
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function str2hexa(s)
|
||||||
|
return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
|
||||||
|
end
|
||||||
|
|
||||||
|
local function num2s(l, n)
|
||||||
|
local s = ""
|
||||||
|
for i = 1, n do
|
||||||
|
local rem = l % 256
|
||||||
|
s = string.char(rem) .. s
|
||||||
|
l = (l - rem) / 256
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
local function s232num(s, i)
|
||||||
|
local n = 0
|
||||||
|
for i = i, i + 3 do n = n*256 + string.byte(s, i) end
|
||||||
|
return n
|
||||||
|
end
|
||||||
|
|
||||||
|
local function preproc(msg, len)
|
||||||
|
local extra = 64 - ((len + 9) % 64)
|
||||||
|
len = num2s(8 * len, 8)
|
||||||
|
msg = msg .. "\128" .. string.rep("\0", extra) .. len
|
||||||
|
assert(#msg % 64 == 0)
|
||||||
|
return msg
|
||||||
|
end
|
||||||
|
|
||||||
|
local function initH256(H)
|
||||||
|
H[1] = 0x6a09e667
|
||||||
|
H[2] = 0xbb67ae85
|
||||||
|
H[3] = 0x3c6ef372
|
||||||
|
H[4] = 0xa54ff53a
|
||||||
|
H[5] = 0x510e527f
|
||||||
|
H[6] = 0x9b05688c
|
||||||
|
H[7] = 0x1f83d9ab
|
||||||
|
H[8] = 0x5be0cd19
|
||||||
|
return H
|
||||||
|
end
|
||||||
|
|
||||||
|
local function digestblock(msg, i, H)
|
||||||
|
local w = {}
|
||||||
|
for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
|
||||||
|
for j = 17, 64 do
|
||||||
|
local v = w[j - 15]
|
||||||
|
local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
|
||||||
|
v = w[j - 2]
|
||||||
|
w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
|
||||||
|
end
|
||||||
|
|
||||||
|
local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
|
||||||
|
for i = 1, 64 do
|
||||||
|
local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
|
||||||
|
local maj = bxor(band(a, b), band(a, c), band(b, c))
|
||||||
|
local t2 = s0 + maj
|
||||||
|
local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
|
||||||
|
local ch = bxor (band(e, f), band(bnot(e), g))
|
||||||
|
local t1 = h + s1 + ch + k[i] + w[i]
|
||||||
|
h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
|
||||||
|
end
|
||||||
|
|
||||||
|
H[1] = band(H[1] + a)
|
||||||
|
H[2] = band(H[2] + b)
|
||||||
|
H[3] = band(H[3] + c)
|
||||||
|
H[4] = band(H[4] + d)
|
||||||
|
H[5] = band(H[5] + e)
|
||||||
|
H[6] = band(H[6] + f)
|
||||||
|
H[7] = band(H[7] + g)
|
||||||
|
H[8] = band(H[8] + h)
|
||||||
|
end
|
||||||
|
|
||||||
|
return function(msg)
|
||||||
|
msg = preproc(msg, #msg)
|
||||||
|
local H = initH256({})
|
||||||
|
for i = 1, #msg, 64 do digestblock(msg, i, H) end
|
||||||
|
return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
|
||||||
|
num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
|
||||||
|
end
|
||||||
0
disks/1h/lib/lua/lexer
Normal file
0
disks/1h/lib/lua/lexer
Normal file
0
disks/1h/lib/lua/minify
Normal file
0
disks/1h/lib/lua/minify
Normal file
47
disks/1h/sbin/spm.lua
Normal file
47
disks/1h/sbin/spm.lua
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args = {...}
|
||||||
|
local os = require("system")
|
||||||
|
local fs=require("filesystem")
|
||||||
|
local term = os.getEnvar("term")
|
||||||
|
|
||||||
|
if args[1] == "help" or args[1] == "-h" then
|
||||||
|
term.print("SPM V1.0.0")
|
||||||
|
term.print("Usage:")
|
||||||
|
term.print(" install <package> : searches for package and installs it")
|
||||||
|
term.print(" add-repo <URL> : adds repo to search list appends package to end of URL")
|
||||||
|
term.print(" download <URL> : downloads package from URL")
|
||||||
|
term.print(" local <dir> : downloads package from file")
|
||||||
|
term.print(" get <dir> : executes commands from list")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function install(package)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function addRepo(url)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function download(url)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function localPackage(dir)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function run(command)
|
||||||
|
local list = string.split(command, " ")
|
||||||
|
if list[1] == "install" then
|
||||||
|
install(list[2])
|
||||||
|
elseif list[1] == "add-repo" then
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if args[1] == "get" then
|
||||||
|
local list=string.split(fs.readAllText(args[2]), "\n")
|
||||||
|
for i, v in ipairs(list) do
|
||||||
|
|
||||||
|
end
|
||||||
|
else run(args) end
|
||||||
1
disks/1h/sys/db/os.reg
Normal file
1
disks/1h/sys/db/os.reg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
40
disks/1h/sys/drivers/ac.disk.ko
Normal file
40
disks/1h/sys/drivers/ac.disk.ko
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "fs"
|
||||||
|
driver.name = "Advanced Computers disk driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers disks"
|
||||||
|
driver.manifest = "ac.disk.ko"
|
||||||
|
|
||||||
|
driver.api = function(component)
|
||||||
|
return {
|
||||||
|
readAllText = function(dir)
|
||||||
|
local drive = component:open(dir)
|
||||||
|
local file = drive.read()
|
||||||
|
drive = nil
|
||||||
|
return file
|
||||||
|
end,
|
||||||
|
writeAllText = function(dir, content)
|
||||||
|
local drive = component:open(dir)
|
||||||
|
drive.write(content)
|
||||||
|
drive = nil
|
||||||
|
end,
|
||||||
|
appendAllText = function(dir, content)
|
||||||
|
local drive = component:open(dir)
|
||||||
|
drive.append(content)
|
||||||
|
drive = nil
|
||||||
|
end,
|
||||||
|
list = function(dir)
|
||||||
|
return component:list(dir)
|
||||||
|
end,
|
||||||
|
mkFile = function(dir)
|
||||||
|
component:makeFile(dir)
|
||||||
|
end,
|
||||||
|
mkDir = function(dir)
|
||||||
|
component:makeDirectory(dir)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return driver
|
||||||
26
disks/1h/sys/drivers/ac.screen.ko
Normal file
26
disks/1h/sys/drivers/ac.screen.ko
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "terminal"
|
||||||
|
driver.name = "Advanced Computers screen driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers screens"
|
||||||
|
driver.manifest = "ac.screen.ko"
|
||||||
|
|
||||||
|
driver.api=function(component)
|
||||||
|
return {
|
||||||
|
write=function(...)
|
||||||
|
component.printInline(...)
|
||||||
|
end,
|
||||||
|
print=function(...)
|
||||||
|
component.print(...)
|
||||||
|
end,
|
||||||
|
printInline=function(...)
|
||||||
|
component.printInline(...)
|
||||||
|
end,
|
||||||
|
clear=function(...)
|
||||||
|
component.clear()
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return driver
|
||||||
16
disks/1h/sys/drivers/ac.udisk.ko
Normal file
16
disks/1h/sys/drivers/ac.udisk.ko
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "ufs"
|
||||||
|
driver.name = "Advanced Computers unmanaged disk driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers unmanaged disks"
|
||||||
|
driver.manifest = "ac.udisk.ko"
|
||||||
|
|
||||||
|
driver.api = function(component)
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return driver
|
||||||
8
disks/1h/sys/drivers/ac.wlan.ko
Normal file
8
disks/1h/sys/drivers/ac.wlan.ko
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
local driver = {}
|
||||||
|
|
||||||
|
driver.type = "wlan"
|
||||||
|
driver.name = "Advanced Computers http driver"
|
||||||
|
driver.version = "1.0.0"
|
||||||
|
driver.apiVersion = 1
|
||||||
|
driver.description = "Driver for Advanced Computers http"
|
||||||
|
driver.manifest = "ac.wlan.ko"
|
||||||
245
disks/1h/sys/kernel/filesystem.sys
Normal file
245
disks/1h/sys/kernel/filesystem.sys
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
-- File open modes
|
||||||
|
-- M | H | D
|
||||||
|
-- rc | r | Read and close
|
||||||
|
-- r | r | Read
|
||||||
|
-- w | w | Write
|
||||||
|
-- o | w | Overite file
|
||||||
|
-- om | m | Overite and modify
|
||||||
|
-- rw | m | Read and write
|
||||||
|
-- x | f | get function
|
||||||
|
|
||||||
|
local args=({...})[1]
|
||||||
|
local fs={}
|
||||||
|
local disks={}
|
||||||
|
local mounts={}
|
||||||
|
local bootDrive=args.bootDrive
|
||||||
|
local auth=args.auth
|
||||||
|
local log=args.logging
|
||||||
|
|
||||||
|
for t, o in component.list() do
|
||||||
|
if t=="disk" then
|
||||||
|
if o.id==bootDrive.id then
|
||||||
|
else disks[o.id]=o end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function resolve(path)
|
||||||
|
if string.sub(path,1,1)~="/" then
|
||||||
|
path="/"..path
|
||||||
|
end
|
||||||
|
local drive=bootDrive
|
||||||
|
for i,v in pairs(mounts) do
|
||||||
|
if string.hasPrefix(path,v) then
|
||||||
|
drive=disks[i]
|
||||||
|
path=string.getSuffix(path,v)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return drive, path
|
||||||
|
end
|
||||||
|
|
||||||
|
local function checkPerms(path, mode)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getHandle(backing,typ,clear)
|
||||||
|
local ret={}
|
||||||
|
local close=false
|
||||||
|
ret.close=function()
|
||||||
|
close=true
|
||||||
|
end
|
||||||
|
if typ=="r" then
|
||||||
|
ret.read=function()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return backing.read()
|
||||||
|
end
|
||||||
|
ret.lines=function()
|
||||||
|
if close then error() end
|
||||||
|
local lines=string.split(backing.read(), "\n")
|
||||||
|
local i=0
|
||||||
|
return function()
|
||||||
|
i=i+1
|
||||||
|
return lines[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif typ=="w" then
|
||||||
|
ret.write=function(data)
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
backing.append(data)
|
||||||
|
end
|
||||||
|
elseif typ=="m" then
|
||||||
|
ret.read=function()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return backing.read()
|
||||||
|
end
|
||||||
|
ret.lines=function()
|
||||||
|
if close then error() end
|
||||||
|
local lines=string.split(backing.read(), "\n")
|
||||||
|
local i=0
|
||||||
|
return function()
|
||||||
|
i=i+1
|
||||||
|
return lines[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ret.write=function(data)
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
backing.append(data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if clear then
|
||||||
|
ret.clear=function()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
backing.write()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
local function open(path, mode, arg, pc)
|
||||||
|
if pc then
|
||||||
|
checkPerms(path, mode)
|
||||||
|
end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
if drive:directoryExists(newPath) then error("Cannot open directory") end
|
||||||
|
if not drive:fileExists(newPath) then error("File does not exist") end
|
||||||
|
local backing=drive:open(newPath)
|
||||||
|
if mode=="rc" then
|
||||||
|
local file=getHandle(backing,"r")
|
||||||
|
local text=file.read()
|
||||||
|
file.close()
|
||||||
|
return text
|
||||||
|
elseif mode=="r" then
|
||||||
|
return getHandle(backing,"r")
|
||||||
|
elseif mode=="w" then
|
||||||
|
return getHandle(backing,"w")
|
||||||
|
elseif mode=="o" then
|
||||||
|
local file=getHandle(backing,"w",true)
|
||||||
|
file.clear()
|
||||||
|
file.clear=nil
|
||||||
|
return file
|
||||||
|
elseif mode=="om" then
|
||||||
|
local file=getHandle(backing,"m",true)
|
||||||
|
file.clear()
|
||||||
|
file.clear=nil
|
||||||
|
return file
|
||||||
|
elseif mode=="rw" then
|
||||||
|
return getHandle(backing,"m")
|
||||||
|
elseif mode=="x" then
|
||||||
|
local file=getHandle(backing,"r")
|
||||||
|
local text=file.read()
|
||||||
|
file.close()
|
||||||
|
return load(text, path, nil, table.deepcopy(_G))
|
||||||
|
elseif mode=="xe" then
|
||||||
|
local file=getHandle(backing,"r")
|
||||||
|
local text=file.read()
|
||||||
|
file.close()
|
||||||
|
return load(text, path, nil, arg)
|
||||||
|
else
|
||||||
|
error("Invailid mode")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.open(path, mode, arg)
|
||||||
|
return open(path, mode, arg, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.copy(orig, dest)
|
||||||
|
local destFile = fs.open(dest,"o")
|
||||||
|
local origFile = fs.open(orig, "rc")
|
||||||
|
destFile.write(origFile)
|
||||||
|
destFile.close()
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.move(orig, dest)
|
||||||
|
local destFile = fs.open(dest,"o")
|
||||||
|
local origFile = fs.open(orig, "rc")
|
||||||
|
destFile.write(origFile)
|
||||||
|
destFile.close()
|
||||||
|
fs.delete(orig)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- This fixes the weirdest bug ever
|
||||||
|
local isDir = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "r") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return drive:directoryExists(newPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
local exists = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "r") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return ((drive:directoryExists(newPath)) or (drive:fileExists(newPath)))
|
||||||
|
end
|
||||||
|
|
||||||
|
local delete = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "w") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return drive:delete(newPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
local list = function(path, pc)
|
||||||
|
if pc then checkPerms(path, "w") end
|
||||||
|
local drive, newPath = resolve(path)
|
||||||
|
return drive:list(newPath)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.list(path)
|
||||||
|
return list(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.isDir(path)
|
||||||
|
return isDir(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.exists(path)
|
||||||
|
return exists(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.delete(path)
|
||||||
|
return delete(path, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
function fs.getSudo(key)
|
||||||
|
if auth.sudo.isAproved(key) then
|
||||||
|
return {
|
||||||
|
createVirtDisk=function(virtualDiskName,virtualDiskObj)
|
||||||
|
disks[virtualDiskName]=virtualDiskObj
|
||||||
|
log.log("Created VirtIO disk named "..virtualDiskName)
|
||||||
|
end,
|
||||||
|
mount=function(hardwareDir,path)
|
||||||
|
mounts[hardwareDir]=path
|
||||||
|
log.log("Mounted disk ")
|
||||||
|
end,
|
||||||
|
unmount=function(hardwareDir)
|
||||||
|
mounts[hardwareDir]=nil
|
||||||
|
end,
|
||||||
|
eject=function(hardwareDir)
|
||||||
|
disks[hardwareDir]=nil
|
||||||
|
end,
|
||||||
|
sfs={
|
||||||
|
open=function(path, mode, arg)
|
||||||
|
return open(path, mode, arg)
|
||||||
|
end,
|
||||||
|
delete=function(path)
|
||||||
|
return delete(path)
|
||||||
|
end,
|
||||||
|
copy=fs.copy,
|
||||||
|
move=fs.move,
|
||||||
|
exists=function(path)
|
||||||
|
return exists(path)
|
||||||
|
end,
|
||||||
|
isDir=function(path)
|
||||||
|
return isDir(path)
|
||||||
|
end,
|
||||||
|
list=function(path)
|
||||||
|
return list(path)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error("sudo request denied")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return fs
|
||||||
50
disks/1h/sys/kernel/glib/component.lua
Normal file
50
disks/1h/sys/kernel/glib/component.lua
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
--local oldComponent = component
|
||||||
|
--_G.component={}
|
||||||
|
--local components={}
|
||||||
|
--local all={}
|
||||||
|
--local blacklisted={}
|
||||||
|
--
|
||||||
|
--function table.contains(tabl, query)
|
||||||
|
-- for i,v in ipairs(tabl) do
|
||||||
|
-- if v==query then
|
||||||
|
-- return true
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- return false
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--for i,v in oldComponent.list() do
|
||||||
|
-- if not components[i] then
|
||||||
|
-- components[i]={}
|
||||||
|
-- end
|
||||||
|
-- components[i][#components[i]+1]={typ=i,obj=v}
|
||||||
|
-- all[#all+1]={typ=i,obj=v}
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--function component.list(filter)
|
||||||
|
-- filter=filter or "all"
|
||||||
|
-- local filtered
|
||||||
|
-- if filter=="all" then
|
||||||
|
-- filtered=all
|
||||||
|
-- else
|
||||||
|
-- filtered=components[filter]
|
||||||
|
-- end
|
||||||
|
-- local i=0
|
||||||
|
-- return function()
|
||||||
|
-- while i<#filtered do
|
||||||
|
-- i=i+1
|
||||||
|
-- if not table.contains(blacklisted, v.typ) then
|
||||||
|
-- return v.typ, v.obj
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--function component.getSudo(key)
|
||||||
|
-- if key==masterKey then
|
||||||
|
-- return oldComponent
|
||||||
|
-- end
|
||||||
|
--end
|
||||||
|
--
|
||||||
|
--
|
||||||
53
disks/1h/sys/kernel/glib/string.lua
Normal file
53
disks/1h/sys/kernel/glib/string.lua
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
function string.hasSuffix(str, suffix)
|
||||||
|
return string.sub(str, #suffix+1) == suffix
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.hasPrefix(str, prefix)
|
||||||
|
return string.sub(str, 1, #prefix) == prefix
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.getSuffix(str, prefix)
|
||||||
|
return string.sub(str, #prefix+1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.getPrefix(str, suffix)
|
||||||
|
return string.sub(str, 1, #suffix)
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.join(delim, ...)
|
||||||
|
return table.concat(table.pack(...), delim)
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.split(str, delim, maxResultCountOrNil)
|
||||||
|
assert(#delim == 1, "only delim len 1 supported for now")
|
||||||
|
maxResultCountOrNil = (maxResultCountOrNil or 0)-1
|
||||||
|
local rv = {}
|
||||||
|
local buf = ""
|
||||||
|
for i = 1, #str do
|
||||||
|
local c = string.sub(str,i,i)
|
||||||
|
if #rv ~= maxResultCountOrNil and c == delim then
|
||||||
|
table.insert(rv, buf)
|
||||||
|
buf = ""
|
||||||
|
else
|
||||||
|
buf = buf..c
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(rv, buf)
|
||||||
|
return rv
|
||||||
|
end
|
||||||
|
|
||||||
|
function string.replace(str, search, replacement)
|
||||||
|
local rv = ""
|
||||||
|
local consumedLen = 1
|
||||||
|
local i = 1
|
||||||
|
while i<#str do
|
||||||
|
if string.sub(str, i, i+#search-1) == search then
|
||||||
|
rv = rv .. string.sub(str, consumedLen, i-1) .. replacement
|
||||||
|
i=i+#search
|
||||||
|
consumedLen = i
|
||||||
|
end
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
return rv .. string.sub(str, consumedLen)
|
||||||
|
end
|
||||||
39
disks/1h/sys/kernel/glib/table.lua
Normal file
39
disks/1h/sys/kernel/glib/table.lua
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
function table.deepcopy(orig, copies)
|
||||||
|
copies = copies or {}
|
||||||
|
|
||||||
|
if type(orig) ~= 'table' then
|
||||||
|
return orig
|
||||||
|
elseif copies[orig] then
|
||||||
|
return copies[orig]
|
||||||
|
end
|
||||||
|
|
||||||
|
local copy = {}
|
||||||
|
copies[orig] = copy
|
||||||
|
|
||||||
|
for k, v in next, orig, nil do
|
||||||
|
local copied_key = table.deepcopy(k, copies)
|
||||||
|
local copied_val = table.deepcopy(v, copies)
|
||||||
|
copy[copied_key] = copied_val
|
||||||
|
end
|
||||||
|
|
||||||
|
return copy
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.hasKey(tabl, query)
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
if i==query then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function table.hasVal(tabl, query)
|
||||||
|
for i,v in pairs(tabl) do
|
||||||
|
if v==query then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
1
disks/1h/sys/kernel/ioManager.sys
Normal file
1
disks/1h/sys/kernel/ioManager.sys
Normal file
@@ -0,0 +1 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
29
disks/1h/sys/kernel/userManager.sys
Normal file
29
disks/1h/sys/kernel/userManager.sys
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args=({...})[1]
|
||||||
|
local masterKey=args.masterKey
|
||||||
|
local disk=args.bootDrive
|
||||||
|
local auth={}
|
||||||
|
auth.sudo={}
|
||||||
|
local keys={}
|
||||||
|
local ok,sha256=pcall(load(disk:open("/lib/crypto/sha256").read()))
|
||||||
|
if not ok then
|
||||||
|
error("sha256 failed to load")
|
||||||
|
end
|
||||||
|
|
||||||
|
local users={}
|
||||||
|
local file=disk:open("/etc/passwd").read()
|
||||||
|
-- for p,i in ipairs(string.split(file,"\n")) do
|
||||||
|
-- for t,v in ipairs(string.split(v,":")) do
|
||||||
|
-- users[p][t]=v
|
||||||
|
-- end
|
||||||
|
-- end
|
||||||
|
|
||||||
|
function auth.sudo.isAproved(key)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function auth.sudo.elevatePerms(password)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return auth
|
||||||
14
disks/1h/sys/modules/consumer
Normal file
14
disks/1h/sys/modules/consumer
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local lib={}
|
||||||
|
|
||||||
|
function lib.create(def)
|
||||||
|
local function func(fun)
|
||||||
|
if type(fun)=="function" then
|
||||||
|
func=fun
|
||||||
|
end
|
||||||
|
return def
|
||||||
|
end
|
||||||
|
return func
|
||||||
|
end
|
||||||
|
|
||||||
|
return lib
|
||||||
6
disks/1h/sys/modules/ipc
Normal file
6
disks/1h/sys/modules/ipc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local pipes={}
|
||||||
|
local ports={}
|
||||||
|
local sharedObjects={}
|
||||||
|
local net=require("net")
|
||||||
|
|
||||||
86
disks/1h/sys/modules/require
Normal file
86
disks/1h/sys/modules/require
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args=({...})[1]
|
||||||
|
local log=args.logging
|
||||||
|
local fs=args.filesystem
|
||||||
|
local loaded=args.preload or {}
|
||||||
|
local function dot_to_slash(name)
|
||||||
|
local parts = {}
|
||||||
|
local start = 1
|
||||||
|
for i = 1, #name do
|
||||||
|
if name:sub(i, i) == "." then
|
||||||
|
table.insert(parts, name:sub(start, i - 1))
|
||||||
|
start = i + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(parts, name:sub(start))
|
||||||
|
return table.concat(parts, "/")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function replace_question_mark(path, name_path)
|
||||||
|
local result = {}
|
||||||
|
local replaced = false
|
||||||
|
for i = 1, #path do
|
||||||
|
local ch = path:sub(i, i)
|
||||||
|
if ch == "?" and not replaced then
|
||||||
|
table.insert(result, name_path)
|
||||||
|
replaced = true
|
||||||
|
else
|
||||||
|
table.insert(result, ch)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table.concat(result)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function search_module(name,search_paths)
|
||||||
|
local name_path = dot_to_slash(name)
|
||||||
|
|
||||||
|
for _, path in ipairs(search_paths) do
|
||||||
|
local filename = replace_question_mark(path, name_path)
|
||||||
|
if fs.exists(filename) and not fs.isDir(filename) then
|
||||||
|
local code=fs.open(filename,"x")
|
||||||
|
if code then
|
||||||
|
return code, filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil, "module not found: " .. name
|
||||||
|
end
|
||||||
|
|
||||||
|
return {
|
||||||
|
makeRequire=function(search_paths)
|
||||||
|
local config=string.split(search_paths,";")
|
||||||
|
return {
|
||||||
|
require=function(query)
|
||||||
|
if loaded[query] then return table.deepcopy(loaded[query]) end
|
||||||
|
local code,file=search_module(query,config)
|
||||||
|
if code==nil then
|
||||||
|
error(file)
|
||||||
|
end
|
||||||
|
local ok,_,lib=pcall(pcall,code)
|
||||||
|
if ok then
|
||||||
|
log.log("Added: \""..query.."\" to require registry.")
|
||||||
|
loaded[query]=lib
|
||||||
|
return table.deepcopy(lib), file
|
||||||
|
else
|
||||||
|
log.warn("ERR in module "..file)
|
||||||
|
return nil, "ERR in module "..file.."."
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
load=function(query, lib)
|
||||||
|
loaded[query]=lib
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
list=function()
|
||||||
|
local list={}
|
||||||
|
for i,v in pairs(loaded) do
|
||||||
|
list[#list+1]={i=i,v=v}
|
||||||
|
end
|
||||||
|
local i=0
|
||||||
|
while i<#list do
|
||||||
|
i=i+1
|
||||||
|
return list[i].i, list[i].v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
0
disks/1h/sys/system/sysinit.sys
Normal file
0
disks/1h/sys/system/sysinit.sys
Normal file
152
disks/1h/sys/system/system.sys
Normal file
152
disks/1h/sys/system/system.sys
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
-- Copyright (C) 2025 ASTRONAND
|
||||||
|
local args=({...})[1]
|
||||||
|
local fs=require("filesystem")
|
||||||
|
--local sfs=fs.getSudo(args.masterKey)
|
||||||
|
local auth=require("auth")
|
||||||
|
local system={}
|
||||||
|
local uuid=-1
|
||||||
|
local computer=component.getFirst("computer")
|
||||||
|
local time=computer.time()
|
||||||
|
local tasks={}
|
||||||
|
local currentTask={}
|
||||||
|
|
||||||
|
system.version="1.0.0"
|
||||||
|
system.name="HyperionOS"
|
||||||
|
-- Task status
|
||||||
|
-- "R" | Runnable/Running
|
||||||
|
-- "S" | Sleeping/Waiting
|
||||||
|
-- "P" | Stopped/Paused
|
||||||
|
-- "Z" | Exited/Zombie
|
||||||
|
-- "E" | Errored
|
||||||
|
-- "T" | Terminate
|
||||||
|
-- "X" | Marked for GC
|
||||||
|
|
||||||
|
local function UUID()
|
||||||
|
uuid=uuid+1
|
||||||
|
return tostring(uuid)
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.createTaskFromFunc(func, name, ...)
|
||||||
|
local id=UUID()
|
||||||
|
local fargs={...}
|
||||||
|
local task={}
|
||||||
|
local handle={}
|
||||||
|
task={
|
||||||
|
sleep=0,
|
||||||
|
state="N",
|
||||||
|
thread=coroutine.create(function()
|
||||||
|
local ret={pcall(func, table.unpack(fargs))}
|
||||||
|
local ok, tret = ret[1], {table.unpack(ret,2)}
|
||||||
|
if not ok then
|
||||||
|
task.state="E"
|
||||||
|
task.exit_state=tret[1]
|
||||||
|
task.exit_code=1
|
||||||
|
else
|
||||||
|
if #tret>0 then
|
||||||
|
task.state="Z"
|
||||||
|
task.exit_state=tret
|
||||||
|
task.exit_code=0
|
||||||
|
else
|
||||||
|
task.state="X"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
PID=id,
|
||||||
|
name=name,
|
||||||
|
comm=string.sub(name, 1, 32),
|
||||||
|
parent=currentTask,
|
||||||
|
chlidren={},
|
||||||
|
sibling=currentTask.chlidren,
|
||||||
|
files={},
|
||||||
|
nvcsw=0,
|
||||||
|
nivcsw=0,
|
||||||
|
handle=handle,
|
||||||
|
start_time=computer.time()
|
||||||
|
}
|
||||||
|
tasks[id]=task
|
||||||
|
local close=false
|
||||||
|
function handle.exists()
|
||||||
|
return not close
|
||||||
|
end
|
||||||
|
function handle.kill()
|
||||||
|
close=true
|
||||||
|
task.state="T"
|
||||||
|
end
|
||||||
|
function handle.pause()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
if task.state=="R" then
|
||||||
|
task.state="P"
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function handle.resume()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
if task.state=="P" then
|
||||||
|
task.state="R"
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function handle.getPID()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return task.PID
|
||||||
|
end
|
||||||
|
function handle.getParent()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return task.parent.PID
|
||||||
|
end
|
||||||
|
function handle.getChildren()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
local ret = {}
|
||||||
|
for i,v in pairs(task.chlidren) do
|
||||||
|
ret[#ret+1] = v.PID
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
function handle.getState()
|
||||||
|
if close then return "Handle closed" end
|
||||||
|
return task.state
|
||||||
|
end
|
||||||
|
return handle
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.createTaskFromFile(path, name, ...)
|
||||||
|
local file = fs.open(path, "x")
|
||||||
|
return system.createTaskFromFunc(file, name, ...)
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.getTaskInfo(pid)
|
||||||
|
local task = tasks[pid]
|
||||||
|
if task == nil then return "No task with id "..pid end
|
||||||
|
return {
|
||||||
|
PID=task.PID,
|
||||||
|
parent=task.parent.PID,
|
||||||
|
sibling=(function()
|
||||||
|
local ret = {}
|
||||||
|
for i,v in pairs(task.sibling) do
|
||||||
|
ret[#ret+1] = i
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end)(),
|
||||||
|
chlidren=(function()
|
||||||
|
local ret = {}
|
||||||
|
for i,v in pairs(task.chlidren) do
|
||||||
|
ret[#ret+1] = i
|
||||||
|
end
|
||||||
|
return ret
|
||||||
|
end)(),
|
||||||
|
name=task.name,
|
||||||
|
state=task.state,
|
||||||
|
nvcsw=task.nvcsw,
|
||||||
|
nivcsw=task.nivcsw,
|
||||||
|
start_time=task.start_time
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function system.getCurrentTask()
|
||||||
|
return system.getTaskInfo(currentTask.PID)
|
||||||
|
end
|
||||||
|
|
||||||
1
disks/1h/var/log/kernel/bootData
Normal file
1
disks/1h/var/log/kernel/bootData
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{["errorCount"]=4,["prevError"]=[=[random panic for testing purposes]=],["mode"]=[=["CLI"]=]}
|
||||||
0
disks/2f/burn.lua
Normal file
0
disks/2f/burn.lua
Normal file
48
docs
Normal file
48
docs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
disk:
|
||||||
|
open(path).
|
||||||
|
read()
|
||||||
|
write(text)
|
||||||
|
append(text)
|
||||||
|
list(path)
|
||||||
|
fileExists(path)
|
||||||
|
directoryExists(path)
|
||||||
|
makeDirectory(path)
|
||||||
|
delete(path)
|
||||||
|
copy(path)
|
||||||
|
move(path)
|
||||||
|
getSize(path)
|
||||||
|
type -> "hdd" | "fdd" | "udd"
|
||||||
|
id -> "disk_[id]"
|
||||||
|
__UDATA_id -> [id]
|
||||||
|
|
||||||
|
computer.
|
||||||
|
time()
|
||||||
|
setData(address, data)
|
||||||
|
getData(address)
|
||||||
|
saveData()
|
||||||
|
beep(freq, length)
|
||||||
|
getMachineEvent()
|
||||||
|
shutdown()
|
||||||
|
rebbot()
|
||||||
|
|
||||||
|
screen.
|
||||||
|
print(...)
|
||||||
|
printInline(...)
|
||||||
|
clear()
|
||||||
|
id -> "screen_[id]"
|
||||||
|
__UDATA_id -> [id]
|
||||||
|
|
||||||
|
internet:
|
||||||
|
get(url)
|
||||||
|
|
||||||
|
bios.
|
||||||
|
getData()
|
||||||
|
setData(text)
|
||||||
|
id -> "bios"
|
||||||
|
|
||||||
|
uDisk: labeled disk
|
||||||
|
readBytes(start, length)
|
||||||
|
writeBytes(data)
|
||||||
|
getSize()
|
||||||
|
id -> "disk_[id]"
|
||||||
|
__UDATA_id -> [id]
|
||||||
121
startup.lua
121
startup.lua
@@ -1,118 +1,5 @@
|
|||||||
-- UnBIOS by JackMacWindows
|
if fs.exists("/aceExit") then
|
||||||
-- This will undo most of the changes/additions made in the BIOS, but some things may remain wrapped if `debug` is unavailable
|
return
|
||||||
-- To use, just place a `bios.lua` in the root of the drive, and run this program
|
else
|
||||||
-- Here's a list of things that are irreversibly changed:
|
dofile("/unbios.lua")
|
||||||
-- * both `bit` and `bit32` are kept for compatibility
|
|
||||||
-- * string metatable blocking (on old versions of CC)
|
|
||||||
-- In addition, if `debug` is not available these things are also irreversibly changed:
|
|
||||||
-- * old Lua 5.1 `load` function (for loading from a function)
|
|
||||||
-- * `loadstring` prefixing (before CC:T 1.96.0)
|
|
||||||
-- * `http.request`
|
|
||||||
-- * `os.shutdown` and `os.reboot`
|
|
||||||
-- * `peripheral`
|
|
||||||
-- * `turtle.equip[Left|Right]`
|
|
||||||
-- Licensed under the MIT license
|
|
||||||
if _HOST:find("UnBIOS") then return end
|
|
||||||
local keptAPIs = {bit32 = true, bit = true, ccemux = true, config = true, coroutine = true, debug = true, fs = true, http = true, mounter = true, os = true, periphemu = true, peripheral = true, redstone = true, rs = true, term = true, utf8 = true, _HOST = true, _CC_DEFAULT_SETTINGS = true, _CC_DISABLE_LUA51_FEATURES = true, _VERSION = true, assert = true, collectgarbage = true, error = true, gcinfo = true, getfenv = true, getmetatable = true, ipairs = true, __inext = true,load = true, loadstring = true, math = true, newproxy = true, next = true, pairs = true, pcall = true, rawequal = true, rawget = true, rawlen = true, rawset = true, select = true, setfenv = true, setmetatable = true, string = true, table = true, tonumber = true, tostring = true, type = true, unpack = true, xpcall = true, turtle = true, pocket = true, commands = true, _G = true, keys=true}
|
|
||||||
local t = {}
|
|
||||||
for k in pairs(_G) do if not keptAPIs[k] then table.insert(t, k) end end
|
|
||||||
for _,k in ipairs(t) do _G[k] = nil end
|
|
||||||
local native = _G.term.native()
|
|
||||||
for _, method in ipairs {"nativePaletteColor", "nativePaletteColour", "screenshot"} do native[method] = _G.term[method] end
|
|
||||||
_G.term = native
|
|
||||||
if _G.http then
|
|
||||||
_G.http.checkURL = _G.http.checkURLAsync
|
|
||||||
_G.http.websocket = _G.http.websocketAsync
|
|
||||||
end
|
end
|
||||||
if _G.commands then _G.commands = _G.commands.native end
|
|
||||||
if _G.turtle then _G.turtle.native, _G.turtle.craft = nil end
|
|
||||||
local delete = {os = {"version", "pullEventRaw", "pullEvent", "run", "loadAPI", "unloadAPI", "sleep"}, http = _G.http and {"get", "post", "put", "delete", "patch", "options", "head", "trace", "listen", "checkURLAsync", "websocketAsync"}, fs = {"complete", "isDriveRoot"}}
|
|
||||||
for k,v in pairs(delete) do for _,a in ipairs(v) do _G[k][a] = nil end end
|
|
||||||
-- Set up TLCO
|
|
||||||
-- This functions by crashing `rednet.run` by removing `os.pullEventRaw`. Normally
|
|
||||||
-- this would cause `parallel` to throw an error, but we replace `error` with an
|
|
||||||
-- empty placeholder to let it continue and return without throwing. This results
|
|
||||||
-- in the `pcall` returning successfully, preventing the error-displaying code
|
|
||||||
-- from running - essentially making it so that `os.shutdown` is called immediately
|
|
||||||
-- after the new BIOS exits.
|
|
||||||
--
|
|
||||||
-- From there, the setup code is placed in `term.native` since it's the first
|
|
||||||
-- thing called after `parallel` exits. This loads the new BIOS and prepares it
|
|
||||||
-- for execution. Finally, it overwrites `os.shutdown` with the new function to
|
|
||||||
-- allow it to be the last function called in the original BIOS, and returns.
|
|
||||||
-- From there execution continues, calling the `term.redirect` dummy, skipping
|
|
||||||
-- over the error-handling code (since `pcall` returned ok), and calling
|
|
||||||
-- `os.shutdown()`. The real `os.shutdown` is re-added, and the new BIOS is tail
|
|
||||||
-- called, which effectively makes it run as the main chunk.
|
|
||||||
local olderror = error
|
|
||||||
_G.error = function() end
|
|
||||||
_G.term.redirect = function() end
|
|
||||||
function _G.term.native()
|
|
||||||
_G.term.native = nil
|
|
||||||
_G.term.redirect = nil
|
|
||||||
_G.error = olderror
|
|
||||||
term.setBackgroundColor(32768)
|
|
||||||
term.setTextColor(1)
|
|
||||||
term.setCursorPos(1, 1)
|
|
||||||
term.setCursorBlink(true)
|
|
||||||
term.clear()
|
|
||||||
local file = fs.open("/aceVM/init", "r")
|
|
||||||
if file == nil then
|
|
||||||
term.setCursorBlink(false)
|
|
||||||
term.setTextColor(16384)
|
|
||||||
term.write("Could not find aceVM. UnBIOS cannot continue.")
|
|
||||||
term.setCursorPos(1, 2)
|
|
||||||
term.write("Press any key to continue")
|
|
||||||
coroutine.yield("key")
|
|
||||||
os.shutdown()
|
|
||||||
end
|
|
||||||
local fn, err = loadstring(file.readAll(), "@aceVM")
|
|
||||||
file.close()
|
|
||||||
if fn == nil then
|
|
||||||
term.setCursorBlink(false)
|
|
||||||
term.setTextColor(16384)
|
|
||||||
term.write("Could not load aceVM. UnBIOS cannot continue.")
|
|
||||||
term.setCursorPos(1, 2)
|
|
||||||
term.write(err)
|
|
||||||
term.setCursorPos(1, 3)
|
|
||||||
term.write("Press any key to continue")
|
|
||||||
coroutine.yield("key")
|
|
||||||
os.shutdown()
|
|
||||||
end
|
|
||||||
setfenv(fn, _G)
|
|
||||||
local oldshutdown = os.shutdown
|
|
||||||
os.shutdown = function()
|
|
||||||
os.shutdown = oldshutdown
|
|
||||||
return fn(true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if debug then
|
|
||||||
-- Restore functions that were overwritten in the BIOS
|
|
||||||
-- Apparently this has to be done *after* redefining term.native
|
|
||||||
local function restoreValue(tab, idx, name, hint)
|
|
||||||
local i, key, value = 1, debug.getupvalue(tab[idx], hint)
|
|
||||||
while key ~= name and key ~= nil do
|
|
||||||
key, value = debug.getupvalue(tab[idx], i)
|
|
||||||
i=i+1
|
|
||||||
end
|
|
||||||
tab[idx] = value or tab[idx]
|
|
||||||
end
|
|
||||||
restoreValue(_G, "loadstring", "nativeloadstring", 1)
|
|
||||||
restoreValue(_G, "load", "nativeload", 5)
|
|
||||||
if http then restoreValue(http, "request", "nativeHTTPRequest", 3) end
|
|
||||||
restoreValue(os, "shutdown", "nativeShutdown", 1)
|
|
||||||
restoreValue(os, "reboot", "nativeReboot", 1)
|
|
||||||
if turtle then
|
|
||||||
restoreValue(turtle, "equipLeft", "v", 1)
|
|
||||||
restoreValue(turtle, "equipRight", "v", 1)
|
|
||||||
end
|
|
||||||
do
|
|
||||||
local i, key, value = 1, debug.getupvalue(peripheral.isPresent, 2)
|
|
||||||
while key ~= "native" and key ~= nil do
|
|
||||||
key, value = debug.getupvalue(peripheral.isPresent, i)
|
|
||||||
i=i+1
|
|
||||||
end
|
|
||||||
_G.peripheral = value or peripheral
|
|
||||||
end
|
|
||||||
end
|
|
||||||
coroutine.yield()
|
|
||||||
118
unbios.lua
Normal file
118
unbios.lua
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
-- UnBIOS by JackMacWindows
|
||||||
|
-- This will undo most of the changes/additions made in the BIOS, but some things may remain wrapped if `debug` is unavailable
|
||||||
|
-- To use, just place a `bios.lua` in the root of the drive, and run this program
|
||||||
|
-- Here's a list of things that are irreversibly changed:
|
||||||
|
-- * both `bit` and `bit32` are kept for compatibility
|
||||||
|
-- * string metatable blocking (on old versions of CC)
|
||||||
|
-- In addition, if `debug` is not available these things are also irreversibly changed:
|
||||||
|
-- * old Lua 5.1 `load` function (for loading from a function)
|
||||||
|
-- * `loadstring` prefixing (before CC:T 1.96.0)
|
||||||
|
-- * `http.request`
|
||||||
|
-- * `os.shutdown` and `os.reboot`
|
||||||
|
-- * `peripheral`
|
||||||
|
-- * `turtle.equip[Left|Right]`
|
||||||
|
-- Licensed under the MIT license
|
||||||
|
if _HOST:find("UnBIOS") then return end
|
||||||
|
local keptAPIs = {bit32 = true, bit = true, ccemux = true, config = true, coroutine = true, debug = true, fs = true, http = true, mounter = true, os = true, periphemu = true, peripheral = true, redstone = true, rs = true, term = true, utf8 = true, _HOST = true, _CC_DEFAULT_SETTINGS = true, _CC_DISABLE_LUA51_FEATURES = true, _VERSION = true, assert = true, collectgarbage = true, error = true, gcinfo = true, getfenv = true, getmetatable = true, ipairs = true, __inext = true,load = true, loadstring = true, math = true, newproxy = true, next = true, pairs = true, pcall = true, rawequal = true, rawget = true, rawlen = true, rawset = true, select = true, setfenv = true, setmetatable = true, string = true, table = true, tonumber = true, tostring = true, type = true, unpack = true, xpcall = true, turtle = true, pocket = true, commands = true, _G = true, keys=true}
|
||||||
|
local t = {}
|
||||||
|
for k in pairs(_G) do if not keptAPIs[k] then table.insert(t, k) end end
|
||||||
|
for _,k in ipairs(t) do _G[k] = nil end
|
||||||
|
local native = _G.term.native()
|
||||||
|
for _, method in ipairs {"nativePaletteColor", "nativePaletteColour", "screenshot"} do native[method] = _G.term[method] end
|
||||||
|
_G.term = native
|
||||||
|
if _G.http then
|
||||||
|
_G.http.checkURL = _G.http.checkURLAsync
|
||||||
|
_G.http.websocket = _G.http.websocketAsync
|
||||||
|
end
|
||||||
|
if _G.commands then _G.commands = _G.commands.native end
|
||||||
|
if _G.turtle then _G.turtle.native, _G.turtle.craft = nil end
|
||||||
|
local delete = {os = {"version", "pullEventRaw", "pullEvent", "run", "loadAPI", "unloadAPI", "sleep"}, http = _G.http and {"get", "post", "put", "delete", "patch", "options", "head", "trace", "listen", "checkURLAsync", "websocketAsync"}, fs = {"complete", "isDriveRoot"}}
|
||||||
|
for k,v in pairs(delete) do for _,a in ipairs(v) do _G[k][a] = nil end end
|
||||||
|
-- Set up TLCO
|
||||||
|
-- This functions by crashing `rednet.run` by removing `os.pullEventRaw`. Normally
|
||||||
|
-- this would cause `parallel` to throw an error, but we replace `error` with an
|
||||||
|
-- empty placeholder to let it continue and return without throwing. This results
|
||||||
|
-- in the `pcall` returning successfully, preventing the error-displaying code
|
||||||
|
-- from running - essentially making it so that `os.shutdown` is called immediately
|
||||||
|
-- after the new BIOS exits.
|
||||||
|
--
|
||||||
|
-- From there, the setup code is placed in `term.native` since it's the first
|
||||||
|
-- thing called after `parallel` exits. This loads the new BIOS and prepares it
|
||||||
|
-- for execution. Finally, it overwrites `os.shutdown` with the new function to
|
||||||
|
-- allow it to be the last function called in the original BIOS, and returns.
|
||||||
|
-- From there execution continues, calling the `term.redirect` dummy, skipping
|
||||||
|
-- over the error-handling code (since `pcall` returned ok), and calling
|
||||||
|
-- `os.shutdown()`. The real `os.shutdown` is re-added, and the new BIOS is tail
|
||||||
|
-- called, which effectively makes it run as the main chunk.
|
||||||
|
local olderror = error
|
||||||
|
_G.error = function() end
|
||||||
|
_G.term.redirect = function() end
|
||||||
|
function _G.term.native()
|
||||||
|
_G.term.native = nil
|
||||||
|
_G.term.redirect = nil
|
||||||
|
_G.error = olderror
|
||||||
|
term.setBackgroundColor(32768)
|
||||||
|
term.setTextColor(1)
|
||||||
|
term.setCursorPos(1, 1)
|
||||||
|
term.setCursorBlink(true)
|
||||||
|
term.clear()
|
||||||
|
local file = fs.open("/AceVM/init", "r")
|
||||||
|
if file == nil then
|
||||||
|
term.setCursorBlink(false)
|
||||||
|
term.setTextColor(16384)
|
||||||
|
term.write("Could not find AceVM. UnBIOS cannot continue.")
|
||||||
|
term.setCursorPos(1, 2)
|
||||||
|
term.write("Press any key to continue")
|
||||||
|
coroutine.yield("key")
|
||||||
|
os.shutdown()
|
||||||
|
end
|
||||||
|
local fn, err = loadstring(file.readAll(), "@AceVM")
|
||||||
|
file.close()
|
||||||
|
if fn == nil then
|
||||||
|
term.setCursorBlink(false)
|
||||||
|
term.setTextColor(16384)
|
||||||
|
term.write("Could not load AceVM. UnBIOS cannot continue.")
|
||||||
|
term.setCursorPos(1, 2)
|
||||||
|
term.write(err)
|
||||||
|
term.setCursorPos(1, 3)
|
||||||
|
term.write("Press any key to continue")
|
||||||
|
coroutine.yield("key")
|
||||||
|
os.shutdown()
|
||||||
|
end
|
||||||
|
setfenv(fn, _G)
|
||||||
|
local oldshutdown = os.shutdown
|
||||||
|
os.shutdown = function()
|
||||||
|
os.shutdown = oldshutdown
|
||||||
|
return fn(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if debug then
|
||||||
|
-- Restore functions that were overwritten in the BIOS
|
||||||
|
-- Apparently this has to be done *after* redefining term.native
|
||||||
|
local function restoreValue(tab, idx, name, hint)
|
||||||
|
local i, key, value = 1, debug.getupvalue(tab[idx], hint)
|
||||||
|
while key ~= name and key ~= nil do
|
||||||
|
key, value = debug.getupvalue(tab[idx], i)
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
tab[idx] = value or tab[idx]
|
||||||
|
end
|
||||||
|
restoreValue(_G, "loadstring", "nativeloadstring", 1)
|
||||||
|
restoreValue(_G, "load", "nativeload", 5)
|
||||||
|
if http then restoreValue(http, "request", "nativeHTTPRequest", 3) end
|
||||||
|
restoreValue(os, "shutdown", "nativeShutdown", 1)
|
||||||
|
restoreValue(os, "reboot", "nativeReboot", 1)
|
||||||
|
if turtle then
|
||||||
|
restoreValue(turtle, "equipLeft", "v", 1)
|
||||||
|
restoreValue(turtle, "equipRight", "v", 1)
|
||||||
|
end
|
||||||
|
do
|
||||||
|
local i, key, value = 1, debug.getupvalue(peripheral.isPresent, 2)
|
||||||
|
while key ~= "native" and key ~= nil do
|
||||||
|
key, value = debug.getupvalue(peripheral.isPresent, i)
|
||||||
|
i=i+1
|
||||||
|
end
|
||||||
|
_G.peripheral = value or peripheral
|
||||||
|
end
|
||||||
|
end
|
||||||
|
coroutine.yield()
|
||||||
Reference in New Issue
Block a user