34 Commits

Author SHA1 Message Date
8762b8f022 Merge pull request '1.2-dev' (#9) from 1.2-dev into main
Reviewed-on: #9
2026-03-11 10:37:44 -04:00
677b2cccec user login fixed 2026-03-11 10:37:13 -04:00
a5e8624368 forgot to edit login 2026-03-11 08:54:47 -04:00
bbda3b3937 fixed elevate VULN 2026-03-11 08:52:41 -04:00
585d39bec2 Merge pull request '1.2-dev' (#8) from 1.2-dev into main
Reviewed-on: #8
2026-03-11 08:23:21 -04:00
b08b14763a i am a we bit stupid (fixed cct bug) 2026-03-11 08:22:53 -04:00
de6696003b fix capitaization part 2 2026-03-11 07:26:38 -04:00
9220281365 fix capitalization part 1 2026-03-11 07:25:52 -04:00
813ddabd9d fixed disk detection i think 2026-03-10 21:13:52 -04:00
5177639d71 Merge pull request 'update build.tar' (#7) from 1.2-dev into main
Reviewed-on: #7
i was dumb
2026-03-10 20:05:26 -04:00
528b4f31bd update build.tar 2026-03-10 20:04:53 -04:00
60162c7c57 Merge pull request '1.2.4' (#6) from 1.2-dev into main
Reviewed-on: #6
2026-03-10 20:02:20 -04:00
18f5c454bb fixed bug where cct drivers are inaccessable 2026-03-10 20:00:21 -04:00
849ecb7dd6 made procfs self 2026-03-10 19:41:54 -04:00
e41bd6bee7 Merge pull request '1.2-dev merge' (#5) from 1.2-dev into main
Reviewed-on: #5
2026-03-10 12:27:08 -04:00
359198c1ea Merge branch '1.2-dev' of https://git.astronand.dev/Hyperion/HyperionOS into 1.2-dev 2026-03-10 10:57:27 -04:00
beebf01223 remove tar during install 2026-03-10 10:57:10 -04:00
2d4ea1bbf4 Update README.md 2026-03-10 10:39:01 -04:00
ea3a7e99a7 Update install/installcc.lua 2026-03-10 10:34:36 -04:00
be0fe5dc5a install works (i think) 2026-03-10 10:32:32 -04:00
12669d9f82 adde /proc fs and working on install 2026-03-10 09:17:21 -04:00
f12159bfb9 fixed build script 2026-03-09 11:31:31 -04:00
1590e1f3f7 more reorganizeing and $PKGCONFIG.ini files added B to ls -lh for "Bytes" 2026-03-09 11:28:09 -04:00
a69f945b91 did some reorganizing 2026-03-06 09:57:45 -05:00
7da67899db finished hyperion manifest :D 2026-03-05 10:36:43 -05:00
62e032e4c5 made sysinit in /usr/lib/sysinit and sped up micro added kernel.firstBoot in kernel table 2026-03-05 09:53:30 -05:00
6fefa2d9ff cp should not copy perms 2026-03-03 12:25:25 -05:00
bb354cc706 mv syscallautofill 2026-03-03 11:45:05 -05:00
fabc061731 made lua not clear screen 2026-03-03 10:06:04 -05:00
82c3e2b346 fix ll 2026-03-03 08:57:45 -05:00
e2e1d5b8a5 making descriptions for syscalls 2026-03-03 08:52:55 -05:00
9342b9b2b3 Merge branch '1.2-dev' of https://git.astronand.dev/Hyperion/HyperionOS into 1.2-dev 2026-03-03 08:02:09 -05:00
9a7db6c243 syscalls now autocomplete is vsc 2026-03-03 08:02:05 -05:00
f00453f703 Merge pull request '1.2-dev merge' (#5) from 1.2-dev into main
Reviewed-on: #5
2026-02-24 02:12:36 -05:00
76 changed files with 1400 additions and 316 deletions

View File

@@ -1,3 +1,4 @@
[![Download on PineStore](https://raster.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpinestore.cc%2Fapi%2Fproject%2F225&query=%24.project.downloads&suffix=%20downloads&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNzYuOTA0IiBoZWlnaHQ9Ijg5LjI5NSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDc2OS4wNCA4OTIuOTUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%2BCiA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTQuNzQgLTQuNjgyNikiIGZpbGw9IiM5YWIyZjIiPgogIDxwYXRoIGQ9Im00MTAgODUxYzAtMTIgMjYtMjEgNTgtMjEgMTUgMCAyMiA0IDE3IDktMTQgMTItNzUgMjItNzUgMTJ6Ii8%2BCiAgPHBhdGggZD0ibTU4NSA3NDJjLTEtNDkgNC03MiAxNi04NSAyMi0yNCAzMC02OCAxNi04Ni0xMi0xNC0yNy0zOS00OC03OC0xMC0xOS05LTI2IDQtNDEgMjItMjQgMjEtNjctMi0xNDQtMjEtNjktMzktMTQ0LTQ4LTE5NS00LTI2LTItMzMgMTEtMzMgMzEgMCAxMTIgMzMgMTQxIDU4IDI4IDIzIDgxIDkyIDcxIDkyLTIgMCA1IDI2IDE2IDU3IDI4IDc5IDI5IDIyNCAzIDMwOC0xMCAzMy0xOSA2Mi0xOSA2NS00IDI2LTEzMiAxNTAtMTU1IDE1MC0zIDAtNi0zMC02LTY4eiIvPgogIDxwYXRoIGQ9Im02OCA2NzNjLTcyLTEwOS03MS0yNzggMy00MjMgMzYtNzEgNjItMTAwIDEyOC0xNDAgNDMtMjcgNjUtMzQgMTE4LTM2IDEwMC00IDk4IDExLTE5IDEzNi0zNCAzNy03OCA4OC05NiAxMTMtMjggMzktMzEgNDgtMjEgNjUgMTEgMTcgNiAyNy0zMyA3OS00MCA1My00NCA2Mi0zMiA3OCAxNyAyMyAxOCA1NyAyIDczLTYgNi0xNCAzMS0xNyA1NC02IDQyLTYgNDItMzMgMXoiLz4KIDwvZz4KIDxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNC43NCAtNC42ODI2KSIgZmlsbD0iIzU5YTY0ZiI%2BCiAgPHBhdGggZD0ibTM2NSA4MTNjLTUzLTYtMTM5LTMzLTE5Mi02MS02OC0zNS04My02Ny01OC0xMjIgMjYtNTkgNDAtNjcgNzgtNDkgNjggMzMgMTY3IDU4IDI2NiA2OSA1OCA1IDEwNiAxMiAxMDkgMTQgMiAzIDYgMzIgOSA2NSA4IDg1IDAgOTEtMTAxIDkwLTQ0LTEtOTQtNC0xMTEtNnoiLz4KICA8cGF0aCBkPSJtNDEwIDQ1OWMtNjctNy0xNjAtMjktMTk5LTQ4LTI3LTE0LTM0LTM2LTIwLTYzIDIxLTM4IDk3LTEzNiAxNTAtMTkzIDI1LTI3IDU4LTcxIDczLTk3IDI1LTQzIDMxLTQ3IDU0LTQyIDQwIDEwIDQyIDEyIDQyIDUyIDAgMjAgNiA1NyAxNCA4MiAyNCA3MyA1NCAxOTIgNjIgMjM2IDUgMzUgMyA0NS0xNSA2My0yMyAyMy0zNiAyNC0xNjEgMTB6Ii8%2BCiA8L2c%2BCiA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTQuNzQgLTQuNjgyNikiIGZpbGw9IiM3ZWNiMjUiPgogIDxwYXRoIGQ9Im01NTggNjc0Yy0yLTItNTEtOS0xMDktMTQtMTAyLTExLTIwNC0zNy0yNjQtNjktMTYtOC0zMi0xNC0zNC0xMi00IDMtMzEtNDgtMzEtNjEgMC01IDIxLTMxIDQ2LTU4IDUxLTU0IDcxLTYwIDEzMC0zNSAxOSA4IDgzIDE5IDE0MiAyNSA1OCA2IDEwNyAxMiAxMDcgMTNzMTUgMjYgMzMgNTZjMjcgNDMgMzIgNjMgMzAgOTktMiAzNS04IDQ3LTI1IDUzLTExIDQtMjMgNi0yNSAzeiIvPgogPC9nPgogPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTE0Ljc0IC00LjY4MjYpIiBmaWxsPSIjZWNlZGVmIj4KICA8cGF0aCBkPSJtMjYwIDg5MGMtMzQtOC03MC00MS03MC02NSAwLTYtOS0yMC0yMC0zMHMtMjAtMjItMjAtMjctMTMtMjEtMzAtMzVjLTM1LTI5LTQxLTgzLTEzLTEyMiAxNS0yMiAxNS0yNi0xLTU2LTE4LTMzLTE4LTMzIDI3LTkxIDI4LTM2IDQyLTYzIDM2LTY4LTIzLTI1IDktNzggMTIwLTE5NyAzNi0zOCA3Mi04MSA4Mi05NiAxMC0xNCAyNS0zMCAzMy0zNSAzNi0yMCA3IDMyLTUzIDk3LTQ4IDUxLTEyNiAxNTAtMTQ5IDE4OS0xMCAxOC05IDI0IDEwIDQwIDIzIDE5IDIzIDE5LTI5IDcxLTUzIDUyLTUzIDUyLTM4IDgyIDE0IDI4IDE0IDMzLTEwIDc2LTMyIDU3LTIzIDgxIDQ2IDEyMCAzNCAxOSA0OSAzMyA0NSA0Mi0xNCAzNyAzNiA3NSA5OCA3NSAyNSAwIDQwLTcgNTQtMjUgMTgtMjMgMjctMjUgOTUtMjUgOTQgMCAxMDItOCA5My04OS02LTUzLTUtNTkgMTQtNjQgMzItOCAyNi02NC0xNS0xMzItMzUtNTgtMzUtNTgtOS04MiAyMS0xOSAyNC0yOSAxOS01Ni0xMC00Ny00NC0xNzUtNjEtMjI3LTgtMjUtMTQtNjItMTQtODMgMC0yNy01LTM5LTE3LTQzLTEwLTMtMjUtOC0zMy0xMC0xMi00LTEyLTYtMS0xNCAyNy0xNiA1NiA1IDY5IDUxIDM1IDExNyA0MyAxNDggNDYgMTcwIDIgMTMgMTEgNTEgMjEgODQgMjEgNzEgMjEgMTIxIDAgMTQ1LTE0IDE1LTEzIDE5IDUgNDMgMTEgMTQgMjAgMzAgMjAgMzVzNyAxNSAxNSAyMmMyMSAxNyAxNiA3NS0xMCAxMDItMTggMTktMjAgMzItMTcgNzkgNCA1MCAyIDU4LTE5IDcyLTEyIDktNTAgMTktODMgMjMtNDUgNS02NSAxMy04MyAzMi0yNiAyOC05MiAzOC0xNTMgMjJ6Ii8%2BCiA8L2c%2BCiA8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTQuNzQgLTQuNjgyNikiIGZpbGw9IiM3ZTY3NGQiPgogIDxwYXRoIGQ9Im0yNDggODU0Yy0zMC0xNi00Ny01OS0zMC03NiA4LTggMjMtNyA1NCAyIDI0IDcgNjEgMTQgODMgMTcgNTQgNyA1OSAxNSAzNSA0Ni0xOCAyMy0yOSAyNy02OCAyNy0yNi0xLTU5LTctNzQtMTZ6Ii8%2BCiA8L2c%2BCjwvc3ZnPgo%3D&label=PineStore)](https://pinestore.cc/projects/225/hyperionos)
# HyperionOS # HyperionOS
HyperionOS is a modular, hybrid kernel operating system written entirely in Lua. It features a custom task scheduler, virtual filesystem, syscall interface, and separates core functionality from user-space services. HyperionOS is a modular, hybrid kernel operating system written entirely in Lua. It features a custom task scheduler, virtual filesystem, syscall interface, and separates core functionality from user-space services.

View File

@@ -1,5 +1,5 @@
local io = {} local io = {}
local fs = require("sys.fs") local fs = require("fs")
function io.open(path, mode) function io.open(path, mode)
return fs.open(path, mode) return fs.open(path, mode)

View File

@@ -1,6 +0,0 @@
local sys = {}
local fs = require("sys.fs")
return sys

View File

@@ -1,5 +0,0 @@
local sys = {}
sys.fs = require("sys.fs")
sys.hpv = require("sys.hpv")
sys.ipc = require("sys.ipc")
return sys

View File

@@ -1,3 +0,0 @@
local ipc = {}
return ipc

View File

@@ -1,71 +0,0 @@
local term = {}
function term.clear()
coroutine.yield("VFS_write", 1, "\27C\25")
end
function term.setCursorPos(x, y)
coroutine.yield("VFS_write", 1, "\27cs"..tostring(y)..";"..tostring(x).."\25")
end
function term.size()
coroutine.yield("VFS_write", 1, "\27ts\25")
local ok, data = coroutine.yield("VFS_read", 0, 16) -- read response
if not ok then error("Failed to get terminal size") end
local x, y = string.match(data, "%R(%d+);(%d+)\25")
return tonumber(x), tonumber(y)
end
function term.getCursorPos()
coroutine.yield("VFS_write", 1, "\27gc\25")
local ok, data = coroutine.yield("VFS_read", 0, 16) -- read response
if not ok then error("Failed to get cursor position") end
local y, x = string.match(data, "%R(%d+);(%d+)\25")
return tonumber(x), tonumber(y)
end
function term.write(data)
coroutine.yield("VFS_write", 1, data)
end
function term.setTextColor(color)
local ok, err = coroutine.yield("VFS_type", 1)
if not ok then error(err) end
if ok ~= "tty" then return end
coroutine.yield("VFS_write", 1, "\27f"..tostring(color).."\25")
end
function term.setBackgroundColor(color)
local ok, err = coroutine.yield("VFS_type", 1)
if not ok then error(err) end
if ok ~= "tty" then return end
coroutine.yield("VFS_write", 1, "\27b"..tostring(color).."\25")
end
function term.isColor()
local ok, err = coroutine.yield("VFS_type", 1)
if not ok then error(err) end
return ok == "tty"
end
function term.scroll(n)
coroutine.yield("VFS_write", 1, "\27S"..tostring(n).."\25")
end
function term.setDefault(color, layer)
if layer then
coroutine.yield("VFS_write", 1, "\27F"..tostring(color).."\25")
else
coroutine.yield("VFS_write", 1, "\27B"..tostring(color).."\25")
end
end
function term.showCursor(show)
if show then
coroutine.yield("VFS_write", 1, "\27sc\25")
else
coroutine.yield("VFS_write", 1, "\27hc\25")
end
end
return term

View File

@@ -6,31 +6,147 @@ local native = apis.peripheral
local peripheral = {} local peripheral = {}
local sides = {"top", "bottom", "left", "right", "front", "back"} local sides = {"top", "bottom", "left", "right", "front", "back"}
function peripheral.getType(name) function peripheral.getNames()
if native.isPresent(name) then return native.getType(name) end local results = {}
for n = 1, #sides do for n = 1, #sides do
local side = sides[n] local side = sides[n]
if native.hasType(side, "peripheral_hub") and if native.isPresent(side) then
native.call(side, "isPresentRemote", name) then table.insert(results, side)
return native.call(side, "getTypeRemote", name) if native.hasType(side, "peripheral_hub") then
local remote = native.call(side, "getNamesRemote")
for _, name in ipairs(remote) do
table.insert(results, name)
end
end
end
end
return results
end
function peripheral.isPresent(name)
if native.isPresent(name) then
return true
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return true
end
end
return false
end
function peripheral.getType(peripheral)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.getType(peripheral)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "getTypeRemote", peripheral)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return table.unpack(mt.types)
end
end
function peripheral.hasType(peripheral, peripheral_type)
if type(peripheral) == "string" then
if native.isPresent(peripheral) then
return native.hasType(peripheral, peripheral_type)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
end
end
return nil
else
local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.types[peripheral_type] ~= nil
end
end
function peripheral.getMethods(name)
if native.isPresent(name) then
return native.getMethods(name)
end
for n = 1, #sides do
local side = sides[n]
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
return native.call(side, "getMethodsRemote", name)
end end
end end
return nil return nil
end end
function peripheral.getNames() function peripheral.getName(peripheral)
local names = {} local mt = getmetatable(peripheral)
if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then
error("bad argument #1 (table is not a peripheral)", 2)
end
return mt.name
end
function peripheral.call(name, method, ...)
if native.isPresent(name) then
return native.call(name, method, ...)
end
for n = 1, #sides do for n = 1, #sides do
local side = sides[n] local side = sides[n]
if native.isPresent(side) then table.insert(names, side) end if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
if native.hasType(side, "peripheral_hub") then return native.call(side, "callRemote", name, method, ...)
local hubSides = native.call(side, "getConnectedSides") end
for _, hubSide in ipairs(hubSides) do end
table.insert(names, hubSide) return nil
end
function peripheral.wrap(name)
local methods = peripheral.getMethods(name)
if not methods then
return nil
end
local types = { peripheral.getType(name) }
for i = 1, #types do types[types[i]] = true end
local result = setmetatable({}, {
__name = "peripheral",
name = name,
type = types[1],
types = types,
})
for _, method in ipairs(methods) do
result[method] = function(...)
return peripheral.call(name, method, ...)
end
end
return result
end
function peripheral.find(ty, filter)
local results = {}
for _, name in ipairs(peripheral.getNames()) do
if peripheral.hasType(name, ty) then
local wrapped = peripheral.wrap(name)
if filter == nil or filter(name, wrapped) then
table.insert(results, wrapped)
end end
end end
end end
return names return table.unpack(results)
end end
local disks = {} local disks = {}
@@ -130,14 +246,9 @@ local function refresh()
if not peripheral.getType(id) then disks[id] = nil end if not peripheral.getType(id) then disks[id] = nil end
end end
for _, name in ipairs(peripheral.getNames()) do for _, disk in ipairs({peripheral.find("drive")}) do
if peripheral.getType(name) == "disk" then if disk.isDiskPresent() then
if not disks[name] then disks[tostring(disk.getDiskID())]=createDisk("cctdisk"..tostring(disk.getDiskID()), disk.getMountPath(), false, fs)
local mount = disk.getMountPath(name)
if mount then
disks[name] = createDisk(name, mount, false, disk)
end
end
end end
end end
end end

View File

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

View File

@@ -1,4 +1,5 @@
--:Minify:-- --:Minify:--
local kernel = ... local kernel = ...
local apis = kernel.apis local apis = kernel.apis
local native = apis.peripheral local native = apis.peripheral

View File

@@ -1,3 +1,4 @@
U $;/ U $;/
U devfs0000;/dev/ U devfs0000;/dev/
U tmpfs0000;/tmp/ U tmpfs0000;/tmp/
U procfs0000;/proc/

View File

@@ -113,8 +113,9 @@ local split = function(str, delim, maxResultCountOrNil)
end end
if not ifs.isFile("/boot/boot.cfg") then if not ifs.isFile("/boot/boot.cfg") then
kernel.log("boot.cfg missing or corrupted!, Attempting to write recovery boot.cfg", "ERROR", 2) kernel.log("First boot detected writing boot.cfg", "INFO", 3)
ifs.writeAllText("/boot/boot.cfg",ifs.readAllText("/boot/safeboot.cfg")) ifs.writeAllText("/boot/boot.cfg",ifs.readAllText("/boot/safeboot.cfg"))
kernel.firstBoot=true
end end
local initCfgFunc, err = load(ifs.readAllText("/boot/boot.cfg"), "@boot.cfg") local initCfgFunc, err = load(ifs.readAllText("/boot/boot.cfg"), "@boot.cfg")
@@ -149,10 +150,6 @@ function kernel.saveLog()
ifs.writeAllText("/var/log/syslog.log", kernel.LOG_Text) ifs.writeAllText("/var/log/syslog.log", kernel.LOG_Text)
end end
function loadcstr(string)
end
function kernel.newFifo() function kernel.newFifo()
local fifo = {} local fifo = {}
fifo.push=function(data) fifo.push=function(data)

View File

@@ -4,7 +4,7 @@
-- This file is auto-generated during the build process. -- This file is auto-generated during the build process.
-- DEFAULT BOOT CONFIGURATION FILE -- DEFAULT BOOT CONFIGURATION FILE
return { return {
initPath = "/sbin/init.lua", initPath = "/sbin/init",
maxOpenFiles = 128, maxOpenFiles = 128,
maxFilesPerTask = 16, maxFilesPerTask = 16,
preempt=true preempt=true

View File

@@ -1,4 +1,5 @@
--:Minify:-- --:Minify:--
--- @diagnostic disable: duplicate-set-field
local kernel = ... local kernel = ...
kernel.allowGlobalOverwrites = true kernel.allowGlobalOverwrites = true
@@ -172,6 +173,27 @@ function table.indexOf(t, value)
return -1 return -1
end end
function table.merge(...)
local args={...}
local out = {}
local outi = {}
for _,t in ipairs(args) do
for i,v in pairs(t) do
out[i]=v
end
for i,v in ipairs(t) do
outi[#outi+1]=v
end
end
for i,v in ipairs(outi) do
out[i]=v
end
return out
end
function string.replace(s, target, repl) function string.replace(s, target, repl)
local result = {} local result = {}
local i = 1 local i = 1

View File

@@ -0,0 +1,265 @@
--:Minify:--
local kernel = ...
local proxy = {}
local data = {}
proxy.address = "procfs0000"
proxy.isvirt = true
proxy.isReadOnly = function() return false end
proxy.spaceUsed = function() return 0 end
proxy.spaceTotal = function() return 0 end
proxy.makeDirectory = function() error("EACCES") end
proxy.remove = function() error("EACCES") end
proxy.setLabel = function() error("EACCES") end
proxy.getLabel = function() return "procfs" end
proxy.attributes = function(path) return {
size = 0,
modified = 0,
created = 0
} end
local function buildMeta(entries, opts)
opts = opts or {}
local uid = opts.uid or 0
local gid = opts.gid or 0
local perms = opts.perms or 0x3F -- default read/write for owner/group/world
local chunks = {}
table.insert(chunks, string.char(0x02)) -- version header
for path, target in pairs(entries) do
local name = path
local nameLen = #name
if nameLen > 255 then
error("Filename too long (>255 bytes): "..name)
end
-- Determine entry type: 0x01 = symlink if target ~= nil and target ~= ""
local entryType = 0x00
local cmeta = ""
if target and target ~= "" then
entryType = 0x01
cmeta = target
end
local cmetaLen = #cmeta
if cmetaLen > 255 then
error("cmeta too long (>255 bytes) for "..name)
end
-- Build entry as bytes
table.insert(chunks, string.char(nameLen)) -- name length
table.insert(chunks, name) -- name
table.insert(chunks, string.char(entryType)) -- entry type
table.insert(chunks, string.char(uid % 256, math.floor(uid/256) % 256)) -- uid
table.insert(chunks, string.char(gid % 256, math.floor(gid/256) % 256)) -- gid
table.insert(chunks, string.char(perms % 256, math.floor(perms/256) % 256)) -- perms
table.insert(chunks, string.char(cmetaLen)) -- cmeta length
if cmetaLen > 0 then
table.insert(chunks, cmeta)
end
end
return table.concat(chunks)
end
local function simpleFile(r,w)
return function(op, mode)
if op=="type" then
return "character device"
elseif op=="open" then
if mode=="r" then
return {
read=r
}
elseif mode=="w" then
return {
write=w
}
end
end
end
end
local function strFile(str)
local dat=tostring(str)
local pos=1
return simpleFile(function(amount)
pos=pos+amount
return dat:sub(pos-amount, pos)
end,function() error("EACCES") end)
end
local function newtaskproxy(task)
local files,siblings,children={},{},{}
if task.fd[0] then files["0"]=task.fd[0].path end
for i,v in ipairs(task.fd) do
files[tostring(i)]=tostring(v.path)
end
for i,v in ipairs(task.siblings) do
siblings[tostring(v.pid)]="/proc/"..tostring(v.pid)
end
for i,v in ipairs(task.children) do
children[tostring(v.pid)]="/proc/"..tostring(v.pid)
end
return {
[".meta"]=strFile(buildMeta({cwd=task.cwd,parent="/proc/"..tostring(task.parent.pid)})),
uid=strFile(task.uid),
comm=strFile(task.name),
fd={
[".meta"]=strFile(buildMeta(files))
},
siblings={
[".meta"]=strFile(buildMeta(siblings))
},
children={
[".meta"]=strFile(buildMeta(children))
}
}
end
function proxy:open(path, mode)
local steps = kernel.vfs.splitPath(path)
local step = data
if tonumber(steps[1]) then
local task=kernel.tasks[tostring(steps[1])]
local step = newtaskproxy(task)
for i=2, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("open", mode)
end
elseif tostring(steps[1])=="self" then
local task=kernel.currentTask
local step = newtaskproxy(task)
for i=2, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("open", mode)
end
else
for i=1, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("open", mode)
end
end
error("ENFILE")
end
function proxy:type(path, mode)
local steps = kernel.vfs.splitPath(path)
local step = data
if #steps == 0 then
return "directory"
end
if tonumber(steps[1]) then
local task=kernel.tasks[steps[1]]
if #steps==1 then return "directory" end
local step = newtaskproxy(task)
for i=2, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("type", mode)
end
if type(step[steps[#steps]]) == "table" then
return "directory"
end
elseif tostring(steps[1])=="self" then
local task=kernel.currentTask
if #steps==1 then return "directory" end
local step = newtaskproxy(task)
for i=2, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("type", mode)
end
if type(step[steps[#steps]]) == "table" then
return "directory"
end
else
for i=1, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENFILE") end
step=dat
end
if type(step[steps[#steps]]) == "function" then
return step[steps[#steps]]("type", mode)
end
if type(step[steps[#steps]]) == "table" then
return "directory"
end
end
error("ENOENT")
end
function proxy:list(path)
local steps = kernel.vfs.splitPath(path)
local step = data
if #steps == 0 then
return table.merge(table.keys(data),table.keys(kernel.tasks),{"self"})
end
if tonumber(steps[1]) then
local task=kernel.tasks[steps[1]]
local step = newtaskproxy(task)
if #steps==1 then return table.keys(step) end
for i=2, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENOENT") end
step=dat
end
if type(step[steps[#steps]]) == "table" then
return table.keys(step[steps[#steps]])
end
elseif tostring(steps[1])=="self" then
local task=kernel.currentTask
local step = newtaskproxy(task)
if #steps==1 then return table.keys(step) end
for i=2, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENOENT") end
step=dat
end
if type(step[steps[#steps]]) == "table" then
return table.keys(step[steps[#steps]])
end
else
for i=1, #steps-1 do
local dat = step[steps[i]]
if type(dat) ~= "table" then error("ENOENT") end
step=dat
end
if type(step[steps[#steps]]) == "table" then
return table.keys(step[steps[#steps]])
end
end
error("ENOENT")
end
function proxy:fileExists(path)
local ok = pcall(function()
return self:type(path)
end)
return ok
end
data.uptime=simpleFile(function()return tostring(kernel.computer:getUptime())end,function()error("EACCES")end)
kernel.procfs={}
kernel.procfs.data=data
kernel.procfs.proxy=proxy
kernel.disks["procfs0000"]=proxy

View File

@@ -236,19 +236,18 @@ local function nextUID()
return max + 1 return max + 1
end end
function auth.login(username, password) function auth.login(uid, password)
if type(username) ~= "string" or type(password) ~= "string" then if type(uid) ~= "number" or type(password) ~= "string" then
return nil, "Authentication failure" return nil, "Authentication failure"
end end
local entry = getPasswdByUsername(username) local entry = getPasswdByUID(uid)
if not entry then if not entry then
-- timing attack resistance -- timing attack resistance
hashPassword(password, "aaaaaaaaaaaaaaaa") hashPassword(password, "aaaaaaaaaaaaaaaa")
return nil, "Authentication failure" return nil, "Authentication failure"
end end
local uid = tonumber(entry[1])
local sEntry = getShadowByUID(uid) local sEntry = getShadowByUID(uid)
if not sEntry then if not sEntry then
hashPassword(password, "aaaaaaaaaaaaaaaa") hashPassword(password, "aaaaaaaaaaaaaaaa")
@@ -273,7 +272,7 @@ function auth.login(username, password)
_task.egid = tonumber(entry[2]) or uid _task.egid = tonumber(entry[2]) or uid
end end
kernel.log("AUTH: login uid=" .. tostring(uid) .. " (" .. username .. ")") kernel.log("AUTH: login uid=" .. tostring(uid) .. " (" .. getPasswdByUID(uid)[3] .. ")")
return true return true
end end

View File

@@ -82,7 +82,8 @@ local function mergeMeta(dir, entries)
end end
end end
kernel.log("Seeding filesystem permissions...", "INFO") if kernel.firstBoot then
kernel.log("Seeding filesystem permissions...")
mergeMeta("/", { mergeMeta("/", {
{"bin", REG, 0, 0, RWX_RX_RX}, {"bin", REG, 0, 0, RWX_RX_RX},
@@ -95,7 +96,8 @@ mergeMeta("/", {
{"sbin", REG, 0, 0, RWX_RX_RX}, {"sbin", REG, 0, 0, RWX_RX_RX},
{"tmp", REG, 0, 0, RWXRWXRWX}, {"tmp", REG, 0, 0, RWXRWXRWX},
{"usr", REG, 0, 0, RWX_RX_RX}, {"usr", REG, 0, 0, RWX_RX_RX},
{"var", REG, 0, 0, RWX_RX_RX}, {"var", REG, 0, 0, RWXRWXRWX},
{"opt", REG, 0, 0, RWX_RX_RX},
}) })
mergeMeta("/bin", { mergeMeta("/bin", {
@@ -107,11 +109,12 @@ mergeMeta("/bin", {
mergeMeta("/etc", { mergeMeta("/etc", {
{"passwd", REG, 0, 0, RW_R_R }, {"passwd", REG, 0, 0, RW_R_R },
{"shadow", REG, 0, 0, RW____ }, {"shadow", REG, 0, 0, RW____ },
{"pam.d", REG, 0, 0, RWX_RX_RX}, {"pam.d", REG, 0, 0, RW____ },
}) })
mergeMeta("/etc/pam.d", { mergeMeta("/etc/pam.d", {
{"secret", REG, 0, 0, RW____}, {"secret", REG, 0, 0, RW____},
}) })
kernel.log("Filesystem permissions seeded.", "INFO") kernel.log("Filesystem permissions seeded.")
end

View File

@@ -5,7 +5,7 @@ syscall.open("/dev/null","w") --stderr (device 2)
local success, errorMsg = xpcall(function() local success, errorMsg = xpcall(function()
local fs = require("sys.fs") local fs = require("fs")
syscall.devctl(1,"clear") syscall.devctl(1,"clear")
syscall.devctl(1,"sfgc",1) syscall.devctl(1,"sfgc",1)
@@ -15,7 +15,7 @@ print("HyperionOS hysh Shell")
local userhost = (syscall.getUsername() or "Unknown").."@"..(syscall.getHostname() or "Unknown") local userhost = (syscall.getUsername() or "Unknown").."@"..(syscall.getHostname() or "Unknown")
local commandHistory = {} local commandHistory = {}
local terminate = false local terminate = false
syscall.setEnviron("SHELL","rtbash") syscall.setEnviron("SHELL","hysh")
syscall.setEnviron("PATH","/bin/") syscall.setEnviron("PATH","/bin/")
local _home = syscall.getEnviron("HOME") local _home = syscall.getEnviron("HOME")
if _home and _home ~= "" then if _home and _home ~= "" then
@@ -133,8 +133,6 @@ local function copyfile(src, dst)
if not data then return false, err end if not data then return false, err end
local ok, err2 = writefile(dst, data) local ok, err2 = writefile(dst, data)
if not ok then return false, err2 end if not ok then return false, err2 end
local ok2, stat = pcall(syscall.stat, src)
if ok2 and stat and stat.perms then pcall(syscall.chmod, dst, stat.perms) end
return true return true
end end

View File

@@ -1,3 +1,3 @@
local args={...} local args={...}
table.insert(args, "-lah") table.insert(args, "-lah")
syscall.exec("/bin/ls", args)2 syscall.exec("/bin/ls", args)

View File

@@ -130,8 +130,9 @@ local function doLogin()
syscall.write(1, "Password: ") syscall.write(1, "Password: ")
local password = readLine("*") local password = readLine("*")
local uid = syscall.getuidbyname(username)
local ok, err = syscall.login(username, password) local ok, err = syscall.login(uid, password)
if ok then if ok then
local uid = syscall.getuid() local uid = syscall.getuid()
local pwent = syscall.getpasswd(uid) local pwent = syscall.getpasswd(uid)

View File

@@ -43,7 +43,7 @@ if opts.help then
return return
end end
local fs = require("sys.fs") local fs = require("fs")
if opts.x then if opts.x then
if #args < 2 then if #args < 2 then

View File

@@ -45,7 +45,7 @@ if cloptions.help then
return return
end end
local fs = require("sys.fs") local fs = require("fs")
local dir = args[1] or "" local dir = args[1] or ""
if dir:sub(1, 1) ~= "/" then if dir:sub(1, 1) ~= "/" then
dir = syscall.getcwd() .. "/" .. dir dir = syscall.getcwd() .. "/" .. dir
@@ -84,7 +84,7 @@ local function humanSize(size)
size = size / 1024 size = size / 1024
scale = scale + 1 scale = scale + 1
end end
if scale == 0 then return tostring(size) end if scale == 0 then return tostring(size).."B" end
if size < 10 then if size < 10 then
return string.format("%.1f%s", size, sizePrefixes[scale]) return string.format("%.1f%s", size, sizePrefixes[scale])
end end
@@ -148,7 +148,7 @@ if cloptions.l then
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 1)
end end
elseif isDir then elseif isDir then
syscall.devctl(1, "sfgc", 4) syscall.devctl(1, "sfgc", 14)
printInline(v) printInline(v)
syscall.devctl(1, "sfgc", 1) syscall.devctl(1, "sfgc", 1)
else else
@@ -177,7 +177,7 @@ for i, v in ipairs(list) do
if isSym then if isSym then
syscall.devctl(1, "sfgc", 6) syscall.devctl(1, "sfgc", 6)
elseif isDir then elseif isDir then
syscall.devctl(1, "sfgc", 4) syscall.devctl(1, "sfgc", 14)
else else
local isExec = stat and stat.perms and (math.floor(stat.perms / (2^9)) % 2 == 1) local isExec = stat and stat.perms and (math.floor(stat.perms / (2^9)) % 2 == 1)
syscall.devctl(1, "sfgc", isExec and 3 or 1) syscall.devctl(1, "sfgc", isExec and 3 or 1)

View File

@@ -9,7 +9,7 @@ local currentUid = syscall.getuid()
local targetUid local targetUid
if targetName then if targetName then
targetUid = syscall.getuid(targetName) targetUid = syscall.getuid()
if not targetUid then if not targetUid then
print("passwd: user '" .. targetName .. "' does not exist") print("passwd: user '" .. targetName .. "' does not exist")
syscall.exit(1); return syscall.exit(1); return
@@ -36,7 +36,7 @@ if currentUid ~= 0 then
if #cur > 0 then cur=cur:sub(1,-2); syscall.write(1,"\b \b") end if #cur > 0 then cur=cur:sub(1,-2); syscall.write(1,"\b \b") end
else cur=cur..ch; syscall.write(1,"*") end else cur=cur..ch; syscall.write(1,"*") end
end end
local ok, err = syscall.elevate(targetName, cur) local ok, err = syscall.login(targetUid, cur)
if not ok then if not ok then
sleep(1) sleep(1)
print("passwd: authentication failure") print("passwd: authentication failure")

View File

@@ -1,7 +1,12 @@
--:Minify:-- --:Minify:--
local targetUser = ({ ... })[1] or "root" local targetUser = ({ ... })[1]
local currentUid = syscall.getuid() local currentUid = syscall.getuid()
local targetUid = syscall.getuidbyname(targetUser) local targetUid
if targetUser then
targetUid = syscall.getuidbyname(targetUser)
else
targetUid = 0
end
if not targetUid then if not targetUid then
print("su: user '" .. targetUser .. "' does not exist") print("su: user '" .. targetUser .. "' does not exist")
@@ -25,20 +30,21 @@ if currentUid ~= 0 then
end end
end end
local ok, err = syscall.elevate(targetUser, pw) local ok, err = syscall.login(targetUid, pw)
if not ok then if not ok then
sleep(1) sleep(1)
print("su: Authentication failure") print("su: Authentication failure")
syscall.exit(1) syscall.exit(1)
return return
end end
end else
syscall.setuid(targetUid) syscall.setuid(targetUid)
end
local pwent = syscall.getpasswd(targetUid) local pwent = syscall.getpasswd(targetUid)
local shell = (pwent and pwent.shell) or "/bin/hysh" local shell = (pwent and pwent.shell) or "/bin/hysh"
local homedir = (pwent and pwent.homedir) or "/" local homedir = (pwent and pwent.homedir) or "/"
local username= (pwent and pwent.username)or "Unknown"
local ok_cd, err_cd = pcall(syscall.chdir, homedir) local ok_cd, err_cd = pcall(syscall.chdir, homedir)
if not ok_cd then if not ok_cd then
@@ -46,7 +52,7 @@ if not ok_cd then
syscall.chdir(homedir) syscall.chdir(homedir)
end end
syscall.setEnviron("HOME", homedir) syscall.setEnviron("HOME", homedir)
syscall.setEnviron("USER", targetUser) syscall.setEnviron("USER", username)
syscall.setEnviron("SHELL", shell) syscall.setEnviron("SHELL", shell)
local ok, err = pcall(syscall.exec, shell) local ok, err = pcall(syscall.exec, shell)

View File

@@ -1,5 +1,5 @@
--:Minify:-- --:Minify:--
local fs = require("sys.fs") local fs = require("fs")
local cmdArgs = {...} local cmdArgs = {...}
local targetUser = "root" local targetUser = "root"
@@ -55,7 +55,7 @@ if currentUid ~= 0 then
end end
end end
local ok, err = syscall.elevate("root", pw) local ok, err = syscall.login(0, pw)
if not ok then if not ok then
sleep(1) sleep(1)
print("sudo: Authentication failure") print("sudo: Authentication failure")

View File

@@ -29,7 +29,7 @@ if not ok then
end end
if removeHome and pwent and pwent.homedir then if removeHome and pwent and pwent.homedir then
local fs = require("sys.fs") local fs = require("fs")
local ok2, err2 = pcall(function() local ok2, err2 = pcall(function()
local function rmdir(path) local function rmdir(path)
for _, f in ipairs(fs.list(path) or {}) do for _, f in ipairs(fs.list(path) or {}) do

38
Src/iniparse/lib/iniparse Normal file
View File

@@ -0,0 +1,38 @@
local ini = {}
function ini.parse(str)
local config = {}
local section = nil
for line in str:gmatch("[^\r\n]+") do
-- trim whitespace
line = line:match("^%s*(.-)%s*$")
-- skip empty lines and comments
if line ~= "" and not line:match("^[;#]") then
-- section
local sec = line:match("^%[(.-)%]$")
if sec then
section = sec
config[section] = config[section] or {}
else
-- key=value
local key, value = line:match("^(.-)=(.*)$")
if key then
key = key:match("^%s*(.-)%s*$")
value = value:match("^%s*(.-)%s*$")
if section then
config[section][key] = value
else
config[key] = value
end
end
end
end
end
return config
end
return ini

View File

@@ -260,17 +260,17 @@ local function getUserInput(prompt, history)
while true do while true do
local key = syscall.read(0) local key = syscall.read(0)
if key and key ~= "" then if key and key ~= "" then
if key == "\19" then if key == "" then
if cursor > 1 then cursor = cursor - 1; dirty = true end if cursor > 1 then cursor = cursor - 1; dirty = true end
elseif key == "\20" then elseif key == "" then
if cursor <= #input then cursor = cursor + 1; dirty = true end if cursor <= #input then cursor = cursor + 1; dirty = true end
elseif key == "\17" then elseif key == "" then
if history and histIdx < #history then if history and histIdx < #history then
histIdx = histIdx + 1 histIdx = histIdx + 1
input = history[#history - histIdx + 1] input = history[#history - histIdx + 1]
cursor = #input + 1; dirty = true cursor = #input + 1; dirty = true
end end
elseif key == "\18" then elseif key == "" then
if histIdx > 1 then if histIdx > 1 then
histIdx = histIdx - 1 histIdx = histIdx - 1
input = history[#history - histIdx + 1] input = history[#history - histIdx + 1]
@@ -288,8 +288,8 @@ local function getUserInput(prompt, history)
syscall.devctl(1,"spos",ox,oy) syscall.devctl(1,"spos",ox,oy)
w(input .. " \n") w(input .. " \n")
return input return input
else elseif #key == 1 and key:byte(1) >= 32 and key:byte(1) < 127 then
input = input:sub(1, cursor-1) .. key .. input:sub(cursor) input=string.sub(input,1,cursor-1)..key..string.sub(input,cursor)
cursor=cursor+1;dirty=true cursor=cursor+1;dirty=true
end end
end end
@@ -299,8 +299,6 @@ local function getUserInput(prompt, history)
end end
end end
syscall.devctl(1, "clear")
syscall.devctl(1, "spos", 1, 1)
c(C_PROMPT); w("HyperionOS " .. _VERSION .. "\n") c(C_PROMPT); w("HyperionOS " .. _VERSION .. "\n")
c(C_NIL) c(C_NIL)
w("Interactive Lua REPL. exit() to quit.\n\n") w("Interactive Lua REPL. exit() to quit.\n\n")

View File

@@ -413,8 +413,6 @@ while running do
redraw() redraw()
dirty = false dirty = false
end end
sleep(0.05)
end end
tclear(); tfg(1); tbg(16); tpos(1,1) tclear(); tfg(1); tbg(16); tpos(1,1)

View File

@@ -1,101 +0,0 @@
syscall={}
syscall.sethomedir=function(uid, homedir) end
syscall.read=function(fd, amount) end
syscall.getTask=function(pid) end
syscall.connect=function(fd, address) end
syscall.getcwd=function() end
syscall.lodetach=function(id) end
syscall.stop=function(pid) end
syscall.recv
syscall.write=function(fd, data) end
syscall.getppid=function() end
syscall.lstat
syscall.open=function(path, mode) end
syscall.lseek=function(fd, offset, whence) end
syscall.setHostname=function(hostname) end
syscall.chroot
syscall.dup2
syscall.getpid=function() end
syscall.fchown
syscall.close=function(fd) end
syscall.umount
syscall.getTasks=function() end
syscall.sysdump=function() end
syscall.fchmod
syscall.getHostname=function() end
syscall.listen
syscall.dup
syscall.gpio_read
syscall.fget_suid
syscall.gpio_write
syscall.setpassword
syscall.setEnviron=function(key, value) end
syscall.losetup
syscall.reboot=function() end
syscall.getuid=function() end
syscall.sigsend
syscall.sleep=function(time) end
syscall.exit=function(code) end
syscall.getEnviron=function(key) end
syscall.continue=function(pid) end
syscall.socket
syscall.log=function(text, tag, color) end
syscall.loimgwrite
syscall.exists=function(path) end
syscall.setuid=function(uid) end
syscall.exec=function(path, args, envars) end
syscall.execspawn=function(path, name, envars, args, tgid) end
syscall.loimgcreate
syscall.time=function() end
syscall.newuser
syscall.spawn=function(func, name, envars, args, tgid) end
syscall.collect=function(pid) end
syscall.setshell
syscall.devctl=function(fd, funcname) end
syscall.listusers
syscall.unlockuser
syscall.mount
syscall.accept
syscall.lolist
syscall.readlink
syscall.deleteuser
syscall.remove=function(path) end
syscall.type=function(path) end
syscall.elevate
syscall.mkdir=function(path) end
syscall.getuidbyname
syscall.whoami=function() end
syscall.sendfile
syscall.setusername
syscall.geteuid
syscall.login
syscall.getHost
syscall.getUptime
syscall.httpget
syscall.stat
syscall.symlink
syscall.pread
syscall.chdir
syscall.arch=function() end
syscall.pwrite
syscall.sockshutdown
syscall.resolve
syscall.send
syscall.fstat
syscall.chown
syscall.fsync
syscall.lockuser
syscall.getUsername
syscall.getsockname
syscall.bind
syscall.kill=function(pid) end
syscall.setgid
syscall.getpeername
syscall.sigcatch
syscall.shutdown
syscall.access
syscall.sigignore
syscall.getpasswd
syscall.version
syscall.chmod=function(path, perms) end
syscall.listdir=function(path) end

View File

@@ -0,0 +1 @@
[symlinks]

4
Src/sysinit/sbin/init Normal file
View File

@@ -0,0 +1,4 @@
local args={...}
syscall.remove("/sbin/init")
syscall.symlink("/usr/lib/sysinit/sysinit", "/sbin/init")
syscall.exec("/sbin/init", args)

View File

@@ -1,6 +1,6 @@
--:Minify:-- --:Minify:--
local kernel=... local kernel=...
local fs=require("sys.fs") local fs=require("fs")
for i,v in pairs(kernel.processes) do for i,v in pairs(kernel.processes) do
kernel.log("Spawning kernel task "..i) kernel.log("Spawning kernel task "..i)
@@ -41,6 +41,6 @@ for i,v in ipairs(files) do
end end
while true do while true do
sleep(1) sleep(5)
kernel.saveLog() kernel.saveLog()
end end

View File

@@ -1,4 +1,4 @@
local fs=require("sys.fs") local fs=require("fs")
local units=fs.list("/usr/lib/hunit/") local units=fs.list("/usr/lib/hunit/")
fs.mkdir("/tmp/hunit/") fs.mkdir("/tmp/hunit/")
local errors={} local errors={}

View File

@@ -1,3 +1,3 @@
local fs = require("sys.fs") local fs = require("fs")
assert(fs.mkdir("/tmp/hunit/testdir"), "failed to make directory") assert(fs.mkdir("/tmp/hunit/testdir"), "failed to make directory")
assert(fs.isDir("/tmp/hunit/testdir"), "directory does not exist") assert(fs.isDir("/tmp/hunit/testdir"), "directory does not exist")

View File

@@ -90,6 +90,10 @@ def process_root(src_root: Path, out_root: Path, minify: bool, micro: bool):
continue continue
rel = src.relative_to(pkg_dir) rel = src.relative_to(pkg_dir)
if rel.name=="$PKGCONFIG.ini":
continue
dst = out_root / rel dst = out_root / rel
dst.parent.mkdir(parents=True, exist_ok=True) dst.parent.mkdir(parents=True, exist_ok=True)

BIN
install/data/Build.tar Normal file

Binary file not shown.

157
install/data/tarbad Normal file
View File

@@ -0,0 +1,157 @@
local function octal_to_number(str)
str = str:gsub("%z", ""):match("^%s*(.-)%s*$")
return tonumber(str, 8) or 0
end
local function dedupe_path(path)
local parts = {}
for p in path:gmatch("[^/]+") do table.insert(parts, p) end
for prefix_len = 1, math.floor(#parts / 2) do
local ok = true
for i = 1, prefix_len do
if parts[i] ~= parts[i + prefix_len] then
ok = false
break
end
end
if ok then
local cleaned = {}
for i = 1, #parts - prefix_len do
cleaned[#cleaned + 1] = parts[i + prefix_len]
end
return table.concat(cleaned, "/")
end
end
return path
end
local function make_dirs(root, path)
local cur = root
for part in path:gmatch("([^/]+)/") do
if not cur[part] then
cur[part] = { __type = "dir", __entries = {} }
end
cur = cur[part].__entries
end
return cur
end
local function flatten(node, prefix)
local out = {}
prefix = prefix or ""
for name, obj in pairs(node) do
local full = prefix .. name
if obj.__type == "file" then
out[#out+1] = {
name = full,
type = "file",
contents = obj.__contents
}
elseif obj.__type == "dir" then
out[#out+1] = {
name = full .. "/",
type = "dir",
contents = flatten(obj.__entries, full .. "/")
}
end
end
return out
end
local function unpack_tar(tarstr)
local i = 1
local len = #tarstr
local root = {}
while i + 512 <= len do
local header = tarstr:sub(i, i + 511)
if header:match("^\0+$") then break end
local name_raw = header:sub(1, 100):gsub("%z.*", "")
local prefix_raw = header:sub(346, 500):gsub("%z.*", "")
local name
if prefix_raw ~= "" then
name = prefix_raw .. "/" .. name_raw
else
name = name_raw
end
name = name:gsub("^%./", ""):gsub("/+", "/")
name = dedupe_path(name)
local size = octal_to_number(header:sub(125,136))
local typeflag = header:sub(157,157)
i = i + 512
local contents = tarstr:sub(i, i + size - 1)
local pad = (512 - (size % 512)) % 512
i = i + size + pad
if name == "" then goto continue end
local is_dir = typeflag == "5" or name:sub(-1) == "/"
local clean_name = name:gsub("/$", "")
if clean_name == "" then goto continue end
local parent_path = clean_name:match("(.+)/")
local fname = clean_name:match("([^/]+)$")
if not fname then goto continue end
local parent = root
if parent_path then
parent = make_dirs(root, parent_path .. "/")
end
if is_dir then
parent[fname] = parent[fname] or { __type = "dir", __entries = {} }
else
parent[fname] = { __type = "file", __contents = contents }
end
::continue::
end
return flatten(root)
end
local function write_directory(prefix, items)
for _, v in ipairs(items) do
if v.type == "dir" then
fs.makeDir(prefix..v.name)
write_directory(prefix, v.contents)
elseif v.type == "file" then
local file = fs.open(prefix..v.name, "w")
file.write(v.contents)
file.close()
end
end
end
local in_tar = ({...})[1]
local out_dir = ({...})[2]
if not in_tar or not out_dir then
print("Usage: unpack_tar <tarfile> <output_dir>")
return
end
local f = fs.open(in_tar, "r")
local tarstr = f.readAll()
f.close()
local list = unpack_tar(tarstr)
write_directory(out_dir, list)
print("TAR extracted into: " .. out_dir)

27
install/installcc.lua Normal file
View File

@@ -0,0 +1,27 @@
print("Hello, World!")
sleep(1)
term.clear()
print("Do you want to install HyperionOS? [Y/n]")
local input=read()
if input=="y" or input=="Y" or input=="" then
goto install
else
goto exit
end
::install::
print("Installing tar but bad...")
shell.run("wget https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/1.2-dev/install/data/tarbad /tar.lua")
print("Installing HyperionOS...")
print("Installing precompiled tar")
shell.run("wget https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/1.2-dev/install/data/Build.tar /Build.tar")
shell.run("tar Build.tar /")
print("Removing tar but bad...")
shell.run("rm /tar.lua")
shell.run("rm $")
shell.run("cp Build $")
shell.run("rm Build")
shell.run("rm Build.tar")
fs.copy("/$/boot/cct/eeprom","/startup.lua")
dofile("startup.lua")
::exit::

664
manifest.lua Normal file
View File

@@ -0,0 +1,664 @@
--- @version 1.2.3
--- @diagnostic disable: missing-return
--- @diagnostic disable: duplicate-set-field
syscall={}
--- @alias userinfo {username:string,homedir:string,shell:string,uid:number,gid:number}
--- Sets home directory of User with corresponding uid to homedir
--- @param uid integer
--- @param homedir string
--- @return true|nil, nil|string
syscall.sethomedir=function(uid, homedir) end
--- Reads amount from fd and returns content or nil
--- @param fd integer
--- @param amount? integer
--- @return string|nil
syscall.read=function(fd, amount) end
--- Gets information of task with id of pid
---@param pid integer
---@return table|nil
syscall.getTask=function(pid) end
--- Connects a client socket to a server address
---@param fd integer
---@param address string
---@return boolean, string|nil
syscall.connect=function(fd, address) end
--- Get current working directory
--- @return string
syscall.getcwd=function() end
--- Detach loop device (must be unmounted first)
--- @param id string
--- @return boolean, string|nil
syscall.lodetach=function(id) end
--- Stops task with id of pid
--- @param pid integer
--- @return boolean, string|nil
syscall.stop=function(pid) return true end
--- Receive bytes from socket (blocking poll, returns "" if no data)
--- @param fd integer
--- @param amount integer
--- @return string
syscall.recv=function(fd, amount) end
--- Write data to file descriptor
--- @param fd integer
--- @param data string
--- @return boolean, string|nil
syscall.write=function(fd, data) end
--- Get parent process ID
--- @return integer
syscall.getppid=function() end
--- Get file information (metadata)
--- @param path string
--- @return table|nil
syscall.lstat=function(path) end
--- Open a file with mode ("r", "w", etc.)
--- @param path string
--- @param mode string
--- @return integer|nil, string|nil
syscall.open=function(path, mode) end
--- Seek in a file descriptor
--- @param fd integer
--- @param offset integer
--- @param whence integer
--- @return integer|nil
syscall.lseek=function(fd, offset, whence) end
--- Set system hostname
--- @param hostname string
--- @return boolean
syscall.setHostname=function(hostname) end
--- Change root directory
--- @param path string
--- @return boolean, string|nil
syscall.chroot=function(path) end
--- Duplicate file descriptor
--- @param src integer
--- @param dst integer
--- @return integer|nil, string|nil
syscall.dup2=function(src, dst) end
--- Get current process ID
--- @return integer
syscall.getpid=function() end
--- Change ownership of a file descriptor
--- @param fd integer
--- @param uid integer
--- @param gid integer
--- @return boolean, string|nil
syscall.fchown=function(fd, uid, gid) end
--- Close a file descriptor
--- @param fd integer
--- @return boolean, string|nil
syscall.close=function(fd) end
--- Unmount a target
--- @param target string
--- @return boolean, string|nil
syscall.umount=function(target) end
--- Get all task IDs
--- @return integer[]
syscall.getTasks=function() end
--- Dump all syscalls for debugging
--- @return table
syscall.sysdump=function() end
--- Change permissions of a file descriptor
--- @param fd integer
--- @param perms integer
--- @return boolean, string|nil
syscall.fchmod=function(fd, perms) end
--- Get system hostname
--- @return string
syscall.getHostname=function() end
--- Listen for incoming connections
--- @param fd integer
--- @param backlog integer
--- @return boolean, string|nil
syscall.listen=function(fd, backlog) end
--- Duplicate a file descriptor
--- @param fd integer
--- @return integer|nil
syscall.dup=function(fd) end
--- Read GPIO pin
--- @param pin integer
--- @return number|nil
syscall.gpio_read=function(pin) end
--- Get SUID bit from fd
--- @param fd integer
--- @return boolean
syscall.fget_suid=function(fd) end
--- Write GPIO pin
--- @param pin integer
--- @param data number
--- @return boolean
syscall.gpio_write=function(pin, data) end
--- Set password for user
--- @param uid integer
--- @param newPassword string
--- @return boolean, string|nil
syscall.setpassword=function(uid, newPassword) end
--- Set environment variable
--- @param key string
--- @param value any
--- @return boolean
syscall.setEnviron=function(key, value) end
--- Setup a loop device with filePath
--- @param filePath string
--- @param forceImage boolean
--- @return string|nil, string|nil
syscall.losetup=function(filePath, forceImage) end
--- Reboot the system
syscall.reboot=function() end
--- Get current user ID
--- @return integer
syscall.getuid=function() end
--- Send signal to task
--- @param pid integer
--- @param sigid integer|string
--- @return boolean, string|nil
syscall.sigsend=function(pid, sigid) end
--- Sleep current task for time seconds
--- @param time number
syscall.sleep=function(time) end
--- Exit current task
--- @param code integer|nil
syscall.exit=function(code) end
--- Get environment variable
--- @param key string
--- @return any
syscall.getEnviron=function(key) end
--- Continue a stopped task
--- @param pid integer
--- @return boolean, string|nil
syscall.continue=function(pid) end
--- Create a socket
--- @param domain integer
--- @param socktype integer
--- @return integer|nil
syscall.socket=function(domain, socktype) end
--- Log a message
--- @param text string
--- @param tag string
--- @param color integer
syscall.log=function(text, tag, color) end
--- Write an image to disk
--- @param imgStr string
--- @param destPath string
--- @return boolean, string|nil
syscall.loimgwrite=function(imgStr, destPath) end
--- Check if file exists
--- @param path string
--- @return boolean
syscall.exists=function(path) end
--- Set user ID of current task
--- @param uid integer
--- @return boolean, string|nil
syscall.setuid=function(uid) end
--- Replace current task with executable
--- @param path string
--- @param args? table
--- @param envars? table
syscall.exec=function(path, args, envars) end
--- Spawn a new task from executable
--- @param path string
--- @param name? string
--- @param envars? table
--- @param args? table
--- @param tgid? integer
--- @return integer
syscall.execspawn=function(path, name, envars, args, tgid) end
--- Create image from file
--- @param srcPath string
--- @return string|nil
syscall.loimgcreate=function(srcPath) end
--- Get system time in ms
--- @return number
syscall.time=function() end
--- Create a new user
--- @param username string
--- @param password string
--- @param gid integer
--- @param homedir string
--- @param shell string
--- @return integer|nil
syscall.newuser=function(username, password, gid, homedir, shell) end
--- Spawn a new task from function
--- @param func function
--- @param name? string
--- @param envars? table
--- @param args? table
--- @param tgid? integer
--- @return integer
syscall.spawn=function(func, name, envars, args, tgid) end
--- Collect exit code of a dead child task
--- @param pid integer
--- @return boolean, integer|string
syscall.collect=function(pid) end
--- Set shell of user
--- @param uid integer
--- @param shell string
--- @return boolean
syscall.setshell=function(uid, shell) end
--- Device control
--- @param fd integer
--- @param funcname string
--- @param ... any
--- @return any
syscall.devctl=function(fd, funcname, ...) end
--- List all users
--- @return table
syscall.listusers=function() end
--- Unlock a user account
--- @param uid integer
--- @return boolean
syscall.unlockuser=function(uid) end
--- Mount a disk or loop device
--- @param target string
--- @param diskOrId string
--- @return boolean, string|nil
syscall.mount=function(target, diskOrId) end
--- Accept a client connection on a socket
--- @param fd integer
--- @return integer|nil
syscall.accept=function(fd) end
--- List loop devices
--- @return table
syscall.lolist=function() end
--- Read a symbolic link
--- @param path string
--- @return string|nil
syscall.readlink=function(path) end
--- Delete a user
--- @param uid integer
--- @return boolean
syscall.deleteuser=function(uid) end
--- Remove a file
--- @param path string
--- @return boolean, string|nil
syscall.remove=function(path) end
--- Get type of a path (file, dir, link)
--- @param path string
--- @return string|nil
syscall.type=function(path) end
--- Elevate to root with password (Disabled due to VULN)
--- @param targetUsername string
--- @param password string
--- @return boolean
syscall.elevate=function(targetUsername, password) end
--- Make a directory
--- @param path string
--- @return boolean, string|nil
syscall.mkdir=function(path) end
--- Get UID by username
--- @param username string
--- @return integer|nil
syscall.getuidbyname=function(username) end
--- Get current user name
--- @return string
syscall.whoami=function() end
--- Send file content
--- @param src string
--- @param dest string
--- @param amount integer
--- @return boolean, string|nil
syscall.sendfile=function(src, dest, amount) end
--- Change username of user
--- @param uid integer
--- @param newUsername string
--- @return boolean
syscall.setusername=function(uid, newUsername) end
--- Get effective UID
--- @return integer
syscall.geteuid=function() end
--- Login as user
--- @param uid integer
--- @param password string
--- @return boolean
syscall.login=function(uid, password) end
--- Get system hostname
--- @return string
syscall.getHost=function() end
--- Get system uptime in ms
--- @return number
syscall.getUptime=function() end
--- HTTP GET request
--- @param url string
--- @param headers table|nil
--- @return string|nil
syscall.httpget=function(url, headers) end
--- Get file metadata
--- @param path string
--- @return table|nil
syscall.stat=function(path) end
--- Create symbolic link
--- @param target string
--- @param linkPath string
--- @return boolean, string|nil
syscall.symlink=function(target, linkPath) end
--- Read from fd at offset
--- @param fd integer
--- @param count integer
--- @param offset integer
--- @return string|nil
syscall.pread=function(fd, count, offset) end
--- Change current working directory
--- @param path string
--- @return boolean, string|nil
syscall.chdir=function(path) end
--- Get system architecture
--- @return string
syscall.arch=function() end
--- Write to fd at offset
--- @param fd integer
--- @param data string
--- @param offset integer
--- @return boolean, string|nil
syscall.pwrite=function(fd, data, offset) end
--- Shutdown socket
--- @param fd integer
--- @return boolean, string|nil
syscall.sockshutdown=function(fd) end
--- Resolve hostname to IP
--- @param hostname string
--- @return string|nil
syscall.resolve=function(hostname) end
--- Send data over socket
--- @param fd integer
--- @param data string
--- @return boolean, string|nil
syscall.send=function(fd, data) end
--- Get file descriptor info
--- @param fd integer
--- @return table|nil
syscall.fstat=function(fd) end
--- Change ownership of path
--- @param path string
--- @param uid integer
--- @param gid integer
--- @return boolean, string|nil
syscall.chown=function(path, uid, gid) end
--- Flush file descriptor
--- @param fd integer
--- @return boolean, string|nil
syscall.fsync=function(fd) end
--- Lock user account
--- @param uid integer
--- @return boolean
syscall.lockuser=function(uid) end
--- Get username by UID
--- @param uid integer
--- @return string|nil
syscall.getUsername=function(uid) end
--- Get socket name
--- @param fd integer
--- @return string|nil
syscall.getsockname=function(fd) end
--- Bind socket to address
--- @param fd integer
--- @param address string
--- @return boolean, string|nil
syscall.bind=function(fd, address) end
--- Kill a task
--- @param pid integer
--- @return boolean, string|nil
syscall.kill=function(pid) end
--- Set GID for user
--- @param uid integer
--- @param gid integer
--- @return boolean
syscall.setgid=function(uid, gid) end
--- Get peer name of socket
--- @param fd integer
--- @return string|nil
syscall.getpeername=function(fd) end
--- Set signal handler
--- @param handler function
syscall.sigcatch=function(handler) end
--- Shutdown the system
syscall.shutdown=function() end
--- Check file access mode
--- @param path string
--- @param mode string
--- @return boolean
syscall.access=function(path, mode) end
--- Ignore current signal
syscall.sigignore=function() end
--- Get user information
--- @param uid integer
--- @return userinfo|nil
syscall.getpasswd=function(uid) end
--- Get OS version
--- @return string
syscall.version=function() end
--- Change file permissions
--- @param path string
--- @param perms integer
--- @return boolean
syscall.chmod=function(path, perms) end
--- List directory contents
--- @param path string
--- @return table
syscall.listdir=function(path) end
----------------------------------------------
--- STDLib manifest
----------------------------------------------
--- Gets the index of value or -1
--- @param tabl table
--- @param value string|integer
--- @return integer
table.indexOf=function(tabl, value) end
-- Returns true if tabl has key else false
--- @param tabl table
--- @param query string
--- @return boolean
table.hasKey=function(tabl, query) end
--- Returns true if tabl has value else false
--- @param tabl table
--- @param query any
--- @return boolean
table.hasVal=function(tabl, query) end
--- Creates a deepcopy of tabl
--- @param tabl table
--- @return table
table.deepcopy=function(tabl) end
--- Returns the keys of tabl
--- @param tabl table
--- @return table
table.keys=function(tabl) end
--- Returns the values of tabl
--- @param tabl table
--- @return table
table.values=function(tabl) end
--- Returns a serialized version of tabl
--- @param tabl table
--- @return string
table.serialize=function(tabl) end
--- Returns a merged table with a and b
--- @param ... table
--- @return table
table.merge=function(...) end
--- Gets prefix of string with suffix
--- @param str string
--- @param suffix string
--- @return string
string.getPrefix=function(str, suffix) end
--- Gets suffix of string with prefix
--- @param str string
--- @param prefix string
--- @return string
string.getSuffix=function(str, prefix) end
--- Returns if sting has prefix
--- @param str string
--- @param prefix string
--- @return boolean
string.hasPrefix=function(str, prefix) end
--- Returns if sting has suffix
--- @param str string
--- @param suffix string
--- @return boolean
string.hasSuffix=function(str, suffix) end
--- Joins all args
--- @param str string
--- @param ... string
--- @return string
string.join=function(str, ...) end
--- Joins all strings with delim
--- @param delim string
--- @param ... string
--- @return string
string.delim=function(delim, ...) end
--- Splits a string by delim
--- @param str string
--- @param delim string
--- @return table
string.split=function(str, delim) end
--- Replaces all instances of target with repl
--- @param str string
--- @param target string
--- @param repl string
--- @return string
string.replace=function(str, target, repl) end
--- Converts a number to hex
--- @param num integer
--- @return string
toHex=function(num) end
--- Returns if obj is equal to all in ...
--- @param obj any
--- @param ... any
--- @return boolean
isEqualToAll=function(obj, ...) end
--- Returns if obj is equal to any in ...
--- @param obj any
--- @param ... any
--- @return boolean
isEqualToAny=function(obj, ...) end
--- Prints text to stdout
--- @param ... any
print=function(...) end
--- Prints text to stdout but with no trailing newline
--- @param ... any
printInline=function(...) end
--- Prints text to stdout with format
--- @param fmt string
--- @param ... any
printf=function(fmt, ...) end