working on require needs to be done before EOW

This commit is contained in:
2025-11-10 09:50:32 -05:00
parent fdb67d9afb
commit b288bb3cae
124 changed files with 9828 additions and 1 deletions

18
LICENSE Normal file
View File

@@ -0,0 +1,18 @@
MIT License
Copyright (c) 2025 Astronand
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# HyperionOS
A OS made for lua enviroments.

34
docs/api/drivers/fs.txt Normal file
View File

@@ -0,0 +1,34 @@
readAllText(dir) Returns string:contents
reads all text from directory on disk
writeAllText(dir, content) Returns nil
writes all content to file
appendAllText(dir, content) Returns nil
appends all content to file
getAtributes(dir) Returns table:atributes
returns atributes of a file or directory
list(dir) Returns table:files
returns contents of directory
mkdir(dir) Returns nil
makes specified directory
mkfile(dir) Returns nil
makes specified file
-------------------------------------------------------
Atributes table
number:size
size of file in bytes
number:owner
owner UUID
number:group
group UUID
number:perms
file perms 0-21

View File

@@ -0,0 +1,16 @@
# drivers
---
## driver types
---
```
http - internet
lan - local networks
fs - filesystems
disk - normal disks
udisk - byte array disks
terminal - screens that only support text
```
### Driver APIS

View File

@@ -0,0 +1,8 @@
print(text) Returns nil
Prints text to the terminal with a trailing \n
printInline(text) Returns nil
Same as print without the trailing \n
clear() Returns nil
Clears screen

0
docs/api/kernel.txt Normal file
View File

1
e
View File

@@ -1 +0,0 @@
e

188
src/computers/0/bios.lua Normal file
View File

@@ -0,0 +1,188 @@
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)
local function 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 = deepcopy(k, copies)
local copied_val = deepcopy(v, copies)
copy[copied_key] = copied_val
end
return copy
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
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
_VG=deepcopy(_G)
print("├─ Created virtual ENV.")
local _,func = pcall(load,code,drive.id.." | "..path,nil,_G)
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

View File

@@ -0,0 +1,3 @@
{
"disks":[1,2,3,56]
}

254
src/computers/0/nvram.dat Normal file
View File

@@ -0,0 +1,254 @@
HyperionOS
disk_1
/boot/ac/boot.ac
HyperionOS Dev
disk_2
/boot/Hyprkrnl.sys
$EOF

58
src/computers/1/bios.lua Normal file
View File

@@ -0,0 +1,58 @@
local computer = component.getFirst("computer")
local screen=component.getFirst("screen")
if not screen then
computer.beep(400,0.2)
sleep(0.2)
computer.beep(400,0.2)
while true do
computer.shutdown()
end
end
local idx = 1
local ok, err = xpcall(function()
for t, a in component.list() do
if t == "disk" then
if a:fileExists("boot.lua") then
screen.print("Bootable file found on "..a.id.." - reading...")
local code = a:open("boot.lua").read()
screen.print("Compiling boot.lua...")
local f = load(code)
if not f then error("bios boot compilation failed") end
screen.print("Booting...")
---@diagnostic disable-next-line: need-check-nil
local ok, err = xpcall(f, debug.traceback)
if not ok then screen.print(err); sleep(3) end
break
else
idx = idx+1
end
end
end
end, debug.traceback)
if not ok then
screen.print("BIOS error: "..err)
computer.beep(800,0.2)
osleep(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
computer.beep(400,0.4)
screen.print("No bootable filesystem found!")
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

View File

@@ -0,0 +1,3 @@
{
"disks":[3,4,8]
}

249
src/computers/1/nvram.dat Normal file
View File

@@ -0,0 +1,249 @@

189
src/computers/2/bios.lua Normal file
View File

@@ -0,0 +1,189 @@
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

View File

@@ -0,0 +1,3 @@
{
"disks":[1,2,3,4,8]
}

249
src/computers/2/nvram.dat Normal file
View File

@@ -0,0 +1,249 @@
HyperionOS
disk_3
/boot/ac/boot.ac

46
src/computers/6/bios.lua Normal file
View File

@@ -0,0 +1,46 @@
local driverutil={}
function driverutil.getFirst(type)
if drivers[type] then
if drivers[type][1] then
return drivers[type][1]
end
end
end
function driverutil.list(type)
if not type then
local tmp={}
for i,v in ipairs(drivers.raw) do
tmp[#tmp+1] = {type=v.type, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp[i].type, tmp[i].obj
end
else
local tmp={}
for i,v in ipairs(drivers[type]) do
tmp[#tmp+1] = {type=v.type, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp[i].type, tmp[i].obj
end
end
end
local function runAsKernel(path, ...)
local func, err = load("return {'e'}", path, "t", _G)
if not func then return false, "\t"..err end
local ret = {xpcall(func, debug.traceback, ...)}
if not ret[1] then
return false, ret[2]
end
return true, table.unpack(ret, 2)
end
runAsKernel(e, driverutil)

View File

@@ -0,0 +1,3 @@
{
"disks":[1,2,3,4,8]
}

249
src/computers/6/nvram.dat Normal file
View File

@@ -0,0 +1,249 @@
HyperionOS
disk_3
/boot/ac/boot.ac

1
src/disks/.ignore Normal file
View File

@@ -0,0 +1 @@

0
src/disks/1h/bin/BASIC Normal file
View File

0
src/disks/1h/bin/hex.lua Normal file
View File

10
src/disks/1h/bin/lua.lua Normal file
View File

@@ -0,0 +1,10 @@
local args={...}
if #args>0 then
load(args[1])(table.unpack(args, 2))
else
local sys = require("system")
local evhook = sys.addEventHook("keyTyped", function()
end)
local term = sys.getParentTermObject()
end

View File

783
src/disks/1h/bin/shell.lua Normal file
View File

@@ -0,0 +1,783 @@
-- SPDX-FileCopyrightText: 2017 Daniel Ratcliffe
--
-- SPDX-License-Identifier: LicenseRef-CCPL
--[[- The shell API provides access to CraftOS's command line interface.
It allows you to @{run|start programs}, @{setCompletionFunction|add completion
for a program}, and much more.
@{shell} is not a "true" API. Instead, it is a standard program, which injects
its API into the programs that it launches. This allows for multiple shells to
run at the same time, but means that the API is not available in the global
environment, and so is unavailable to other @{os.loadAPI|APIs}.
## Programs and the program path
When you run a command with the shell, either from the prompt or
@{shell.run|from Lua code}, the shell API performs several steps to work out
which program to run:
1. Firstly, the shell attempts to resolve @{shell.aliases|aliases}. This allows
us to use multiple names for a single command. For example, the `list`
program has two aliases: `ls` and `dir`. When you write `ls /rom`, that's
expanded to `list /rom`.
2. Next, the shell attempts to find where the program actually is. For this, it
uses the @{shell.path|program path}. This is a colon separated list of
directories, each of which is checked to see if it contains the program.
`list` or `list.lua` doesn't exist in `.` (the current directory), so she
shell now looks in `/rom/programs`, where `list.lua` can be found!
3. Finally, the shell reads the file and checks if the file starts with a
`#!`. This is a [hashbang][], which says that this file shouldn't be treated
as Lua, but instead passed to _another_ program, the name of which should
follow the `#!`.
[hashbang]: https://en.wikipedia.org/wiki/Shebang_(Unix)
@module[module] shell
]]
local make_package = dofile("rom/modules/main/cc/require.lua").make
local multishell = multishell
local parentShell = shell
local parentTerm = term.current()
if multishell then
multishell.setTitle(multishell.getCurrent(), "shell")
end
local bExit = false
local sDir = parentShell and parentShell.dir() or ""
local sPath = parentShell and parentShell.path() or ".:/rom/programs"
local tAliases = parentShell and parentShell.aliases() or {}
local tCompletionInfo = parentShell and parentShell.getCompletionInfo() or {}
local tProgramStack = {}
local shell = {} --- @export
local function createShellEnv(dir)
local env = { shell = shell, multishell = multishell }
env.require, env.package = make_package(env, dir)
return env
end
-- Set up a dummy require based on the current shell, for loading some of our internal dependencies.
local require
do
local env = setmetatable(createShellEnv("/rom/programs"), { __index = _ENV })
require = env.require
end
local expect = require("cc.expect").expect
local exception = require "cc.internal.exception"
-- Colours
local promptColour, textColour, bgColour
if term.isColour() then
promptColour = colours.yellow
textColour = colours.white
bgColour = colours.black
else
promptColour = colours.white
textColour = colours.white
bgColour = colours.black
end
local function tokenise(...)
local sLine = table.concat({ ... }, " ")
local tWords = {}
local bQuoted = false
for match in string.gmatch(sLine .. "\"", "(.-)\"") do
if bQuoted then
table.insert(tWords, match)
else
for m in string.gmatch(match, "[^ \t]+") do
table.insert(tWords, m)
end
end
bQuoted = not bQuoted
end
return tWords
end
-- Execute a program using os.run, unless a shebang is present.
-- In that case, execute the program using the interpreter specified in the hashbang.
-- This may occur recursively, up to the maximum number of times specified by remainingRecursion
-- Returns the same type as os.run, which is a boolean indicating whether the program exited successfully.
local function executeProgram(remainingRecursion, path, args)
local file, err = fs.open(path, "r")
if not file then
printError(err)
return false
end
-- First check if the file begins with a #!
local contents = file.readLine() or ""
if contents:sub(1, 2) == "#!" then
file.close()
remainingRecursion = remainingRecursion - 1
if remainingRecursion == 0 then
printError("Hashbang recursion depth limit reached when loading file: " .. path)
return false
end
-- Load the specified hashbang program instead
local hashbangArgs = tokenise(contents:sub(3))
local originalHashbangPath = table.remove(hashbangArgs, 1)
local resolvedHashbangProgram = shell.resolveProgram(originalHashbangPath)
if not resolvedHashbangProgram then
printError("Hashbang program not found: " .. originalHashbangPath)
return false
elseif resolvedHashbangProgram == "rom/programs/shell.lua" and #hashbangArgs == 0 then
-- If we try to launch the shell then our shebang expands to "shell <program>", which just does a
-- shell.run("<program>") again, resulting in an infinite loop. This may still happen (if the user
-- has a custom shell), but this reduces the risk.
-- It's a little ugly special-casing this, but it's probably worth warning about.
printError("Cannot use the shell as a hashbang program")
return false
end
-- Add the path and any arguments to the interpreter's arguments
table.insert(hashbangArgs, path)
for _, v in ipairs(args) do
table.insert(hashbangArgs, v)
end
hashbangArgs[0] = originalHashbangPath
return executeProgram(remainingRecursion, resolvedHashbangProgram, hashbangArgs)
end
contents = contents .. "\n" .. (file.readAll() or "")
file.close()
local dir = fs.getDir(path)
local env = setmetatable(createShellEnv(dir), { __index = _G })
env.arg = args
local func, err = load(contents, "@/" .. fs.combine(path), nil, env)
if not func then
-- We had a syntax error. Attempt to run it through our own parser if
-- the file is "small enough", otherwise report the original error.
if #contents < 1024 * 128 then
local parser = require "cc.internal.syntax"
if parser.parse_program(contents) then printError(err) end
else
printError(err)
end
return false
end
if settings.get("bios.strict_globals", false) then
getmetatable(env).__newindex = function(_, name)
error("Attempt to create global " .. tostring(name), 2)
end
end
local ok, err, co = exception.try(func, table.unpack(args, 1, args.n))
if ok then return true end
if err and err ~= "" then
printError(err)
exception.report(err, co)
end
return false
end
--- Run a program with the supplied arguments.
--
-- Unlike @{shell.run}, each argument is passed to the program verbatim. While
-- `shell.run("echo", "b c")` runs `echo` with `b` and `c`,
-- `shell.execute("echo", "b c")` runs `echo` with a single argument `b c`.
--
-- @tparam string command The program to execute.
-- @tparam string ... Arguments to this program.
-- @treturn boolean Whether the program exited successfully.
-- @since 1.88.0
-- @usage Run `paint my-image` from within your program:
--
-- shell.execute("paint", "my-image")
function shell.execute(command, ...)
expect(1, command, "string")
for i = 1, select('#', ...) do
expect(i + 1, select(i, ...), "string")
end
local sPath = shell.resolveProgram(command)
if sPath ~= nil then
tProgramStack[#tProgramStack + 1] = sPath
if multishell then
local sTitle = fs.getName(sPath)
if sTitle:sub(-4) == ".lua" then
sTitle = sTitle:sub(1, -5)
end
multishell.setTitle(multishell.getCurrent(), sTitle)
end
local result = executeProgram(100, sPath, { [0] = command, ... })
tProgramStack[#tProgramStack] = nil
if multishell then
if #tProgramStack > 0 then
local sTitle = fs.getName(tProgramStack[#tProgramStack])
if sTitle:sub(-4) == ".lua" then
sTitle = sTitle:sub(1, -5)
end
multishell.setTitle(multishell.getCurrent(), sTitle)
else
multishell.setTitle(multishell.getCurrent(), "shell")
end
end
return result
else
printError("No such program")
return false
end
end
-- Install shell API
--- Run a program with the supplied arguments.
--
-- All arguments are concatenated together and then parsed as a command line. As
-- a result, `shell.run("program a b")` is the same as `shell.run("program",
-- "a", "b")`.
--
-- @tparam string ... The program to run and its arguments.
-- @treturn boolean Whether the program exited successfully.
-- @usage Run `paint my-image` from within your program:
--
-- shell.run("paint", "my-image")
-- @see shell.execute Run a program directly without parsing the arguments.
-- @changed 1.80pr1 Programs now get their own environment instead of sharing the same one.
-- @changed 1.83.0 `arg` is now added to the environment.
function shell.run(...)
local tWords = tokenise(...)
local sCommand = tWords[1]
if sCommand then
return shell.execute(sCommand, table.unpack(tWords, 2))
end
return false
end
--- Exit the current shell.
--
-- This does _not_ terminate your program, it simply makes the shell terminate
-- after your program has finished. If this is the toplevel shell, then the
-- computer will be shutdown.
function shell.exit()
bExit = true
end
--- Return the current working directory. This is what is displayed before the
-- `> ` of the shell prompt, and is used by @{shell.resolve} to handle relative
-- paths.
--
-- @treturn string The current working directory.
-- @see setDir To change the working directory.
function shell.dir()
return sDir
end
--- Set the current working directory.
--
-- @tparam string dir The new working directory.
-- @throws If the path does not exist or is not a directory.
-- @usage Set the working directory to "rom"
--
-- shell.setDir("rom")
function shell.setDir(dir)
expect(1, dir, "string")
if not fs.isDir(dir) then
error("Not a directory", 2)
end
sDir = fs.combine(dir, "")
end
--- Set the path where programs are located.
--
-- The path is composed of a list of directory names in a string, each separated
-- by a colon (`:`). On normal turtles will look in the current directory (`.`),
-- `/rom/programs` and `/rom/programs/turtle` folder, making the path
-- `.:/rom/programs:/rom/programs/turtle`.
--
-- @treturn string The current shell's path.
-- @see setPath To change the current path.
function shell.path()
return sPath
end
--- Set the @{path|current program path}.
--
-- Be careful to prefix directories with a `/`. Otherwise they will be searched
-- for from the @{shell.dir|current directory}, rather than the computer's root.
--
-- @tparam string path The new program path.
-- @since 1.2
function shell.setPath(path)
expect(1, path, "string")
sPath = path
end
--- Resolve a relative path to an absolute path.
--
-- The @{fs} and @{io} APIs work using absolute paths, and so we must convert
-- any paths relative to the @{dir|current directory} to absolute ones. This
-- does nothing when the path starts with `/`.
--
-- @tparam string path The path to resolve.
-- @usage Resolve `startup.lua` when in the `rom` folder.
--
-- shell.setDir("rom")
-- print(shell.resolve("startup.lua"))
-- -- => rom/startup.lua
function shell.resolve(path)
expect(1, path, "string")
local sStartChar = string.sub(path, 1, 1)
if sStartChar == "/" or sStartChar == "\\" then
return fs.combine("", path)
else
return fs.combine(sDir, path)
end
end
local function pathWithExtension(_sPath, _sExt)
local nLen = #sPath
local sEndChar = string.sub(_sPath, nLen, nLen)
-- Remove any trailing slashes so we can add an extension to the path safely
if sEndChar == "/" or sEndChar == "\\" then
_sPath = string.sub(_sPath, 1, nLen - 1)
end
return _sPath .. "." .. _sExt
end
--- Resolve a program, using the @{path|program path} and list of @{aliases|aliases}.
--
-- @tparam string command The name of the program
-- @treturn string|nil The absolute path to the program, or @{nil} if it could
-- not be found.
-- @since 1.2
-- @usage Locate the `hello` program.
--
-- shell.resolveProgram("hello")
-- -- => rom/programs/fun/hello.lua
function shell.resolveProgram(command)
expect(1, command, "string")
-- Substitute aliases firsts
if tAliases[command] ~= nil then
command = tAliases[command]
end
-- If the path is a global path, use it directly
if command:find("/") or command:find("\\") then
local sPath = shell.resolve(command)
if fs.exists(sPath) and not fs.isDir(sPath) then
return sPath
else
local sPathLua = pathWithExtension(sPath, "lua")
if fs.exists(sPathLua) and not fs.isDir(sPathLua) then
return sPathLua
end
end
return nil
end
-- Otherwise, look on the path variable
for sPath in string.gmatch(sPath, "[^:]+") do
sPath = fs.combine(shell.resolve(sPath), command)
if fs.exists(sPath) and not fs.isDir(sPath) then
return sPath
else
local sPathLua = pathWithExtension(sPath, "lua")
if fs.exists(sPathLua) and not fs.isDir(sPathLua) then
return sPathLua
end
end
end
-- Not found
return nil
end
--- Return a list of all programs on the @{shell.path|path}.
--
-- @tparam[opt] boolean include_hidden Include hidden files. Namely, any which
-- start with `.`.
-- @treturn { string } A list of available programs.
-- @usage textutils.tabulate(shell.programs())
-- @since 1.2
function shell.programs(include_hidden)
expect(1, include_hidden, "boolean", "nil")
local tItems = {}
-- Add programs from the path
for sPath in string.gmatch(sPath, "[^:]+") do
sPath = shell.resolve(sPath)
if fs.isDir(sPath) then
local tList = fs.list(sPath)
for n = 1, #tList do
local sFile = tList[n]
if not fs.isDir(fs.combine(sPath, sFile)) and
(include_hidden or string.sub(sFile, 1, 1) ~= ".") then
if #sFile > 4 and sFile:sub(-4) == ".lua" then
sFile = sFile:sub(1, -5)
end
tItems[sFile] = true
end
end
end
end
-- Sort and return
local tItemList = {}
for sItem in pairs(tItems) do
table.insert(tItemList, sItem)
end
table.sort(tItemList)
return tItemList
end
local function completeProgram(sLine)
local bIncludeHidden = settings.get("shell.autocomplete_hidden")
if #sLine > 0 and (sLine:find("/") or sLine:find("\\")) then
-- Add programs from the root
return fs.complete(sLine, sDir, {
include_files = true,
include_dirs = false,
include_hidden = bIncludeHidden,
})
else
local tResults = {}
local tSeen = {}
-- Add aliases
for sAlias in pairs(tAliases) do
if #sAlias > #sLine and string.sub(sAlias, 1, #sLine) == sLine then
local sResult = string.sub(sAlias, #sLine + 1)
if not tSeen[sResult] then
table.insert(tResults, sResult)
tSeen[sResult] = true
end
end
end
-- Add all subdirectories. We don't include files as they will be added in the block below
local tDirs = fs.complete(sLine, sDir, {
include_files = false,
include_dirs = false,
include_hidden = bIncludeHidden,
})
for i = 1, #tDirs do
local sResult = tDirs[i]
if not tSeen[sResult] then
table.insert (tResults, sResult)
tSeen [sResult] = true
end
end
-- Add programs from the path
local tPrograms = shell.programs()
for n = 1, #tPrograms do
local sProgram = tPrograms[n]
if #sProgram > #sLine and string.sub(sProgram, 1, #sLine) == sLine then
local sResult = string.sub(sProgram, #sLine + 1)
if not tSeen[sResult] then
table.insert(tResults, sResult)
tSeen[sResult] = true
end
end
end
-- Sort and return
table.sort(tResults)
return tResults
end
end
local function completeProgramArgument(sProgram, nArgument, sPart, tPreviousParts)
local tInfo = tCompletionInfo[sProgram]
if tInfo then
return tInfo.fnComplete(shell, nArgument, sPart, tPreviousParts)
end
return nil
end
--- Complete a shell command line.
--
-- This accepts an incomplete command, and completes the program name or
-- arguments. For instance, `l` will be completed to `ls`, and `ls ro` will be
-- completed to `ls rom/`.
--
-- Completion handlers for your program may be registered with
-- @{shell.setCompletionFunction}.
--
-- @tparam string sLine The input to complete.
-- @treturn { string }|nil The list of possible completions.
-- @see _G.read For more information about completion.
-- @see shell.completeProgram
-- @see shell.setCompletionFunction
-- @see shell.getCompletionInfo
-- @since 1.74
function shell.complete(sLine)
expect(1, sLine, "string")
if #sLine > 0 then
local tWords = tokenise(sLine)
local nIndex = #tWords
if string.sub(sLine, #sLine, #sLine) == " " then
nIndex = nIndex + 1
end
if nIndex == 1 then
local sBit = tWords[1] or ""
local sPath = shell.resolveProgram(sBit)
if tCompletionInfo[sPath] then
return { " " }
else
local tResults = completeProgram(sBit)
for n = 1, #tResults do
local sResult = tResults[n]
local sPath = shell.resolveProgram(sBit .. sResult)
if tCompletionInfo[sPath] then
tResults[n] = sResult .. " "
end
end
return tResults
end
elseif nIndex > 1 then
local sPath = shell.resolveProgram(tWords[1])
local sPart = tWords[nIndex] or ""
local tPreviousParts = tWords
tPreviousParts[nIndex] = nil
return completeProgramArgument(sPath , nIndex - 1, sPart, tPreviousParts)
end
end
return nil
end
--- Complete the name of a program.
--
-- @tparam string program The name of a program to complete.
-- @treturn { string } A list of possible completions.
-- @see cc.shell.completion.program
function shell.completeProgram(program)
expect(1, program, "string")
return completeProgram(program)
end
--- Set the completion function for a program. When the program is entered on
-- the command line, this program will be called to provide auto-complete
-- information.
--
-- The completion function accepts four arguments:
--
-- 1. The current shell. As completion functions are inherited, this is not
-- guaranteed to be the shell you registered this function in.
-- 2. The index of the argument currently being completed.
-- 3. The current argument. This may be the empty string.
-- 4. A list of the previous arguments.
--
-- For instance, when completing `pastebin put rom/st` our pastebin completion
-- function will receive the shell API, an index of 2, `rom/st` as the current
-- argument, and a "previous" table of `{ "put" }`. This function may then wish
-- to return a table containing `artup.lua`, indicating the entire command
-- should be completed to `pastebin put rom/startup.lua`.
--
-- You completion entries may also be followed by a space, if you wish to
-- indicate another argument is expected.
--
-- @tparam string program The path to the program. This should be an absolute path
-- _without_ the leading `/`.
-- @tparam function(shell: table, index: number, argument: string, previous: { string }):({ string }|nil) complete
-- The completion function.
-- @see cc.shell.completion Various utilities to help with writing completion functions.
-- @see shell.complete
-- @see _G.read For more information about completion.
-- @since 1.74
function shell.setCompletionFunction(program, complete)
expect(1, program, "string")
expect(2, complete, "function")
tCompletionInfo[program] = {
fnComplete = complete,
}
end
--- Get a table containing all completion functions.
--
-- This should only be needed when building custom shells. Use
-- @{setCompletionFunction} to add a completion function.
--
-- @treturn { [string] = { fnComplete = function } } A table mapping the
-- absolute path of programs, to their completion functions.
function shell.getCompletionInfo()
return tCompletionInfo
end
--- Returns the path to the currently running program.
--
-- @treturn string The absolute path to the running program.
-- @since 1.3
function shell.getRunningProgram()
if #tProgramStack > 0 then
return tProgramStack[#tProgramStack]
end
return nil
end
--- Add an alias for a program.
--
-- @tparam string command The name of the alias to add.
-- @tparam string program The name or path to the program.
-- @since 1.2
-- @usage Alias `vim` to the `edit` program
--
-- shell.setAlias("vim", "edit")
function shell.setAlias(command, program)
expect(1, command, "string")
expect(2, program, "string")
tAliases[command] = program
end
--- Remove an alias.
--
-- @tparam string command The alias name to remove.
function shell.clearAlias(command)
expect(1, command, "string")
tAliases[command] = nil
end
--- Get the current aliases for this shell.
--
-- Aliases are used to allow multiple commands to refer to a single program. For
-- instance, the `list` program is aliased to `dir` or `ls`. Running `ls`, `dir`
-- or `list` in the shell will all run the `list` program.
--
-- @treturn { [string] = string } A table, where the keys are the names of
-- aliases, and the values are the path to the program.
-- @see shell.setAlias
-- @see shell.resolveProgram This uses aliases when resolving a program name to
-- an absolute path.
function shell.aliases()
-- Copy aliases
local tCopy = {}
for sAlias, sCommand in pairs(tAliases) do
tCopy[sAlias] = sCommand
end
return tCopy
end
if multishell then
--- Open a new @{multishell} tab running a command.
--
-- This behaves similarly to @{shell.run}, but instead returns the process
-- index.
--
-- This function is only available if the @{multishell} API is.
--
-- @tparam string ... The command line to run.
-- @see shell.run
-- @see multishell.launch
-- @since 1.6
-- @usage Launch the Lua interpreter and switch to it.
--
-- local id = shell.openTab("lua")
-- shell.switchTab(id)
function shell.openTab(...)
local tWords = tokenise(...)
local sCommand = tWords[1]
if sCommand then
local sPath = shell.resolveProgram(sCommand)
if sPath == "rom/programs/shell.lua" then
return multishell.launch(createShellEnv("rom/programs"), sPath, table.unpack(tWords, 2))
elseif sPath ~= nil then
return multishell.launch(createShellEnv("rom/programs"), "rom/programs/shell.lua", sCommand, table.unpack(tWords, 2))
else
printError("No such program")
end
end
end
--- Switch to the @{multishell} tab with the given index.
--
-- @tparam number id The tab to switch to.
-- @see multishell.setFocus
-- @since 1.6
function shell.switchTab(id)
expect(1, id, "number")
multishell.setFocus(id)
end
end
local tArgs = { ... }
if #tArgs > 0 then
-- "shell x y z"
-- Run the program specified on the commandline
shell.run(...)
else
local function show_prompt()
term.setBackgroundColor(bgColour)
term.setTextColour(promptColour)
write(shell.dir() .. "> ")
term.setTextColour(textColour)
end
-- "shell"
-- Print the header
term.setBackgroundColor(bgColour)
term.setTextColour(promptColour)
print(os.version())
term.setTextColour(textColour)
-- Run the startup program
if parentShell == nil then
shell.run("/rom/startup.lua")
end
-- Read commands and execute them
local tCommandHistory = {}
while not bExit do
term.redirect(parentTerm)
if term.setGraphicsMode then term.setGraphicsMode(0) end
show_prompt()
local complete
if settings.get("shell.autocomplete") then complete = shell.complete end
local ok, result
local co = coroutine.create(read)
assert(coroutine.resume(co, nil, tCommandHistory, complete))
while coroutine.status(co) ~= "dead" do
local event = table.pack(os.pullEvent())
if event[1] == "file_transfer" then
-- Abandon the current prompt
local _, h = term.getSize()
local _, y = term.getCursorPos()
if y == h then
term.scroll(1)
term.setCursorPos(1, y)
else
term.setCursorPos(1, y + 1)
end
term.setCursorBlink(false)
-- Run the import script with the provided files
local ok, err = require("cc.internal.import")(event[2].getFiles())
if not ok and err then printError(err) end
-- And attempt to restore the prompt.
show_prompt()
term.setCursorBlink(true)
event = { "term_resize", n = 1 } -- Nasty hack to force read() to redraw.
end
if result == nil or event[1] == result or event[1] == "terminate" then
ok, result = coroutine.resume(co, table.unpack(event, 1, event.n))
if not ok then error(result, 0) end
end
end
if result:match("%S") and tCommandHistory[#tCommandHistory] ~= result then
table.insert(tCommandHistory, result)
end
shell.run(result)
end
end

View File

@@ -0,0 +1,228 @@
local bootLoader={...}
local MODE=bootLoader[1]
local apis=bootLoader[2]
local bootDisk=bootLoader[3]
local term=bootLoader[4]
local getFile=bootLoader[5]
local bootData
do
local tmp=load("return "..(getFile("/var/log/kernel/bootData").readAllText() or "{}"))
if not tmp then error("Bootdata failed to load") end
bootData=tmp()
end
local list=bootLoader[6]
local computer=bootLoader[7]
local startup=true
local osleep=sleep
_G._SYSDEBUG=bootData.debug
local drivers={}
local eventCache={}
while true do
local event={computer.getMachineEvent()}
if event[1]==nil then break end
eventCache[#eventCache+1] = event
end
term.clear()
term.print("Welcome to Hyperion OS")
term.print("Creating logger")
osleep(1)
local log=load(getFile("/sys/util/logger.lua").readAllText())(computer)
term.clear()
local logHook=log.setHook(term.print)
log.api.log("Created logger")
local function saveLog()
local logNum=bootData.logNum
getFile("/var/log/kernel/"..tostring(logNum)..".log").writeAllText(log.api.get())
getFile("/var/log/kernel/latest.log").writeAllText(log.api.get())
if bootData.logNum==10 then
bootData.logNum=0
else
bootData.logNum=bootData.logNum+1
end
end
if bootData.debug then _G.saveLog=saveLog 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) == "boolean" then
if v == true then
output=output.."true"
else
output=output.."false"
end
elseif type(v) == "function" then
output=output.."function()"
else
error("serialization of type \""..type(v).."\" is not supported")
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
-- Make PANIC
local function PANIC(err)
term.clear()
term.print(log.api.get())
saveLog()
if err==bootData.prevError then
bootData.errorCount=bootData.errorCount+1
else
bootData.prevError=err
bootData.errorCount=0
end
getFile("/var/log/kernel/bootData").writeAllText(t2t(bootData))
term.print("KERNEL PANIC: "..err)
term.print("Log saved to /var/log/kernel/"..tostring(bootData.logNum)..".log\n")
term.print("Press enter to continue...")
while true do
local event = {computer.getMachineEvent()}
if event[1]~=nil then
term.print(table.concat(event, " "))
end
if event[1] == "keyTyped" then
if event[3] == "\n" then
break
end
end
end
computer.reboot()
end
local function runAsKernel(path, ...)
local func, err = load(getFile(path).readAllText(), path, "t", _G)
if not func then return false, "\t"..err end
local ret = {xpcall(func, debug.traceback, ...)}
if not ret[1] then
return false, ret[2]
end
return true, table.unpack(ret, 2)
end
log.api.log("Loading globals...")
for i,v in ipairs(list("/sys/api/")) do
if bootData.debug then log.api.debug("Loading "..v) end
local ok, err = runAsKernel("/sys/api/"..v, getFile, log)
if not ok then log.api.warn(err) end
end
local driverutil={}
function driverutil.getFirst(type)
if drivers[type] then
if drivers[type][1] then
return drivers[type][1]
end
end
end
function driverutil.list(type)
if not type then
local tmp={}
for i,v in ipairs(drivers.raw) do
tmp[#tmp+1] = {type=v.type, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp[i].type, tmp[i].obj
end
else
local tmp={}
for i,v in ipairs(drivers[type]) do
tmp[#tmp+1] = {type=v.type, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp[i].type, tmp[i].obj
end
end
end
log.api.log("Loading drivers...")
for i,v in ipairs(list("/sys/modules/")) do
if bootData.debug then log.api.debug("Loading module "..v) end
local ok, err = runAsKernel("/sys/modules/"..v, apis, drivers, log, driverutil)
if not ok then log.api.warn("["..v.."] exited with ERR:\n"..err) end
end
log.api.log("Unloading non \""..MODE.."\" specific drivers...")
do
local tmp={}
for i,v in ipairs(drivers) do
if type(v.arch)=="table" then
for i2,v2 in ipairs(v.arch) do
if v2==MODE or v2=="ANY" then
tmp[#tmp+1] = v
end
end
else
if v.arch==MODE or v.arch=="ANY" then
tmp[#tmp+1] = v
end
end
end
drivers={}
drivers.raw=tmp
end
if bootData.debug then log.api.debug("Sorting drivers...") end
for i,v in ipairs(drivers.raw) do
if not drivers[v.type] then drivers[v.type]={} end
drivers[v.type][#drivers[v.type]+1] = v
end
if bootData.debug then log.api.debug("Initializing drivers...") end
for i,v in ipairs(drivers.raw) do
if v.init then
local ok, err = xpcall(v.init, debug.traceback)
if not ok then
log.api.warn("["..v.name.."]: Init function ERR:\n"..err)
if bootData.debug then log.api.debug("Removing driver ["..v.name.."]") end
table.remove(drivers.raw, i)
end
end
end
log.api.log("Loaded "..tostring(#drivers.raw).." drivers")
log.api.log("Loading filesystem...")
local ok, fs = runAsKernel("/sys/fs/init", drivers, log, bootDisk, driverutil)
if not ok then PANIC(fs) end
if not fs then PANIC("filesystem failed to load") end
fs.delete("/tmp")
fs.mkDir("/tmp")
log.api.log("Loading system...")
local ok, err = runAsKernel("/sys/Hyperion.sys", drivers, log)
if not ok then PANIC(err) end
local hyperion = err
if type(hyperion)~="function" then PANIC("Hyperion failed to load:\nHyperion was: "..tostring(hyperion)) end
hyperion(fs, log, drivers, PANIC, driverutil)
PANIC("OS EXITED MAIN()")

View File

@@ -0,0 +1,135 @@
local biosData = ({...})[1]
local apis = {}
local lua = {
coroutine = true,
debug = true,
_HOST = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = true,
getfenv = 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,
setfenv = true,
setmetatable = true,
string = true,
table = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true,
_G = true
}
local print=component.getFirst("screen").print
local comp=component
-- Sandbox globals
local _REAL_G = _G
local _PAIRS = pairs
if type(_REAL_G) ~= "table" then
error("Global environment (_G) is not a table")
end
for i, v in _PAIRS(_REAL_G) do
if not lua[i] then
apis[i] = v
_REAL_G[i] = nil
end
end
apis.component=comp
-- File abstraction compatible with open() -> {read,write,append}
local function getFile(path)
return {
readAllText = function()
local handle = biosData.bootDrive:open(path)
if not handle or type(handle.read) ~= "function" then
error("Cannot open file for reading: " .. tostring(path))
end
return handle.read() or ""
end,
writeAllText = function(text)
if not biosData.bootDrive:fileExists(path) then
biosData.bootDrive:createFile(path)
end
local handle = biosData.bootDrive:open(path)
if not handle or type(handle.write) ~= "function" then
error("Cannot open file for writing: " .. tostring(path))
end
handle.write(text)
end,
appendText = function(text)
local handle = biosData.bootDrive:open(path)
if not handle or type(handle.append) ~= "function" then
error("Cannot open file for appending: " .. tostring(path))
end
handle.append(text)
end
}
end
local function list(path)
return biosData.bootDrive:list(path)
end
function coroutine.resumeWithTimeout(CORO, LINES, ...)
local ret = { coroutine.resume(CORO, ...) }
if math.random(0, 1) == 0 then
return false, table.unpack(ret)
else
return true, table.unpack(ret)
end
end
-- Safety: verify APIs exist
if not apis.component then
error("Component API missing in environment")
end
if not biosData.bootDrive then
error("bootDrive missing from biosData")
end
local computer = apis.component.getFirst("computer")
-- Read kernel file correctly
local kernelSource = getFile("/boot/Hyprkrnl.sys").readAllText()
if not kernelSource or kernelSource == "" then
error("Kernel file empty or unreadable")
end
local kernel, err = load(kernelSource, "@kernel", "t", _G)
if not kernel then
error("Failed to load kernel: " .. tostring(err))
end
-- Run kernel safely
local ok, perr = xpcall(function()
kernel(
"ac",
apis,
biosData.bootDrive.id,
apis.component.getFirst("screen"),
getFile,
list,
apis.component.getFirst("computer")
)
end, debug.traceback)
if not ok then
error("Kernel execution failed: " .. tostring(perr))
end

View File

@@ -0,0 +1,119 @@
-- 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
local args = {...}
if _HOST:find("UnBIOS") then return end
local keptAPIs = {keys=true, 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}
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
_G._HOST = _G._HOST .. " (UnBIOS)"
-- 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("/disk/boot/cc/preboot.cc", "r")
if file == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not find /boot/cc/bootloader.cc. 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(), "@preboot.cc")
file.close()
if fn == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not load /boot/cc/bootloader.cc. 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(table.unpack(args))
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

View File

@@ -0,0 +1,236 @@
local apis={}
local lua = {
coroutine = true,
debug = true,
_HOST = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = true,
getfenv = 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,
setfenv = true,
setmetatable = true,
string = true,
table = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true,
_G=true
}
for i,v in pairs(_G) do
if not lua[i] or lua[i]==nil then
apis[i]=v
_G[i]=nil
end
end
function sleep(time)
coroutine.yield("CC_TIMER", time)
end
local function catErr(text)
apis.term.setCursorPos(1,1)
apis.term.write(text)
while true do
coroutine.yield()
end
end
local function getFile(path)
if path:sub(1,1) ~= "/" then
path="/"..path
end
path="/disk"..path
if not apis.fs.exists(path) then error("File does not exist") end
if apis.fs.isDir(path) then error("Cannot open a directory") end
return {
readAllText=function()
local file = apis.fs.open(path, "r")
local text = file.readAll()
file.close()
return text
end,
writeAllText=function(text)
local file = apis.fs.open(path, "w")
file.write(text)
file.close()
end
}
end
-- Prints text handling \n, \t, and \b with scrolling (no wrapping)
local function write(text)
local x, y = apis.term.getCursorPos()
local w, h = apis.term.getSize()
for i = 1, #text do
local c = text:sub(i, i)
if c == "\n" then
y = y + 1
x = 1
elseif c == "\t" then
local tabSize = 4
local spaces = tabSize - ((x - 1) % tabSize)
apis.term.write(string.rep(" ", spaces))
x = x + spaces
elseif c == "\b" then
if x > 1 then
x = x - 1
apis.term.setCursorPos(x, y)
apis.term.write(" ")
apis.term.setCursorPos(x, y)
end
else
if x <= w and y <= h then
apis.term.setCursorPos(x, y)
apis.term.write(c)
x = x + 1
end
end
-- Handle scrolling if we go past bottom
if y > h then
apis.term.scroll(1)
y = h
apis.term.setCursorPos(x, y)
end
end
apis.term.setCursorPos(x, y)
end
local event_queue = {}
local function addEventRaw(...)
event_queue[#event_queue+1] = {...}
end
local function getEvent()
local event = event_queue[1]
event_queue = {table.unpack(event_queue, 2)}
return table.unpack(event or {})
end
local lkeys={}
lkeys[apis.keys.enter]="\n"
lkeys[apis.keys.backspace]="\b"
lkeys[apis.keys.tab]="\t"
local computer={}
computer.beep=function() end
computer.shutdown=apis.os.shutdown
computer.reboot=apis.os.reboot
computer.time=function()
return apis.os.epoch("utc")
end
computer.getMachineEvent=getEvent
computer.date=apis.os.date
local function list(path)
if path:sub(1,1) ~= "/" then
path="/"..path
end
path="/disk"..path
if not apis.fs.isDir(path) then return {} end
return apis.fs.list(path)
end
function coroutine.resumeWithTimeout(CORO, LINES, ...)
local yeildKey = {}
debug.sethook(CORO, function()
coroutine.yield(yeildKey)
end, "l", LINES)
local ret = {coroutine.resume(CORO, ...)}
debug.sethook(CORO)
if ret[2]==yeildKey then return false else return true, table.unpack(ret, 2) end
end
local kernel = load(getFile("/boot/Hyprkrnl.sys").readAllText(), "@kernel", "t", _G)
if not kernel then
catErr("KERNEL COMPILE ERR")
end
local kernel_coro = coroutine.create(function()
local ok,err = pcall(function()
local ok, err=xpcall(kernel, debug.traceback, "cc", apis, "disk", {
print=function(text)
write(text.."\n")
end,
printInline=function(text)
write(text)
end,
clear=function()
apis.term.clear()
apis.term.setCursorPos(1,1)
end,
getSize=function ()
return apis.term.getSize()
end
}, getFile, list, computer)
if not ok then
write(err)
while true do
coroutine.yield()
end
end
end)
if not ok then
catErr(err)
end
end)
apis.term.setCursorBlink(false)
while true do
local ret = {coroutine.resumeWithTimeout(kernel_coro, 200)}
if coroutine.status(kernel_coro) == "dead" then
catErr("KERNEL EXITED")
end
if ret[1] then
if ret[2]=="CC_TIMER" and ret[3]~=nil and type(ret[3])=="number" then
local timer = apis.os.startTimer(ret[3])
repeat
local _, param = coroutine.yield("timer")
until param == timer
end
end
apis.os.queueEvent("nosleep")
local exit = false
repeat
local event = {coroutine.yield()}
if event[1] == "nosleep" then
exit=true
elseif event[1]==nil then
elseif event[1]=="key" then
addEventRaw("keyPressed", 1, event[2])
if lkeys[event[2]] then
addEventRaw("keyTyped", 1, lkeys[event[2]])
end
elseif event[1]=="char" then
addEventRaw("keyTyped", 1, event[2])
elseif event[1]=="key_up" then
addEventRaw("keyReleased", 1, event[2])
elseif event[1]=="disk" then
addEventRaw("componentAdded", "disk")
elseif event[1]=="disk_eject" then
addEventRaw("componentRemoved", "disk")
end
until exit
end
apis.os.reboot()

3435
src/disks/1h/lib/LibDeflate Normal file

File diff suppressed because it is too large Load Diff

View File

View File

10
src/disks/1h/lib/array/x Normal file
View File

@@ -0,0 +1,10 @@
local lib = {}
function lib.create()
local array = {}
return setmetatable(array,{
__add=function(t1, t2)
end
})
end

View File

View File

0
src/disks/1h/sbin/init Normal file
View File

View File

@@ -0,0 +1,22 @@
local args={...}
local fs=args[1]
local log=args[2]
local drivers=args[3]
local PANIC=args[4]
local driverutil=args[5]
local sys={}
local task={}
sys._VERSION = "HyperionOS V1.0.4"
local function run(file, args)
local func, err=fs.loadAsFunc(file)
if not file then return 8, err end
local ret={xpcall(func, debug.traceback, table.unpack(args))}
if not ret[1] then return 1, ret[2] end
return 0, table.unpack(ret, 2)
end
local exitcode, req=run("/sys/system/require", {sys})
if exitcode~=0 then PANIC(req) end
_G.require=req

View File

@@ -0,0 +1,57 @@
-- 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(str, ...)
return table.concat(table.pack(str, ...))
end
function string.delim(str, ...)
return table.concat(table.pack(...), str)
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

View File

@@ -0,0 +1,81 @@
-- 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
local function serialize(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..serialize(v)
end
elseif type(v) == "string" then
output=output.."[=["..v.."]=]"
elseif type(v) == "number" then
output=output..tostring(v)
elseif type(v) == "boolean" then
if v == true then
output=output.."true"
else
output=output.."false"
end
elseif type(v) == "function" then
output=output.."function() end"
else
error("serialization of type \""..type(v).."\" is not supported")
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
table.serialize=serialize

124
src/disks/1h/sys/fs/init Normal file
View File

@@ -0,0 +1,124 @@
local args={...}
local drivers=args[1]
local log=args[2]
local bootDisk=args[3]
local driverutil=args[4]
local wd="/"
log.api.log("Bootdrive is "..bootDisk)
if not drivers.disk then
error("WTF") -- ???
end
local disks={}
local mounts={
["/"]=bootDisk
}
local meta={}
local function refreshDisks()
local diskstmp={}
local tmp={}
for i,v in driverutil.list("disk") do
tmp[#tmp+1] = v
end
for _,d in ipairs(tmp) do
for i,v in d.api.list() do
if diskstmp[i]==nil then
diskstmp[i]=v
end
end
end
disks=diskstmp
end
refreshDisks()
--[[
meta=load("return "..(disks[bootDisk].readAllText("/sys/fs/meta.ltn") or "{}"), "meta")()
if not meta then error("Meta failed to load") end
]]
local function resolve(path)
if path:sub(1,1)~="/" then path=wd..path end
local currmatch="/"
for i,_ in pairs(mounts) do
if string.hasPrefix(path, i) then
if #i>#currmatch then
currmatch=i
end
end
end
local drive=disks[mounts[currmatch]]
local newPath=string.getSuffix(path, currmatch)
return drive, newPath
end
local fs={}
function fs.list(path)
local drive, newPath = resolve(path)
return drive.list(newPath)
end
function fs.readAllText(path)
local drive, newPath = resolve(path)
return drive.readAllText(newPath)
end
function fs.writeAllText(path, content)
local drive, newPath = resolve(path)
return drive.writeAllText(newPath, content)
end
function fs.delete(path)
local drive, newPath = resolve(path)
return drive.delete(newPath)
end
function fs.exists(path)
local drive, newPath = resolve(path)
return (drive.fileExists(newPath) or drive.directoryExists(newPath))
end
function fs.fileExists(path)
local drive, newPath = resolve(path)
return drive.fileExists(newPath)
end
function fs.directoryExists(path)
local drive, newPath = resolve(path)
return drive.directoryExists(newPath)
end
function fs.createFile(path)
local drive, newPath = resolve(path)
return drive.makeFile(newPath)
end
function fs.createDirectory(path)
local drive, newPath = resolve(path)
return drive.makeDirectory(newPath)
end
fs.mkDir=fs.createDirectory
fs.mkFile=fs.createFile
fs.isDir=fs.directoryExists
fs.isFile=fs.fileExists
function fs.getWorkingDir()
return wd
end
function fs.setWorkingDir(dir)
if type(dir)~="string" then error("Invailid path") end
if dir:sub(1,1)~="/" then dir=wd..dir end
if dir:sub(#dir,#dir)~="/" then dir=dir.."/" end
if not fs.isDir(dir) then error("Invailid path") end
end
function fs.loadAsFunc(path)
local file = fs.readAllText(path)
return load(file, path, "t", setmetatable({},{
__index=_G,
__metatable=false
}))
end
return fs

View File

@@ -0,0 +1,69 @@
{["/sys/util/logger.lua"]={["p"]=21,["o"]=0,["g"]=0}
,["/bin/hex.lua"]={["p"]=21,["o"]=0,["g"]=0}
,["/opt"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/modules/cc.component.kd"]={["p"]=21,["o"]=0,["g"]=0}
,["/opt/astronand/ZDelta/init"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/api"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/10.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/7.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/1.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/bin/BASIC"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot/cc/preboot.cc"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot/ac"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/fs/init"]={["p"]=21,["o"]=0,["g"]=0}
,["/lib"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/api/table.lua"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/5.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/usr/share/doc"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/3.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/opt/astronand/ZDelta"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/hypervisor/init.sys"]={["p"]=21,["o"]=0,["g"]=0}
,["/usr/share"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/modules"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/6.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/hypervisor"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/4.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/lib/array/math"]={["p"]=21,["o"]=0,["g"]=0}
,["/var"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/util/conhost.lua"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot/Hyprkrnl.sys"]={["p"]=21,["o"]=0,["g"]=0}
,["/bin"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/modules/ac.disks.kd"]={["p"]=21,["o"]=0,["g"]=0}
,["/lib/array/x"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/modules/cc.disks.kd"]={["p"]=21,["o"]=0,["g"]=0}
,["/opt/astronand/dbg"]={["p"]=21,["o"]=0,["g"]=0}
,["/usr"]={["p"]=21,["o"]=0,["g"]=0}
,["/usr/share/doc/kernel/drivers"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/util"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/8.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/9.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/latest.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/lib/array"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot/cc/boot.cc"]={["p"]=21,["o"]=0,["g"]=0}
,["/home"]={["p"]=21,["o"]=0,["g"]=0}
,["/usr/share/doc/kernel/drivers/disk.md"]={["p"]=21,["o"]=0,["g"]=0}
,["/lib/LibDeflate"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/fs/meta.ltn"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/0.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/bootData"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/api/string.lua"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log"]={["p"]=21,["o"]=0,["g"]=0}
,["/bin/shell.hex"]={["p"]=21,["o"]=0,["g"]=0}
,["/opt/astronand/dbg/init"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot/bootloader.sys"]={["p"]=21,["o"]=0,["g"]=0}
,["/lib/array/2d"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot/cc"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot/ac/boot.ac"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/log/kernel/2.log"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/modules/ccpc.disk.kd"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/api/require.lua"]={["p"]=21,["o"]=0,["g"]=0}
,["/bin/lua.lua"]={["p"]=21,["o"]=0,["g"]=0}
,["/usr/share/doc/kernel"]={["p"]=21,["o"]=0,["g"]=0}
,["/boot"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/fs"]={["p"]=21,["o"]=0,["g"]=0}
,["/var/system"]={["p"]=21,["o"]=0,["g"]=0}
,["/sys/modules/cc.terminal.kd"]={["p"]=21,["o"]=0,["g"]=0}
,["/opt/astronand"]={["p"]=21,["o"]=0,["g"]=0}
}

View File

@@ -0,0 +1,75 @@
local kernelArgs={...}
local apis=kernelArgs[1]
local drivers=kernelArgs[2]
local log=kernelArgs[3]
local driver={}
local disks = {}
driver.type = "disk"
driver.name = "AC:Disk"
driver.version = "1.0.0"
driver.apiVersion = 1
driver.description = "Driver for AC disks"
driver.arch = "ac"
driver.api = {}
local function refreshDisks()
local tmp={}
for i,v in apis.component.list() do
if i=="disk" then
tmp[v.id]={
readAllText=function(path)
return v:open(path).read()
end,
writeAllText=function(path, content)
return v:open(path).write(content)
end,
list=function(path)
return v:list(path)
end,
delete=function(path)
return v:delete(path)
end,
makeDirectory=function(path)
return v:makeDirectory(path)
end,
makeFile=function(path)
return v:makeFile(path)
end,
directoryExists=function(path)
return v:directoryExists(path)
end,
fileExists=function(path)
return v:fileExists(path)
end
}
end
end
disks=tmp
end
function driver.init()
refreshDisks()
end
function driver.api.list()
local tmp={}
for i,v in pairs(disks) do
tmp[#tmp+1]={id=i, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp.id, tmp.obj
end
end
function driver.main()
while true do
refreshDisks()
sleep(5)
end
end
drivers[#drivers+1]=driver

View File

@@ -0,0 +1,100 @@
local kernelArgs={...}
local apis=kernelArgs[1]
local drivers=kernelArgs[2]
local log=kernelArgs[3]
local driver={}
local disks={}
local driverutil=kernelArgs[4]
driver.type = "disk"
driver.name = "CC:Disks"
driver.version = "1.0.0"
driver.apiVersion = 1
driver.description = "Driver for CC:Tweaked disks"
driver.arch = "cc"
driver.api = {}
local function abs(path)
if path:sub(1,1)~="/" then path="/"..path end
return path
end
local function newDisk(root)
root="/"..root
return {
readAllText=function(path)
local file=apis.fs.open(root..abs(path),"r")
local text=file.readAll()
file.close()
return text
end,
writeAllText=function(path, content)
local file=apis.fs.open(root..abs(path),"w")
file.write(content)
file.close()
end,
list=function(path)
return apis.fs.list(root..abs(path))
end,
delete=function(path)
return apis.fs.delete(root..abs(path))
end,
makeDirectory=function(path)
return apis.fs.makeDir(root..abs(path))
end,
makeFile=function(path)
local file=apis.fs.open(root..abs(path),"w")
file.close()
end,
directoryExists=function(path)
return apis.fs.exists(root..abs(path)) and apis.fs.isDir(root..abs(path))
end,
fileExists=function(path)
return apis.fs.exists(root..abs(path)) and not apis.fs.isDir(root..abs(path))
end
}
end
local function refreshDisks(peripheral)
local tmp2={}
tmp2["disk"]=newDisk("disk")
for i,v in ipairs(peripheral.api.getNames()) do
if peripheral.api.isType(v, "drive") then
local p=peripheral.api.wrap(v)
if p.isDiskPresent() then
if p.getMountPath()~="disk" then
tmp2["disk_"..p.getID()] = newDisk(p.getMountPath())
end
end
end
end
disks=tmp2
return true
end
function driver.init()
local peripheral=driverutil.getFirst("component")
refreshDisks(peripheral)
end
function driver.api.list()
local tmp={}
for i,v in pairs(disks) do
tmp[#tmp+1]={id=i, obj=v}
end
local i=0
return function()
i=i+1
if tmp[i]==nil then return end
return tmp[i].id, tmp[i].obj
end
end
function driver.main()
while true do
refreshDisks()
sleep(5)
end
end
drivers[#drivers+1] = driver

View File

@@ -0,0 +1,129 @@
local kernelArgs={...}
local apis=kernelArgs[1]
local drivers=kernelArgs[2]
local log=kernelArgs[3]
local driver={}
driver.type = "component"
driver.name = "CC:Periph"
driver.version = "1.0.0"
driver.apiVersion = 1
driver.description = "Driver for CC:Tweaked peripherals"
driver.arch = "cc"
driver.api = {}
local native,sides
if apis.peripheral then
native = apis.peripheral
sides = apis.rs.getSides()
end
function driver.api.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 driver.api.getType(peripheral)
if type(peripheral) == "string" then -- Peripheral name passed
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 driver.api.isType(peripheral, peripheral_type)
if type(peripheral) == "string" then -- Peripheral name passed
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 driver.api.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 driver.api.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 driver.api.wrap(name)
local methods = driver.api.getMethods(name)
if not methods then
return nil
end
local types = { driver.api.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 driver.api.call(name, method, ...)
end
end
return result
end
drivers[#drivers+1] = driver

View File

@@ -0,0 +1,74 @@
local kernelArgs={...}
local apis=kernelArgs[1]
local drivers=kernelArgs[2]
local log=kernelArgs[3]
local driver={}
driver.type = "terminal"
driver.name = "CC:Term"
driver.version = "1.0.0"
driver.apiVersion = 1
driver.description = "Driver for CC:Tweaked screens"
driver.arch = "cc"
driver.api = {}
-- Prints text handling \n, \t, and \b with scrolling (no wrapping)
local function write(text)
local x, y = apis.term.getCursorPos()
local w, h = apis.term.getSize()
for i = 1, #text do
local c = text:sub(i, i)
if c == "\n" then
y = y + 1
x = 1
elseif c == "\t" then
local tabSize = 4
local spaces = tabSize - ((x - 1) % tabSize)
apis.term.write(string.rep(" ", spaces))
x = x + spaces
elseif c == "\b" then
if x > 1 then
x = x - 1
apis.term.setCursorPos(x, y)
apis.term.write(" ")
apis.term.setCursorPos(x, y)
end
else
if x <= w and y <= h then
apis.term.setCursorPos(x, y)
apis.term.write(c)
x = x + 1
end
end
-- Handle scrolling if we go past bottom
if y > h then
apis.term.scroll(1)
y = h
apis.term.setCursorPos(x, y)
end
end
apis.term.setCursorPos(x, y)
end
function driver.api.print(text)
write(text.."\n")
end
function driver.api.printInline(text)
write(text)
end
function driver.api.clear()
apis.term.clear()
apis.term.setCursorPos(1,1)
end
function driver.api.getSize()
return apis.term.getSize()
end
drivers[#drivers+1] = driver

View File

View File

View File

View File

@@ -0,0 +1,3 @@
-- <!ARCH>
-- @ICON$101003000000000000092492492490080000000010082000000010080400000010080080000010080400000010082002492010080000000010092492492490000000000000092492492490080000000010080000000010092492492490000000000000

View File

@@ -0,0 +1,70 @@
local args={...}
local computer=args[1]
local logs={["nil"]=""}
local hooks={["nil"]=function()end}
local log={api={}}
local function convert_epoch(epoch)
return computer.date("[%b %d %H:%M:%S]", epoch/1000)
end
function log.getProcess(func)
if type(func)=="function" then
log.getProcess=func
else
return "Hyprkrnl"
end
end
function log.api.log(text, logID)
local appendedText=convert_epoch(computer.time()).." "..log.getProcess()..":[IN] "..text
logs[tostring(logID)]=logs[tostring(logID)]..appendedText.."\n"
hooks[tostring(logID)](appendedText)
end
function log.api.warn(text, logID)
local appendedText=convert_epoch(computer.time()).." "..log.getProcess()..":[WN] "..text
logs[tostring(logID)]=logs[tostring(logID)]..appendedText.."\n"
hooks[tostring(logID)](appendedText)
end
function log.api.fail(text, logID)
local appendedText=convert_epoch(computer.time()).." "..log.getProcess()..":[FA] "..text
logs[tostring(logID)]=logs[tostring(logID)]..appendedText.."\n"
hooks[tostring(logID)](appendedText)
end
function log.api.debug(text, logID)
local appendedText=convert_epoch(computer.time()).." "..log.getProcess()..":[DE] "..text
logs[tostring(logID)]=logs[tostring(logID)]..appendedText.."\n"
hooks[tostring(logID)](appendedText)
end
function log.api.error(text, logID)
local appendedText=convert_epoch(computer.time()).." "..log.getProcess()..":[ER] "..text
logs[tostring(logID)]=logs[tostring(logID)]..appendedText.."\n"
hooks[tostring(logID)](appendedText)
end
function log.api.get(logID)
return logs[tostring(logID)]
end
function log.setHook(func, logID)
hooks[tostring(logID)]=func
return {
removeHook=function()
hooks[tostring(logID)]=function()end
end
}
end
local UUID = 0
function log.api.createLog(logID)
if logs[tostring(logID)]~=nil then error("cannot create duplicate log") end
if logID==nil then UUID=UUID+1; logID=UUID end
hooks[tostring(logID)]=function()end
logs[tostring(logID)]=""
end
return log

View File

@@ -0,0 +1,6 @@
### API:
---
```
getDisks():id, obj
```

View File

@@ -0,0 +1,17 @@
[Oct 31 18:33:08] Hyprkrnl:[IN] Created logger
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading globals...
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading string.lua
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading table.lua
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading drivers...
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 31 18:33:08] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 31 18:33:08] Hyprkrnl:[DE] Sorting drivers...
[Oct 31 18:33:08] Hyprkrnl:[DE] Initializing drivers...
[Oct 31 18:33:08] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading filesystem...
[Oct 31 18:33:08] Hyprkrnl:[IN] Bootdrive is disk
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading system...

View File

@@ -0,0 +1,19 @@
[Oct 24 14:20:21] Hyprkrnl:[IN] Created logger
[Oct 24 14:20:21] Hyprkrnl:[IN] Loading globals...
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading require.lua
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading string.lua
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading table.lua
[Oct 24 14:20:21] Hyprkrnl:[IN] Loading drivers...
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 24 14:20:21] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 24 14:20:21] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 24 14:20:21] Hyprkrnl:[DE] Sorting drivers...
[Oct 24 14:20:21] Hyprkrnl:[DE] Initializing drivers...
[Oct 24 14:20:21] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 24 14:20:21] Hyprkrnl:[IN] Loading filesystem...
[Oct 24 14:20:21] Hyprkrnl:[IN] Bootdrive is disk
[Oct 24 14:20:21] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 24 14:20:21] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,17 @@
[Oct 30 18:13:15] Hyprkrnl:[IN] Created logger
[Oct 30 18:13:15] Hyprkrnl:[IN] Loading globals...
[Oct 30 18:13:15] Hyprkrnl:[DE] Loading string.lua
[Oct 30 18:13:15] Hyprkrnl:[DE] Loading table.lua
[Oct 30 18:13:15] Hyprkrnl:[IN] Loading drivers...
[Oct 30 18:13:15] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 30 18:13:15] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 30 18:13:15] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 30 18:13:15] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 30 18:13:15] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 30 18:13:15] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 30 18:13:15] Hyprkrnl:[DE] Sorting drivers...
[Oct 30 18:13:15] Hyprkrnl:[DE] Initializing drivers...
[Oct 30 18:13:15] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 30 18:13:15] Hyprkrnl:[IN] Loading filesystem...
[Oct 30 18:13:15] Hyprkrnl:[IN] Bootdrive is disk
[Oct 30 18:13:15] Hyprkrnl:[IN] Loading system...

View File

@@ -0,0 +1,19 @@
[Oct 29 21:46:16] Hyprkrnl:[IN] Created logger
[Oct 29 21:46:17] Hyprkrnl:[IN] Loading globals...
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading require.lua
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading string.lua
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading table.lua
[Oct 29 21:46:17] Hyprkrnl:[IN] Loading drivers...
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 29 21:46:17] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 29 21:46:17] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 29 21:46:17] Hyprkrnl:[DE] Sorting drivers...
[Oct 29 21:46:17] Hyprkrnl:[DE] Initializing drivers...
[Oct 29 21:46:17] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 29 21:46:17] Hyprkrnl:[IN] Loading filesystem...
[Oct 29 21:46:17] Hyprkrnl:[IN] Bootdrive is disk
[Oct 29 21:46:17] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 29 21:46:17] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,19 @@
[Oct 29 21:46:38] Hyprkrnl:[IN] Created logger
[Oct 29 21:46:38] Hyprkrnl:[IN] Loading globals...
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading require.lua
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading string.lua
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading table.lua
[Oct 29 21:46:38] Hyprkrnl:[IN] Loading drivers...
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 29 21:46:38] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 29 21:46:38] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 29 21:46:38] Hyprkrnl:[DE] Sorting drivers...
[Oct 29 21:46:38] Hyprkrnl:[DE] Initializing drivers...
[Oct 29 21:46:38] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 29 21:46:38] Hyprkrnl:[IN] Loading filesystem...
[Oct 29 21:46:38] Hyprkrnl:[IN] Bootdrive is disk
[Oct 29 21:46:38] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 29 21:46:38] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,19 @@
[Oct 30 17:41:54] Hyprkrnl:[IN] Created logger
[Oct 30 17:41:54] Hyprkrnl:[IN] Loading globals...
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading require.lua
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading string.lua
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading table.lua
[Oct 30 17:41:54] Hyprkrnl:[IN] Loading drivers...
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 30 17:41:54] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 30 17:41:54] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 30 17:41:54] Hyprkrnl:[DE] Sorting drivers...
[Oct 30 17:41:54] Hyprkrnl:[DE] Initializing drivers...
[Oct 30 17:41:54] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 30 17:41:54] Hyprkrnl:[IN] Loading filesystem...
[Oct 30 17:41:54] Hyprkrnl:[IN] Bootdrive is disk
[Oct 30 17:41:54] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 30 17:41:54] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,19 @@
[Oct 30 17:43:09] Hyprkrnl:[IN] Created logger
[Oct 30 17:43:09] Hyprkrnl:[IN] Loading globals...
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading require.lua
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading string.lua
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading table.lua
[Oct 30 17:43:09] Hyprkrnl:[IN] Loading drivers...
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 30 17:43:09] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 30 17:43:09] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 30 17:43:09] Hyprkrnl:[DE] Sorting drivers...
[Oct 30 17:43:09] Hyprkrnl:[DE] Initializing drivers...
[Oct 30 17:43:09] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 30 17:43:09] Hyprkrnl:[IN] Loading filesystem...
[Oct 30 17:43:09] Hyprkrnl:[IN] Bootdrive is disk
[Oct 30 17:43:09] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 30 17:43:09] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,19 @@
[Oct 30 17:44:55] Hyprkrnl:[IN] Created logger
[Oct 30 17:44:55] Hyprkrnl:[IN] Loading globals...
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading require.lua
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading string.lua
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading table.lua
[Oct 30 17:44:55] Hyprkrnl:[IN] Loading drivers...
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 30 17:44:55] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 30 17:44:55] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 30 17:44:55] Hyprkrnl:[DE] Sorting drivers...
[Oct 30 17:44:55] Hyprkrnl:[DE] Initializing drivers...
[Oct 30 17:44:55] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 30 17:44:55] Hyprkrnl:[IN] Loading filesystem...
[Oct 30 17:44:55] Hyprkrnl:[IN] Bootdrive is disk
[Oct 30 17:44:55] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 30 17:44:55] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,19 @@
[Oct 30 17:45:15] Hyprkrnl:[IN] Created logger
[Oct 30 17:45:15] Hyprkrnl:[IN] Loading globals...
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading require.lua
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading string.lua
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading table.lua
[Oct 30 17:45:15] Hyprkrnl:[IN] Loading drivers...
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 30 17:45:15] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 30 17:45:15] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 30 17:45:15] Hyprkrnl:[DE] Sorting drivers...
[Oct 30 17:45:15] Hyprkrnl:[DE] Initializing drivers...
[Oct 30 17:45:15] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 30 17:45:15] Hyprkrnl:[IN] Loading filesystem...
[Oct 30 17:45:15] Hyprkrnl:[IN] Bootdrive is disk
[Oct 30 17:45:15] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 30 17:45:15] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,19 @@
[Oct 30 18:02:54] Hyprkrnl:[IN] Created logger
[Oct 30 18:02:54] Hyprkrnl:[IN] Loading globals...
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading require.lua
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading string.lua
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading table.lua
[Oct 30 18:02:54] Hyprkrnl:[IN] Loading drivers...
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 30 18:02:54] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 30 18:02:54] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 30 18:02:54] Hyprkrnl:[DE] Sorting drivers...
[Oct 30 18:02:54] Hyprkrnl:[DE] Initializing drivers...
[Oct 30 18:02:54] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 30 18:02:54] Hyprkrnl:[IN] Loading filesystem...
[Oct 30 18:02:54] Hyprkrnl:[IN] Bootdrive is disk
[Oct 30 18:02:54] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 30 18:02:54] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,19 @@
[Oct 30 18:03:46] Hyprkrnl:[IN] Created logger
[Oct 30 18:03:46] Hyprkrnl:[IN] Loading globals...
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading require.lua
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading string.lua
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading table.lua
[Oct 30 18:03:46] Hyprkrnl:[IN] Loading drivers...
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 30 18:03:46] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 30 18:03:46] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 30 18:03:46] Hyprkrnl:[DE] Sorting drivers...
[Oct 30 18:03:46] Hyprkrnl:[DE] Initializing drivers...
[Oct 30 18:03:46] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 30 18:03:46] Hyprkrnl:[IN] Loading filesystem...
[Oct 30 18:03:46] Hyprkrnl:[IN] Bootdrive is disk
[Oct 30 18:03:46] Hyprkrnl:[IN] [REQUIRE]: Initialized FS
[Oct 30 18:03:46] Hyprkrnl:[IN] Loading hypervisor...

View File

@@ -0,0 +1,2 @@
{["debug"]=true,["errorCount"]=1,["logNum"]=1,["prevError"]=[=[Hyperion failed to load:
Hyperion was: nil]=]}

View File

@@ -0,0 +1,17 @@
[Oct 31 18:33:08] Hyprkrnl:[IN] Created logger
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading globals...
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading string.lua
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading table.lua
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading drivers...
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module ac.disks.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module cc.disks.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module cc.periph.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module cc.terminal.kd
[Oct 31 18:33:08] Hyprkrnl:[DE] Loading module ccpc.disk.kd
[Oct 31 18:33:08] Hyprkrnl:[IN] Unloading non "cc" specific drivers...
[Oct 31 18:33:08] Hyprkrnl:[DE] Sorting drivers...
[Oct 31 18:33:08] Hyprkrnl:[DE] Initializing drivers...
[Oct 31 18:33:08] Hyprkrnl:[IN] Loaded 3 drivers
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading filesystem...
[Oct 31 18:33:08] Hyprkrnl:[IN] Bootdrive is disk
[Oct 31 18:33:08] Hyprkrnl:[IN] Loading system...

14
src/disks/2f/burn.lua Normal file
View File

@@ -0,0 +1,14 @@
local biosData = ({...})[1]
local disks = {}
for i,v in component.list() do
if i == "disk" then
disks[v.id]=v
end
end
local bootDisk = disks[biosData.bootDrive.open("/config").read()]
if not bootDisk.type=="udd" then
error("invalid")
end

1
src/disks/2f/config Normal file
View File

@@ -0,0 +1 @@
disk_56

View File

View File

@@ -0,0 +1,50 @@
local biosData = ({...})[1]
local apis={}
local lua = {
coroutine = true,
debug = true,
_HOST = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = true,
getfenv = 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,
setfenv = true,
setmetatable = true,
string = true,
table = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true
}
for i,v in ipairs(_G) do
if not lua[i] then
apis[i]=v
_G[i]=nil
end
end
local function getFile(path)
return biosData.bootDrive:open(path).read()
end
local computer = apis.component.getFirst("computer")
local kernel = load(getFile("/boot/Hyprkrnl.sys"), "@kernel", "t", _G)
kernel("ac", apis, biosData.bootDrive.id, apis.component.getFirst("screen"), computer.getMachineEvent)

View File

@@ -0,0 +1,119 @@
-- 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 = {keys=true, 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}
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
_G._HOST = _G._HOST .. " (UnBIOS)"
-- 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("/boot/cc/bootloader.cc", "r")
if file == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not find /boot/cc/bootloader.cc. 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(), "@bootloader.cc")
file.close()
if fn == nil then
term.setCursorBlink(false)
term.setTextColor(16384)
term.write("Could not load /boot/cc/bootloader.cc. 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()
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
os.shutdown()

View File

@@ -0,0 +1,115 @@
local apis={}
local lua = {
coroutine = true,
debug = true,
_HOST = true,
_VERSION = true,
assert = true,
collectgarbage = true,
error = true,
gcinfo = true,
getfenv = 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,
setfenv = true,
setmetatable = true,
string = true,
table = true,
tonumber = true,
tostring = true,
type = true,
xpcall = true
}
for i,v in ipairs(_G) do
if not lua[i] then
apis[i]=v
_G[i]=nil
end
end
local function getFile(path)
if path:sub(1,1) ~= "/" then
path="/"..path
end
local file = apis.fs.open("/root"..path)
end
local function write(text)
end
local event_queue = {}
local function addEventRaw(...)
event_queue[#event_queue+1] = {...}
end
local function getEvent()
local event = event_queue[1]
event_queue = {table.unpack(event_queue, 2)}
return table.unpack(event)
end
local lkeys={}
lkeys[keys.enter]="\n"
lkeys[keys.backspace]="\b"
lkeys[keys.tab]="\t"
local kernel = load(getFile("/boot/Hyprkrnl.sys"), "@kernel", "t", _G)
local kernel_coro = coroutine.create(function()
kernel("cc", apis, "internal", {
print=function(text)
write(text)
write("\n")
end,
printInline=function(text)
write(text)
end,
clear=function()
apis.term.clear()
apis.term.setCursorPos(1,1)
end
}, getEvent)
end)
debug.sethook(kernel_coro, function() coroutine.yield("CC:TWEAKED", "CORO_TIMEOUT") end, "l", 3000)
while true do
local ret = {coroutine.resume(kernel_coro)}
if coroutine.status(kernel_coro) == "dead" then
break
end
local timer = os.startTimer(0)
local exit = false
repeat
local event = {coroutine.yield()}
if event[1] == "timer" and event[2]==timer then
exit=true
elseif event[1]==nil then
elseif event[1]=="key" then
addEventRaw("keyPressed", 1, event[2])
if lkeys[event[2]] then
addEventRaw("keyTyped", 1, lkeys[event[2]])
end
elseif event[1]=="char" then
addEventRaw("keyTyped", 1, event[2])
elseif event[1]=="key_up" then
addEventRaw("keyReleased", 1, event[2])
elseif event[1]=="disk" then
addEventRaw("componentAdded", "disk", sandboxedFS.new(api.disk.getMountPath(event[2]), apis.disk.getID(event[2])))
elseif event[1]=="disk_eject" then
addEventRaw("componentRemoved", "disk")
end
until exit
end

View File

2
src/disks/45h/bin_/beep Normal file
View File

@@ -0,0 +1,2 @@
local computer=component.getFirst("computer")
computer.beep(800, 0.2, 1)

2
src/disks/45h/bin_/clear Normal file
View File

@@ -0,0 +1,2 @@
local term=component.getFirst("screen")
term.clear()

17
src/disks/45h/bin_/debug Normal file
View 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

0
src/disks/45h/bin_/ls Normal file
View File

View 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
src/disks/45h/bin_/pge Normal file
View 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)

View File

@@ -0,0 +1,2 @@
local computer=component.getFirst("computer")
computer.reboot()

52
src/disks/45h/bin_/shell Normal file
View 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
src/disks/45h/bin_/t Normal file
View File

@@ -0,0 +1,2 @@
local print=component.getFirst("screen").print
print("test")

23
src/disks/45h/bin_/top Normal file
View 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

View 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

View 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 :)")

View File

@@ -0,0 +1 @@
if

View File

0
src/disks/45h/etc/fstab Normal file
View File

2
src/disks/45h/etc/group Normal file
View File

@@ -0,0 +1,2 @@
root:0:root
sudo:1:root

1
src/disks/45h/etc/passwd Normal file
View File

@@ -0,0 +1 @@
root:x:0:0::/root:/bin/pshell

1
src/disks/45h/etc/shadow Normal file
View File

@@ -0,0 +1 @@
root:$5$9a7f8e2b4cd01ac18d7cbb4da74f5c1e$53326d6a24ef6a050b5ef88dbbe5906d4afbcf191725f9750e44a818ab22bd62:0

View 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/

View File

@@ -0,0 +1 @@
root

View File

@@ -0,0 +1,5 @@
[Unit]
Description=Shutdown of system
Conflicts=reboot.target halt.target
[Service]

View File

@@ -0,0 +1,16 @@
function color.screen8(r, g, b)
-- Ensure input is within valid 0-255 range
r = math.max(0, math.min(255, r))
g = math.max(0, math.min(255, g))
b = math.max(0, math.min(255, b))
-- Convert 8-bit to reduced bit depth
local r3 = math.floor(r / 32) -- 8-bit to 3-bit
local g3 = math.floor(g / 32) -- 8-bit to 3-bit
local b2 = math.floor(b / 64) -- 8-bit to 2-bit
-- Pack into a single 8-bit value: RRR GGG BB
local rgb332 = (r3 << 5) | (g3 << 2) | b2
return rgb332
end

View 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

View 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

View 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

Some files were not shown because too many files have changed in this diff Show More