finished http implementation working on spm and liveboot env
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
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
|
||||||
@@ -26,8 +26,7 @@ local function parseUrl(url)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function buildRequest(req)
|
local function buildRequest(req)
|
||||||
local host, path =
|
local host, path = parseUrl(req.url)
|
||||||
parseUrl(req.url)
|
|
||||||
|
|
||||||
if not host then
|
if not host then
|
||||||
return nil, path
|
return nil, path
|
||||||
@@ -75,73 +74,39 @@ local function buildRequest(req)
|
|||||||
return table.concat(out, "\r\n")
|
return table.concat(out, "\r\n")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function parseResponse(raw)
|
local function parseResponse(response)
|
||||||
local headerEnd =
|
local headerBlock, body = response:match("^(.-)\r\n\r\n(.*)$")
|
||||||
raw:find(
|
if not headerBlock then
|
||||||
"\r\n\r\n",
|
return nil, "invalid HTTP response"
|
||||||
1,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
if not headerEnd then
|
|
||||||
return nil, "EBADMSG"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local headerPart =
|
|
||||||
raw:sub(1, headerEnd - 1)
|
|
||||||
|
|
||||||
local body =
|
|
||||||
raw:sub(headerEnd + 4)
|
|
||||||
|
|
||||||
local lines = {}
|
|
||||||
|
|
||||||
for line in headerPart:gmatch("[^\r\n]+") do
|
|
||||||
lines[#lines + 1] = line
|
|
||||||
end
|
|
||||||
|
|
||||||
local _, code, msg =
|
|
||||||
lines[1]:match(
|
|
||||||
"^(HTTP/%S+)%s+(%d+)%s*(.*)$"
|
|
||||||
)
|
|
||||||
|
|
||||||
local headers = {}
|
local headers = {}
|
||||||
|
|
||||||
for i = 2, #lines do
|
-- Parse status line
|
||||||
local k, v =
|
local statusLine, rest = headerBlock:match("^(.-)\r\n(.*)$")
|
||||||
lines[i]:match(
|
if not statusLine then
|
||||||
"^([^:]+):%s*(.*)$"
|
statusLine = headerBlock
|
||||||
)
|
rest = ""
|
||||||
|
end
|
||||||
|
|
||||||
if k then
|
local version, code, message = statusLine:match("^(HTTP/%d+%.%d+)%s+(%d+)%s+(.*)$")
|
||||||
headers[k:lower()] = v
|
|
||||||
|
-- Parse headers
|
||||||
|
for line in (rest .. "\r\n"):gmatch("(.-)\r\n") do
|
||||||
|
local key, value = line:match("^([^:]+):%s*(.*)$")
|
||||||
|
if key then
|
||||||
|
headers[key:lower()] = value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
code = tonumber(code),
|
code=tonumber(code),
|
||||||
message = msg,
|
message=message,
|
||||||
headers = headers,
|
headers=headers,
|
||||||
body = body
|
body=body
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local function readAll(fd)
|
|
||||||
local out = ""
|
|
||||||
|
|
||||||
while true do
|
|
||||||
local chunk =
|
|
||||||
syscall.read(fd, 4096)
|
|
||||||
|
|
||||||
if not chunk or chunk == "" then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
out = out .. chunk
|
|
||||||
end
|
|
||||||
|
|
||||||
return out
|
|
||||||
end
|
|
||||||
|
|
||||||
function http.request(req)
|
function http.request(req)
|
||||||
local raw, err =
|
local raw, err =
|
||||||
buildRequest(req)
|
buildRequest(req)
|
||||||
@@ -151,34 +116,50 @@ function http.request(req)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local fd =
|
local fd =
|
||||||
syscall.socket(0, 0)
|
syscall.socket()
|
||||||
|
|
||||||
if not fd then
|
if not fd then
|
||||||
return nil, "ESOCKET"
|
return nil, "ESOCKET"
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok, err =
|
local host, path = parseUrl(req.url)
|
||||||
syscall.connect(fd, req.url)
|
|
||||||
|
if not host then
|
||||||
|
syscall.close(fd)
|
||||||
|
return nil, path
|
||||||
|
end
|
||||||
|
|
||||||
|
local proto = req.url:match("^(https?://)")
|
||||||
|
|
||||||
|
local base = proto .. host
|
||||||
|
|
||||||
|
local ok, err = syscall.connect(fd, base)
|
||||||
|
|
||||||
if not ok then
|
if not ok then
|
||||||
syscall.close(fd)
|
syscall.close(fd)
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok2, err2 =
|
local ok2, err2 = syscall.write(fd, raw)
|
||||||
syscall.write(fd, raw)
|
|
||||||
|
|
||||||
if not ok2 then
|
if not ok2 then
|
||||||
syscall.close(fd)
|
syscall.close(fd)
|
||||||
return nil, err2
|
return nil, err2
|
||||||
end
|
end
|
||||||
|
|
||||||
local resp =
|
local out = {}
|
||||||
readAll(fd)
|
|
||||||
|
while true do
|
||||||
|
local chunk = syscall.read(fd, 4096)
|
||||||
|
if chunk == "" then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
out[#out+1] = chunk
|
||||||
|
end
|
||||||
|
|
||||||
syscall.close(fd)
|
syscall.close(fd)
|
||||||
|
return parseResponse(table.concat(out))
|
||||||
return parseResponse(resp)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function http.get(url, headers)
|
function http.get(url, headers)
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Core library for Hyperion
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
|
GHXX (Advanced Computers)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
firmware for Advanced Computers
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
firmware for CraftOS PC
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -9,25 +9,15 @@ kernel.cct.httpqueue = kernel.cct.httpqueue or {}
|
|||||||
kernel.cct.httpresponse = kernel.cct.httpresponse or {}
|
kernel.cct.httpresponse = kernel.cct.httpresponse or {}
|
||||||
kernel.cct.httperror = kernel.cct.httperror or {}
|
kernel.cct.httperror = kernel.cct.httperror or {}
|
||||||
|
|
||||||
local function parseRawRequest(raw)
|
local function parseRawRequest(raw, address)
|
||||||
local sepLen = 4
|
local headerEnd = raw:find("\r\n\r\n", 1, true)
|
||||||
|
|
||||||
local headerEnd =
|
|
||||||
raw:find("\r\n\r\n", 1, true)
|
|
||||||
|
|
||||||
if not headerEnd then
|
|
||||||
headerEnd =
|
|
||||||
raw:find("\n\n", 1, true)
|
|
||||||
|
|
||||||
sepLen = 2
|
|
||||||
end
|
|
||||||
|
|
||||||
local headerPart
|
local headerPart
|
||||||
local body = ""
|
local body = ""
|
||||||
|
|
||||||
if headerEnd then
|
if headerEnd then
|
||||||
headerPart = raw:sub(1, headerEnd - 1)
|
headerPart = raw:sub(1, headerEnd - 1)
|
||||||
body = raw:sub(headerEnd + sepLen)
|
body = raw:sub(headerEnd + 4)
|
||||||
else
|
else
|
||||||
headerPart = raw
|
headerPart = raw
|
||||||
end
|
end
|
||||||
@@ -42,37 +32,25 @@ local function parseRawRequest(raw)
|
|||||||
return nil, "EINVAL"
|
return nil, "EINVAL"
|
||||||
end
|
end
|
||||||
|
|
||||||
local method, path =
|
local split=string.split(lines[1], " ")
|
||||||
lines[1]:match("^(%S+)%s+(%S+)")
|
if #split~=3 then
|
||||||
|
return nil, "EINVAL"
|
||||||
if not method or not path then
|
|
||||||
return nil, "EBADMSG"
|
|
||||||
end
|
end
|
||||||
|
local method, path, ver = table.unpack(split)
|
||||||
|
|
||||||
local headers = {}
|
local headers = {}
|
||||||
|
|
||||||
for i = 2, #lines do
|
for i = 2, #lines do
|
||||||
local k, v =
|
local k, v = lines[i]:match("^([^:]+):%s*(.*)$")
|
||||||
lines[i]:match("^([^:]+):%s*(.*)$")
|
|
||||||
|
|
||||||
if k then
|
if k then
|
||||||
headers[k] = v
|
headers[k] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local host = headers.Host or headers.host
|
if path:sub(1,1)~="/" then
|
||||||
|
return nil, "EINVAL"
|
||||||
if not host and not path:match("^https?://") then
|
|
||||||
return nil, "EHOSTUNREACH"
|
|
||||||
end
|
|
||||||
|
|
||||||
local url
|
|
||||||
|
|
||||||
if path:match("^https?://") then
|
|
||||||
url = path
|
|
||||||
else
|
|
||||||
url = "http://" .. host .. path
|
|
||||||
end
|
end
|
||||||
|
local url = address..path
|
||||||
|
|
||||||
local req = {
|
local req = {
|
||||||
url = url,
|
url = url,
|
||||||
@@ -84,7 +62,7 @@ local function parseRawRequest(raw)
|
|||||||
req.body = body
|
req.body = body
|
||||||
end
|
end
|
||||||
|
|
||||||
return req
|
return req, url
|
||||||
end
|
end
|
||||||
|
|
||||||
local function buildResponse(resp)
|
local function buildResponse(resp)
|
||||||
@@ -93,37 +71,19 @@ local function buildResponse(resp)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local code, msg = resp.getResponseCode()
|
local code, msg = resp.getResponseCode()
|
||||||
|
local headers = resp.getResponseHeaders()
|
||||||
local headers =
|
local body = resp.readAll() or ""
|
||||||
resp:getResponseHeaders()
|
resp.close()
|
||||||
|
|
||||||
local body =
|
|
||||||
resp:readAll() or ""
|
|
||||||
|
|
||||||
local out = {
|
local out = {
|
||||||
"HTTP/1.1 " ..
|
"HTTP/1.1 " ..
|
||||||
tostring(code) ..
|
tostring(code) ..
|
||||||
" " ..
|
" " ..
|
||||||
tostring(msg)
|
tostring(msg or "")
|
||||||
}
|
}
|
||||||
|
|
||||||
local hasLength = false
|
for i,v in pairs(headers) do
|
||||||
|
out[#out+1] = i..": "..v
|
||||||
for k, v in pairs(headers or {}) do
|
|
||||||
if k:lower() == "content-length" then
|
|
||||||
hasLength = true
|
|
||||||
end
|
|
||||||
|
|
||||||
out[#out + 1] =
|
|
||||||
tostring(k) ..
|
|
||||||
": " ..
|
|
||||||
tostring(v)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not hasLength then
|
|
||||||
out[#out + 1] =
|
|
||||||
"Content-Length: " ..
|
|
||||||
tostring(#body)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
out[#out + 1] = ""
|
out[#out + 1] = ""
|
||||||
@@ -139,155 +99,91 @@ function handler.connect(fd, address)
|
|||||||
return nil, "EBADF"
|
return nil, "EBADF"
|
||||||
end
|
end
|
||||||
|
|
||||||
fdo.socket.rbuf = ""
|
|
||||||
fdo.socket.closed = false
|
|
||||||
fdo.socket.httpid = nil
|
|
||||||
|
|
||||||
fdo.handle.write = function(raw)
|
fdo.handle.write = function(raw)
|
||||||
local req, err =
|
local req, url = parseRawRequest(raw, address)
|
||||||
parseRawRequest(raw)
|
|
||||||
|
|
||||||
if not req then
|
if not req then
|
||||||
return nil, err
|
return nil, url
|
||||||
end
|
end
|
||||||
|
|
||||||
local id =
|
kernel.cct.httpqueue[url] = true
|
||||||
tostring(kernel.uuid())
|
local ok, err = http.request(req)
|
||||||
|
|
||||||
fdo.socket.httpid = id
|
|
||||||
|
|
||||||
kernel.cct.httpqueue[id] = true
|
|
||||||
|
|
||||||
local ok, err =
|
|
||||||
http.request(req, id)
|
|
||||||
|
|
||||||
if not ok then
|
if not ok then
|
||||||
kernel.cct.httpqueue[id] = nil
|
kernel.cct.httpqueue[url] = nil
|
||||||
return nil, err
|
return nil, err
|
||||||
end
|
end
|
||||||
|
if fdo.socket.active then
|
||||||
|
fdo.socket.content=nil
|
||||||
|
fdo.socket.file.close()
|
||||||
|
fdo.socket.file=nil
|
||||||
|
end
|
||||||
|
fdo.socket.active=true
|
||||||
|
fdo.socket.url=url
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
fdo.handle.read = function(count)
|
fdo.handle.read = function(count)
|
||||||
count = count or 4096
|
if not fdo.socket.active then
|
||||||
|
|
||||||
local sock = fdo.socket
|
|
||||||
|
|
||||||
if #sock.rbuf > 0 then
|
|
||||||
local out =
|
|
||||||
sock.rbuf:sub(1, count)
|
|
||||||
|
|
||||||
sock.rbuf =
|
|
||||||
sock.rbuf:sub(count + 1)
|
|
||||||
|
|
||||||
return out
|
|
||||||
end
|
|
||||||
|
|
||||||
local id = sock.httpid
|
|
||||||
|
|
||||||
if not id then
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local function finish(resp)
|
|
||||||
sock.rbuf =
|
|
||||||
buildResponse(resp) or ""
|
|
||||||
|
|
||||||
local out =
|
|
||||||
sock.rbuf:sub(1, count)
|
|
||||||
|
|
||||||
sock.rbuf =
|
|
||||||
sock.rbuf:sub(count + 1)
|
|
||||||
|
|
||||||
return out
|
|
||||||
end
|
|
||||||
|
|
||||||
if kernel.cct.httpresponse[id] then
|
|
||||||
local resp =
|
|
||||||
kernel.cct.httpresponse[id]
|
|
||||||
|
|
||||||
kernel.cct.httpresponse[id] = nil
|
|
||||||
kernel.cct.httpqueue[id] = nil
|
|
||||||
|
|
||||||
return finish(resp)
|
|
||||||
end
|
|
||||||
|
|
||||||
if kernel.cct.httperror[id] then
|
|
||||||
local err =
|
|
||||||
kernel.cct.httperror[id]
|
|
||||||
|
|
||||||
kernel.cct.httperror[id] = nil
|
|
||||||
kernel.cct.httpqueue[id] = nil
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
end
|
|
||||||
|
|
||||||
kernel.currentTask.status = "D"
|
|
||||||
|
|
||||||
local coro
|
|
||||||
|
|
||||||
coro = function()
|
|
||||||
if kernel.cct.httpresponse[id] then
|
|
||||||
local resp =
|
|
||||||
kernel.cct.httpresponse[id]
|
|
||||||
|
|
||||||
kernel.cct.httpresponse[id] = nil
|
|
||||||
kernel.cct.httpqueue[id] = nil
|
|
||||||
|
|
||||||
kernel.asyncReturn(
|
|
||||||
finish(resp)
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if kernel.cct.httperror[id] then
|
if not kernel.cct.httpqueue[fdo.socket.url] then
|
||||||
local err =
|
fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url]))
|
||||||
kernel.cct.httperror[id]
|
kernel.cct.httpqueue[fdo.socket.url]=nil
|
||||||
|
kernel.cct.httpresponse[fdo.socket.url]=nil
|
||||||
|
end
|
||||||
|
|
||||||
kernel.cct.httperror[id] = nil
|
if not fdo.socket.file then
|
||||||
kernel.cct.httpqueue[id] = nil
|
kernel.currentTask.io=function()
|
||||||
|
if not kernel.cct.httpqueue[fdo.socket.url] then
|
||||||
kernel.asyncReturn(
|
fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url]))
|
||||||
nil,
|
kernel.cct.httpqueue[fdo.socket.url]=nil
|
||||||
err
|
kernel.cct.httpresponse[fdo.socket.url]=nil
|
||||||
)
|
return fdo.socket.file.read(count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
kernel.currentTask.status="D"
|
||||||
|
return
|
||||||
|
else
|
||||||
|
return fdo.socket.file.read(count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
fdo.handle.seek = function(whence, offset)
|
||||||
|
if not fdo.socket.active then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
coroutine.yield()
|
if not kernel.cct.httpqueue[fdo.socket.url] then
|
||||||
|
fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url]))
|
||||||
|
kernel.cct.httpqueue[fdo.socket.url]=nil
|
||||||
|
kernel.cct.httpresponse[fdo.socket.url]=nil
|
||||||
end
|
end
|
||||||
|
|
||||||
kernel.currentTask.ksh =
|
if not fdo.socket.file then
|
||||||
coroutine.create(function()
|
kernel.currentTask.io=function()
|
||||||
local ok, err =
|
if not kernel.cct.httpqueue[fdo.socket.url] then
|
||||||
xpcall(
|
fdo.socket.file=kernel.sfile(buildResponse(kernel.cct.httpresponse[fdo.socket.url]))
|
||||||
coro,
|
kernel.cct.httpqueue[fdo.socket.url]=nil
|
||||||
debug.traceback
|
kernel.cct.httpresponse[fdo.socket.url]=nil
|
||||||
)
|
return fdo.socket.file.seek(whence, offset)
|
||||||
|
end
|
||||||
if not ok then
|
end
|
||||||
kernel.asyncReturn(
|
kernel.currentTask.status="D"
|
||||||
nil,
|
return
|
||||||
err
|
else
|
||||||
)
|
return fdo.socket.file.seek(whence, offset)
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
fdo.handle.close = function()
|
fdo.handle.close = function()
|
||||||
fdo.socket.closed = true
|
fdo.socket.file.close()
|
||||||
|
fdo.socket.active=false
|
||||||
local id =
|
kernel.cct.httpqueue[fdo.socket.url] = nil
|
||||||
fdo.socket.httpid
|
kernel.cct.httpresponse[fdo.socket.url] = nil
|
||||||
|
kernel.cct.httperror[fdo.socket.url] = nil
|
||||||
if id then
|
|
||||||
kernel.cct.httpqueue[id] = nil
|
|
||||||
kernel.cct.httpresponse[id] = nil
|
|
||||||
kernel.cct.httperror[id] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -74,11 +74,16 @@ kernel.processes.cctdeamon = function()
|
|||||||
kernel.cct.fifo.push("[nT")
|
kernel.cct.fifo.push("[nT")
|
||||||
end
|
end
|
||||||
elseif eventType == "http_success" then
|
elseif eventType == "http_success" then
|
||||||
|
if kernel.cct.httpqueue[event[2]] then
|
||||||
kernel.cct.httpqueue[event[2]]=nil
|
kernel.cct.httpqueue[event[2]]=nil
|
||||||
kernel.cct.httpresponse[event[2]]=event[3]
|
kernel.cct.httpresponse[event[2]]=event[3]
|
||||||
|
end
|
||||||
elseif eventType == "http_failure" then
|
elseif eventType == "http_failure" then
|
||||||
|
if kernel.cct.httpqueue[event[2]] then
|
||||||
kernel.cct.httpqueue[event[2]]=nil
|
kernel.cct.httpqueue[event[2]]=nil
|
||||||
kernel.cct.httperror[event[2]]=event[3]
|
kernel.cct.httperror[event[2]]=event[3]
|
||||||
|
kernel.cct.httpresponse[event[2]]=event[4]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
timeout = false
|
timeout = false
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
firmware for ComputerCraft Tweaked
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.3.0
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Hyperion
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
firmware for Opencomputers
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
0.1.0
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
|
Spsf
|
||||||
@@ -193,6 +193,100 @@ function kernel.newUUID()
|
|||||||
return uuid
|
return uuid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function kernel.sfile(str, writeable)
|
||||||
|
local buf = {str or ""}
|
||||||
|
local pos = 1
|
||||||
|
local closed = false
|
||||||
|
|
||||||
|
local function content()
|
||||||
|
return table.concat(buf)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function set_content(s)
|
||||||
|
buf = {s}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function flush()
|
||||||
|
str=content()
|
||||||
|
end
|
||||||
|
|
||||||
|
local file = {}
|
||||||
|
|
||||||
|
function file.read(n)
|
||||||
|
assert(not closed, "file is closed")
|
||||||
|
|
||||||
|
local s = content()
|
||||||
|
local len = #s
|
||||||
|
|
||||||
|
if not n then
|
||||||
|
local out = s:sub(pos)
|
||||||
|
pos = len + 1
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
local out = s:sub(pos, pos + n - 1)
|
||||||
|
pos = pos + #out
|
||||||
|
return out
|
||||||
|
end
|
||||||
|
|
||||||
|
if writeable then
|
||||||
|
function file.write(data)
|
||||||
|
assert(not closed, "file is closed")
|
||||||
|
|
||||||
|
local s = content()
|
||||||
|
local before = s:sub(1, pos - 1)
|
||||||
|
local after = s:sub(pos + #data)
|
||||||
|
|
||||||
|
set_content(before .. data .. after)
|
||||||
|
pos = pos + #data
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function file.seek(whence, offset)
|
||||||
|
assert(not closed, "file is closed")
|
||||||
|
|
||||||
|
local s = content()
|
||||||
|
local len = #s
|
||||||
|
|
||||||
|
whence = whence or "cur"
|
||||||
|
offset = offset or 0
|
||||||
|
|
||||||
|
if whence == "set" then
|
||||||
|
pos = offset + 1
|
||||||
|
elseif whence == "cur" then
|
||||||
|
pos = pos + offset
|
||||||
|
elseif whence == "end" then
|
||||||
|
pos = len + offset + 1
|
||||||
|
else
|
||||||
|
error("invalid whence")
|
||||||
|
end
|
||||||
|
|
||||||
|
if pos < 1 then pos = 1 end
|
||||||
|
if pos > len + 1 then pos = len + 1 end
|
||||||
|
|
||||||
|
return pos - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function file.close()
|
||||||
|
assert(not closed, "file is closed")
|
||||||
|
flush()
|
||||||
|
closed = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function file.flush()
|
||||||
|
assert(not closed, "file is closed")
|
||||||
|
flush()
|
||||||
|
end
|
||||||
|
|
||||||
|
function file.content()
|
||||||
|
return str
|
||||||
|
end
|
||||||
|
|
||||||
|
return file
|
||||||
|
end
|
||||||
|
|
||||||
kernel.syscalls={}
|
kernel.syscalls={}
|
||||||
local modules={[0]={}}
|
local modules={[0]={}}
|
||||||
for i=0, 100 do
|
for i=0, 100 do
|
||||||
@@ -297,6 +391,7 @@ kernel.syscalls["halt"]=function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
kernel.saveLog()
|
||||||
kernel.log("Running modules")
|
kernel.log("Running modules")
|
||||||
for _,p in ipairs(modules) do
|
for _,p in ipairs(modules) do
|
||||||
for _,v in ipairs(p) do
|
for _,v in ipairs(p) do
|
||||||
@@ -310,6 +405,7 @@ for _,p in ipairs(modules) do
|
|||||||
local status, err = xpcall(func,debug.traceback, kernel)
|
local status, err = xpcall(func,debug.traceback, kernel)
|
||||||
if not status then kernel.panic("ModuRunErr: "..tostring(err)) end
|
if not status then kernel.panic("ModuRunErr: "..tostring(err)) end
|
||||||
if kernel.config.showModLoad then kernel.log("Loaded module "..v, "DBUG", 0x00FFFF) end
|
if kernel.config.showModLoad then kernel.log("Loaded module "..v, "DBUG", 0x00FFFF) end
|
||||||
|
if kernel.config.moreLogsaves then kernel.saveLog() end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -9,55 +9,39 @@ kernel.reqcache = cache
|
|||||||
|
|
||||||
local function require(module, ...)
|
local function require(module, ...)
|
||||||
if cache[module] then return cache[module].ret end
|
if cache[module] then return cache[module].ret end
|
||||||
kernel.currentTask.status = "D"
|
|
||||||
local args = {...}
|
local args = {...}
|
||||||
kernel.currentTask.ksh = coroutine.create(function()
|
|
||||||
local coro = function()
|
|
||||||
for _, path in ipairs(kernel.searchpaths) do
|
for _, path in ipairs(kernel.searchpaths) do
|
||||||
local filepath = path:gsub("?", module)
|
local filepath = path:gsub("?", module)
|
||||||
if kernel.vfs.exists(filepath) then
|
if kernel.vfs.exists(filepath) then
|
||||||
if kernel.vfs.type(filepath) == "directory" then
|
if kernel.vfs.type(filepath) == "directory" then
|
||||||
filepath = filepath .. "/init.lua"
|
filepath = filepath .. "/init.lua"
|
||||||
if kernel.vfs.type(filepath) == "directory" then
|
if kernel.vfs.type(filepath) == "directory" then
|
||||||
kernel.asyncReturn(false, "Module not found: "..module)
|
error("Module not found: "..module)
|
||||||
return
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local fd = kernel.vfs.open(filepath, "r")
|
local fd = kernel.vfs.open(filepath, "r")
|
||||||
local chunks = {}
|
local chunks = {}
|
||||||
while true do
|
while true do
|
||||||
local chunk = kernel.vfs.read(fd, 4096)
|
local chunk = kernel.vfs.read(fd, 4096)
|
||||||
if not chunk or chunk == "" then break end
|
if not chunk or chunk == "" then break end
|
||||||
chunks[#chunks + 1] = chunk
|
chunks[#chunks + 1] = chunk
|
||||||
coroutine.yield()
|
|
||||||
end
|
end
|
||||||
kernel.vfs.close(fd)
|
kernel.vfs.close(fd)
|
||||||
local data = table.concat(chunks)
|
local data = table.concat(chunks)
|
||||||
local func, err = load(data, "@"..module, "t", kernel._U)
|
local func, err = load(data, "@"..module, "t", kernel._U)
|
||||||
if not func then
|
if not func then
|
||||||
kernel.asyncReturn(false, "Error loading module "..module..": "..tostring(err))
|
error("Error loading module "..module..": "..tostring(err))
|
||||||
return
|
|
||||||
end
|
end
|
||||||
local ok, ret = xpcall(func, debug.traceback, table.unpack(args))
|
local ok, ret = xpcall(func, debug.traceback, table.unpack(args))
|
||||||
if not ok then
|
if not ok then
|
||||||
kernel.asyncReturn(false, "Error running module "..module..": "..tostring(ret))
|
error("Error running module "..module..": "..tostring(ret))
|
||||||
return
|
|
||||||
end
|
end
|
||||||
cache[module] = {ret = ret, expires = kernel.EFI:getEpochMs() + 120000}
|
cache[module] = {ret = ret, expires = kernel.EFI:getEpochMs() + 120000}
|
||||||
kernel.asyncReturn(true, ret)
|
return ret
|
||||||
return
|
|
||||||
end
|
end
|
||||||
coroutine.yield()
|
coroutine.yield()
|
||||||
end
|
end
|
||||||
kernel.asyncReturn(false, "Module not found: "..module)
|
error("Module not found: "..module)
|
||||||
end
|
|
||||||
local status, err = xpcall(coro, debug.traceback)
|
|
||||||
if not status then
|
|
||||||
kernel.asyncReturn(false, "Error in require coroutine for module "..module..": "..tostring(err))
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
kernel.syscalls["require"] = require
|
_G.require = function(...) return require(...) end
|
||||||
_G.require = function(...) return syscall.require(...) end
|
|
||||||
@@ -217,7 +217,7 @@ data[".meta"]=strFile(buildMeta({
|
|||||||
log="/var/log/syslog.log"
|
log="/var/log/syslog.log"
|
||||||
}))
|
}))
|
||||||
|
|
||||||
if kernel.EFI:getEEPROM() then
|
if kernel.EFI.getEEPROM then
|
||||||
function data.eeprom(op, mode)
|
function data.eeprom(op, mode)
|
||||||
if op=="type" then
|
if op=="type" then
|
||||||
return "character device"
|
return "character device"
|
||||||
@@ -255,7 +255,7 @@ if kernel.EFI:getEEPROM() then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if kernel.EFI:getNvram() then
|
if kernel.EFI.getNvram then
|
||||||
function data.nvram(op, mode)
|
function data.nvram(op, mode)
|
||||||
if op=="type" then
|
if op=="type" then
|
||||||
return "character device"
|
return "character device"
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ local function getHandler(address)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function socket.socket(domain, socktype)
|
function socket.socket()
|
||||||
local fd = kernel.vfs.newfd({
|
local fd = kernel.vfs.newfd({
|
||||||
handle = {},
|
handle = {},
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ function socket.socket(domain, socktype)
|
|||||||
local fdo = kernel.currentTask.fd[fd]
|
local fdo = kernel.currentTask.fd[fd]
|
||||||
|
|
||||||
fdo.handle.read = function()
|
fdo.handle.read = function()
|
||||||
return ""
|
return nil, "ENOTCONN"
|
||||||
end
|
end
|
||||||
|
|
||||||
fdo.handle.write = function()
|
fdo.handle.write = function()
|
||||||
|
|||||||
@@ -396,22 +396,16 @@ function kernel.main()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if task.status == "D" then
|
if task.status == "D" then
|
||||||
if task.ksh then
|
if task.io then
|
||||||
coroutine.resume(task.ksh)
|
local ret = {xpcall(task.io, debug.traceback)}
|
||||||
if coroutine.status(task.ksh) == "dead" then
|
if not ret[1] then
|
||||||
task.ksh = nil
|
task.syscallReturn = {false, table.unpack(ret, 2)}
|
||||||
if task.status == "D" then
|
|
||||||
task.status = "R"
|
task.status = "R"
|
||||||
end
|
task.io=nil
|
||||||
|
elseif #ret>1 then
|
||||||
if kernel.config.debugSyscalls then
|
task.syscallReturn = {true, table.unpack(ret, 2)}
|
||||||
kernel.log("Task " .. task.pid .. " IO wait completed", "DBUG", 0x00FFFF)
|
task.status = "R"
|
||||||
local sysret = task.syscallReturn
|
task.io=nil
|
||||||
for i = 2, #sysret do
|
|
||||||
local v = type(sysret[i]) == "table" and table.serialize(sysret[i]) or tostring(sysret[i])
|
|
||||||
kernel.log(" retval[" .. (i-1) .. "] = " .. v, "DBUG", 0x00FFFF)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ kernel.tasks["1"] = {
|
|||||||
else
|
else
|
||||||
kernel.panic("Init system exited: " .. tostring(err))
|
kernel.panic("Init system exited: " .. tostring(err))
|
||||||
end
|
end
|
||||||
|
kernel.saveLog()
|
||||||
end),
|
end),
|
||||||
|
|
||||||
name = "sysinit",
|
name = "sysinit",
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
--:Minify:--
|
|
||||||
local kernel = ...
|
|
||||||
if not kernel.vfs.exists("/root") then kernel.vfs.mkdir("/root") end
|
|
||||||
|
|
||||||
kernel.processes.login = function()
|
|
||||||
local ok, err = pcall(kernel.hpv.execspawn, "/bin/login", "login")
|
|
||||||
if not ok then
|
|
||||||
kernel.log("Failed to exec /bin/login: " .. tostring(err), "ERROR", 0xFF0000)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Hyperion kernel package
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.5.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Lua
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Bit32 package for Hyperion
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
blake2s package for Hyperion
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
|
Spsf
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
--:Minify:--
|
||||||
|
syscall.open("/dev/input/keyboard1", "r") --stdin (fd 0)
|
||||||
|
syscall.open("/dev/tty/1", "w") --stdout (fd 1)
|
||||||
|
syscall.open("/dev/null", "w") --stderr (fd 2)
|
||||||
|
|
||||||
|
|
||||||
|
local MAX_ATTEMPTS = 3
|
||||||
|
|
||||||
|
local function readLine(mask)
|
||||||
|
local input = ""
|
||||||
|
while true do
|
||||||
|
local ch = syscall.read(0)
|
||||||
|
if not ch or ch == "" then
|
||||||
|
elseif ch == "\n" then
|
||||||
|
syscall.write(1, "\n")
|
||||||
|
return input
|
||||||
|
elseif ch == "\b" then
|
||||||
|
if #input > 0 then
|
||||||
|
input = input:sub(1, -2)
|
||||||
|
syscall.write(1, "\b \b")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
input = input .. ch
|
||||||
|
syscall.write(1, mask or ch)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function firstBoot()
|
||||||
|
local shadow = ""
|
||||||
|
local _fd, _fderr = pcall(function()
|
||||||
|
local fd = syscall.open("/etc/shadow", "r")
|
||||||
|
shadow = syscall.read(fd, 65535) or ""
|
||||||
|
syscall.close(fd)
|
||||||
|
end)
|
||||||
|
if shadow:match("%S") then return end
|
||||||
|
|
||||||
|
syscall.devctl(1, "clear")
|
||||||
|
syscall.devctl(1, "spos", 1, 1)
|
||||||
|
syscall.devctl(1, "sfgc", 0x00FF00)
|
||||||
|
syscall.write(1, "HyperionOS First Boot Setup\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
syscall.write(1, "No root password is set. Please create one now.\n\n")
|
||||||
|
|
||||||
|
while true do
|
||||||
|
syscall.write(1, "New root password: ")
|
||||||
|
local pw1 = readLine("*")
|
||||||
|
syscall.write(1, "Confirm password: ")
|
||||||
|
local pw2 = readLine("*")
|
||||||
|
|
||||||
|
if pw1 ~= pw2 then
|
||||||
|
syscall.devctl(1, "sfgc", 0xFF0000)
|
||||||
|
syscall.write(1, "Passwords do not match. Try again.\n\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
elseif #pw1 < 6 then
|
||||||
|
syscall.devctl(1, "sfgc", 0xFF0000)
|
||||||
|
syscall.write(1, "Password too short (minimum 6 characters).\n\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
else
|
||||||
|
local ok, err = syscall.setpassword(0, pw1)
|
||||||
|
if ok then
|
||||||
|
syscall.devctl(1, "sfgc", 0x00FF00)
|
||||||
|
syscall.write(1, "Root password set.\n\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
sleep(0.5)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
syscall.devctl(1, "sfgc", 0xFF0000)
|
||||||
|
syscall.write(1, "Error: " .. tostring(err) .. "\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function spawnShell(username, uid, shell, homedir)
|
||||||
|
local existsOk, existsErr = pcall(syscall.exists, shell)
|
||||||
|
if not existsOk or not existsErr then
|
||||||
|
syscall.write(1, "login: shell not found: " .. shell .. "\n")
|
||||||
|
sleep(2)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local accessOk, accessErr = pcall(syscall.access, shell, "rx")
|
||||||
|
|
||||||
|
syscall.setEnviron("HOME", homedir)
|
||||||
|
syscall.setEnviron("USER", username)
|
||||||
|
syscall.setEnviron("SHELL", shell)
|
||||||
|
syscall.setEnviron("PATH", "/bin/")
|
||||||
|
|
||||||
|
local setuidOk, setuidErr = pcall(syscall.setuid, uid)
|
||||||
|
if not setuidOk then
|
||||||
|
syscall.write(1, "login: setuid failed: " .. tostring(setuidErr) .. "\n")
|
||||||
|
sleep(2)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local chdirOk, chdirErr = pcall(syscall.chdir, homedir)
|
||||||
|
if not chdirOk then
|
||||||
|
pcall(syscall.chdir, "/")
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, err = pcall(syscall.execspawn, shell, username .. ":shell")
|
||||||
|
if not ok then
|
||||||
|
syscall.write(1, "login: failed to launch shell: " .. tostring(err) .. "\n")
|
||||||
|
sleep(2)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
syscall.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function doLogin()
|
||||||
|
syscall.devctl(1, "clear")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
syscall.devctl(1, "sbgc", 0x000000)
|
||||||
|
syscall.devctl(1, "spos", 1, 1)
|
||||||
|
|
||||||
|
local hostname = syscall.getHostname() or "hyperion"
|
||||||
|
syscall.write(1, "HyperionOS\n")
|
||||||
|
syscall.write(1, hostname .. " login\n\n")
|
||||||
|
|
||||||
|
local attempts = 0
|
||||||
|
while attempts < MAX_ATTEMPTS do
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
syscall.write(1, "Username: ")
|
||||||
|
local username = readLine(nil)
|
||||||
|
|
||||||
|
if username ~= "" then
|
||||||
|
|
||||||
|
syscall.write(1, "Password: ")
|
||||||
|
local password = readLine("*")
|
||||||
|
local uid = syscall.getuidbyname(username)
|
||||||
|
|
||||||
|
local ok, err = syscall.login(uid, password)
|
||||||
|
if ok then
|
||||||
|
local uid = syscall.getuid()
|
||||||
|
local pwent = syscall.getpasswd(uid)
|
||||||
|
|
||||||
|
local shell = (pwent and pwent.shell) or "/bin/hysh"
|
||||||
|
local homedir = (pwent and pwent.homedir) or "/"
|
||||||
|
|
||||||
|
syscall.devctl(1, "sfgc", 0x00FF00)
|
||||||
|
syscall.write(1, "\nWelcome, " .. username .. "!\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
sleep(0.3)
|
||||||
|
|
||||||
|
spawnShell(username, uid, shell, homedir)
|
||||||
|
return -- back to login prompt
|
||||||
|
else
|
||||||
|
attempts = attempts + 1
|
||||||
|
sleep(1)
|
||||||
|
syscall.devctl(1, "sfgc", 0xFF0000)
|
||||||
|
syscall.write(1, "Login incorrect.\n\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
syscall.devctl(1, "sfgc", 0xFF0000)
|
||||||
|
syscall.write(1, "Maximum login attempts exceeded.\n")
|
||||||
|
syscall.devctl(1, "sfgc", 0xFFFFFF)
|
||||||
|
sleep(5)
|
||||||
|
end
|
||||||
|
|
||||||
|
firstBoot()
|
||||||
|
while true do
|
||||||
|
doLogin()
|
||||||
|
end
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
core utilities for user management
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Haoqian He
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Libdeflate for Hyperion
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0-release
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
package providing kernel support for framebuffers and graphics
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Spsf
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Official Hyperion shell package
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.3.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ini parser
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
[
|
|
||||||
"Hyperion-kernel",
|
|
||||||
"Hyperion-core",
|
|
||||||
"hysh",
|
|
||||||
"lua",
|
|
||||||
"micro",
|
|
||||||
"sysinit",
|
|
||||||
"bit32",
|
|
||||||
"json",
|
|
||||||
"muxzcat",
|
|
||||||
"spm"
|
|
||||||
]
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Hyperion os live installer
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
rxi
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
JSON library for Hyperion
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Spsf
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Interactive lua shell
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.2.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Spsf
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
micro text editor
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Hyperion
|
||||||
|
Mark Langen
|
||||||
|
Astronand (added goto support)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
lua minifier
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Proportional Integral Derivative library
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
+65
-3
@@ -1,6 +1,68 @@
|
|||||||
local args={...}
|
local args={...}
|
||||||
|
|
||||||
local json=require("json")
|
-- local test repo
|
||||||
local http=require("http")
|
local rootRepo="http://localhost:8000/spm.json"
|
||||||
local rootRepo="https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm/spm.src"
|
--local rootRepo="https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/spm.json"
|
||||||
|
|
||||||
|
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
|
||||||
|
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 = {root}
|
||||||
|
local head = 1
|
||||||
|
|
||||||
|
while head <= #queue do
|
||||||
|
local url = queue[head]
|
||||||
|
head = head + 1
|
||||||
|
|
||||||
|
if not visited[url] then
|
||||||
|
visited[url] = true
|
||||||
|
|
||||||
|
local ok, repo = checkRepo(url)
|
||||||
|
if ok then
|
||||||
|
table.insert(repos, {
|
||||||
|
url = url,
|
||||||
|
data = repo
|
||||||
|
})
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
local function getPkg(name)
|
||||||
|
|
||||||
|
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")
|
||||||
|
end
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Simple Package Manager
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
--:Minify:--
|
--:Minify:--
|
||||||
local kernel=...
|
local kernel=...
|
||||||
local fs=require("fs")
|
|
||||||
kernel.log("Sysinit started...")
|
kernel.log("Sysinit started...")
|
||||||
kernel.saveLog()
|
kernel.saveLog()
|
||||||
|
local fs=require("fs")
|
||||||
|
kernel.log("Loaded 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)
|
||||||
@@ -16,22 +17,25 @@ for i,v in pairs(kernel.processes) do
|
|||||||
end, i)
|
end, i)
|
||||||
end
|
end
|
||||||
|
|
||||||
if not fs.exists("/bin/startup") then
|
-- config file path setup
|
||||||
fs.mkdir("/bin/startup")
|
if not fs.exists("/etc/sysinit/") then
|
||||||
|
kernel.log("Creating conf path")
|
||||||
|
fs.mkdir("/etc/sysinit/")
|
||||||
|
fs.mkdir("/etc/sysinit/autorun/")
|
||||||
|
fs.mkdir("/etc/sysinit/system/")
|
||||||
|
fs.mkdir("/etc/sysinit/user/")
|
||||||
end
|
end
|
||||||
|
|
||||||
local files = fs.list("/bin/startup")
|
local files = fs.list("/etc/sysinit/autorun/")
|
||||||
if not files then error("Failed to list /bin/startup") end
|
if not files then error("Failed to list autorun") end
|
||||||
for i,v in ipairs(files) do
|
for i,v in ipairs(files) do
|
||||||
if v:sub(-4) == ".lua" then
|
local filepath = "/etc/sysinit/autorun/" .. v
|
||||||
local filepath = "/bin/startup/" .. v
|
|
||||||
kernel.log("Executing startup script: " .. filepath)
|
kernel.log("Executing startup script: " .. filepath)
|
||||||
local startupFunc, err = load(fs.readAllText(filepath), "@" .. filepath)
|
local startupFunc, err = load(fs.readAllText(filepath), "@" .. filepath)
|
||||||
if not startupFunc then
|
if not startupFunc then
|
||||||
kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
|
kernel.log("Error loading startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
|
||||||
else
|
else
|
||||||
syscall.spawn(function()
|
syscall.spawn(function()
|
||||||
syscall.setuid(1)
|
|
||||||
local status, err = pcall(startupFunc)
|
local status, err = pcall(startupFunc)
|
||||||
if not status then
|
if not status then
|
||||||
kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
|
kernel.log("Error executing startup script '" .. filepath .. "': " .. err, "ERROR", 0xFF0000)
|
||||||
@@ -40,7 +44,6 @@ for i,v in ipairs(files) do
|
|||||||
end
|
end
|
||||||
end, "startup:" .. v)
|
end, "startup:" .. v)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
kernel.saveLog()
|
kernel.saveLog()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
System init package
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.1.0
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Hyperion
|
||||||
|
Astronand
|
||||||
|
pts@fazekas.hu
|
||||||
|
JackMacWindows
|
||||||
|
hanzhao
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
XZ compression library
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import tarfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
ROOT = Path(__file__).resolve().parent
|
||||||
|
SOURCE = ROOT / "Src"
|
||||||
|
PACKAGE_ROOT = ROOT / "packages"
|
||||||
|
PACKAGE_DIR = PACKAGE_ROOT / "raw"
|
||||||
|
|
||||||
|
# main repo
|
||||||
|
#API_ROOT = "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main"
|
||||||
|
|
||||||
|
# local repo
|
||||||
|
API_ROOT = "http://localhost:8000"
|
||||||
|
|
||||||
|
DEFAULT_VERSION = "0.0.0"
|
||||||
|
DEFAULT_DESCRIPTION = "No description provided"
|
||||||
|
DEFAULT_AUTHORS = []
|
||||||
|
DEFAULT_DEPENDENCIES = []
|
||||||
|
|
||||||
|
|
||||||
|
def debug(message):
|
||||||
|
print(f"[COMPILE] {message}", flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
def sha256(path):
|
||||||
|
hasher = hashlib.sha256()
|
||||||
|
|
||||||
|
with open(path, "rb") as file:
|
||||||
|
while chunk := file.read(1024 * 1024):
|
||||||
|
hasher.update(chunk)
|
||||||
|
|
||||||
|
return hasher.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def exclude(info):
|
||||||
|
blocked = (".git", "__pycache__", ".pyc")
|
||||||
|
|
||||||
|
if any(item in info.name.split("/") for item in blocked):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
def read_file(folder, names, default):
|
||||||
|
for name in names:
|
||||||
|
file = folder / name
|
||||||
|
|
||||||
|
if file.exists():
|
||||||
|
return file.read_text(encoding="utf-8").strip()
|
||||||
|
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
|
def read_authors(folder):
|
||||||
|
authors_file = folder / "authors.txt"
|
||||||
|
|
||||||
|
if not authors_file.exists():
|
||||||
|
return DEFAULT_AUTHORS
|
||||||
|
|
||||||
|
authors = []
|
||||||
|
|
||||||
|
for line in authors_file.read_text(encoding="utf-8").splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if line:
|
||||||
|
authors.append(line)
|
||||||
|
|
||||||
|
return authors if authors else DEFAULT_AUTHORS
|
||||||
|
|
||||||
|
|
||||||
|
def read_dependencies(folder):
|
||||||
|
dependencies_file = folder / "dependencies.txt"
|
||||||
|
|
||||||
|
if not dependencies_file.exists():
|
||||||
|
return DEFAULT_DEPENDENCIES
|
||||||
|
|
||||||
|
dependencies = []
|
||||||
|
|
||||||
|
for line in dependencies_file.read_text(encoding="utf-8").splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if line:
|
||||||
|
dependencies.append(line)
|
||||||
|
|
||||||
|
return dependencies if dependencies else DEFAULT_DEPENDENCIES
|
||||||
|
|
||||||
|
|
||||||
|
def create_package(folder):
|
||||||
|
name = folder.name
|
||||||
|
|
||||||
|
tarball = PACKAGE_DIR / f"{name}.tar.gz"
|
||||||
|
pkg_file = PACKAGE_ROOT / f"{name}.pkg"
|
||||||
|
|
||||||
|
if tarball.exists():
|
||||||
|
debug(f"Replacing {tarball.name}")
|
||||||
|
tarball.unlink()
|
||||||
|
|
||||||
|
debug(f"Packing {name}")
|
||||||
|
|
||||||
|
with tarfile.open(tarball, "w:gz") as archive:
|
||||||
|
archive.add(folder, arcname=name, filter=exclude)
|
||||||
|
|
||||||
|
package_hash = sha256(tarball)
|
||||||
|
|
||||||
|
metadata = {
|
||||||
|
"id": name,
|
||||||
|
"description": read_file(
|
||||||
|
folder,
|
||||||
|
["description.md", "description.txt"],
|
||||||
|
DEFAULT_DESCRIPTION,
|
||||||
|
),
|
||||||
|
"authors": read_authors(folder),
|
||||||
|
"dependencies": read_dependencies(folder),
|
||||||
|
"version": read_file(
|
||||||
|
folder,
|
||||||
|
["version.txt"],
|
||||||
|
DEFAULT_VERSION,
|
||||||
|
),
|
||||||
|
"hash": package_hash,
|
||||||
|
"tarball": f"{API_ROOT}/packages/raw/{name}.tar.xz",
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(pkg_file, "w", encoding="utf-8") as file:
|
||||||
|
json.dump(metadata, file, indent=4)
|
||||||
|
file.write("\n")
|
||||||
|
|
||||||
|
debug(f"Generated {pkg_file.name}")
|
||||||
|
debug(f"{name}: {package_hash}")
|
||||||
|
|
||||||
|
return tarball
|
||||||
|
|
||||||
|
def load_spm():
|
||||||
|
spm_file = ROOT / "spm.json"
|
||||||
|
|
||||||
|
if not spm_file.exists():
|
||||||
|
return {
|
||||||
|
"refs": {},
|
||||||
|
"maintainers": [],
|
||||||
|
"packages": {}
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(spm_file, "r", encoding="utf-8") as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
data.setdefault("refs", {})
|
||||||
|
data.setdefault("maintainers", [])
|
||||||
|
data.setdefault("packages", {})
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def update_spm():
|
||||||
|
spm = load_spm()
|
||||||
|
|
||||||
|
packages = {}
|
||||||
|
|
||||||
|
for pkg in sorted(PACKAGE_ROOT.glob("*.pkg")):
|
||||||
|
with open(pkg, "r", encoding="utf-8") as file:
|
||||||
|
metadata = json.load(file)
|
||||||
|
|
||||||
|
packages[metadata["id"]] = f"{API_ROOT}/packages/{pkg.name}"
|
||||||
|
|
||||||
|
spm["packages"] = packages
|
||||||
|
|
||||||
|
with open(ROOT / "spm.json", "w", encoding="utf-8") as file:
|
||||||
|
json.dump(spm, file, indent=4)
|
||||||
|
file.write("\n")
|
||||||
|
|
||||||
|
debug("Generated spm.json")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not SOURCE.exists():
|
||||||
|
debug("Src directory missing")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
if PACKAGE_ROOT.exists():
|
||||||
|
shutil.rmtree(PACKAGE_ROOT)
|
||||||
|
|
||||||
|
PACKAGE_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
for folder in sorted(SOURCE.iterdir()):
|
||||||
|
if folder.is_dir():
|
||||||
|
create_package(folder)
|
||||||
|
|
||||||
|
update_spm()
|
||||||
|
debug("Complete")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
term.clear()
|
|
||||||
term.setTextColor(colors.white)
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
print("HyperionOS CCT Installer //")
|
|
||||||
local w,h = term.getSize()
|
|
||||||
local exitall,releasename,packagelist=false,"",{}
|
|
||||||
|
|
||||||
local function printc(...)
|
|
||||||
local args={...}
|
|
||||||
for i=1, #args do
|
|
||||||
if type(args[i]) == "number" then
|
|
||||||
term.setTextColor(args[i])
|
|
||||||
else
|
|
||||||
term.write(args[i])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print("")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function download(url)
|
|
||||||
printc(colors.gray, "[ ", colors.green, " FETCH ", colors.gray, " ] ", colors.white, url)
|
|
||||||
local data,err=http.get(url)
|
|
||||||
if not data then error(err) end
|
|
||||||
local text=data.readAll()
|
|
||||||
data.close()
|
|
||||||
return text
|
|
||||||
end
|
|
||||||
|
|
||||||
local function writeFile(path, data)
|
|
||||||
printc(colors.gray, "[ ", colors.green, "WRITING", colors.gray, " ] ", colors.white, path)
|
|
||||||
local file=fs.open(path, "w")
|
|
||||||
file.write(data)
|
|
||||||
file.close()
|
|
||||||
end
|
|
||||||
|
|
||||||
print("Installing JSON to /hyinstall/json...")
|
|
||||||
writeFile("/hyinstall/json",download("https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/misc/json"))
|
|
||||||
print("Loading JSON...")
|
|
||||||
local json=loadfile("/hyinstall/json")()
|
|
||||||
|
|
||||||
local function printTitle()
|
|
||||||
term.clear()
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
term.setTextColor(colors.white)
|
|
||||||
print("HyperionOS CCT Installer //")
|
|
||||||
print("Orange is prerelease...")
|
|
||||||
term.setCursorPos(1,h-1)
|
|
||||||
print("DESCLAIMER: This will wipe your system on install...")
|
|
||||||
term.write("Bspc: Back | Enter: execute | Tab: description")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function pc(text, y, c)
|
|
||||||
local x=(w/2)-#text/2
|
|
||||||
term.setTextColor(c)
|
|
||||||
term.setCursorPos(x, y)
|
|
||||||
term.write(text)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function drawMenu(menu, sel)
|
|
||||||
local y=(h/2)-#menu/2
|
|
||||||
for i,v in ipairs(menu) do
|
|
||||||
if i==sel then
|
|
||||||
pc("[ "..v.name.." ]", y+i, v.color)
|
|
||||||
else
|
|
||||||
pc(v.name, y+i, v.color)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function desc(description)
|
|
||||||
term.clear()
|
|
||||||
term.setTextColor(colors.white)
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
print("HyperionOS CCT Installer //\n")
|
|
||||||
print(description)
|
|
||||||
term.setCursorPos(1,h)
|
|
||||||
term.write("Press enter to continue...")
|
|
||||||
while not exitall do
|
|
||||||
local _,key = os.pullEvent("key")
|
|
||||||
if key==keys.enter then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function menu(m)
|
|
||||||
local exit,sel=false,1
|
|
||||||
while not exit and not exitall do
|
|
||||||
printTitle()
|
|
||||||
drawMenu(m, sel)
|
|
||||||
local _,key = os.pullEvent("key")
|
|
||||||
if key==keys.down then
|
|
||||||
if sel<#m then
|
|
||||||
sel=sel+1
|
|
||||||
end
|
|
||||||
elseif key==keys.up then
|
|
||||||
if sel>1 then
|
|
||||||
sel=sel-1
|
|
||||||
end
|
|
||||||
elseif key==keys.enter then
|
|
||||||
m[sel].func()
|
|
||||||
elseif key==keys.tab then
|
|
||||||
desc(m[sel].desc)
|
|
||||||
elseif key==keys.backspace then
|
|
||||||
exit=true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local releases,page={},1
|
|
||||||
while true do
|
|
||||||
local raw=download("https://git.astronand.dev/api/v1/repos/Hyperion/HyperionOS/releases?page="..tostring(page).."&limit=1")
|
|
||||||
if raw=="[]\n" then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
releases[page]=json.decode(raw)[1]
|
|
||||||
page=page+1
|
|
||||||
end
|
|
||||||
|
|
||||||
local function makePage(start, num)
|
|
||||||
local m={}
|
|
||||||
for i=start, num do
|
|
||||||
if not releases[i] then break end
|
|
||||||
local release=releases[i]
|
|
||||||
m[#m+1]={
|
|
||||||
name=release.name,
|
|
||||||
desc=release.body,
|
|
||||||
color=release.prerelease and colors.orange or colors.white,
|
|
||||||
func=function()
|
|
||||||
term.clear()
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
local data=download("https://git.astronand.dev/Hyperion/HyperionOS/raw/tag/"..release.tag_name.."/Src/install.json")
|
|
||||||
if not data then
|
|
||||||
term.clear()
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
print("Unable to find package list for ver "..release.tag_name..":\n"..err)
|
|
||||||
sleep(3)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
releasename=release.tag_name
|
|
||||||
packagelist=json.decode(data)
|
|
||||||
exitall=true
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
if #releases>start+num then
|
|
||||||
m[#m+1]={
|
|
||||||
name="Next",
|
|
||||||
desc="Next menu",
|
|
||||||
color=colors.cyan,
|
|
||||||
func=function()
|
|
||||||
local menudata=makePage(start+num, num)
|
|
||||||
menu(menudata)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
return m
|
|
||||||
end
|
|
||||||
|
|
||||||
printTitle()
|
|
||||||
menu(makePage(1,5))
|
|
||||||
if not exitall then error("Exited") end
|
|
||||||
term.clear()
|
|
||||||
term.setCursorPos(1,1)
|
|
||||||
term.setTextColor(colors.white)
|
|
||||||
term.write("Formating disk in ")
|
|
||||||
for i=5, 1, -1 do
|
|
||||||
term.write(tostring(i))
|
|
||||||
sleep(.25)
|
|
||||||
for v=1, 3 do
|
|
||||||
term.write(".")
|
|
||||||
sleep(.25)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print("")
|
|
||||||
|
|
||||||
local function delDir(dir)
|
|
||||||
printc(colors.gray, "[ ", colors.green, " LSDIR ", colors.gray, " ] ", colors.white, dir)
|
|
||||||
local list=fs.list(dir)
|
|
||||||
printc(colors.gray, "[ ", colors.red, " DELET ", colors.gray, " ] ", colors.white, dir)
|
|
||||||
for i=1, #list do
|
|
||||||
if fs.isDir(dir..list[i]) then
|
|
||||||
if dir..list[i] ~= "/rom" then
|
|
||||||
delDir(dir..list[i].."/")
|
|
||||||
fs.delete(dir..list[i])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
fs.delete(dir..list[i])
|
|
||||||
printc(colors.gray, "[ ", colors.red, " DELET ", colors.gray, " ] ", colors.white, dir..list[i])
|
|
||||||
end
|
|
||||||
sleep(.01)
|
|
||||||
end
|
|
||||||
sleep(.15)
|
|
||||||
end
|
|
||||||
|
|
||||||
delDir("/")
|
|
||||||
|
|
||||||
print("")
|
|
||||||
printc(colors.cyan, " \\\\Installing//")
|
|
||||||
print("")
|
|
||||||
printc(colors.white, "Getting package list...")
|
|
||||||
|
|
||||||
local function installdir(path, dir, pkg)
|
|
||||||
local data=json.decode(download("https://git.astronand.dev/api/v1/repos/Hyperion/HyperionOS/contents/prod/"..pkg..dir.."?ref="..releasename))
|
|
||||||
if not data then error("Uh Oh: JSON decode error...") end
|
|
||||||
for i=1, #data do
|
|
||||||
local entry=data[i]
|
|
||||||
if entry.type == "dir" then
|
|
||||||
installdir(path, dir..entry.name.."/", pkg)
|
|
||||||
elseif entry.type == "file" then
|
|
||||||
writeFile(path..dir..entry.name, download(entry.download_url))
|
|
||||||
else
|
|
||||||
error("Uh Oh: unknown entrytype "..entry.path)
|
|
||||||
end
|
|
||||||
sleep(.01)
|
|
||||||
end
|
|
||||||
sleep(.15)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function installpkg(pkg)
|
|
||||||
installdir("/$", "/", pkg)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1, #packagelist do
|
|
||||||
installpkg(packagelist[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
installpkg("Hyperion-firmware-cct")
|
|
||||||
fs.copy("/$/boot/cct/eeprom", "/startup.lua")
|
|
||||||
|
|
||||||
printc(colors.white, "Rebooting...")
|
|
||||||
sleep(1)
|
|
||||||
os.reboot()
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "Hyperion-core",
|
||||||
|
"description": "Core library for Hyperion",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "e83a8dc42a871c1e16cd56c214cf0ca4bb0079432dc8bd198abbe11d6cf31d4e",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/Hyperion-core.tar.xz"
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "Hyperion-firmware-ac",
|
||||||
|
"description": "firmware for Advanced Computers",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand",
|
||||||
|
"GHXX (Advanced Computers)"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "f64be830fc02394eeb9c049a528ed47b97430c6682a577c789d16303dcaad6fc",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ac.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "Hyperion-firmware-ccpc",
|
||||||
|
"description": "firmware for CraftOS PC",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "f3f030d6f6faa137f9950f0ce4ccc598a9b29c729380c100c920fad5aa254076",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-ccpc.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "Hyperion-firmware-cct",
|
||||||
|
"description": "firmware for ComputerCraft Tweaked",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.3.0",
|
||||||
|
"hash": "dd69c26ba6f46acb99d6f839474fc50283524bd99df7f67a5d300a749af86dde",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-cct.tar.xz"
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"id": "Hyperion-firmware-oc",
|
||||||
|
"description": "firmware for Opencomputers",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "0.1.0",
|
||||||
|
"hash": "8b1bbff272dd07f0e5023c90007ec8d3a84f5b29a59449a75894319c86ee10cd",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/Hyperion-firmware-oc.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "Hyperion-kernel",
|
||||||
|
"description": "Hyperion kernel package",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand",
|
||||||
|
"Spsf"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.5.0",
|
||||||
|
"hash": "a17552597f1a4e661804bcf23d26e19664cb6f75cb3058357603df59b033155a",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/Hyperion-kernel.tar.xz"
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "bit32",
|
||||||
|
"description": "Bit32 package for Hyperion",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Lua"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "9bc32da8ab97f899e85faeb47064433ef4a167e45924c0e583d30f901551bdf5",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/bit32.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "blake2s",
|
||||||
|
"description": "blake2s package for Hyperion",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "c32e2bbeba5d8609f720bce59fad0505d490ee22a6e54b4d830a524e609ac415",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/blake2s.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "coreutils",
|
||||||
|
"description": "core utilities for user management",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand",
|
||||||
|
"Spsf"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "c52244c7fd2ca96780ed684327ebb55872757a4f6c8d90e18367ec4e0d8f10ad",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/coreutils.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "deflate",
|
||||||
|
"description": "Libdeflate for Hyperion",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Haoqian He"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0-release",
|
||||||
|
"hash": "43a3df0e6da39aa97c0ee0ce4217e9acffadba4178d03dae5c66bf4627147644",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/deflate.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "gfxterm",
|
||||||
|
"description": "package providing kernel support for framebuffers and graphics",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "88eb9f9bb7bb86fb7752601c67e4ab62e88fb7562057a83c101aaf7ffc3ccdc0",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/gfxterm.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "hysh",
|
||||||
|
"description": "Official Hyperion shell package",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Spsf"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.3.0",
|
||||||
|
"hash": "d0baaeb889eeaa38a9f100c4954b8f30c36c220ba73d8b8fa878e0fcaeaadb15",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/hysh.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "iniparse",
|
||||||
|
"description": "ini parser",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "f26f900027066dc2f498a4ccb8306f48c93210e7869b11f4aef9900f2e00e066",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/iniparse.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "installer",
|
||||||
|
"description": "Hyperion os live installer",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"Astronand"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "8623a44260062d0066aecc683b45c2ea9e6f438fd74cef050e7bcac7daa33a4f",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/installer.tar.xz"
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"id": "json",
|
||||||
|
"description": "JSON library for Hyperion",
|
||||||
|
"authors": [
|
||||||
|
"Hyperion",
|
||||||
|
"rxi"
|
||||||
|
],
|
||||||
|
"dependencies": [],
|
||||||
|
"version": "1.0.0",
|
||||||
|
"hash": "8344035d687f5cafb8c918d6bddd2ba5a7d6c2025aa43def84b942a614583282",
|
||||||
|
"tarball": "http://localhost:8000/packages/raw/json.tar.xz"
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user