Compare commits
3
Commits
8a861ca725
...
1.2-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbaafc7cff | ||
|
|
8edf246e02 | ||
|
|
6b4cc974b0 |
No files matched your search
@@ -0,0 +1,5 @@
|
||||
--:Minify:--
|
||||
local kernel=...
|
||||
if kernel.arch~="cct" then
|
||||
kernel.deny("cc-tweaked/31_keyboards.kmod")
|
||||
end
|
||||
File renamed without changes.
@@ -0,0 +1,12 @@
|
||||
--:Minify:--
|
||||
local kernel=...
|
||||
if kernel.arch~="cct" then
|
||||
kernel.deny("cc-tweaked/01_periph.kmod")
|
||||
kernel.deny("cc-tweaked/13_devraw.kmod")
|
||||
kernel.deny("cc-tweaked/22_http.kmod")
|
||||
kernel.deny("cc-tweaked/25_mouse.kmod")
|
||||
kernel.deny("cc-tweaked/25_tty.kmod")
|
||||
kernel.deny("cc-tweaked/30_daemon.kmod")
|
||||
kernel.deny("cc-tweaked/46_scheduler.kmod")
|
||||
kernel.deny("cc-tweaked/51_gpio.kmod")
|
||||
end
|
||||
@@ -18,7 +18,13 @@ local function createDisk(id, hw)
|
||||
if not hw.exists(path) or not hw.isDirectory(path) then
|
||||
return nil, "not directory"
|
||||
end
|
||||
return hw.list(path)
|
||||
local ret={}
|
||||
for i,v in ipairs(hw.list(path)) do
|
||||
if v:sub(-1)=="/" then
|
||||
ret[i]=v:sub(1,#v-1)
|
||||
else ret[i]=v end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function disk:fileExists(path)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--:Minify:--
|
||||
local kernel=...
|
||||
if kernel.arch~="oc" then
|
||||
kernel.deny("opencomputers/01_devices.kmod")
|
||||
kernel.deny("opencomputers/13_devraw.kmod")
|
||||
kernel.deny("opencomputers/22_http.kmod")
|
||||
kernel.deny("opencomputers/25_tty.kmod")
|
||||
kernel.deny("opencomputers/26_keyboards.kmod")
|
||||
kernel.deny("opencomputers/30_daemon.kmod")
|
||||
kernel.deny("opencomputers/36_scheduler.kmod")
|
||||
end
|
||||
@@ -155,6 +155,9 @@ local function newtty(addr)
|
||||
end,
|
||||
gplt=function()
|
||||
return plt
|
||||
end,
|
||||
gfx=function()
|
||||
return false
|
||||
end
|
||||
}
|
||||
if mode=="rw" then
|
||||
|
||||
@@ -0,0 +1,593 @@
|
||||
--:Minify:--
|
||||
local BOOT_DRIVE_PATH = ({...})[1] or "/$"
|
||||
---@diagnostic disable-next-line: undefined-global
|
||||
local lterm = term
|
||||
local function write(text, term)
|
||||
local x, y = term.getCursorPos()
|
||||
local w, h = term.getSize()
|
||||
|
||||
for i = 1, #text do
|
||||
local c = text:sub(i, i)
|
||||
|
||||
if c == "\n" then
|
||||
y = y + 1
|
||||
x = 1
|
||||
elseif c == "\t" then
|
||||
local tabSize = 4
|
||||
local spaces = tabSize - ((x - 1) % tabSize)
|
||||
term.write(string.rep(" ", spaces))
|
||||
x = x + spaces
|
||||
elseif c == "\b" then
|
||||
if x > 1 then
|
||||
x = x - 1
|
||||
term.setCursorPos(x, y)
|
||||
term.write(" ")
|
||||
term.setCursorPos(x, y)
|
||||
end
|
||||
else
|
||||
if x <= w and y <= h then
|
||||
term.setCursorPos(x, y)
|
||||
term.write(c)
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
|
||||
if x > w then
|
||||
x = 1
|
||||
y = y + 1
|
||||
end
|
||||
|
||||
if y - 1 >= h then
|
||||
term.scroll(1)
|
||||
y = h
|
||||
term.setCursorPos(x, y)
|
||||
end
|
||||
end
|
||||
|
||||
term.setCursorPos(x, y)
|
||||
end
|
||||
|
||||
local function displaySuperBadError(err, noyield)
|
||||
lterm.setBackgroundColor(0x1)
|
||||
lterm.setTextColor(0x4)
|
||||
lterm.clear()
|
||||
lterm.setCursorPos(1, 1)
|
||||
lterm.write("A critical error occurred while loading the system:")
|
||||
lterm.setCursorPos(1, 3)
|
||||
write(err, lterm)
|
||||
coroutine.yield("key")
|
||||
end
|
||||
|
||||
term.setCursorBlink(false)
|
||||
local ok, err = xpcall(function()
|
||||
--p
|
||||
local apis = {BOOT_DRIVE_PATH = BOOT_DRIVE_PATH}
|
||||
|
||||
local lua = {
|
||||
coroutine = true,
|
||||
debug = true,
|
||||
_VERSION = true,
|
||||
assert = true,
|
||||
collectgarbage = true,
|
||||
error = true,
|
||||
gcinfo = true,
|
||||
getmetatable = true,
|
||||
ipairs = true,
|
||||
__inext = true,
|
||||
load = true,
|
||||
math = true,
|
||||
next = true,
|
||||
pairs = true,
|
||||
pcall = true,
|
||||
rawequal = true,
|
||||
rawget = true,
|
||||
rawlen = true,
|
||||
rawset = true,
|
||||
select = true,
|
||||
setmetatable = true,
|
||||
string = true,
|
||||
table = true,
|
||||
tonumber = true,
|
||||
tostring = true,
|
||||
type = true,
|
||||
xpcall = true,
|
||||
_G = true
|
||||
}
|
||||
|
||||
local debug = debug
|
||||
for i, v in pairs(_G) do
|
||||
if not lua[i] or lua[i] == nil then
|
||||
apis[i] = v
|
||||
_G[i] = nil
|
||||
end
|
||||
end
|
||||
--p
|
||||
|
||||
local acekeys={
|
||||
[apis.keys.enter]="\n",
|
||||
[apis.keys.tab]="\t",
|
||||
[apis.keys.backspace]="\b",
|
||||
[apis.keys.up]="\17",
|
||||
[apis.keys.down]="\18",
|
||||
[apis.keys.left]="\19",
|
||||
[apis.keys.right]="\20",
|
||||
}
|
||||
|
||||
function sleep(time)
|
||||
local stoptime = apis.os.clock() + (time)
|
||||
while stoptime > apis.os.clock() do end
|
||||
end
|
||||
|
||||
apis.term.setPaletteColor(0x1, 0xFFFFFF) -- #000000
|
||||
apis.term.setPaletteColor(0x2, 0xFF0000) -- #FFFFFF
|
||||
apis.term.setPaletteColor(0x4, 0x00FF00) -- #FF0000
|
||||
apis.term.setPaletteColor(0x8, 0x0000FF) -- #00FF00
|
||||
apis.term.setPaletteColor(0x10, 0x00FFFF) -- #0000FF
|
||||
apis.term.setPaletteColor(0x20, 0xFF00FF) -- #00FFFF
|
||||
apis.term.setPaletteColor(0x40, 0xFFFF00) -- #FF00FF
|
||||
apis.term.setPaletteColor(0x80, 0xFF6D00) -- #FFFF00
|
||||
apis.term.setPaletteColor(0x100, 0x6DFF55) -- #FF6D00
|
||||
apis.term.setPaletteColor(0x200, 0x24FFFF) -- #6DFF55
|
||||
apis.term.setPaletteColor(0x400, 0x924900) -- #24FFFF
|
||||
apis.term.setPaletteColor(0x800, 0x6D6D55) -- #924900
|
||||
apis.term.setPaletteColor(0x1000, 0xDBDBAA) -- #6D6D55
|
||||
apis.term.setPaletteColor(0x2000, 0x6D00FF) -- #DBDBAA
|
||||
apis.term.setPaletteColor(0x4000, 0xB6FF00) -- #6D00FF
|
||||
apis.term.setPaletteColor(0x8000, 0x000000) -- #B6FF00
|
||||
|
||||
local function getFile(path)
|
||||
local file = apis.fs.open(path, "r")
|
||||
if not file then
|
||||
displaySuperBadError("Could not open file: " .. path)
|
||||
end
|
||||
local content = file.readAll()
|
||||
file.close()
|
||||
return content
|
||||
end
|
||||
|
||||
local Kernel = load(getFile(BOOT_DRIVE_PATH .. "/kernel.lua"),"@Kernel")
|
||||
local initFs = load(getFile(BOOT_DRIVE_PATH .. "/cct/initdisks"),"@Init_disks")(apis)
|
||||
local fs = load(getFile(BOOT_DRIVE_PATH .. "/initfs"), "@InitFs")()
|
||||
|
||||
if not Kernel then displaySuperBadError("Could not load kernel.") end
|
||||
if not initFs then displaySuperBadError("Could not load initdisks.") end
|
||||
if not fs then displaySuperBadError("Could not load initfs.") end
|
||||
|
||||
if not apis.fs.exists("/nvram.dat") then
|
||||
local file = apis.fs.open("/nvram.dat", "w")
|
||||
file.write("Hello, World!")
|
||||
file.close()
|
||||
end
|
||||
|
||||
local eeprom
|
||||
if apis.fs.exists("/startup.lua") then
|
||||
eeprom="/startup.lua"
|
||||
elseif apis.fs.exists("/eeprom") then
|
||||
eeprom="/eeprom"
|
||||
end
|
||||
|
||||
local eventQueue = {}
|
||||
|
||||
local function queueEvent(event, ...)
|
||||
table.insert(eventQueue, {event, ...})
|
||||
end
|
||||
|
||||
local colors = {
|
||||
[0xFFFFFF]=0x0001,
|
||||
[0xFF0000]=0x0002,
|
||||
[0x00FF00]=0x0004,
|
||||
[0x0000FF]=0x0008,
|
||||
[0x00FFFF]=0x0010,
|
||||
[0xFF00FF]=0x0020,
|
||||
[0xFFFF00]=0x0040,
|
||||
[0xFF6D00]=0x0080,
|
||||
[0x6DFF55]=0x0100,
|
||||
[0x24FFFF]=0x0200,
|
||||
[0x924900]=0x0400,
|
||||
[0x6D6D55]=0x0800,
|
||||
[0xDBDBAA]=0x1000,
|
||||
[0x6D00FF]=0x2000,
|
||||
[0xB6FF00]=0x4000,
|
||||
[0x000000]=0x8000
|
||||
}
|
||||
|
||||
local fg,bg=0x6D6D55,0x000000
|
||||
local l1f,l1d,l2,ops={},{},{},0
|
||||
|
||||
local function findClosest(tbl, target)
|
||||
local closest = nil
|
||||
local smallestDiff = math.huge
|
||||
|
||||
for k, _ in pairs(tbl) do
|
||||
if k==target then return k end
|
||||
local diff = math.abs(k - target)
|
||||
if diff < smallestDiff then
|
||||
smallestDiff = diff
|
||||
closest = k
|
||||
end
|
||||
end
|
||||
|
||||
return closest
|
||||
end
|
||||
|
||||
local function aprox(c24)
|
||||
ops = ops + 1
|
||||
|
||||
if ops % 1024 == 0 then
|
||||
l1d = {}
|
||||
l1f = {}
|
||||
end
|
||||
|
||||
if ops % 8192 == 0 then
|
||||
l2 = {}
|
||||
end
|
||||
|
||||
if l2[c24] ~= nil then
|
||||
return l2[c24]
|
||||
end
|
||||
|
||||
if l1d[c24] ~= nil then
|
||||
l1f[c24] = l1f[c24] + 1
|
||||
|
||||
if l1f[c24] >= 16 then
|
||||
l2[c24] = l1d[c24]
|
||||
l1d[c24] = nil
|
||||
l1f[c24] = nil
|
||||
return l2[c24]
|
||||
end
|
||||
|
||||
return l1d[c24]
|
||||
end
|
||||
|
||||
local closestKey = findClosest(colors, c24)
|
||||
if not closestKey then return nil end
|
||||
|
||||
local value = colors[closestKey]
|
||||
|
||||
l1d[c24] = value
|
||||
l1f[c24] = 1
|
||||
|
||||
return value
|
||||
end
|
||||
|
||||
--p
|
||||
local p={}
|
||||
local native = apis.peripheral
|
||||
local sides = {"top", "bottom", "left", "right", "front", "back"}
|
||||
|
||||
function p.getNames()
|
||||
local results = {}
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.isPresent(side) then
|
||||
table.insert(results, side)
|
||||
if native.hasType(side, "peripheral_hub") then
|
||||
local remote = native.call(side, "getNamesRemote")
|
||||
for _, name in ipairs(remote) do
|
||||
table.insert(results, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
function p.isPresent(name)
|
||||
if native.isPresent(name) then
|
||||
return true
|
||||
end
|
||||
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function p.getType(peripheral)
|
||||
if type(peripheral) == "string" then
|
||||
if native.isPresent(peripheral) then
|
||||
return native.getType(peripheral)
|
||||
end
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
|
||||
return native.call(side, "getTypeRemote", peripheral)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
else
|
||||
local mt = getmetatable(peripheral)
|
||||
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
|
||||
error("bad argument #1 (table is not a peripheral)", 2)
|
||||
end
|
||||
return table.unpack(mt.types)
|
||||
end
|
||||
end
|
||||
|
||||
function p.hasType(peripheral, peripheral_type)
|
||||
if type(peripheral) == "string" then
|
||||
if native.isPresent(peripheral) then
|
||||
return native.hasType(peripheral, peripheral_type)
|
||||
end
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", peripheral) then
|
||||
return native.call(side, "hasTypeRemote", peripheral, peripheral_type)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
else
|
||||
local mt = getmetatable(peripheral)
|
||||
if not mt or mt.__name ~= "peripheral" or type(mt.types) ~= "table" then
|
||||
error("bad argument #1 (table is not a peripheral)", 2)
|
||||
end
|
||||
return mt.types[peripheral_type] ~= nil
|
||||
end
|
||||
end
|
||||
|
||||
function p.getMethods(name)
|
||||
if native.isPresent(name) then
|
||||
return native.getMethods(name)
|
||||
end
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
|
||||
return native.call(side, "getMethodsRemote", name)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function p.getName(peripheral)
|
||||
local mt = getmetatable(peripheral)
|
||||
if not mt or mt.__name ~= "peripheral" or type(mt.name) ~= "string" then
|
||||
error("bad argument #1 (table is not a peripheral)", 2)
|
||||
end
|
||||
return mt.name
|
||||
end
|
||||
|
||||
function p.call(name, method, ...)
|
||||
if native.isPresent(name) then
|
||||
return native.call(name, method, ...)
|
||||
end
|
||||
|
||||
for n = 1, #sides do
|
||||
local side = sides[n]
|
||||
if native.hasType(side, "peripheral_hub") and native.call(side, "isPresentRemote", name) then
|
||||
return native.call(side, "callRemote", name, method, ...)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function p.wrap(name)
|
||||
local methods = p.getMethods(name)
|
||||
if not methods then
|
||||
return nil
|
||||
end
|
||||
|
||||
local types = { p.getType(name) }
|
||||
for i = 1, #types do types[types[i]] = true end
|
||||
local result = setmetatable({}, {
|
||||
__name = "peripheral",
|
||||
name = name,
|
||||
type = types[1],
|
||||
types = types,
|
||||
})
|
||||
for _, method in ipairs(methods) do
|
||||
result[method] = function(...)
|
||||
return p.call(name, method, ...)
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function p.find(ty, filter)
|
||||
local results = {}
|
||||
for _, name in ipairs(p.getNames()) do
|
||||
if p.hasType(name, ty) then
|
||||
local wrapped = p.wrap(name)
|
||||
if filter == nil or filter(name, wrapped) then
|
||||
table.insert(results, wrapped)
|
||||
end
|
||||
end
|
||||
end
|
||||
return table.unpack(results)
|
||||
end
|
||||
--p
|
||||
local allscreens = {p.find("monitor")}
|
||||
for i=1, #allscreens do
|
||||
allscreens[i].setTextScale(.5)
|
||||
allscreens[i].clear()
|
||||
allscreens[i].setCursorPos(1,1)
|
||||
end
|
||||
|
||||
allscreens[#allscreens+1] = apis.term
|
||||
|
||||
local callAsyncQueue = {}
|
||||
local callAsyncReturn = {}
|
||||
apis.callAsyncReturn = callAsyncReturn
|
||||
local callidx=0
|
||||
|
||||
function apis.callAsync(func, ...)
|
||||
callidx=callidx+1
|
||||
callAsyncQueue[#callAsyncQueue+1] = {callidx, func, ...}
|
||||
return callidx
|
||||
end
|
||||
|
||||
local EFI = {
|
||||
yield=function() end,
|
||||
getEpochMs = function() return apis.os.epoch("utc") end,
|
||||
getUptime = function() return apis.os.clock() * 1000 end,
|
||||
date = function() return apis.os.date("!%Y-%m-%dT%H:%M:%SZ", apis.os.epoch("utc") / 1000) end,
|
||||
getMachineEvent = function()
|
||||
if #eventQueue > 0 then
|
||||
return table.unpack(table.remove(eventQueue, 1))
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end,
|
||||
getEEPROM = function() return getFile(eeprom) end,
|
||||
setEEPROM = function(_, text)
|
||||
local h = apis.fs.open(eeprom, "w")
|
||||
h.write(text)
|
||||
h.close()
|
||||
end,
|
||||
initfs=fs,
|
||||
disks=initFs,
|
||||
screenCtl={
|
||||
print = function(_, text)
|
||||
for i=1, #allscreens do
|
||||
write(text.."\n", allscreens[i])
|
||||
end
|
||||
end,
|
||||
printInline = function(_, text)
|
||||
for i=1, #allscreens do
|
||||
write(text, allscreens[i])
|
||||
end
|
||||
end,
|
||||
clear = function()
|
||||
for i=1, #allscreens do
|
||||
allscreens[i].clear()
|
||||
allscreens[i].setCursorPos(1, 1)
|
||||
end
|
||||
end,
|
||||
resetCursor = function()
|
||||
for i=1, #allscreens do
|
||||
allscreens[i].setCursorPos(1, 1)
|
||||
end
|
||||
end,
|
||||
setBackgroundColor = function(_, color)
|
||||
bg=color
|
||||
for i=1, #allscreens do
|
||||
allscreens[i].setBackgroundColor(aprox(color))
|
||||
end
|
||||
end,
|
||||
setTextColor = function(_, color)
|
||||
fg=color
|
||||
for i=1, #allscreens do
|
||||
allscreens[i].setTextColor(aprox(color))
|
||||
end
|
||||
end,
|
||||
getBackgroundColor = function()
|
||||
return bg
|
||||
end,
|
||||
getTextColor = function()
|
||||
return fg
|
||||
end,
|
||||
enable=function()
|
||||
for i=1, #allscreens do
|
||||
allscreens[i].clear()
|
||||
allscreens[i].setCursorPos(1, 1)
|
||||
end
|
||||
end,
|
||||
disable=function() end
|
||||
},
|
||||
architecture="cct",
|
||||
getNvram = function() return getFile("/nvram.dat") end,
|
||||
setNvram = function(_, text)
|
||||
local h = apis.fs.open("/nvram.dat", "w")
|
||||
h.write(text)
|
||||
h.close()
|
||||
end,
|
||||
firmware=apis,
|
||||
status="running",
|
||||
beep=function() end
|
||||
}
|
||||
|
||||
apis.term.setBackgroundColor(0x8000)
|
||||
apis.term.setTextColor(0x1000)
|
||||
apis.term.clear()
|
||||
apis.term.setCursorPos(1, 1)
|
||||
|
||||
local kernelCoro = coroutine.create(function()
|
||||
--pf
|
||||
---@diagnostic disable-next-line: param-type-mismatch
|
||||
local ok, err = xpcall(Kernel, debug.traceback, EFI)
|
||||
if not ok then
|
||||
error(err)
|
||||
else
|
||||
apis.os.shutdown()
|
||||
end
|
||||
end)
|
||||
|
||||
function EFI.resumeWithTimeout(co, timeout, ...)
|
||||
local startTime = EFI.getEpochMs()
|
||||
debug.sethook(co, function()
|
||||
if EFI.getEpochMs() > startTime + timeout then
|
||||
return coroutine.yield("timeout")
|
||||
end
|
||||
end, "", 1000)
|
||||
local ret = {coroutine.resume(co, ...)}
|
||||
if ret[1] and ret[2] == "timeout" then
|
||||
return "timeout"
|
||||
elseif ret[1] == false then
|
||||
return "error", ret[2]
|
||||
else
|
||||
debug.sethook(co)
|
||||
return "success", table.unpack(ret, 2)
|
||||
end
|
||||
end
|
||||
|
||||
EFI.screenCtl:print("Loaded in " .. tostring(apis.os.clock()) .. " seconds.\n")
|
||||
--p
|
||||
|
||||
while true do
|
||||
local status, err = EFI.resumeWithTimeout(kernelCoro, 50)
|
||||
apis.os.queueEvent("NoSleep")
|
||||
local exit = false
|
||||
while not exit do
|
||||
local event = {coroutine.yield()}
|
||||
if event[1] == "key" then
|
||||
queueEvent(table.unpack(event))
|
||||
queueEvent("keyPressed", 1, event[2])
|
||||
if acekeys[event[2]] then
|
||||
queueEvent("keyTyped", 1, acekeys[event[2]])
|
||||
end
|
||||
elseif event[1] == "char" then
|
||||
queueEvent(table.unpack(event))
|
||||
queueEvent("keyTyped", 1, event[2])
|
||||
elseif event[1] == "key_up" then
|
||||
queueEvent(table.unpack(event))
|
||||
queueEvent("keyReleased", 1, event[2])
|
||||
elseif event[1] == "NoSleep" then
|
||||
exit = true
|
||||
else
|
||||
queueEvent(table.unpack(event))
|
||||
end
|
||||
end
|
||||
while #callAsyncQueue>0 do
|
||||
local bundle = table.remove(callAsyncQueue, 1)
|
||||
local ret = {xpcall(bundle[2], debug.traceback, table.unpack(bundle, 3))}
|
||||
if not ret[1] then
|
||||
callAsyncReturn[bundle[1]]={false, ret[2]}
|
||||
else
|
||||
callAsyncReturn[bundle[1]]={true, table.unpack(ret,2)}
|
||||
end
|
||||
end
|
||||
if status == "error" or coroutine.status(kernelCoro) == "dead" then
|
||||
if EFI.status=="reboot" then
|
||||
apis.os.reboot()
|
||||
elseif EFI.status=="shutdown" then
|
||||
apis.os.shutdown()
|
||||
end
|
||||
displaySuperBadError("Kernel error: " .. tostring(err))
|
||||
coroutine.yield("key")
|
||||
elseif status == "success" then
|
||||
if EFI.status=="reboot" then
|
||||
apis.os.reboot()
|
||||
elseif EFI.status=="shutdown" then
|
||||
apis.os.shutdown()
|
||||
end
|
||||
displaySuperBadError("Kernel error: Attempted to yield main thread\n"..debug.traceback(kernelCoro, "Attempted to yield main thread"))
|
||||
coroutine.yield("key")
|
||||
end
|
||||
initFs:refresh()
|
||||
end
|
||||
end, debug.traceback)
|
||||
|
||||
if not ok then displaySuperBadError("Fatal error during boot: " .. err) end
|
||||
while true do coroutine.yield("key") end
|
||||
@@ -0,0 +1 @@
|
||||
print("Hyperion OS PUC bootloader")
|
||||
@@ -507,7 +507,7 @@ if kernel.status=="reboot" then
|
||||
elseif kernel.status=="halt" then
|
||||
kernel.log("System halted.")
|
||||
kernel.saveLog()
|
||||
while true do end
|
||||
while true do EFI:yield() end
|
||||
else
|
||||
EFI.status="shutdown"
|
||||
return true
|
||||
|
||||
@@ -694,7 +694,7 @@ function vfs.open(path, mode)
|
||||
if disk:type(diskPath) ~= "directory" then
|
||||
handle = disk:open(diskPath, mode)
|
||||
if type(handle, true) ~= "table" then
|
||||
error("ENFILE")
|
||||
error("ENFILE".." KERR="..type(handle,true))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ local function newtaskproxy(task)
|
||||
children[tostring(v.pid)]="/proc/"..tostring(v.pid)
|
||||
end
|
||||
return {
|
||||
[".meta"]=strFile(buildMeta({cwd=task.cwd,parent="/proc/"..tostring(task.parent.pid)})),
|
||||
[".meta"]=strFile(buildMeta({cwd=task.cwd,parent="/proc/"..tostring(task.parent.pid),root=task.root or "/"})),
|
||||
uid=strFile(task.uid),
|
||||
comm=strFile(task.name),
|
||||
fd={
|
||||
@@ -115,7 +115,9 @@ local function newtaskproxy(task)
|
||||
children={
|
||||
[".meta"]=strFile(buildMeta(children))
|
||||
},
|
||||
pid=strFile(task.pid)
|
||||
pid=strFile(task.pid),
|
||||
ivs=strFile(task.ivs),
|
||||
vs=strFile(task.vs)
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -19,6 +19,17 @@ if not initFunc then kernel.PANIC("Failed to load init system: " .. err) end
|
||||
|
||||
kernel.tasks["1"] = {
|
||||
coro = coroutine.create(function()
|
||||
for i,v in pairs(kernel.processes) do
|
||||
kernel.log("Spawning kernel task "..i)
|
||||
syscall.spawn(function()
|
||||
local status, err = pcall(v)
|
||||
if not status then
|
||||
kernel.log("Error executing kernel task '" .. i .. "': " .. err, "ERROR", 0xFF0000)
|
||||
else
|
||||
kernel.log("Successfully executed kernel task: " .. i)
|
||||
end
|
||||
end, i, nil,nil,nil,true)
|
||||
end
|
||||
local ok, err = xpcall(initFunc, debug.traceback, kernel)
|
||||
if not ok then
|
||||
kernel.panic("Init system crashed: " .. tostring(err))
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.5.0
|
||||
1.2.4
|
||||
@@ -0,0 +1 @@
|
||||
Hyperion
|
||||
@@ -0,0 +1,2 @@
|
||||
Hyperion-kernel
|
||||
Hyperion-core
|
||||
@@ -0,0 +1 @@
|
||||
HyperionOS install package-group
|
||||
@@ -0,0 +1 @@
|
||||
1.2.4
|
||||
@@ -0,0 +1 @@
|
||||
Hyperion
|
||||
@@ -0,0 +1,10 @@
|
||||
Hyperion-kernel
|
||||
Hyperion-core
|
||||
coreutils
|
||||
spm
|
||||
sysinit
|
||||
hysh
|
||||
lua
|
||||
micro
|
||||
Hypersplash
|
||||
math
|
||||
@@ -0,0 +1 @@
|
||||
HyperionOS install package-group
|
||||
@@ -0,0 +1 @@
|
||||
1.2.4
|
||||
@@ -0,0 +1 @@
|
||||
Hyperion
|
||||
@@ -0,0 +1,6 @@
|
||||
Hyperion-kernel
|
||||
Hyperion-core
|
||||
coreutils
|
||||
hysh
|
||||
lua
|
||||
wget
|
||||
@@ -0,0 +1 @@
|
||||
HyperionOS install package-group
|
||||
@@ -0,0 +1 @@
|
||||
1.2.4
|
||||
@@ -1,2 +0,0 @@
|
||||
Hyperion
|
||||
Astronand
|
||||
Whitespace-only changes.
Whitespace-only changes.
@@ -1 +0,0 @@
|
||||
Hyperion os live installer
|
||||
@@ -1 +0,0 @@
|
||||
1.0.0
|
||||
@@ -1,4 +0,0 @@
|
||||
--:Minify:--
|
||||
local lib = {}
|
||||
|
||||
return lib
|
||||
+12
-7
@@ -97,6 +97,7 @@ local spm = function(...)
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
---@diagnostic disable-next-line: cast-local-type
|
||||
i=nil
|
||||
|
||||
if cloptions.help or cloptions.h then
|
||||
@@ -632,9 +633,11 @@ local spm = function(...)
|
||||
if pkgdb[i] then
|
||||
if not cloptions.overwrite then
|
||||
for f,h in pairs(v.data) do
|
||||
if pkgdb[i].files[f]~=md5(fs.readAllText(f)) then
|
||||
w(f.." was modified on disk, specify --overwrite to overwrite")
|
||||
block[f]=true
|
||||
if fs.exists(f) then
|
||||
if pkgdb[i].files[f]~=md5(fs.readAllText(f)) then
|
||||
w(f.." was modified on disk, specify --overwrite to overwrite")
|
||||
block[f]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -655,10 +658,12 @@ local spm = function(...)
|
||||
if pkgdb[i] then
|
||||
for f,c in pairs(pkgdb[i].files) do
|
||||
if not v.data[f] then
|
||||
if c~=md5(fs.readAllText(f)) then
|
||||
w(f.." was modified on disk, specify --overwrite to overwrite")
|
||||
else
|
||||
delete[f]=true
|
||||
if fs.exists(f) then
|
||||
if c~=md5(fs.readAllText(f)) then
|
||||
w(f.." was modified on disk, specify --overwrite to overwrite")
|
||||
else
|
||||
delete[f]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
local args={...}
|
||||
syscall.remove("/sbin/init")
|
||||
syscall.symlink("/usr/lib/sysinit/sysinit", "/sbin/init")
|
||||
syscall.exec("/sbin/init", args)
|
||||
@@ -5,18 +5,6 @@ kernel.saveLog()
|
||||
local fs=require("fs")
|
||||
kernel.log("Loaded fs")
|
||||
|
||||
for i,v in pairs(kernel.processes) do
|
||||
kernel.log("Spawning kernel task "..i)
|
||||
syscall.spawn(function()
|
||||
local status, err = pcall(v)
|
||||
if not status then
|
||||
kernel.log("Error executing kernel task '" .. i .. "': " .. err, "ERROR", 0xFF0000)
|
||||
else
|
||||
kernel.log("Successfully executed kernel task: " .. i)
|
||||
end
|
||||
end, i, nil,nil,nil,true)
|
||||
end
|
||||
|
||||
-- config file path setup
|
||||
if not fs.exists("/etc/sysinit/") then
|
||||
kernel.log("Creating conf path")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "Hyperion-firmware-ccpc",
|
||||
"id": "Hyperion-addon-ccpc-gfx",
|
||||
"description": "firmware for CraftOS PC",
|
||||
"authors": [
|
||||
"Hyperion",
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "b6c3a1bff52636f79f4c8f39def03aa2",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ccpc.tar.gz"
|
||||
"hash": "28835e332f3c81e9417aee029d89dc02",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-addon-ccpc-gfx.tar.gz"
|
||||
}
|
||||
@@ -8,6 +8,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "a4e33985213691b829940e014685ba0d",
|
||||
"hash": "43751951c361c3caba27aef01d37f5d5",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-ac.tar.gz"
|
||||
}
|
||||
@@ -4,6 +4,6 @@
|
||||
"authors": [],
|
||||
"dependencies": [],
|
||||
"version": "0.0.0",
|
||||
"hash": "dd93f2bd27640aea671155c26c3c47c5",
|
||||
"hash": "56892ed6be471cb132c0762882293fe7",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-addon-cct.tar.gz"
|
||||
}
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.3.0",
|
||||
"hash": "15dbb52d9c151a30de521f13e2a16278",
|
||||
"hash": "8fb602c785c57a3a2779345c33dcb850",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-cct.tar.gz"
|
||||
}
|
||||
@@ -8,6 +8,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "913d68c1c1a42afd42bfbab61a10729e",
|
||||
"hash": "164db01c04cd35b1220ac7e3b0c6d9c1",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-oc.tar.gz"
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"id": "Hyperion-firmware-lua",
|
||||
"id": "Hyperion-firmware-puc",
|
||||
"description": "No description provided",
|
||||
"authors": [],
|
||||
"dependencies": [],
|
||||
"version": "0.0.0",
|
||||
"hash": "c8fec163cdbcda36fe01d8bb9fd4e327",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-lua.tar.gz"
|
||||
"hash": "c7ac47aee2275eddb834a933bab1a90e",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-firmware-puc.tar.gz"
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
"Spsf"
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.5.0",
|
||||
"hash": "d45b18adc188a3090e5f1d9aca687347",
|
||||
"version": "1.2.4",
|
||||
"hash": "0ccf68c82625052e8f2a24e4faa311e1",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/Hyperion-kernel.tar.gz"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "HyperionOS-bones",
|
||||
"description": "HyperionOS install package-group",
|
||||
"authors": [
|
||||
"Hyperion"
|
||||
],
|
||||
"dependencies": [
|
||||
"Hyperion-kernel",
|
||||
"Hyperion-core"
|
||||
],
|
||||
"version": "1.2.4",
|
||||
"hash": "aa030c94b32efce1387af837bd5e72c5",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/HyperionOS-bones.tar.gz"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"id": "HyperionOS-full",
|
||||
"description": "HyperionOS install package-group",
|
||||
"authors": [
|
||||
"Hyperion"
|
||||
],
|
||||
"dependencies": [
|
||||
"Hyperion-kernel",
|
||||
"Hyperion-core",
|
||||
"coreutils",
|
||||
"spm",
|
||||
"sysinit",
|
||||
"hysh",
|
||||
"lua",
|
||||
"micro",
|
||||
"Hypersplash",
|
||||
"math"
|
||||
],
|
||||
"version": "1.2.4",
|
||||
"hash": "77e9072b72ed42823723af56d8f35fe8",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/HyperionOS-full.tar.gz"
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"id": "HyperionOS-minimal",
|
||||
"description": "HyperionOS install package-group",
|
||||
"authors": [
|
||||
"Hyperion"
|
||||
],
|
||||
"dependencies": [
|
||||
"Hyperion-kernel",
|
||||
"Hyperion-core",
|
||||
"coreutils",
|
||||
"hysh",
|
||||
"lua",
|
||||
"wget"
|
||||
],
|
||||
"version": "1.2.4",
|
||||
"hash": "ac1d8da249759cf5dd31cff3adf2adb8",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/HyperionOS-minimal.tar.gz"
|
||||
}
|
||||
@@ -8,6 +8,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "34996938f359f52e92a388483c3fb5c9",
|
||||
"hash": "f611bceac262a27951210790f1ccf2d9",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/coreutils.tar.gz"
|
||||
}
|
||||
@@ -1,12 +1,14 @@
|
||||
{
|
||||
"id": "gfx",
|
||||
"id": "fonts",
|
||||
"description": "package providing kernel support for framebuffers and graphics",
|
||||
"authors": [
|
||||
"Hyperion",
|
||||
"Astronand"
|
||||
],
|
||||
"dependencies": [],
|
||||
"dependencies": [
|
||||
"vector"
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"hash": "aaf9664adb4d85aa6d0d504692e8ec26",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/gfx.tar.gz"
|
||||
"hash": "dea723966d4438be36d15ad085024ddf",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/fonts.tar.gz"
|
||||
}
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.3.0",
|
||||
"hash": "cbc352d49cb9837ee825471351dd9ffc",
|
||||
"hash": "43cc19c08476183a808a2a72de1a04b6",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/hysh.tar.gz"
|
||||
}
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.2.0",
|
||||
"hash": "7479232dae56ad762119a8c57767e617",
|
||||
"hash": "3d0e55dd8dacd8b410572c559715c2a8",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/lua.tar.gz"
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"id": "installer",
|
||||
"description": "Hyperion os live installer",
|
||||
"id": "math",
|
||||
"description": "General advanced math libs\nVectorX\nMatrix",
|
||||
"authors": [
|
||||
"Hyperion",
|
||||
"Astronand"
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.0.0",
|
||||
"hash": "897e5abc980bda9051fff8f72c864251",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/installer.tar.gz"
|
||||
"hash": "aef55708381a481860c48d819d817911",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/math.tar.gz"
|
||||
}
|
||||
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.
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"id": "render3d",
|
||||
"description": "No description provided",
|
||||
"authors": [],
|
||||
"dependencies": [],
|
||||
"version": "0.0.0",
|
||||
"hash": "8fcbaa029a137bc0c047a990b9bf3a92",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/render3d.tar.gz"
|
||||
}
|
||||
+1
-1
@@ -14,6 +14,6 @@
|
||||
"Hyperion-core"
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"hash": "996e0fed6b0cb4ae5fb578ba3cfb0680",
|
||||
"hash": "bc76091060b9c3190a6ecd508b213f53",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/spm.tar.gz"
|
||||
}
|
||||
@@ -7,6 +7,6 @@
|
||||
],
|
||||
"dependencies": [],
|
||||
"version": "1.1.0",
|
||||
"hash": "8c4a3ffcf86326bb0c07338060bb7727",
|
||||
"hash": "61dd459f48f7f8fabb6b649331d87886",
|
||||
"tarball": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/raw/sysinit.tar.gz"
|
||||
}
|
||||
@@ -1,27 +1,31 @@
|
||||
{
|
||||
"packages": {
|
||||
"Hyperion-addon-ccpc-gfx": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-addon-ccpc-gfx.pkg",
|
||||
"Hyperion-core": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-core.pkg",
|
||||
"Hyperion-firmware-ac": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-ac.pkg",
|
||||
"Hyperion-firmware-addon-cct": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-addon-cct.pkg",
|
||||
"Hyperion-firmware-ccpc": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-ccpc.pkg",
|
||||
"Hyperion-firmware-cct": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-cct.pkg",
|
||||
"Hyperion-firmware-lua": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-lua.pkg",
|
||||
"Hyperion-firmware-oc": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-oc.pkg",
|
||||
"Hyperion-firmware-puc": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-puc.pkg",
|
||||
"Hyperion-firmware-vm": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-firmware-vm.pkg",
|
||||
"Hyperion-kernel": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/Hyperion-kernel.pkg",
|
||||
"HyperionOS-bones": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/HyperionOS-bones.pkg",
|
||||
"HyperionOS-full": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/HyperionOS-full.pkg",
|
||||
"HyperionOS-minimal": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/HyperionOS-minimal.pkg",
|
||||
"bit32": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/bit32.pkg",
|
||||
"blake2s": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/blake2s.pkg",
|
||||
"coreutils": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/coreutils.pkg",
|
||||
"deflate": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/deflate.pkg",
|
||||
"gfx": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/gfx.pkg",
|
||||
"fonts": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/fonts.pkg",
|
||||
"hysh": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/hysh.pkg",
|
||||
"iniparse": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/iniparse.pkg",
|
||||
"installer": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/installer.pkg",
|
||||
"json": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/json.pkg",
|
||||
"lua": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/lua.pkg",
|
||||
"math": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/math.pkg",
|
||||
"micro": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/micro.pkg",
|
||||
"minify": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/minify.pkg",
|
||||
"pid": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/pid.pkg",
|
||||
"render3d": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/render3d.pkg",
|
||||
"spm": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/spm.pkg",
|
||||
"sysinit": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/sysinit.pkg",
|
||||
"tar": "https://git.astronand.dev/Hyperion/HyperionOS/raw/branch/main/packages/tar.pkg",
|
||||
|
||||
Reference in new issue
Block a user