Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8

This commit is contained in:
Florian Nücke 2015-08-30 17:20:12 +02:00
commit 51e3f8166b
32 changed files with 1098 additions and 51 deletions

View File

@ -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

View File

@ -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

View File

@ -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"}

View File

@ -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

View File

@ -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 = {}

View File

@ -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")

View File

@ -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")

View File

@ -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> "))

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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})

View File

@ -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,
}]])()

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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}

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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/"}}}

View File

@ -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={}}}}}