update
This commit is contained in:
Vendored
+2
-1
@@ -6,6 +6,7 @@
|
||||
"printf",
|
||||
"printInline",
|
||||
"toHex",
|
||||
"loadcstr"
|
||||
"loadcstr",
|
||||
"userinput"
|
||||
]
|
||||
}
|
||||
@@ -15,8 +15,10 @@ See `building.md`.
|
||||
|
||||
- Functionality is split into kernel modules (`.kmod`)
|
||||
- Task-based lightweight thread/task preemptive scheduler with process isolation and IPC support
|
||||
- Virtual filesystem unified interface for disk, RAM, and virtual filesystems
|
||||
- Virtual filesystem
|
||||
- TTY & Shell
|
||||
- Sockets
|
||||
-
|
||||
|
||||
---
|
||||
|
||||
@@ -48,6 +50,12 @@ Add your name to `contributors.md` when your PR is merged.
|
||||
|
||||
---
|
||||
|
||||
## Information
|
||||
|
||||
Trello: https://trello.com/b/8dryrlMi
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the LICENSE file for details.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
local http=require("http")
|
||||
local ok,err = xpcall(http.get, debug.traceback, "http://localhost:8000/spm.json")
|
||||
if not ok then
|
||||
print(err)
|
||||
else
|
||||
print(err.body)
|
||||
end
|
||||
@@ -1,11 +1,6 @@
|
||||
--:Minify:--
|
||||
local fs={}
|
||||
|
||||
-- "open" : open
|
||||
-- "read" : read
|
||||
-- "write" : write
|
||||
-- "close" : close
|
||||
|
||||
function fs.open(path, mode)
|
||||
local fd=syscall.open(path,mode)
|
||||
local ret={
|
||||
@@ -140,4 +135,12 @@ function fs.isDir(path)
|
||||
return syscall.type(path) == "directory"
|
||||
end
|
||||
|
||||
function fs.symlink(target, path)
|
||||
return syscall.syslink(target, path)
|
||||
end
|
||||
|
||||
function fs.readlink(path)
|
||||
return syscall.readlink(path)
|
||||
end
|
||||
|
||||
return fs
|
||||
@@ -463,7 +463,12 @@ local ok, err = xpcall(function()
|
||||
getTextColor = function()
|
||||
return fg
|
||||
end,
|
||||
enable=function() end,
|
||||
enable=function()
|
||||
for i=1, #allscreens do
|
||||
allscreens[i].clear()
|
||||
allscreens[i].setCursorPos(1, 1)
|
||||
end
|
||||
end,
|
||||
disable=function() end
|
||||
},
|
||||
architecture="cct",
|
||||
|
||||
@@ -220,9 +220,6 @@ local function newtty(obj, id, ev)
|
||||
gbgc=function()
|
||||
return bg
|
||||
end,
|
||||
gctrl=function()
|
||||
return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt)
|
||||
end,
|
||||
isvirt=function()
|
||||
return false
|
||||
end,
|
||||
@@ -269,6 +266,9 @@ kernel.devfs.data["input"]["keyboard1"] = function(op, mode)
|
||||
return rv
|
||||
end,
|
||||
write=function(content)
|
||||
end,
|
||||
gctrl=function()
|
||||
return serializeBool(kernel.cct.ctrl)..";"..serializeBool(kernel.cct.alt)
|
||||
end
|
||||
}
|
||||
if mode=="rw" then
|
||||
|
||||
@@ -7,10 +7,10 @@ local disks=EFI.disks
|
||||
local arch=EFI.architecture
|
||||
local kernel = {}
|
||||
kernel.LOG_Text=""
|
||||
kernel.version="HyperionOS V1.2.4-dev_5"
|
||||
kernel.tag="1.2.4-dev_5"
|
||||
kernel.version="HyperionOS V1.2.4"
|
||||
kernel.tag="1.2.4"
|
||||
kernel.process = "Kernel"
|
||||
kernel.users={[0]="root",[1]="User"}
|
||||
kernel.users={[0]="root",[1000]="User"}
|
||||
kernel.hostname = "hyperion"
|
||||
kernel.groups = {}
|
||||
kernel.uid = 0
|
||||
|
||||
@@ -23,6 +23,7 @@ function string.split(str, delim, maxResultCountOrNil)
|
||||
assert(#delim == 1, "only delim len 1 supported for now")
|
||||
if not str then return false end
|
||||
maxResultCountOrNil = (maxResultCountOrNil or 0) - 1
|
||||
if str == "" then return {} end
|
||||
local rv = {}
|
||||
local buf = ""
|
||||
for i = 1, #str do
|
||||
|
||||
@@ -124,7 +124,7 @@ end
|
||||
|
||||
local function validateComponent(comp)
|
||||
local lower = comp:lower()
|
||||
if not lower:match(SAFE_COMPONENT_PATTERN) then
|
||||
if not comp:match(SAFE_COMPONENT_PATTERN) then
|
||||
error("EINVAL: illegal characters in path component: " .. comp, 3)
|
||||
end
|
||||
if lower == ".meta" then
|
||||
@@ -276,7 +276,7 @@ local function namei(path, noFollow, symDepth)
|
||||
|
||||
else
|
||||
validateComponent(comp)
|
||||
local lname = comp:lower()
|
||||
local lname = comp
|
||||
|
||||
local curPath = "/" .. table.concat(stack, "/")
|
||||
|
||||
@@ -374,7 +374,7 @@ local function normalizePath(path)
|
||||
table.remove(stack)
|
||||
end
|
||||
else
|
||||
table.insert(stack, comp:lower())
|
||||
table.insert(stack, comp)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -184,11 +184,16 @@ function socket.sockshutdown(fd)
|
||||
return true
|
||||
end
|
||||
|
||||
function socket.socketendpoints()
|
||||
return table.keys(socket.handlers)
|
||||
end
|
||||
|
||||
sys.socket = socket.socket
|
||||
sys.connect = socket.connect
|
||||
sys.listen = socket.listen
|
||||
sys.send = socket.send
|
||||
sys.recv = socket.recv
|
||||
sys.sockshutdown = socket.sockshutdown
|
||||
sys.socketendpoints = socket.socketendpoints
|
||||
|
||||
kernel.log("Loaded socket module")
|
||||
@@ -19,4 +19,25 @@ function printInline(...)
|
||||
for i = 1, #args do output = output .. tostring(args[i]) .. "\t" end
|
||||
output = output:sub(1, -2)
|
||||
syscall.write(1, output)
|
||||
end
|
||||
|
||||
function userinput(fd, helpstr, replacestr, fdo)
|
||||
local str = ""
|
||||
if helpstr then print(helpstr) end
|
||||
while true do
|
||||
local inp = syscall.read(fd)
|
||||
if inp~="" and inp~=nil then
|
||||
if inp~="\n" then
|
||||
if replacestr then
|
||||
syscall.write(fdo, replacestr)
|
||||
else
|
||||
syscall.write(fdo, inp)
|
||||
end
|
||||
str = inp
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return str
|
||||
end
|
||||
@@ -315,7 +315,9 @@ end
|
||||
|
||||
-- CRC-16/CRC-32 computation
|
||||
local band, bnot, xor, lshift, rshift
|
||||
|
||||
local bit32
|
||||
local ok, temp = pcall(require, "bit32")
|
||||
if ok then bit32=temp end
|
||||
if bit ~= nil then
|
||||
band = bit.band
|
||||
bnot = bit.bnot
|
||||
|
||||
@@ -1211,9 +1211,9 @@ local function runCommand(command)
|
||||
|
||||
local proc = syscall.spawn(function()
|
||||
-- Open standard fds so programs that don't do it themselves work correctly.
|
||||
syscall.open("/dev/input/keyboard1", "r") -- fd 0 stdin
|
||||
syscall.open("/dev/tty/1", "w") -- fd 1 stdout
|
||||
syscall.open("/dev/null", "w") -- fd 2 stderr
|
||||
syscall.open("/proc/self/parent/fd/0", "r") -- fd 0 stdin
|
||||
syscall.open("/proc/self/parent/fd/1", "w") -- fd 1 stdout
|
||||
syscall.open("/proc/self/parent/fd/2", "w") -- fd 2 stderr
|
||||
-- exec replaces this coroutine's code with a fresh isolated environment
|
||||
-- compiled from disk by the kernel (via loadExecutable -> freshUserEnv),
|
||||
-- so the child cannot share any upvalue or syscall table state with hysh.
|
||||
|
||||
+310
-48
@@ -1,68 +1,330 @@
|
||||
local args={...}
|
||||
--:Minify:--
|
||||
local spm = function(...)
|
||||
if syscall.geteuid()~=0 then print("Permission denied") return end
|
||||
local inpArgs = { ... }
|
||||
local args = {}
|
||||
local cloptions = {
|
||||
S = false,
|
||||
y = false,
|
||||
u = false,
|
||||
R = false,
|
||||
h = false,
|
||||
r = false,
|
||||
Q = false,
|
||||
l = false,
|
||||
o = false,
|
||||
i = false,
|
||||
e = false,
|
||||
t = false,
|
||||
sysroot = "",
|
||||
init = false,
|
||||
help = false,
|
||||
source = false
|
||||
}
|
||||
|
||||
-- local test repo
|
||||
local rootRepo="http://localhost:8000/spm.json"
|
||||
--local rootRepo="https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm.json"
|
||||
local i = 1
|
||||
local fs = require("fs")
|
||||
local http = require("http")
|
||||
local json = require("json")
|
||||
local tar = require("tar")
|
||||
local deflate = require("deflate")
|
||||
local httpcache = {}
|
||||
|
||||
local json = require("json")
|
||||
local http = require("http")
|
||||
local deflate = require("deflate")
|
||||
|
||||
local function checkRepo(repo)
|
||||
local resp = http.get(repo)
|
||||
if resp.code ~= 200 then
|
||||
return false
|
||||
local function get(url)
|
||||
if httpcache[url] then return httpcache[url] end
|
||||
local ret = http.get(url)
|
||||
httpcache[url] = ret
|
||||
return ret
|
||||
end
|
||||
local repojson = json.decode(resp.body)
|
||||
if not repojson then
|
||||
return false
|
||||
|
||||
while i <= #inpArgs do
|
||||
local v = inpArgs[i]
|
||||
|
||||
if v:sub(1, 2) == "--" then
|
||||
local opt, value = v:match("^%-%-(.-)=(.*)$")
|
||||
|
||||
if not opt then
|
||||
opt = v:sub(3)
|
||||
end
|
||||
|
||||
if cloptions[opt] == nil then
|
||||
print("spm: unrecognized option '" .. v .. "'.")
|
||||
print("try 'spm --help' for more information.")
|
||||
return
|
||||
end
|
||||
|
||||
if type(cloptions[opt]) == "boolean" then
|
||||
cloptions[opt] = true
|
||||
else
|
||||
if value == nil then
|
||||
i = i + 1
|
||||
value = inpArgs[i]
|
||||
end
|
||||
|
||||
if value == nil then
|
||||
print("spm: option '--" .. opt .. "' requires an argument.")
|
||||
return
|
||||
end
|
||||
|
||||
cloptions[opt] = value
|
||||
end
|
||||
|
||||
elseif v:sub(1, 1) == "-" then
|
||||
for j = 2, #v do
|
||||
local opt = v:sub(j, j)
|
||||
|
||||
if cloptions[opt] == nil then
|
||||
print("spm: invalid option '-" .. opt .. "'.")
|
||||
print("try 'spm --help' for more information.")
|
||||
return
|
||||
end
|
||||
|
||||
if type(cloptions[opt]) ~= "boolean" then
|
||||
print("spm: option '-" .. opt .. "' requires the long form '--" .. opt .. "=value'.")
|
||||
return
|
||||
end
|
||||
|
||||
cloptions[opt] = true
|
||||
end
|
||||
|
||||
else
|
||||
table.insert(args, v)
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
return true, repojson
|
||||
end
|
||||
|
||||
local function getRepos(root)
|
||||
local repos = {}
|
||||
local visited = {}
|
||||
if cloptions.sysroot=="" then
|
||||
syscall.chdir("/")
|
||||
else
|
||||
syscall.chdir(cloptions.sysroot)
|
||||
end
|
||||
|
||||
local queue = {root}
|
||||
local head = 1
|
||||
if cloptions.init then
|
||||
fs.mkdir("var/spm/cache/")
|
||||
fs.mkdir("var/spm/db/")
|
||||
fs.writeAllText("var/spm/db/repos.list","")
|
||||
fs.mkdir("var/spm/db/installed/")
|
||||
fs.mkdir("etc/spm/")
|
||||
fs.writeAllText("etc/spm/sources.list","https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm.json\nhttp://localhost:8000/spm.json")
|
||||
end
|
||||
|
||||
while head <= #queue do
|
||||
local url = queue[head]
|
||||
head = head + 1
|
||||
if not fs.exists("var/spm/") or not fs.exists("etc/spm/") then
|
||||
print("spm not initialized run \"spm --init\"")
|
||||
return
|
||||
end
|
||||
|
||||
if not visited[url] then
|
||||
visited[url] = true
|
||||
local repodb = string.split(fs.readAllText("var/spm/db/repos.list"), "\n")
|
||||
local sourcelist = string.split(fs.readAllText("etc/spm/sources.list"), "\n")
|
||||
local pkgdblist = fs.list("var/spm/db/installed/")
|
||||
local pkgdb = {}
|
||||
|
||||
local ok, repo = checkRepo(url)
|
||||
if ok then
|
||||
table.insert(repos, {
|
||||
url = url,
|
||||
data = repo
|
||||
})
|
||||
for _,v in ipairs(pkgdblist) do
|
||||
local file = fs.readAllText("var/spm/db/installed/"..v)
|
||||
pkgdb[v] = json.decode(file)
|
||||
end
|
||||
|
||||
if repo.refs then
|
||||
for _, ref in ipairs(repo.refs) do
|
||||
if not visited[ref] then
|
||||
queue[#queue + 1] = ref
|
||||
local function printpkgs(list)
|
||||
local colWidth=0
|
||||
local tmp = syscall.devctl(1, "size")
|
||||
local sizeX, sizeY = tonumber(tmp:sub(1, tmp:find(";")-1)), tonumber(tmp:sub(tmp:find(";")+1))
|
||||
for _, v in ipairs(list) do
|
||||
if #v + 2 > colWidth then colWidth = #v + 2 end
|
||||
end
|
||||
local numCols = math.max(1, math.floor(sizeX / colWidth))
|
||||
|
||||
for i, v in ipairs(list) do
|
||||
printInline(v.id)
|
||||
printInline((" "):rep(colWidth - #v))
|
||||
if i % numCols == 0 then print("") end
|
||||
end
|
||||
if #list % numCols ~= 0 then print("") end
|
||||
end
|
||||
|
||||
local function checkRepo(repo)
|
||||
local resp = get(repo)
|
||||
if not resp then return false end
|
||||
if resp.code ~= 200 then
|
||||
return false
|
||||
end
|
||||
local repojson = json.decode(resp.body)
|
||||
if not repojson then
|
||||
return false
|
||||
end
|
||||
return true, repojson
|
||||
end
|
||||
|
||||
local function getRepos(root)
|
||||
local repos = {}
|
||||
local visited = {}
|
||||
|
||||
local queue = table.values(root)
|
||||
local head = 1
|
||||
|
||||
while head <= #queue do
|
||||
local url = queue[head]
|
||||
head = head + 1
|
||||
|
||||
if not visited[url] then
|
||||
visited[url] = true
|
||||
|
||||
print("GET:"..tostring(head-1).." "..url)
|
||||
|
||||
local ok, repo = checkRepo(url)
|
||||
if ok then
|
||||
table.insert(repos, url)
|
||||
|
||||
if repo.refs then
|
||||
for _, ref in ipairs(repo.refs) do
|
||||
if not visited[ref] then
|
||||
queue[#queue + 1] = ref
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return repos
|
||||
end
|
||||
|
||||
return repos
|
||||
end
|
||||
local function getPkg(name)
|
||||
for _, url in ipairs(repodb) do
|
||||
local ok, repo = checkRepo(url)
|
||||
if not ok then
|
||||
print("Failed to contact repository:")
|
||||
print(url)
|
||||
print("Consider running 'spm -Sy' to remove broken repositories.")
|
||||
else
|
||||
if repo.packages then
|
||||
if repo.packages[name] then
|
||||
local pkgurl = repo.packages[name]
|
||||
local resp = get(pkgurl)
|
||||
if not resp then
|
||||
print("Repository: "..url)
|
||||
print("Has broken package: "..name)
|
||||
print("Ignoring")
|
||||
else
|
||||
if resp.code ~= 200 then
|
||||
print("Repository: "..url)
|
||||
print("Has broken package: "..name)
|
||||
print("Ignoring")
|
||||
else
|
||||
local pkgjson = json.decode(resp.body)
|
||||
if not pkgjson then
|
||||
print("Repository: "..url)
|
||||
print("Has broken package: "..name)
|
||||
print("Ignoring")
|
||||
else
|
||||
return {
|
||||
url=pkgurl,
|
||||
tar=pkgjson.tarball,
|
||||
hash=pkgjson.hash,
|
||||
id=pkgjson.id,
|
||||
deps=pkgjson.dependencies,
|
||||
desc=pkgjson.description,
|
||||
auth=pkgjson.authors,
|
||||
ver=pkgjson.version
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false, "target not found: "..name
|
||||
end
|
||||
|
||||
local function getPkg(name)
|
||||
|
||||
end
|
||||
if cloptions.S then
|
||||
if cloptions.y then
|
||||
print("Updating repositories...")
|
||||
repodb={}
|
||||
for _,v in ipairs(getRepos(sourcelist)) do
|
||||
repodb[#repodb+1]=v
|
||||
end
|
||||
print("Writing new data...")
|
||||
local str = ""
|
||||
for _,v in ipairs(repodb) do
|
||||
str=str..v.."\n"
|
||||
end
|
||||
fs.writeAllText("var/spm/db/repos.list", str)
|
||||
end
|
||||
if cloptions.i then
|
||||
-- info remote
|
||||
end
|
||||
local needed = {}
|
||||
local found = {}
|
||||
for i,v in ipairs(args) do
|
||||
local pkg, err = getPkg(v)
|
||||
if not pkg then print(err) syscall.exit(1) end
|
||||
needed[#needed+1] = pkg
|
||||
found[v]=true
|
||||
end
|
||||
if cloptions.u then
|
||||
for i,v in ipairs(table.keys(pkgdb)) do
|
||||
local pkg, err = getPkg(v)
|
||||
if pkg then
|
||||
needed[#needed+1] = pkg
|
||||
found[v]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
local head = 0
|
||||
while head<#needed do
|
||||
head=head+1
|
||||
for i,v in ipairs(needed[head].deps) do
|
||||
if not found[v] and not pkgdb[v] then
|
||||
local pkg, err = getPkg(v)
|
||||
if pkg then
|
||||
needed[#needed+1] = pkg
|
||||
found[v]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if #needed==0 then
|
||||
syscall.exit()
|
||||
end
|
||||
print("")
|
||||
print("Packages("..tostring(#needed).."):")
|
||||
printpkgs(needed)
|
||||
print("")
|
||||
while true do
|
||||
local text = userinput(0, "Proceed with download [Y/n]", nil, 1)
|
||||
if text=="" then
|
||||
break
|
||||
elseif text:lower()=="y" then
|
||||
break
|
||||
elseif text:lower()=="n" then
|
||||
syscall.exit()
|
||||
end
|
||||
end
|
||||
|
||||
if args[1] == "install" then
|
||||
local pkg=getPkg(args[2])
|
||||
elseif args[1] == "sync" then
|
||||
error("not implemented")
|
||||
elseif args[1] == "remove" then
|
||||
error("not implemented")
|
||||
local files = {}
|
||||
for _,v in ipairs(needed) do
|
||||
local file = http.get(v.tar)
|
||||
|
||||
end
|
||||
|
||||
elseif cloptions.R then
|
||||
-- remove tree
|
||||
elseif cloptions.Q then
|
||||
if cloptions.l then
|
||||
-- list installed files
|
||||
elseif cloptions.o then
|
||||
-- get package file arg[1] is from
|
||||
elseif cloptions.e then
|
||||
-- list installed manually
|
||||
elseif cloptions.i then
|
||||
-- list installed info
|
||||
elseif cloptions.t then
|
||||
-- list orphans
|
||||
end
|
||||
end
|
||||
end
|
||||
local ok,err = xpcall(spm, debug.traceback, ...)
|
||||
if not ok then
|
||||
print("Fatal error in spm:")
|
||||
print(err)
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
tar
|
||||
deflate
|
||||
json
|
||||
minify
|
||||
@@ -0,0 +1,2 @@
|
||||
Hyperion
|
||||
Astronand
|
||||
@@ -0,0 +1,201 @@
|
||||
local LibDeflate = require("LibDeflate")
|
||||
local tar = {}
|
||||
|
||||
local function pad512(n)
|
||||
return math.ceil(n / 512) * 512
|
||||
end
|
||||
|
||||
local function octal(n, size)
|
||||
local s = string.format("%0" .. (size - 1) .. "o", n)
|
||||
return s .. "\0"
|
||||
end
|
||||
|
||||
local function header(name, size, typeflag, link)
|
||||
local h = string.rep("\0", 512)
|
||||
|
||||
local function put(pos, len, value)
|
||||
h = h:sub(1, pos - 1) ..
|
||||
value ..
|
||||
h:sub(pos + len)
|
||||
end
|
||||
|
||||
put(1, 100, name)
|
||||
put(101, 8, octal(0, 8))
|
||||
put(109, 8, octal(0, 8))
|
||||
put(117, 8, octal(0, 8))
|
||||
put(125, 12, octal(size, 12))
|
||||
put(137, 12, octal(os.time(), 12))
|
||||
put(149, 8, " ")
|
||||
put(157, 1, typeflag)
|
||||
|
||||
if link then
|
||||
put(158, 100, link)
|
||||
end
|
||||
|
||||
put(257, 6, "ustar\0")
|
||||
put(263, 2, "00")
|
||||
|
||||
local sum = 0
|
||||
for i = 1, 512 do
|
||||
sum = sum + h:byte(i)
|
||||
end
|
||||
|
||||
put(149, 8, string.format("%06o\0 ", sum))
|
||||
|
||||
return h
|
||||
end
|
||||
|
||||
local function add(out, node, prefix)
|
||||
local path = prefix and (prefix .. "/" .. node.name)
|
||||
or node.name
|
||||
|
||||
if node.type == "dir" then
|
||||
table.insert(out, header(path .. "/", 0, "5"))
|
||||
|
||||
for _, child in ipairs(node.content) do
|
||||
add(out, child, path)
|
||||
end
|
||||
|
||||
elseif node.type == "file" then
|
||||
local data = node.content or ""
|
||||
|
||||
table.insert(out, header(path, #data, "0"))
|
||||
table.insert(out, data)
|
||||
|
||||
local padding = pad512(#data) - #data
|
||||
if padding > 0 then
|
||||
table.insert(out, string.rep("\0", padding))
|
||||
end
|
||||
|
||||
elseif node.type == "symlink" then
|
||||
table.insert(out,
|
||||
header(path, 0, "2", node.content)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function tar.pack(tree, gzip)
|
||||
local out = {}
|
||||
|
||||
add(out, tree)
|
||||
|
||||
table.insert(out, string.rep("\0", 1024))
|
||||
|
||||
local data = table.concat(out)
|
||||
|
||||
if gzip then
|
||||
return LibDeflate:CompressGzip(data)
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
local function read_octal(s)
|
||||
s = s:gsub("\0.*", "")
|
||||
return tonumber(s, 8) or 0
|
||||
end
|
||||
|
||||
function tar.unpack(data)
|
||||
if data:sub(1,2) == "\31\139" then
|
||||
data = assert(LibDeflate:DecompressGzip(data))
|
||||
end
|
||||
|
||||
local root = {
|
||||
type = "dir",
|
||||
name = "",
|
||||
content = {}
|
||||
}
|
||||
|
||||
local function add_path(parts, node)
|
||||
local current = root
|
||||
|
||||
for i = 1, #parts - 1 do
|
||||
local name = parts[i]
|
||||
local found
|
||||
|
||||
for _, child in ipairs(current.content) do
|
||||
if child.name == name and child.type == "dir" then
|
||||
found = child
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
found = {
|
||||
type = "dir",
|
||||
name = name,
|
||||
content = {}
|
||||
}
|
||||
table.insert(current.content, found)
|
||||
end
|
||||
|
||||
current = found
|
||||
end
|
||||
|
||||
table.insert(current.content, node)
|
||||
end
|
||||
|
||||
local pos = 1
|
||||
|
||||
while pos + 511 <= #data do
|
||||
local h = data:sub(pos, pos + 511)
|
||||
|
||||
if h == string.rep("\0", 512) then
|
||||
break
|
||||
end
|
||||
|
||||
local name = h:sub(1,100):gsub("\0.*", "")
|
||||
local size = read_octal(h:sub(125,136))
|
||||
local kind = h:sub(157,157)
|
||||
|
||||
local skip = false
|
||||
|
||||
-- Ignore PAX headers and GNU long filename records
|
||||
if kind == "x" or kind == "g" or kind == "L" then
|
||||
skip = true
|
||||
end
|
||||
|
||||
if not skip then
|
||||
local node
|
||||
|
||||
if kind == "5" then
|
||||
node = {
|
||||
type = "dir",
|
||||
name = name:gsub("/$", ""),
|
||||
content = {}
|
||||
}
|
||||
|
||||
elseif kind == "2" then
|
||||
node = {
|
||||
type = "symlink",
|
||||
name = name,
|
||||
content =
|
||||
h:sub(158,257):gsub("\0.*", "")
|
||||
}
|
||||
|
||||
else
|
||||
node = {
|
||||
type = "file",
|
||||
name = name,
|
||||
content =
|
||||
data:sub(pos + 512,
|
||||
pos + 511 + size)
|
||||
}
|
||||
end
|
||||
|
||||
local parts = {}
|
||||
|
||||
for part in node.name:gmatch("[^/]+") do
|
||||
table.insert(parts, part)
|
||||
end
|
||||
|
||||
add_path(parts, node)
|
||||
end
|
||||
|
||||
pos = pos + 512 + pad512(size)
|
||||
end
|
||||
|
||||
return root
|
||||
end
|
||||
|
||||
return tar
|
||||
+2
-1
@@ -122,7 +122,7 @@ def create_package(folder):
|
||||
DEFAULT_VERSION,
|
||||
),
|
||||
"hash": package_hash,
|
||||
"tarball": f"{API_ROOT}/packages/raw/{name}.tar.xz",
|
||||
"tarball": f"{API_ROOT}/packages/raw/{name}.tar.gz",
|
||||
}
|
||||
|
||||
with open(pkg_file, "w", encoding="utf-8") as file:
|
||||
@@ -166,6 +166,7 @@ def update_spm():
|
||||
packages[metadata["id"]] = f"{API_ROOT}/packages/{pkg.name}"
|
||||
|
||||
spm["packages"] = packages
|
||||
spm["self"] = f"{API_ROOT}/spm.json"
|
||||
|
||||
with open(ROOT / "spm.json", "w", encoding="utf-8") as file:
|
||||
json.dump(spm, file, indent=4)
|
||||
|
||||
+8
-1
@@ -670,4 +670,11 @@ printInline=function(...) end
|
||||
--- Prints text to stdout with format
|
||||
--- @param fmt string
|
||||
--- @param ... any
|
||||
printf=function(fmt, ...) end
|
||||
printf=function(fmt, ...) end
|
||||
|
||||
--- Gets input from fd
|
||||
--- @param fd integer
|
||||
--- @param helpstr string
|
||||
--- @param replacechar string
|
||||
--- @param fdo integer
|
||||
userinput=function(fd, helpstr, replacechar, fdo) end
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "e83a8dc42a871c1e16cd56c214cf0ca4bb0079432dc8bd198abbe11d6cf31d4e",
|
||||
"hash": "e70a3cff68a821b6d1641553c2b1495e07930bcd5808db63e8768608a928339e",
|
||||
"tarball": "http://localhost:8000/packages/raw/Hyperion-core.tar.xz"
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "f64be830fc02394eeb9c049a528ed47b97430c6682a577c789d16303dcaad6fc",
|
||||
"hash": "771fd62d79ff857a1ea1cf3caae340a40b08bc2330fcc6b012b9e07d001ddb45",
|
||||
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ac.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "f3f030d6f6faa137f9950f0ce4ccc598a9b29c729380c100c920fad5aa254076",
|
||||
"hash": "f79a5a9f657acc72bb97c7731c06e366f4118c8d5d5324f8e35a958f95be2796",
|
||||
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ccpc.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.3.0",
|
||||
"hash": "dd69c26ba6f46acb99d6f839474fc50283524bd99df7f67a5d300a749af86dde",
|
||||
"hash": "c2b234005baa8bee1b753b96808f0b326a7f035d65e52295cb93320d5a397886",
|
||||
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-cct.tar.xz"
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "0.1.0",
|
||||
"hash": "8b1bbff272dd07f0e5023c90007ec8d3a84f5b29a59449a75894319c86ee10cd",
|
||||
"hash": "f7805a3934a09cc3384d82a20ade2adc81afa3e403055cda191bf5cdc31bcc2b",
|
||||
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-oc.tar.xz"
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.5.0",
|
||||
"hash": "a17552597f1a4e661804bcf23d26e19664cb6f75cb3058357603df59b033155a",
|
||||
"hash": "68b8f1ae21a62e627bad1187b828c959c93454d1b75a29db00a1a31b187796d0",
|
||||
"tarball": "http://localhost:8000/packages/raw/Hyperion-kernel.tar.xz"
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "9bc32da8ab97f899e85faeb47064433ef4a167e45924c0e583d30f901551bdf5",
|
||||
"hash": "a92fbf2d886c1ee965b1d34aed8bcf5294d97fd0f55a981e82ba5d17171e99e9",
|
||||
"tarball": "http://localhost:8000/packages/raw/bit32.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "c32e2bbeba5d8609f720bce59fad0505d490ee22a6e54b4d830a524e609ac415",
|
||||
"hash": "2ee62a46d32e3d302453d4cb04ac8af72771645b8120e1d827eeb47b599eb192",
|
||||
"tarball": "http://localhost:8000/packages/raw/blake2s.tar.xz"
|
||||
}
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "c52244c7fd2ca96780ed684327ebb55872757a4f6c8d90e18367ec4e0d8f10ad",
|
||||
"hash": "dc2b541f3b9eaf8f0fd41afdaef95d2a2c37a05c01e1e6143dd0d17380f75340",
|
||||
"tarball": "http://localhost:8000/packages/raw/coreutils.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0-release",
|
||||
"hash": "43a3df0e6da39aa97c0ee0ce4217e9acffadba4178d03dae5c66bf4627147644",
|
||||
"hash": "e35f29c486d4a002e46b5c4e85676c480310829b606fc72d093ed86e7daab91d",
|
||||
"tarball": "http://localhost:8000/packages/raw/deflate.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "88eb9f9bb7bb86fb7752601c67e4ab62e88fb7562057a83c101aaf7ffc3ccdc0",
|
||||
"hash": "73515e60e945b7dc9e5adb34db499e52cec9a44ff688d30ce7600025572a3e4c",
|
||||
"tarball": "http://localhost:8000/packages/raw/gfxterm.tar.xz"
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.3.0",
|
||||
"hash": "d0baaeb889eeaa38a9f100c4954b8f30c36c220ba73d8b8fa878e0fcaeaadb15",
|
||||
"hash": "f01bd72d19c57a3a12c940fb2fd8d09b53a47eb857e09ecbca6464199dba35ae",
|
||||
"tarball": "http://localhost:8000/packages/raw/hysh.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "f26f900027066dc2f498a4ccb8306f48c93210e7869b11f4aef9900f2e00e066",
|
||||
"hash": "6a883872f8f1db19617b99aae58358dc603f54801b7cde035b603773f03c7ca1",
|
||||
"tarball": "http://localhost:8000/packages/raw/iniparse.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "8623a44260062d0066aecc683b45c2ea9e6f438fd74cef050e7bcac7daa33a4f",
|
||||
"hash": "3d57052898dfbfcb645cc407523702d4df91675a17bd04754b6494c3e9d2a53b",
|
||||
"tarball": "http://localhost:8000/packages/raw/installer.tar.xz"
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "8344035d687f5cafb8c918d6bddd2ba5a7d6c2025aa43def84b942a614583282",
|
||||
"hash": "f27f343ab85bb4dc8bd0ee6882a01aaaceeb38c791f672b54c2f1d6e80d4287e",
|
||||
"tarball": "http://localhost:8000/packages/raw/json.tar.xz"
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.2.0",
|
||||
"hash": "69978317dbe981a50aa3194ed68d35bbd4d1e87ba03191aa7b3574712861e54c",
|
||||
"hash": "0ce3793bcef753f01ced1d5db88f39840ffbbd15eb485e32ebfc9191f0f67360",
|
||||
"tarball": "http://localhost:8000/packages/raw/lua.tar.xz"
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "20619f7885c20cef538842ad1a958dd5dfbd9a3542997acd7de91f89e57e32db",
|
||||
"hash": "cb53fe713bb74dc76f66bac0d856525ab4aeb9ab9ac1c09ca1a674ad646378fd",
|
||||
"tarball": "http://localhost:8000/packages/raw/micro.tar.xz"
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "bbbc1c2137b76aec328bf8cc0d246f852af35943175fbcd8e1bf55fc9348e4ba",
|
||||
"hash": "47f8e1658373657131d514af623e7cf74fdc3165e8d4c05634fd064eb1217ef8",
|
||||
"tarball": "http://localhost:8000/packages/raw/minify.tar.xz"
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "b1941d2a2699774ab94886d866198219608544f63bee6cf2f059d5b1ed9c86e8",
|
||||
"hash": "6736ecf743bbe3a09c223c7f73d5247056a103ec334813ada62f9bd50720f412",
|
||||
"tarball": "http://localhost:8000/packages/raw/pid.tar.xz"
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+6
-2
@@ -5,8 +5,12 @@
|
||||
"Hyperion",
|
||||
"Astronand"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"tar",
|
||||
"deflate",
|
||||
"json"
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"hash": "55f9a95f5fd032f6a9ad27c9528987f9051554d506f1dddb4494daf822db5e1b",
|
||||
"hash": "26d7cf304ad0bc36fbfa80af1b7af957de29a6c233e6d8a302b2b562f78326db",
|
||||
"tarball": "http://localhost:8000/packages/raw/spm.tar.xz"
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.1.0",
|
||||
"hash": "f4a3947d96d85bae5c43342567ed87fae99d1f4e692e99f42df8cec7cb556451",
|
||||
"hash": "379cae7a2c42b5b0c30476c7660148c60ac426664627c649060c8feca01aa33f",
|
||||
"tarball": "http://localhost:8000/packages/raw/sysinit.tar.xz"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "tar",
|
||||
"description": "",
|
||||
"authors": [
|
||||
"Hyperion",
|
||||
"Astronand"
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "",
|
||||
"hash": "2549429f0686c88354b091cbbd0cd7f80148115178cb3e5198924de28c7da6f4",
|
||||
"tarball": "http://localhost:8000/packages/raw/tar.tar.xz"
|
||||
}
|
||||
+1
-1
@@ -10,6 +10,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "1b5d564b4fea1af5a5e3fde1790298b9f9e7182ad2697b936bc551acffa2beef",
|
||||
"hash": "38422b0eb99cef1122d4aeb3472e705ba304f58713280449bd3a6a492bacd521",
|
||||
"tarball": "http://localhost:8000/packages/raw/xz.tar.xz"
|
||||
}
|
||||
|
||||
@@ -21,12 +21,15 @@
|
||||
"pid": "http://localhost:8000/packages/pid.pkg",
|
||||
"spm": "http://localhost:8000/packages/spm.pkg",
|
||||
"sysinit": "http://localhost:8000/packages/sysinit.pkg",
|
||||
"tar": "http://localhost:8000/packages/tar.pkg",
|
||||
"xz": "http://localhost:8000/packages/xz.pkg"
|
||||
},
|
||||
"refs": [
|
||||
"https://git.astronand.dev/Astronand/HyperionOS-packages/raw/branch/main/spm.json"
|
||||
"https://git.astronand.dev/Astronand/HyperionOS-packages/raw/branch/main/spm.json",
|
||||
"http://localhost:8001/spm.json"
|
||||
],
|
||||
"maintainers": [
|
||||
"Hyperion"
|
||||
]
|
||||
],
|
||||
"self": "http://localhost:8000/spm.json"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user