mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-09 15:25:56 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8
This commit is contained in:
commit
51e3f8166b
@ -8,7 +8,7 @@ if #args == 0 then
|
||||
until not read
|
||||
else
|
||||
for i = 1, #args do
|
||||
local file, reason = io.open(args[i])
|
||||
local file, reason = io.open(args[i],"rb")--TODO: make b an option
|
||||
if not file then
|
||||
io.stderr:write(reason .. "\n")
|
||||
return
|
||||
|
@ -67,6 +67,8 @@ for n = 1, options.count do
|
||||
end
|
||||
if options.wait then
|
||||
os.sleep(tonumber(options.wait))
|
||||
else
|
||||
os.sleep(0)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,7 +5,8 @@ local text = require("text")
|
||||
local args, options = shell.parse(...)
|
||||
|
||||
local function formatSize(size)
|
||||
if not options.h then
|
||||
size = tonumber(size) or size
|
||||
if not options.h or type(size) ~= "number" then
|
||||
return tostring(size)
|
||||
end
|
||||
local sizes = {"", "K", "M", "G"}
|
||||
|
@ -73,6 +73,7 @@ local code = ""
|
||||
codeHandler = function(char)
|
||||
if char == "[" then code = code .. char
|
||||
elseif char == "0" then code = code .. char
|
||||
elseif char == "3" then code = code .. char
|
||||
elseif code == "[" and char == "A" then
|
||||
charHandler = baseHandler
|
||||
if y - 1 < 1 then return end
|
||||
@ -139,6 +140,16 @@ codeHandler = function(char)
|
||||
out:write(text)
|
||||
out:close()
|
||||
end
|
||||
elseif code == "[3" and char == "~" then
|
||||
charHandler = baseHandler
|
||||
if x > unicode.len(lines[y]) then
|
||||
lines[y] = lines[y] .. (lines[y + 1] or "")
|
||||
table.remove(lines, y + 1)
|
||||
render(y, atline + edith - y)
|
||||
return
|
||||
end
|
||||
lines[y] = lines[y]:sub(1, x-1) .. lines[y]:sub(x+1)
|
||||
render(y, 1)
|
||||
else
|
||||
charHandler = baseHandler
|
||||
end
|
||||
@ -149,7 +160,7 @@ baseHandler = function(char)
|
||||
code = ""
|
||||
charHandler = codeHandler
|
||||
elseif char == "\n" then
|
||||
line = lines[y]
|
||||
local line = lines[y]
|
||||
lines[y] = unicode.sub(line or "", 1, x - 1)
|
||||
table.insert(lines, y + 1, unicode.sub(line or "", x))
|
||||
x = 1
|
||||
|
@ -199,6 +199,8 @@ local commandList = {}
|
||||
-- \x1b9[Row];[Col];[Height];[Width]F -- fill
|
||||
-- \x1b9[Row];[Col];[Height];[Width];[Dest Row];[Dest Col]c -- copy
|
||||
|
||||
--Add fake gpu component for compat(?)
|
||||
|
||||
function charHandlers.control(char)
|
||||
if char == "\x1b" then
|
||||
commandList = {}
|
||||
|
@ -2,6 +2,21 @@ local network = require "network"
|
||||
local computer = require "computer"
|
||||
local args = {...}
|
||||
|
||||
local function formatSize(size)
|
||||
size = tonumber(size) or size
|
||||
if type(size) ~= "number" then
|
||||
return tostring(size)
|
||||
end
|
||||
local sizes = {"", "K", "M", "G"}
|
||||
local unit = 1
|
||||
local power = 1024
|
||||
while size > power and unit < #sizes do
|
||||
unit = unit + 1
|
||||
size = size / power
|
||||
end
|
||||
return math.floor(size * 10) / 10 .. sizes[unit]
|
||||
end
|
||||
|
||||
local function align(txt)return txt .. (" "):sub(#txt+1)end
|
||||
|
||||
if #args < 1 then
|
||||
@ -14,7 +29,7 @@ if #args < 1 then
|
||||
local pktIn, pktOut, bytesIn, bytesOut = network.info.getInterfaceInfo(node)
|
||||
print(" RX packets:"..tostring(pktIn))
|
||||
print(" TX packets:"..tostring(pktOut))
|
||||
print(" RX bytes:"..tostring(bytesIn).." TX bytes:"..tostring(bytesOut))
|
||||
print(" RX bytes: ".. tostring(bytesIn) .. " (" ..formatSize(bytesIn).. ") TX bytes: " ..tostring(bytesOut) .. " (".. formatSize(bytesOut) .. ")")
|
||||
end
|
||||
elseif args[1] == "bind" and args[2] then
|
||||
print("Address attached")
|
||||
|
@ -1,13 +1,28 @@
|
||||
--Plan9k userspace init for pipes kernel
|
||||
|
||||
--TODO: pcall all + emergency shell(or do it higher, in pipes)
|
||||
|
||||
local pipes = require("pipes")
|
||||
local component = require("component")
|
||||
local filesystem = require("filesystem")
|
||||
local component = require("component")
|
||||
|
||||
os.setenv("LIBPATH", "/lib/?.lua;/usr/lib/?.lua;/home/lib/?.lua;./?.lua;/lib/?/init.lua;/usr/lib/?/init.lua;/home/lib/?/init.lua;./?/init.lua")
|
||||
os.setenv("PATH", "/usr/local/bin:/usr/bin:/bin:.")
|
||||
os.setenv("PWD", "/")
|
||||
os.setenv("PS1", "\x1b[33m$PWD\x1b[31m#\x1b[39m ")
|
||||
|
||||
pipes.log("INIT: Mounting filesystems")
|
||||
|
||||
if filesystem.exists("/etc/fstab") then
|
||||
for entry in io.lines("/etc/fstab") do
|
||||
if entry:sub(1,1) ~= "#" then
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pipes.log("INIT: Starting terminals")
|
||||
|
||||
if not filesystem.exists("/root") then
|
||||
filesystem.makeDirectory("/root")
|
||||
end
|
||||
@ -37,7 +52,6 @@ end
|
||||
|
||||
local sin, sout
|
||||
|
||||
|
||||
local screens = component.list("screen")
|
||||
for gpu in component.list("gpu") do
|
||||
local screen = screens()
|
||||
@ -85,7 +99,11 @@ end
|
||||
pcall(services)
|
||||
|
||||
local kout = io.popen(function()
|
||||
pipes.setThreadName("/bin/tee.lua")
|
||||
if filesystem.exists("/kern.log") then
|
||||
filesystem.remove("/kern.log.old")
|
||||
filesystem.rename("/kern.log", "/kern.log.old")
|
||||
end
|
||||
pipes.setThreadName("[init]/logd")
|
||||
io.output(sout)
|
||||
loadfile("/bin/tee.lua", nil, _G)("/kern.log")
|
||||
end, "w")
|
||||
|
@ -1,5 +1,8 @@
|
||||
local serialization = require("serialization")
|
||||
local term = require("term")
|
||||
local fs = require("filesystem")
|
||||
|
||||
local args = {...}
|
||||
|
||||
local env = setmetatable({}, {__index = _ENV})
|
||||
|
||||
@ -10,6 +13,13 @@ local function optrequire(...)
|
||||
end
|
||||
end
|
||||
|
||||
if args[1] and fs.exists(args[1]) then --non standard, require -i !!!
|
||||
local f = io.open(args[1])
|
||||
local code = load(f:read("*all"), "="..args[1], "t", env)
|
||||
f:close()
|
||||
xpcall(code, debug.traceback)
|
||||
end
|
||||
|
||||
local hist = {}
|
||||
while true do
|
||||
io.write(tostring(env._PROMPT or "lua> "))
|
||||
|
@ -0,0 +1,44 @@
|
||||
local term = require("term")
|
||||
|
||||
function usage()
|
||||
print(
|
||||
[[Usage:
|
||||
more [options] ...
|
||||
|
||||
A file perusal filter for CRT viewing.]])
|
||||
end
|
||||
|
||||
local args = {...}
|
||||
local file = args[1]
|
||||
if not file then usage() return end
|
||||
|
||||
file = io.open(file)
|
||||
|
||||
if not file then
|
||||
print("File not found")
|
||||
return
|
||||
end
|
||||
|
||||
term.clear()
|
||||
local _, h = term.getResolution()
|
||||
io.write("\x1b[1;1H")
|
||||
print("...",h)
|
||||
for i = 1, h - 2 do
|
||||
local line = file:read("*l")
|
||||
if not line then print("input end")return end
|
||||
print(line)
|
||||
end
|
||||
|
||||
io.write("\x1b47m\x1b30m--More--\x1b39m\x1b49m")
|
||||
|
||||
while true do
|
||||
local c = io.read(1)
|
||||
if c == "\n" then
|
||||
local line = file:read("*l")
|
||||
if not line then return end
|
||||
print("\r\x1b[K" .. line)
|
||||
io.write("\x1b47m\x1b30m--More--\x1b39m\x1b49m")
|
||||
elseif c == "q" then
|
||||
return
|
||||
end
|
||||
end
|
@ -203,6 +203,7 @@ while run do
|
||||
if term.getCursor() > 1 then
|
||||
io.write("\n")
|
||||
end
|
||||
io.write("\x1b49m\x1b39m")
|
||||
io.write(expand(os.getenv("PS1")))
|
||||
local cmd = term.read(history)--io.read("*l")
|
||||
--print("--IN: ", cmd)
|
||||
|
@ -3,7 +3,7 @@ local args = {...}
|
||||
local f = io.open(args[1], "a")
|
||||
|
||||
while true do
|
||||
local data = io.read(1)
|
||||
local data = io.read("*L")
|
||||
if not data then
|
||||
f:close()
|
||||
return
|
||||
@ -11,7 +11,7 @@ while true do
|
||||
if io.input().remaining() > 0 then
|
||||
data = data .. io.read(io.input().remaining())
|
||||
end
|
||||
io.write(data)
|
||||
f:write(data)
|
||||
f:flush()
|
||||
io.write(data)
|
||||
end
|
||||
|
@ -9,7 +9,6 @@ proxy.isReadOnly = function() return true end
|
||||
proxy.rename = function() error("Permission Denied") end
|
||||
proxy.remove = function() error("Permission Denied") end
|
||||
proxy.setLabel = function() error("Permission Denied") end
|
||||
proxy.seek = function() error("Not supported") end
|
||||
proxy.size = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
@ -22,7 +21,17 @@ proxy.getLabel = function() return "devfs" end
|
||||
|
||||
local allocator, handles = kernel.modules.util.getAllocator()
|
||||
|
||||
proxy.exists = function()end
|
||||
proxy.exists = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
for _, d in pairs(seg) do
|
||||
if not file[d] then
|
||||
return false
|
||||
end
|
||||
file = file[d]
|
||||
end
|
||||
return file and true or false
|
||||
end
|
||||
proxy.open = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
@ -48,6 +57,9 @@ end
|
||||
proxy.write = function(h, ...)
|
||||
return handles[h].file.write(handles[h], ...)
|
||||
end
|
||||
proxy.seek = function(h, ...)
|
||||
return handles[h].file.seek(handles[h], ...)
|
||||
end
|
||||
proxy.isDirectory = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local dir = data
|
||||
@ -69,8 +81,8 @@ proxy.list = function(path)
|
||||
error("File is not a directory")
|
||||
end
|
||||
local list = {}
|
||||
for f in pairs(dir) do
|
||||
list[#list + 1] = f
|
||||
for f, node in pairs(dir) do
|
||||
list[#list + 1] = f .. (node.__type and "" or "/")
|
||||
end
|
||||
return list
|
||||
end
|
||||
@ -80,6 +92,12 @@ data.null = {
|
||||
__type = "f",
|
||||
write = function()end
|
||||
}
|
||||
data.kmsg = {
|
||||
__type = "f",
|
||||
write = function(h, data)
|
||||
kernel.io.println(data)
|
||||
end
|
||||
}
|
||||
data.zero = {
|
||||
__type = "f",
|
||||
read = function(h, c)
|
||||
|
@ -15,6 +15,7 @@ proxy.getLabel = function() return "procfs" end
|
||||
local allocator, handles = kernel.modules.util.getAllocator()
|
||||
|
||||
proxy.exists = function()end
|
||||
|
||||
proxy.open = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local file = data
|
||||
@ -32,16 +33,21 @@ proxy.open = function(path)
|
||||
end
|
||||
return hnd.id
|
||||
end
|
||||
|
||||
proxy.read = function(h, n)
|
||||
return handles[h]:read(n)
|
||||
end
|
||||
|
||||
proxy.close = function(h)
|
||||
allocator:unset(handles[h])
|
||||
end
|
||||
|
||||
proxy.write = function() error("Permission Denied") end
|
||||
|
||||
proxy.isDirectory = function()
|
||||
|
||||
end
|
||||
|
||||
proxy.list = function(path)
|
||||
local seg = kernel.modules.vfs.segments(path)
|
||||
local dir = data
|
||||
@ -51,11 +57,11 @@ proxy.list = function(path)
|
||||
local list = {}
|
||||
for pid, thr in pairs(kernel.modules.threading.threads) do
|
||||
if thr.coro and dir == data then
|
||||
list[#list + 1] = tostring(pid)
|
||||
list[#list + 1] = tostring(pid) .. "/"
|
||||
end
|
||||
end
|
||||
for f in pairs(dir) do
|
||||
list[#list + 1] = f
|
||||
for f, node in pairs(dir) do
|
||||
list[#list + 1] = f .. (type(node) == "table" and "/" or "")
|
||||
end
|
||||
return list
|
||||
end
|
||||
@ -72,13 +78,36 @@ data.cpuinfo = function()
|
||||
"cpu family : 1\n" ..
|
||||
"model : 1\n" ..
|
||||
"model name : OpenComputers Lua CPU @ unkown Tier\n" ..
|
||||
"microcode : 0x52\n" ..
|
||||
"microcode : " .. (string.pack and "0x53" or "0x52") .. "\n" ..
|
||||
"physical id : 0\n"
|
||||
end
|
||||
|
||||
data.uptime = function()
|
||||
return tostring(computer.uptime())
|
||||
end
|
||||
|
||||
setmetatable(data, {__index = function(_, k)
|
||||
if tonumber(k) and kernel.modules.threading.threads[tonumber(k)] and kernel.modules.threading.threads[tonumber(k)].coro then
|
||||
return {comm = function()return kernel.modules.threading.threads[tonumber(k)].name end}
|
||||
return {
|
||||
comm = function()return kernel.modules.threading.threads[tonumber(k)].name end,
|
||||
limits = function()
|
||||
local limits = "Limit Units Soft Limit\n"
|
||||
limits = limits .. "Max pending signals signals " .. kernel.modules.threading.threads[tonumber(k)].maxPendingSignals .. "\n"
|
||||
limits = limits .. "Max open files files " .. kernel.modules.threading.threads[tonumber(k)].maxOpenFiles .. "\n"
|
||||
return limits
|
||||
end,
|
||||
status = function()
|
||||
local status = ""
|
||||
status = status .. "Name: " .. kernel.modules.threading.threads[tonumber(k)].name .. "\n"
|
||||
status = status .. "State: " .. coroutine.status(kernel.modules.threading.threads[tonumber(k)].coro) .. "\n"
|
||||
status = status .. "Pid: " .. kernel.modules.threading.threads[tonumber(k)].pid .. "\n"
|
||||
status = status .. "Uid: " .. kernel.modules.threading.threads[tonumber(k)].uid .. "\n"
|
||||
|
||||
--TODO: count actual signals
|
||||
status = status .. "SigQ: " .. #kernel.modules.threading.threads[tonumber(k)].eventQueue .. "/" .. kernel.modules.threading.threads[tonumber(k)].maxPendingSignals .. "\n"
|
||||
return status
|
||||
end
|
||||
}
|
||||
end
|
||||
end})
|
||||
|
||||
|
@ -51,6 +51,7 @@ function kernel.userspace.os.spawn(prog, ...)
|
||||
local thread = kernel.modules.threading.spawn(prog, 0, name, isThread, _, ...)
|
||||
thread.io_output = kernel.modules.threading.currentThread.io_output
|
||||
thread.io_input = kernel.modules.threading.currentThread.io_input
|
||||
thread.io_error = kernel.modules.threading.currentThread.io_error
|
||||
return thread.pid
|
||||
end
|
||||
|
||||
@ -78,6 +79,7 @@ end
|
||||
|
||||
function kernel.userspace.os.exit()
|
||||
kernel.modules.threading.kill(kernel.modules.threading.currentThread.pid)
|
||||
coroutine.yield("yield", 0)
|
||||
end
|
||||
|
||||
function kernel.userspace.os.sleep(time)
|
||||
@ -142,7 +144,12 @@ end
|
||||
|
||||
kernel.userspace.coroutine = {}
|
||||
|
||||
kernel.userspace.coroutine.yield = function(...)
|
||||
return coroutine.yield(...)--TODO: FIX; move to debug
|
||||
end
|
||||
|
||||
--lua 5.3 <-> 5.2 compat
|
||||
kernel.userspace.bit32 = bit32 or load([[return {
|
||||
band = function(a, b) return a & b end,
|
||||
bor = function(a, b) return a | b end,
|
||||
bxor = function(a, b) return a ~ b end,
|
||||
bnot = function(a) return ~a end,
|
||||
rshift = function(a, n) return a >> n end,
|
||||
lshift = function(a, n) return a << n end,
|
||||
}]])()
|
||||
|
@ -39,18 +39,17 @@ end
|
||||
local function pathSearcher(module)
|
||||
local filepath, reason = kernel.userspace.package.searchpath(module, kernel.userspace.os.getenv("LIBPATH"))
|
||||
if filepath then
|
||||
local loader, reason = kernel.userspace.loadfile(filepath, "bt", setmetatable({},{__index = kernel.userspace}))
|
||||
local loader
|
||||
loader, reason = kernel.userspace.loadfile(filepath, "bt", setmetatable({},{__index = kernel.userspace}))
|
||||
if loader then
|
||||
local state, mod = pcall(loader)
|
||||
local state
|
||||
state, reason = pcall(loader)
|
||||
if state then
|
||||
return mod
|
||||
else
|
||||
kernel.io.println("Module '" .. tostring(module) .. "' loading failed: " .. tostring(mod))
|
||||
return reason
|
||||
end
|
||||
end
|
||||
else
|
||||
return nil, reason
|
||||
end
|
||||
return nil, reason
|
||||
end
|
||||
|
||||
kernel.userspace.package.searchers[#kernel.userspace.package.searchers + 1] = preloadSearcher
|
||||
@ -65,19 +64,23 @@ kernel.userspace.require = function(module)
|
||||
if kernel.userspace.package.loading[module] then
|
||||
error("Already loading "..tostring(module))
|
||||
else
|
||||
local reason
|
||||
|
||||
kernel.userspace.package.loading[module] = true
|
||||
for _, searcher in ipairs(kernel.userspace.package.searchers) do
|
||||
local res, mod, reason = pcall(searcher, module)
|
||||
if res and mod then
|
||||
local success, mod, res = pcall(searcher, module)
|
||||
if success and mod then
|
||||
kernel.userspace.package.loading[module] = nil
|
||||
kernel.userspace.package.loaded[module] = mod
|
||||
return mod
|
||||
elseif not mod and reason then
|
||||
kernel.io.println("Searcher for '" .. tostring(module) .. "' loading failed: " .. tostring(reason))
|
||||
elseif (not success) and mod then
|
||||
reason = mod
|
||||
elseif res then
|
||||
reason = res
|
||||
end
|
||||
end
|
||||
kernel.userspace.package.loading[module] = nil
|
||||
error("Could not load module " .. tostring(module))
|
||||
error(string.format("Could not load module '%s': %s", module, reason or "module returned nil"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,47 @@
|
||||
cards = {}
|
||||
|
||||
|
||||
local function buildDevfs()
|
||||
for file in pairs(kernel.modules.devfs.data) do
|
||||
if file == "urandom" then
|
||||
kernel.modules.devfs.data[file] = nil
|
||||
end
|
||||
end
|
||||
|
||||
kernel.modules.devfs.data["urandom"] = {
|
||||
__type = "f",
|
||||
read = function(h, len)
|
||||
return component.invoke(cards[1], "random", len)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
local function onComponentAdded(_, address, componentType)
|
||||
if componentType == "data" then
|
||||
cards[#cards + 1] = address
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
|
||||
local function onComponentRemoved(_, address, componentType)
|
||||
if componentType == "data" then
|
||||
local t
|
||||
for i, card in ipairs(cards) do
|
||||
if card == address then
|
||||
t = i
|
||||
break
|
||||
end
|
||||
end
|
||||
table.remove(cards, t)
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
|
||||
--function start()
|
||||
--for card, t in component.list("data") do
|
||||
-- onComponentAdded(_, card, t)
|
||||
--end
|
||||
--end
|
||||
|
||||
kernel.modules.keventd.listen("component_added", onComponentAdded)
|
||||
kernel.modules.keventd.listen("component_removed", onComponentRemoved)
|
@ -0,0 +1,117 @@
|
||||
drives = {}
|
||||
|
||||
function writeSectors(drive, data, at)
|
||||
local sectorSize = component.invoke(drive, "getSectorSize")
|
||||
repeat
|
||||
local atSector = math.floor((at - 1) / sectorSize) + 1
|
||||
|
||||
local inSectorStart = (at - 1) % sectorSize + 1
|
||||
local writable = math.min(#data, sectorSize - inSectorStart + 1)
|
||||
|
||||
local old = component.invoke(drive, "readSector", atSector)
|
||||
|
||||
local before = old:sub(0, inSectorStart - 1)
|
||||
local after = old:sub(inSectorStart + writable)
|
||||
|
||||
local toWrite = before .. data:sub(1, writable) .. after
|
||||
data = data:sub(writable + 1)
|
||||
|
||||
kernel.io.println("Wd: " .. atSector .. "/" .. #toWrite .. ": "..inSectorStart.." [ " .. writable .. " ] "..(inSectorStart + writable) .. " #old="..#old)
|
||||
component.invoke(drive, "writeSector", atSector, toWrite)
|
||||
|
||||
at = at + writable
|
||||
until #data < 1
|
||||
end
|
||||
|
||||
function readSectors(drive, at, len)
|
||||
local data = ""
|
||||
local sectorSize = component.invoke(drive, "getSectorSize")
|
||||
repeat
|
||||
local atSector = math.floor(at / sectorSize) + 1
|
||||
|
||||
sector = component.invoke(drive, "readSector", atSector)
|
||||
kernel.io.println("Rsect " .. atSector .. ": " .. tostring((at - 1) % sectorSize + 1) .. " -> " .. tostring(math.min((at - 1) % sectorSize + len - #data, sectorSize)))
|
||||
local read = sector:sub((at - 1) % sectorSize + 1, math.min((at - 1) % sectorSize + len - #data, sectorSize))
|
||||
|
||||
data = data .. read
|
||||
at = at + #read
|
||||
until #data >= len
|
||||
return data
|
||||
end
|
||||
|
||||
local function buildDevfs()
|
||||
for file in pairs(kernel.modules.devfs.data) do
|
||||
if file:match("^sd") then
|
||||
kernel.modules.devfs.data[file] = nil
|
||||
end
|
||||
end
|
||||
for k, drive in ipairs(drives) do
|
||||
kernel.modules.devfs.data["sd" .. string.char(k + 96)] = {
|
||||
__type = "f",
|
||||
open = function(hnd)
|
||||
--component.invoke(drive, "seek", -math.huge)
|
||||
hnd.drive = drive
|
||||
hnd.pos = 1
|
||||
--kernel.io.println("Od: " .. hnd.pos .. "/" .. component.invoke(drive, "getCapacity"))
|
||||
end,
|
||||
size = function()
|
||||
return component.invoke(drive, "getCapacity")
|
||||
end,
|
||||
write = function(h, data)
|
||||
|
||||
writeSectors(drive, data, h.pos)
|
||||
--kernel.io.println("Wd: " .. h.pos .. "(+" .. #data .. ")/" .. component.invoke(drive, "getCapacity"))
|
||||
h.pos = h.pos + #data
|
||||
return not (h.pos >= component.invoke(drive, "getCapacity"))
|
||||
--TODO: do this correctly
|
||||
end,
|
||||
read = function(h, len)
|
||||
len = math.ceil(len)
|
||||
kernel.io.println("Rd " .. tostring(len) .. ": " .. h.pos .. "/" .. component.invoke(drive, "getCapacity"))
|
||||
if h.pos >= component.invoke(drive, "getCapacity") then
|
||||
return
|
||||
end
|
||||
local data = readSectors(drive, h.pos, len)
|
||||
h.pos = h.pos + len
|
||||
return data
|
||||
end,
|
||||
seek = function(h, whence, offset)
|
||||
offset = offset or 0
|
||||
if whence == "end" then
|
||||
h.pos = math.min(component.invoke(drive, "getCapacity"), math.max(1, component.invoke(drive, "getCapacity") - offset))
|
||||
return h.pos - 1
|
||||
elseif whence == "set" then
|
||||
h.pos = math.min(component.invoke(drive, "getCapacity"), math.max(1, 1 + offset))
|
||||
return h.pos - 1
|
||||
else
|
||||
h.pos = math.min(component.invoke(drive, "getCapacity"), math.max(1, h.pos + offset))
|
||||
return h.pos - 1
|
||||
end
|
||||
return math.floor(h.pos)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function onComponentAdded(_, address, componentType)
|
||||
if componentType == "drive" then
|
||||
drives[#drives + 1] = address
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
|
||||
local function onComponentRemoved(_, address, componentType)
|
||||
if componentType == "drive" then
|
||||
local t
|
||||
for i, drive in ipairs(drives) do
|
||||
if drive == address then
|
||||
t = i
|
||||
break
|
||||
end
|
||||
end
|
||||
table.remove(drives, t)
|
||||
buildDevfs()
|
||||
end
|
||||
end
|
||||
kernel.modules.keventd.listen("component_added", onComponentAdded)
|
||||
kernel.modules.keventd.listen("component_removed", onComponentRemoved)
|
@ -321,6 +321,7 @@ startNetwork = function()
|
||||
end
|
||||
sent = nil
|
||||
else
|
||||
|
||||
--we've already requested this addr so if we get the route
|
||||
--we'll respond
|
||||
routeRequests[dest][#routeRequests[dest]+1] = {type = "R", host = origin}
|
||||
|
@ -15,20 +15,33 @@ local function buildDevfs()
|
||||
end
|
||||
component.invoke(tape, "seek", -math.huge)
|
||||
hnd.tape = tape
|
||||
hnd.pos = 0
|
||||
end,
|
||||
size = function()
|
||||
return component.invoke(tape, "getSize")
|
||||
end,
|
||||
write = function(h, data)
|
||||
component.invoke(tape, "write", data)
|
||||
return not component.invoke(tape, "isEnd", data)
|
||||
h.pos = h.pos + #data
|
||||
return not (h.pos >= component.invoke(tape, "getSize"))
|
||||
--TODO: do this correctly
|
||||
end,
|
||||
read = function(h, len)
|
||||
if component.invoke(tape, "isEnd", data) then
|
||||
if h.pos >= component.invoke(tape, "getSize") then
|
||||
return
|
||||
end
|
||||
h.pos = h.pos + len
|
||||
return component.invoke(tape, "read", len)
|
||||
end,
|
||||
seek = function(h, whence, offset)
|
||||
if whence == "end" then
|
||||
h.pos = h.pos + component.invoke(tape, "seek", component.invoke(tape, "getSize") - h.pos - (offset or 0))
|
||||
elseif whence == "set" then
|
||||
h.pos = h.pos + component.invoke(tape, "seek", (offset or 0) - h.pos)
|
||||
else
|
||||
h.pos = h.pos + component.invoke(tape, "seek", offset or 0)
|
||||
end
|
||||
return math.floor(h.pos)
|
||||
end
|
||||
}
|
||||
end
|
||||
@ -55,11 +68,11 @@ local function onComponentRemoved(_, address, componentType)
|
||||
end
|
||||
end
|
||||
|
||||
function start()
|
||||
for tape, t in component.list("tape_drive") do
|
||||
onComponentAdded(_, tape, t)
|
||||
end
|
||||
end
|
||||
--function start()
|
||||
-- for tape, t in component.list("tape_drive") do
|
||||
-- onComponentAdded(_, tape, t)
|
||||
-- end
|
||||
--end
|
||||
|
||||
kernel.modules.keventd.listen("component_added", onComponentAdded)
|
||||
kernel.modules.keventd.listen("component_removed", onComponentRemoved)
|
||||
|
@ -71,6 +71,8 @@ function spawn(exec, child, name, isthread, _, ...)
|
||||
currentHandlerArg = nil,
|
||||
eventQueue = {{"arg", ...}},
|
||||
name = name or "unnamed",
|
||||
maxPendingSignals = 32,
|
||||
maxOpenFiles = 8,
|
||||
uid = nextUid
|
||||
}
|
||||
|
||||
@ -132,7 +134,7 @@ local function processSignals()
|
||||
for _, thread in ipairs(threads) do
|
||||
if thread.coro then
|
||||
local nsig, oldest = countThreadSignals(thread, "signal")
|
||||
if nsig > 32 then --TODO: make it a bit more intelligent
|
||||
if nsig > thread.maxPendingSignals then --TODO: make it a bit more intelligent
|
||||
table.remove(thread.eventQueue, oldest)
|
||||
end
|
||||
if thread.currentHandler == "yield" then
|
||||
|
@ -1,4 +1,5 @@
|
||||
function joinThread(pid)
|
||||
--coroutine.yield("yield", 0)
|
||||
while true do
|
||||
local dead = coroutine.yield("kill")
|
||||
if pid == dead then
|
||||
@ -30,7 +31,7 @@ function userKill(pid, signal, ...)
|
||||
local args = {...}
|
||||
local thread = kernel.modules.threading.threads[pid]
|
||||
kernel.modules.manageg.protect(thread.sandbox)
|
||||
--TODO: probably ser threading.currentThread here
|
||||
--TODO: probably set threading.currentThread here
|
||||
local res, reason = pcall(function()
|
||||
thread.kill[signal](table.unpack(args))
|
||||
end)
|
||||
@ -41,7 +42,7 @@ function userKill(pid, signal, ...)
|
||||
return true
|
||||
end
|
||||
|
||||
function setKillHandler(signal, handler)
|
||||
function setKillHandler(signal, handler) --WAT
|
||||
if not kernel.modules.threading.threads[pid]
|
||||
or not kernel.modules.threading.threads[pid].coro then
|
||||
return nil, "Thread does not exists"
|
||||
|
@ -1,6 +1,8 @@
|
||||
local term = {}
|
||||
|
||||
local function read(from, to)
|
||||
term.escape = "\x1b"
|
||||
local write = function(text) io.write(term.escape..text) end
|
||||
local read = function(from, to)
|
||||
local started, data
|
||||
while true do
|
||||
local char = io.read(1)
|
||||
@ -19,6 +21,279 @@ local function read(from, to)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
term.color={}
|
||||
term.color.black=30
|
||||
term.color.red=31
|
||||
term.color.green=32
|
||||
term.color.yellow=33
|
||||
term.color.blue=34
|
||||
term.color.magenta=35
|
||||
term.color.cyan=36
|
||||
term.color.white=37
|
||||
|
||||
term.attr={}
|
||||
term.attr.resetAllAttr=0
|
||||
term.attr.bright=1
|
||||
term.attr.dim=2
|
||||
term.attr.blink=5
|
||||
term.attr.reverse=7
|
||||
term.attr.hidden=8
|
||||
|
||||
------------------------------------------
|
||||
--Set Display Attributes
|
||||
------------------------------------------
|
||||
|
||||
--Set Attribute Mode *ESC*[{attr1};...;{attrn}m
|
||||
function term.setAttr(attr)
|
||||
write(attr.."m")
|
||||
end
|
||||
|
||||
function term.setForeground(color)
|
||||
write(color.."m")
|
||||
end
|
||||
|
||||
function term.setBackground(color)
|
||||
write((color+10).."m")
|
||||
end
|
||||
|
||||
------------------------------------------
|
||||
--Erasing Text
|
||||
------------------------------------------
|
||||
|
||||
--Erase End of Line *ESC*[K
|
||||
--Erases from the current cursor position to the end of the current line.
|
||||
function term.eraseEndOfLine()
|
||||
write("[K")
|
||||
end
|
||||
|
||||
--Erase Start of Line *ESC*[1K
|
||||
--Erases from the current cursor position to the start of the current line.
|
||||
function term.eraseStartOfLine()
|
||||
write("[1K")
|
||||
end
|
||||
|
||||
--Erase Line *ESC*[2K
|
||||
--Erases the entire current line.
|
||||
function term.eraseLine()
|
||||
write("[2K")
|
||||
end
|
||||
term.clearLine = term.eraseLine
|
||||
|
||||
--Erase Down *ESC*[J
|
||||
--Erases the screen from the current line down to the bottom of the screen.
|
||||
function term.eraseDown()
|
||||
write("[J")
|
||||
end
|
||||
|
||||
--Erase Up *ESC*[1J
|
||||
--Erases the screen from the current line up to the top of the screen.
|
||||
function term.eraseUp()
|
||||
write("[1J")
|
||||
end
|
||||
|
||||
--Erase Screen *ESC*[2J
|
||||
--Erases the screen with the background colour and moves the cursor to home.
|
||||
function term.clear()
|
||||
write("[2J")
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------
|
||||
--Tab Control
|
||||
------------------------------------------
|
||||
|
||||
--Set Tab *ESC*H
|
||||
--Sets a tab at the current position.
|
||||
function term.tab()
|
||||
write("[H")
|
||||
end
|
||||
|
||||
--Clear Tab *ESC*[g
|
||||
--Clears tab at the current position.
|
||||
function term.clearTab()
|
||||
write("[g")
|
||||
end
|
||||
|
||||
--Clear All Tabs *ESC*[3g
|
||||
--Clears all tabs.
|
||||
function term.clearTabs()
|
||||
write("[3g")
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------
|
||||
--Scrolling
|
||||
------------------------------------------
|
||||
|
||||
--Scroll Screen *ESC*[r
|
||||
--Enable scrolling for entire display.
|
||||
function term.enableScroll()
|
||||
write("[r")
|
||||
end
|
||||
|
||||
--Scroll Screen *ESC*[{start};{end}r
|
||||
--Enable scrolling from row {start} to row {end}.
|
||||
function term.scrollScreen(from,to)
|
||||
write(string.format("[%d;%dr",from,to))
|
||||
end
|
||||
|
||||
--Scroll Down *ESC*D
|
||||
--Scroll display down one line.
|
||||
function term.scrollScreenDown()
|
||||
write("D")
|
||||
end
|
||||
|
||||
--Scroll Up *ESC*M
|
||||
--Scroll display up one line.
|
||||
function term.scrollScreenUp()
|
||||
write("M")
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------
|
||||
--Cursor Control
|
||||
------------------------------------------
|
||||
|
||||
--Cursor Home *ESC*[{ROW};{COLUMN}H
|
||||
--Sets the cursor position where subsequent text will begin. If no row/column parameters are provided (ie. *ESC*[H), the cursor will move to the home position, at the upper left of the screen.
|
||||
function term.setCursorPosition(row,col)
|
||||
write(string.format("[%d;%dH", row, col))
|
||||
end
|
||||
|
||||
function term.resetCursor()
|
||||
write("[H")
|
||||
end
|
||||
|
||||
--Cursor Up *ESC*[{COUNT}A
|
||||
--Moves the cursor up by COUNT rows; the default count is 1.
|
||||
function term.cursorUp(count)
|
||||
write(string.format("[%dA",(count or 1)))
|
||||
end
|
||||
|
||||
--Cursor Down *ESC*[{COUNT}B
|
||||
--Moves the cursor down by COUNT rows; the default count is 1.
|
||||
function term.cursorDown(count)
|
||||
write(string.format("[%dB",(count or 1)))
|
||||
end
|
||||
|
||||
--Cursor Forward *ESC*[{COUNT}C
|
||||
--Moves the cursor forward by COUNT columns; the default count is 1.
|
||||
function term.cursorForward(count)
|
||||
write(string.format("[%dC",(count or 1)))
|
||||
end
|
||||
|
||||
--Cursor Backward *ESC*[{COUNT}D
|
||||
--Moves the cursor backward by COUNT columns; the default count is 1.
|
||||
function term.cursorBackward(count)
|
||||
write(string.format("[%dD",(count or 1)))
|
||||
end
|
||||
|
||||
--Force Cursor Position *ESC*[{ROW};{COLUMN}f
|
||||
--Identical to Cursor Home.
|
||||
function term.forceCursorPosition(row, col)
|
||||
write(string.format("[%d;%df", row, col))
|
||||
end
|
||||
|
||||
--Save Cursor *ESC*[s
|
||||
--Save current cursor position.
|
||||
function term.saveCursor()
|
||||
write("[s")
|
||||
end
|
||||
|
||||
--Unsave Cursor *ESC*[u
|
||||
--Restores cursor position after a Save Cursor.
|
||||
function term.restoreCursor()
|
||||
write("[u")
|
||||
end
|
||||
|
||||
--Save Cursor & Attrs *ESC*7
|
||||
--Save current cursor position.
|
||||
function term.saveCursorAndAttr()
|
||||
write("7")
|
||||
end
|
||||
|
||||
--Restore Cursor & Attrs *ESC*8
|
||||
--Restores cursor position after a Save Cursor.
|
||||
function term.restoreCursorAndAttr()
|
||||
write("8")
|
||||
end
|
||||
|
||||
|
||||
------------------------------------------
|
||||
--Terminal Setup
|
||||
------------------------------------------
|
||||
|
||||
--Reset Device *ESC*c
|
||||
--Reset all terminal settings to default.
|
||||
function term.reset()
|
||||
write("c")
|
||||
end
|
||||
|
||||
--Enable Line Wrap *ESC*[7h
|
||||
--Text wraps to next line if longer than the length of the display area.
|
||||
function term.enableLineWrap()
|
||||
write("[7h")
|
||||
end
|
||||
|
||||
--Disable Line Wrap *ESC*[7l
|
||||
--Disables line wrapping.
|
||||
function term.disableLineWrap()
|
||||
write("[7l")
|
||||
end
|
||||
|
||||
------------------------------------------
|
||||
--Plan9k codes
|
||||
------------------------------------------
|
||||
|
||||
-- \x1b9[H];[W]R - set resolution
|
||||
function term.setResolution(height,width)
|
||||
write(string.format("9%d;%dR", height, width))
|
||||
end
|
||||
|
||||
-- \x1b9[Row];[Col];[Height];[Width]F -- fill
|
||||
function term.fill(row, col, height, width)
|
||||
write(string.format("9%d;%d;%d;%dF", row, col, height, width))
|
||||
end
|
||||
|
||||
-- \x1b9[Row];[Col];[Height];[Width];[Dest Row];[Dest Col]c -- copy
|
||||
function term.copy(row, col, height, width, destRow, destCol)
|
||||
write(string.format("9%d;%d;%d;%d;%d;%dc", row, col, height, width, destRow, destCol ))
|
||||
end
|
||||
|
||||
--get resolution
|
||||
function term.getResolution()
|
||||
local y, x = term.getCursorPosition()
|
||||
term.setCursorPosition(999,999)
|
||||
local h, w = term.getCursorPosition()
|
||||
term.setCursorPosition(y,x)
|
||||
return tonumber(h), tonumber(w)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function term.clear()
|
||||
io.write("\x1b[2J")
|
||||
|
@ -0,0 +1,42 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
|
||||
local args, parms = shell.parse(...)
|
||||
if parms.h or parms.help then
|
||||
io.stderr:write("See: man base64" .. "\n")
|
||||
os.exit(true)
|
||||
end
|
||||
local encodingfun = nil
|
||||
local encode
|
||||
if parms.d or parms.decode then
|
||||
encodingfun = data.decode64
|
||||
encode = false
|
||||
else
|
||||
encodingfun = data.encode64
|
||||
encode = true
|
||||
end
|
||||
|
||||
if #args == 0 then
|
||||
repeat
|
||||
local read = io.read(encode and 3 or 4)
|
||||
if read then
|
||||
io.write(encodingfun(read))
|
||||
end
|
||||
until not read
|
||||
else
|
||||
for i = 1, #args do
|
||||
local file, reason = io.open(shell.resolve(args[i]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local line = file:read(encode and 3 or 4)
|
||||
if line then
|
||||
io.write(encodingfun(line))
|
||||
end
|
||||
until not line
|
||||
file:close()
|
||||
end
|
||||
end
|
@ -0,0 +1,25 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.deflate(read))
|
||||
else
|
||||
local read = ""
|
||||
local file, reason = io.open(shell.resolve(args[1]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.deflate(read))
|
||||
end
|
@ -0,0 +1,244 @@
|
||||
--[[
|
||||
-- A program that allows user to perform all crypto operations provided by Tier II / Tier III data cards
|
||||
-- Author: makkarpov
|
||||
--]]
|
||||
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
local term = require("term")
|
||||
local filesystem = require("filesystem")
|
||||
local serialization = require("serialization")
|
||||
|
||||
local args, options = shell.parse(...)
|
||||
|
||||
local function writeFile(path, data)
|
||||
if filesystem.exists(path) then
|
||||
io.stderr:write("gpg: failed to write file: " .. path .. "\n")
|
||||
io.stderr:write("gpg: error was: file already exists\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if type(data) == "table" then
|
||||
data = serialization.serialize(data)
|
||||
end
|
||||
|
||||
local h, err = io.open(path, "wb")
|
||||
|
||||
if not h then
|
||||
io.stderr:write("gpg: failed to write file: " .. path .. "\n")
|
||||
io.stderr:write("gpg: error was: " .. err .. "\n")
|
||||
return false
|
||||
end
|
||||
|
||||
h:write(data)
|
||||
h:close()
|
||||
return true
|
||||
end
|
||||
|
||||
local function readFile(path, deserialize)
|
||||
local h = io.open(path, "rb")
|
||||
local r = h:read("*a")
|
||||
h:close()
|
||||
|
||||
if deserialize then
|
||||
r = serialization.unserialize(r)
|
||||
end
|
||||
|
||||
return r
|
||||
end
|
||||
|
||||
local function parseKey(path, isPublic)
|
||||
local d = readFile(path, true)
|
||||
local k, err = data.deserializeKey(d.d, d.t)
|
||||
|
||||
if not k then
|
||||
io.stderr:write("gpg: failed to parse key: " .. err .. "\n")
|
||||
return nil
|
||||
end
|
||||
|
||||
if k.isPublic() ~= isPublic then
|
||||
io.stderr:write("gpg: wrong key type\n")
|
||||
return nil
|
||||
end
|
||||
|
||||
return k
|
||||
end
|
||||
|
||||
local function deriveName(base, encrypt)
|
||||
if encrypt then
|
||||
return base .. ".gpg"
|
||||
else
|
||||
local d = base:gsub(".gpg", "")
|
||||
if d == base then
|
||||
d = d .. ".dec"
|
||||
io.write("gpg: decrypting to " .. d .. "\n")
|
||||
end
|
||||
return d
|
||||
end
|
||||
end
|
||||
|
||||
local function ensureMethods(...)
|
||||
if not require("component").isAvailable("data") then
|
||||
io.stderr:write("gpg: you must have data card in order to run this program\n")
|
||||
error("data card is absent")
|
||||
end
|
||||
|
||||
local names = table.pack(...)
|
||||
for i = 1, names.n do
|
||||
if names[i] and not data[names[i]] then
|
||||
io.stderr:write("gpg: method " .. names[i] .. " required on data card to run this program\n")
|
||||
error("data card tier insufficient")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if options['g'] and (#args == 2) then
|
||||
ensureMethods("generateKeyPair")
|
||||
local pub, priv = data.generateKeyPair(384)
|
||||
|
||||
priv = { t = priv.keyType(), d = priv.serialize() }
|
||||
pub = { t = pub.keyType(), d = pub.serialize() }
|
||||
|
||||
if not writeFile(args[1], priv) then
|
||||
io.stderr:write("gpg: failed to write private key, aborting\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if not writeFile(args[2], pub) then
|
||||
io.stderr:write("gpg: failed to write public key, aborting\n")
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if options['c'] and (options['e'] or options['d']) and (#args == 1) then
|
||||
ensureMethods("md5", "sha256", "encrypt", "decrypt", "random")
|
||||
if options['d'] and options['e'] then
|
||||
io.stderr:write("gpg: please specify either -d or -e\n")
|
||||
return false
|
||||
end
|
||||
|
||||
io.write("gpg: enter password: ")
|
||||
local aesKey = data.md5(term.read(nil, nil, nil, "*"))
|
||||
local checkValue = data.sha256(aesKey)
|
||||
|
||||
if options['e'] then
|
||||
local iv = data.random(16)
|
||||
local d = data.encrypt(readFile(args[1]), aesKey, iv)
|
||||
|
||||
return writeFile(deriveName(args[1], true), {
|
||||
t = "pwd",
|
||||
kdf = "md5",
|
||||
iv = iv,
|
||||
cv = checkValue,
|
||||
d = d
|
||||
})
|
||||
else
|
||||
local d = readFile(args[1], true)
|
||||
|
||||
if d.t ~= "pwd" then
|
||||
io.stderr:write("gpg: file is not encrypted with a password\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if checkValue ~= d.cv then
|
||||
io.stderr:write("gpg: password incorrect\n")
|
||||
return false
|
||||
end
|
||||
|
||||
return writeFile(deriveName(args[1], false), data.decrypt(d.d, aesKey, d.iv))
|
||||
end
|
||||
end
|
||||
|
||||
if (options['d'] or options['e']) and (#args == 2) then
|
||||
ensureMethods("md5", "sha256", "encrypt", "decrypt", "random", "generateKeyPair", "deserializeKey", "ecdh")
|
||||
if options['d'] and options['e'] then
|
||||
io.stderr:write("gpg: please specify either -d or -e\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if options['e'] then
|
||||
local userPub = parseKey(args[1], true)
|
||||
local tmpPub, tmpPriv = data.generateKeyPair(384)
|
||||
local aesKey = data.md5(data.ecdh(tmpPriv, userPub))
|
||||
local checkValue = data.sha256(aesKey)
|
||||
local iv = data.random(16)
|
||||
|
||||
local d = data.encrypt(readFile(args[2]), aesKey, iv)
|
||||
return writeFile(deriveName(args[2], true), {
|
||||
t = "ecdh",
|
||||
kdf = "md5",
|
||||
iv = iv,
|
||||
cv = checkValue,
|
||||
k = {
|
||||
t = tmpPub.keyType(),
|
||||
d = tmpPub.serialize()
|
||||
},
|
||||
d = d
|
||||
})
|
||||
else
|
||||
local userPriv = parseKey(args[1], false)
|
||||
local d = readFile(args[2], true)
|
||||
|
||||
if d.t ~= "ecdh" then
|
||||
io.stderr:write("gpg: file is not encrypted with a key\n")
|
||||
return false
|
||||
end
|
||||
|
||||
local tmpPub = data.deserializeKey(d.k.d, d.k.t)
|
||||
local aesKey = data.md5(data.ecdh(userPriv, tmpPub))
|
||||
|
||||
if d.cv ~= data.sha256(aesKey) then
|
||||
io.stderr:write("gpg: invalid key\n")
|
||||
return false
|
||||
end
|
||||
|
||||
return writeFile(deriveName(args[2], false), data.decrypt(d.d, aesKey, d.iv))
|
||||
end
|
||||
end
|
||||
|
||||
if (options['s'] or options['v']) and (#args == 2) then
|
||||
ensureMethods("deserializeKey", "ecdsa")
|
||||
if options['s'] and options['v'] then
|
||||
io.stderr:write("gpg: please specify either -s or -v\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if options['s'] then
|
||||
local userPriv = parseKey(args[1], false)
|
||||
local sign = data.ecdsa(readFile(args[2]), userPriv)
|
||||
|
||||
return writeFile(args[2] .. ".sig", {
|
||||
t = "ecdsa",
|
||||
s = sign
|
||||
})
|
||||
else
|
||||
local userPub = parseKey(args[1], true)
|
||||
local sign = readFile(args[2] .. ".sig", true)
|
||||
|
||||
if sign.t ~= "ecdsa" then
|
||||
io.stderr:write("gpg: unsupported signature type\n")
|
||||
return false
|
||||
end
|
||||
|
||||
if not data.ecdsa(readFile(args[2]), userPub, sign.s) then
|
||||
io.stderr:write("gpg: signature verification failed\n")
|
||||
return false
|
||||
end
|
||||
|
||||
io.write("gpg: signature is valid\n")
|
||||
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
io.write("Usages:\n")
|
||||
io.write("gpg -ce <file> -- encrypt file with password\n")
|
||||
io.write("gpg -cd <file> -- decrypt file with password\n")
|
||||
io.write("gpg -e <key> <file> -- encrypt file\n")
|
||||
io.write("gpg -d <key> <file> -- decrypt file\n")
|
||||
io.write("gpg -g <private key file> <public key file> -- generate keypair\n")
|
||||
io.write("gpg -s <key> <file> -- sign file\n")
|
||||
io.write("gpg -v <key> <file> -- verify file\n")
|
||||
return false
|
@ -0,0 +1,25 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.inflate(read))
|
||||
else
|
||||
local read = ""
|
||||
local file, reason = io.open(shell.resolve(args[1]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.inflate(read))
|
||||
end
|
@ -0,0 +1,27 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.toHex(data.md5(read)))
|
||||
else
|
||||
for i = 1, #args do
|
||||
local read = ""
|
||||
local file, reason = io.open(args[i])
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.toHex(data.md5(read)) .. "\t".. args[i] .. "\n")
|
||||
end
|
||||
end
|
@ -81,17 +81,25 @@ ocBackend = {
|
||||
print(" Upgrade all packages that are out-of-date on the")
|
||||
print(" local system. Only package versions are used to find outdated packages;")
|
||||
print(" replacements are not checked here. This is a ?remove-then-add? process.")
|
||||
print(" -f, --force")
|
||||
print(" Force operation, in case of upgrade it redownloads all packages")
|
||||
print(" --root='/some/dir'")
|
||||
print(" Set alternative root directory")
|
||||
print(" -v")
|
||||
print(" More output")
|
||||
print(" -y")
|
||||
print(" Don't ask any questions, answer automatically")
|
||||
print(" -r, --reboot")
|
||||
print(" reboot after operation")
|
||||
return
|
||||
end
|
||||
|
||||
if options.v then loglevel = 0 end
|
||||
|
||||
if options.f or options.force then
|
||||
core.data.force = true
|
||||
end
|
||||
|
||||
if options.S or options.sync then
|
||||
for _, pack in ipairs(args) do
|
||||
core.install(pack)
|
||||
@ -114,6 +122,8 @@ ocBackend = {
|
||||
if options.y then
|
||||
ocBackend.prompt = function()return true end
|
||||
end
|
||||
|
||||
core.reboot = optionsr or options.reboot
|
||||
core.doWork()
|
||||
end,
|
||||
|
||||
@ -208,7 +218,8 @@ ocBackend = {
|
||||
if p:sub(1,1):upper() ~= "Y" then
|
||||
error("User stopped")
|
||||
end
|
||||
end
|
||||
end,
|
||||
reboot = function()computer.shutdown(true) end
|
||||
}
|
||||
|
||||
local mptFrontend
|
||||
@ -249,7 +260,7 @@ mptFrontend = {
|
||||
local toCheck = {}
|
||||
for pack, data in pairs(base.installed) do
|
||||
if data.frontend == mptFrontend.name then
|
||||
toCheck[pack] = base.installed[pack].data.checksum
|
||||
toCheck[pack] = base.installed[pack].data.checksum .. (core.data.force and "WAT" or "")
|
||||
end
|
||||
end
|
||||
local updateResp = backend.getText(config.frontend.mpt.api.."update", toCheck)
|
||||
@ -368,6 +379,8 @@ core = {
|
||||
upgrade = false,
|
||||
remove = false,
|
||||
|
||||
force = false,
|
||||
|
||||
--User requested packages
|
||||
userInstall = {},
|
||||
|
||||
@ -603,7 +616,8 @@ end
|
||||
core.log(1, "Main", "> Saving settings")
|
||||
core.finalize()
|
||||
|
||||
|
||||
|
||||
if core.reboot then
|
||||
backend.reboot()
|
||||
end
|
||||
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
local shell = require("shell")
|
||||
local data = require("data")
|
||||
|
||||
local args = shell.parse(...)
|
||||
if #args == 0 then
|
||||
local read = ""
|
||||
repeat
|
||||
local current = io.read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
io.write(data.toHex(data.sha256(read)))
|
||||
else
|
||||
for i = 1, #args do
|
||||
local read = ""
|
||||
local file, reason = io.open(shell.resolve(args[i]))
|
||||
if not file then
|
||||
io.stderr:write(tostring(reason) .. "\n")
|
||||
os.exit(false)
|
||||
end
|
||||
repeat
|
||||
local current = file:read("*a")
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.toHex(data.sha256(read)) .. "\t".. args[i] .. "\n")
|
||||
end
|
||||
end
|
@ -0,0 +1,26 @@
|
||||
local component = require("component")
|
||||
|
||||
local data = {}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
-- Converts binary data into hexadecimal string.
|
||||
function data.toHex(data)
|
||||
return (data:gsub('.', function (c)
|
||||
return string.format('%02X', string.byte(c))
|
||||
end))
|
||||
end
|
||||
|
||||
-- Converts hexadecimal string into binary data.
|
||||
function data.fromHex(hex)
|
||||
return (hex:gsub('..', function (cc)
|
||||
return string.char(tonumber(cc, 16))
|
||||
end))
|
||||
end
|
||||
|
||||
-- Forward everything else to the primary data card.
|
||||
setmetatable(data, { __index = function(_, key) return component.data[key] end })
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
return data
|
@ -1 +1 @@
|
||||
{cacheDir="/var/lib/mpt/cache/",database="/var/lib/mpt/base.db",frontend={mpt={api="http://mpt.magik6k.net/api/"}}}
|
||||
{database="/var/lib/mpt/base.db",cacheDir="/var/lib/mpt/cache/",frontend={mpt={api="http://mpt.magik6k.net/api/"}}}
|
@ -1 +1 @@
|
||||
{installed={["plan9k-drivers"]={frontend="MPT",data={name="plan9k-drivers",repo="plan9k",checksum="-2327b14292d5c08f547d24e9b5122349",files={"/lib/modules/base/17_tape.lua","/lib/modules/base/17_eeprom.lua","/lib/modules/base/17_nfc.lua","/lib/modules/base/17_chatbox.lua"},dependencies={}},deps={}},["plan9k-shell"]={frontend="MPT",data={name="plan9k-shell",repo="plan9k",checksum="-4ebb18f6dedde575d4d61460494b3bbb",files={"/bin/sh.lua"},dependencies={}},deps={}},["plan9k-corelibs"]={frontend="MPT",data={name="plan9k-corelibs",repo="plan9k",checksum="1d01d437b10e8561a39cb9f108cc3d47",files={"/lib/serialization.lua","/lib/term.lua","/lib/text.lua","/lib/shell.lua","/lib/event.lua"},dependencies={}},deps={}},mpt={frontend="MPT",data={name="mpt",repo="mpt",checksum="f9d7744571e5c46c658f405043c656",files={"/usr/bin/mpt.lua"},dependencies={}},deps={}},["plan9k-fsutil"]={frontend="MPT",data={name="plan9k-fsutil",repo="plan9k",checksum="aded7c8083efcdcfe43908183370687",files={"/bin/cat.lua","/bin/ln.lua","/bin/ls.lua","/bin/mv.lua","/bin/rm.lua","/bin/tee.lua","/bin/df.lua","/bin/dd.lua","/bin/cp.lua","/bin/touch.lua","/bin/mount.lua","/bin/mount.cow.lua","/bin/mkdir.lua","/bin/pwd.lua"},dependencies={"plan9k-corelibs"}},deps={"plan9k-corelibs"}},["plan9k-network"]={frontend="MPT",data={name="plan9k-network",repo="plan9k",checksum="-29d10c88b7ed4116d5b4eacd019d5ad9",files={"/lib/internet.lua","/bin/pastebin.lua","/bin/wget.lua","/lib/modules/base/17_network.lua","/lib/modules/base/19_libnetwork.lua","/bin/arp.lua","/bin/ifconfig.lua","/bin/ping.lua","/bin/route.lua","/lib/modules/network/loopback.lua","/lib/modules/network/modem.lua","/usr/bin/nc.lua","/lib/modules/network/tunnel.lua"},dependencies={}},deps={}},pipes={frontend="MPT",data={name="pipes",repo="plan9k",checksum="6d088970fd4fb29b78279eef4d417646",files={"/boot/kernel/pipes","/lib/modules/base/05_vfs.lua","/lib/modules/base/20_threading.lua","/lib/modules/base/19_manageg.lua","/lib/modules/base/25_init.lua","/lib/modules/base/15_userspace.lua","/usr/man/pipes","/lib/modules/base/16_buffer.lua","/lib/modules/base/17_io.lua","/lib/modules/base/16_require.lua","/lib/modules/base/18_syscall.lua","/lib/modules/base/21_threadUtil.lua","/lib/modules/base/21_timer.lua","/lib/modules/base/16_component.lua","/lib/modules/base/15_keventd.lua","/lib/modules/base/10_procfs.lua","/lib/modules/base/01_util.lua","/lib/modules/base/10_devfs.lua","/lib/modules/base/18_pty.lua","/lib/modules/base/17_keyboard.lua","/lib/modules/base/06_cowfs.lua","/lib/modules/base/09_rootfs.lua","/lib/modules/base/01_gc.lua"},dependencies={"openloader-init"}},deps={"openloader-init"}},["plan9k-edit"]={frontend="MPT",data={name="plan9k-edit",repo="plan9k",checksum="fed5f4ee1212297b07247afa1cfe3a2",files={"/bin/edit.lua"},dependencies={}},deps={}},["plan9k-core"]={frontend="MPT",data={name="plan9k-core",repo="plan9k",checksum="-4f5e4f44875482035444a2b61e96243d",files={"/bin/init.lua","/bin/getty.lua","/bin/readkey.lua","/lib/rc.lua","/bin/rc.lua"},dependencies={"pipes","plan9k-coreutil","plan9k-shell"}},deps={"pipes","plan9k-coreutil","plan9k-shell"}},plan9k={frontend="MPT",data={name="plan9k",repo="plan9k",checksum="-c16ccdf21a1ff13be8f6258d1a17d89",files={},dependencies={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit"}},deps={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit"}},["plan9k-installer"]={frontend="MPT",data={name="plan9k-installer",repo="plan9k",checksum="52c8f82357c966ce3e19c97bf3942012",files={"/bin/install.lua"},dependencies={"plan9k","mpt"}},deps={"plan9k","mpt"}},["openloader-init"]={frontend="MPT",data={name="openloader-init",repo="disks",checksum="-45e6d7b1e41468c1d335952ee3b89e13",files={"/init.lua"},dependencies={}},deps={}},["plan9k-coreutil"]={frontend="MPT",data={name="plan9k-coreutil",repo="plan9k",checksum="-50d3cee571b07b6cb05f6fb01989997c",files={"/bin/echo.lua","/bin/wc.lua","/bin/ps.lua","/bin/lua.lua","/bin/kill.lua","/bin/reboot.lua","/bin/sleep.lua","/bin/clear.lua","/bin/components.lua","/bin/hostname.lua","/bin/dmesg.lua","/bin/shutdown.lua","/bin/label.lua","/bin/uptime.lua","/bin/resolution.lua"},dependencies={"plan9k-corelibs","plan9k-fsutil"}},deps={"plan9k-corelibs","plan9k-fsutil"}}}}
|
||||
{installed={["plan9k-shell"]={deps={},frontend="MPT",data={checksum="517b9e0693e734a4ab516f12a6798f14",files={"/bin/sh.lua"},name="plan9k-shell",repo="plan9k",dependencies={}}},plan9k={deps={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit","plan9k-data"},frontend="MPT",data={checksum="-2d8f4b84ea60b0c9d5846f57e9f1691c",files={},name="plan9k",repo="plan9k",dependencies={"plan9k-core","plan9k-network","plan9k-drivers","plan9k-edit","plan9k-data"}}},["plan9k-fsutil"]={deps={"plan9k-corelibs"},frontend="MPT",data={checksum="6a974a71f62315e6e2294eae132d1751",files={"/bin/cat.lua","/bin/ln.lua","/bin/ls.lua","/bin/mv.lua","/bin/rm.lua","/bin/tee.lua","/bin/df.lua","/bin/dd.lua","/bin/cp.lua","/bin/touch.lua","/bin/mount.lua","/bin/mount.cow.lua","/bin/mkdir.lua","/bin/pwd.lua","/bin/more.lua"},name="plan9k-fsutil",repo="plan9k",dependencies={"plan9k-corelibs"}}},["plan9k-edit"]={deps={},frontend="MPT",data={checksum="34b1046ac9b7a87a1cdd74f8c03f27ea",files={"/bin/edit.lua"},name="plan9k-edit",repo="plan9k",dependencies={}}},["plan9k-core"]={deps={"pipes","plan9k-coreutil","plan9k-shell"},frontend="MPT",data={checksum="-6f77a020200f96eefd1559dcd8af14a5",files={"/bin/init.lua","/bin/getty.lua","/bin/readkey.lua","/lib/rc.lua","/bin/rc.lua"},name="plan9k-core",repo="plan9k",dependencies={"pipes","plan9k-coreutil","plan9k-shell"}}},["plan9k-installer"]={deps={"plan9k","mpt"},frontend="MPT",data={checksum="52c8f82357c966ce3e19c97bf3942012",files={"/bin/install.lua"},name="plan9k-installer",repo="plan9k",dependencies={"plan9k","mpt"}}},["plan9k-drivers"]={deps={},frontend="MPT",data={checksum="-35f098652460458c13f83499b4633e2d",files={"/lib/modules/base/17_tape.lua","/lib/modules/base/17_eeprom.lua","/lib/modules/base/17_nfc.lua","/lib/modules/base/17_chatbox.lua","/lib/modules/base/17_data.lua","/lib/modules/base/17_drive.lua"},name="plan9k-drivers",repo="plan9k",dependencies={}}},["plan9k-coreutil"]={deps={"plan9k-corelibs","plan9k-fsutil"},frontend="MPT",data={checksum="5fa7e70e3aba17fef97ed65489efb0ca",files={"/bin/echo.lua","/bin/wc.lua","/bin/ps.lua","/bin/lua.lua","/bin/kill.lua","/bin/reboot.lua","/bin/sleep.lua","/bin/clear.lua","/bin/components.lua","/bin/hostname.lua","/bin/dmesg.lua","/bin/shutdown.lua","/bin/label.lua","/bin/uptime.lua","/bin/resolution.lua"},name="plan9k-coreutil",repo="plan9k",dependencies={"plan9k-corelibs","plan9k-fsutil"}}},["openloader-init"]={deps={},frontend="MPT",data={checksum="-45e6d7b1e41468c1d335952ee3b89e13",files={"/init.lua"},name="openloader-init",repo="disks",dependencies={}}},mpt={deps={},frontend="MPT",data={checksum="-3435ded79cf9de20e7185f403eee4a28",files={"/usr/bin/mpt.lua"},name="mpt",repo="mpt",dependencies={}}},pipes={deps={"openloader-init"},frontend="MPT",data={checksum="123b56992859cf05cd03af825437d734",files={"/boot/kernel/pipes","/lib/modules/base/05_vfs.lua","/lib/modules/base/20_threading.lua","/lib/modules/base/19_manageg.lua","/lib/modules/base/25_init.lua","/lib/modules/base/15_userspace.lua","/usr/man/pipes","/lib/modules/base/16_buffer.lua","/lib/modules/base/17_io.lua","/lib/modules/base/16_require.lua","/lib/modules/base/18_syscall.lua","/lib/modules/base/21_threadUtil.lua","/lib/modules/base/21_timer.lua","/lib/modules/base/16_component.lua","/lib/modules/base/15_keventd.lua","/lib/modules/base/10_procfs.lua","/lib/modules/base/01_util.lua","/lib/modules/base/10_devfs.lua","/lib/modules/base/18_pty.lua","/lib/modules/base/17_keyboard.lua","/lib/modules/base/06_cowfs.lua","/lib/modules/base/09_rootfs.lua","/lib/modules/base/01_gc.lua"},name="pipes",repo="plan9k",dependencies={"openloader-init"}}},["plan9k-corelibs"]={deps={},frontend="MPT",data={checksum="1cb7fa12e1a1a35fc168409b60cfe552",files={"/lib/serialization.lua","/lib/term.lua","/lib/text.lua","/lib/shell.lua","/lib/event.lua"},name="plan9k-corelibs",repo="plan9k",dependencies={}}},["plan9k-data"]={deps={},frontend="MPT",data={checksum="480a898a741b2bf424f9e0e86e5072ba",files={"/usr/bin/base64.lua","/usr/lib/data.lua","/usr/bin/deflate.lua","/usr/bin/inflate.lua","/usr/bin/md5sum.lua","/usr/bin/sha256sum.lua","/usr/bin/gpg.lua"},name="plan9k-data",repo="plan9k",dependencies={}}},["plan9k-network"]={deps={},frontend="MPT",data={checksum="6e06e6cf5028583fe54047ba9e19abc6",files={"/lib/internet.lua","/bin/pastebin.lua","/bin/wget.lua","/lib/modules/base/17_network.lua","/lib/modules/base/19_libnetwork.lua","/bin/arp.lua","/bin/ifconfig.lua","/bin/ping.lua","/bin/route.lua","/lib/modules/network/loopback.lua","/lib/modules/network/modem.lua","/usr/bin/nc.lua","/lib/modules/network/tunnel.lua"},name="plan9k-network",repo="plan9k",dependencies={}}}}}
|
Loading…
x
Reference in New Issue
Block a user