transition to kernel

This commit is contained in:
kepler155c@gmail.com 2018-01-13 15:17:26 -05:00
parent fc8d44b60d
commit bd37b57780
20 changed files with 336 additions and 223 deletions

View File

@ -127,6 +127,8 @@ local function getProxy(pi)
error("Timed out attaching peripheral: " .. pi.uri) error("Timed out attaching peripheral: " .. pi.uri)
end end
-- write the uri of the periperal we are requesting...
-- ie. type/monitor
socket:write(pi.path) socket:write(pi.path)
local proxy = socket:read(3) local proxy = socket:read(3)
@ -134,6 +136,10 @@ local function getProxy(pi)
error("Timed out attaching peripheral: " .. pi.uri) error("Timed out attaching peripheral: " .. pi.uri)
end end
if type(proxy) == 'string' then
error(proxy)
end
local methods = proxy.methods local methods = proxy.methods
proxy.methods = nil proxy.methods = nil
@ -166,6 +172,9 @@ local function getProxy(pi)
socket:read() socket:read()
end) end)
end end
if not socket.connected then
error("Timed out communicating with peripheral: " .. pi.uri)
end
table.insert(queue, { table.insert(queue, {
fn = method, fn = method,
@ -222,7 +231,7 @@ end
function Peripheral.lookup(uri) function Peripheral.lookup(uri)
local pi = parse(uri) local pi = parse(uri)
if pi.host then if pi.host and _G.device.wireless_modem then
return getProxy(pi) return getProxy(pi)
end end

View File

@ -9,7 +9,6 @@ local os = _G.os
local socketClass = { } local socketClass = { }
function socketClass:read(timeout) function socketClass:read(timeout)
local data, distance = _G.transport.read(self) local data, distance = _G.transport.read(self)
if data then if data then
return data, distance return data, distance
@ -31,6 +30,9 @@ function socketClass:read(timeout)
os.cancelTimer(timerId) os.cancelTimer(timerId)
return data, distance return data, distance
end end
if not self.connected then
break
end
elseif e == 'timer' and id == timerId then elseif e == 'timer' and id == timerId then
if timeout or not self.connected then if timeout or not self.connected then
@ -104,6 +106,9 @@ local function newSocket(isLoopback)
end end
function Socket.connect(host, port) function Socket.connect(host, port)
if not device.wireless_modem then
return false, 'Wireless modem not found'
end
local socket = newSocket(host == os.getComputerID()) local socket = newSocket(host == os.getComputerID())
socket.dhost = tonumber(host) socket.dhost = tonumber(host)
@ -149,7 +154,6 @@ function Socket.connect(host, port)
end end
local function trusted(msg, port) local function trusted(msg, port)
if port == 19 or msg.shost == os.getComputerID() then if port == 19 or msg.shost == os.getComputerID() then
-- no auth for trust server or loopback -- no auth for trust server or loopback
return true return true
@ -172,7 +176,6 @@ local function trusted(msg, port)
end end
function Socket.server(port) function Socket.server(port)
device.wireless_modem.open(port) device.wireless_modem.open(port)
Logger.log('socket', 'Waiting for connections on port ' .. port) Logger.log('socket', 'Waiting for connections on port ' .. port)

View File

@ -6,7 +6,40 @@ local _gsub = string.gsub
local Terminal = { } local Terminal = { }
function Terminal.scrollable(ct, size) function Terminal.scrollable(win, size)
local w, h = win.getSize()
local scrollPos = 0
local scp = win.setCursorPos
win.setCursorPos = function(x, y)
scp(x, y)
if y > scrollPos + h then
win.scrollTo(y - h)
elseif y < scrollPos then
win.scrollTo(y - 2)
end
end
win.scrollUp = function()
win.scrollTo(scrollPos - 1)
end
win.scrollDown = function()
win.scrollTo(scrollPos + 1)
end
win.scrollTo = function(p)
p = math.min(math.max(p, 0), size)
if p ~= scrollPos then
scrollPos = p
win.reposition(1, -scrollPos + 1, w, h + size)
end
end
win.reposition(1, 1, w, h + size, true)
end
function Terminal.scrollable2(ct, size)
local w, h = ct.getSize() local w, h = ct.getSize()
local win = _G.window.create(ct, 1, 1, w, h + size, true) local win = _G.window.create(ct, 1, 1, w, h + size, true)
@ -63,7 +96,6 @@ function Terminal.scrollable(ct, size)
return win return win
end end
function Terminal.toGrayscale(ct) function Terminal.toGrayscale(ct)
local scolors = { local scolors = {

View File

@ -563,22 +563,23 @@ function Util.wordWrap(str, limit)
end end
function Util.args(arg) function Util.args(arg)
local tab = { remainder = { } } local options, args = { }, { }
local k = 1 local k = 1
while k <= #arg do while k <= #arg do
local v = arg[k] local v = arg[k]
if string.sub(v, 1, 1) == '-' then if string.sub(v, 1, 1) == '-' then
local jopt = string.sub(v, 2) local opt = string.sub(v, 2)
tab[ jopt ] = arg[ k + 1 ] options[opt] = arg[k + 1]
k = k + 1 k = k + 1
else else
table.insert(tab.remainder, v) table.insert(args, v)
end end
k = k + 1 k = k + 1
end end
return tab return options, args
end end
-- http://lua-users.org/wiki/AlternativeGetOpt -- http://lua-users.org/wiki/AlternativeGetOpt
local function getopt( arg, options ) local function getopt( arg, options )
local tab = {} local tab = {}

View File

@ -1,9 +1,8 @@
local injector = _G.requireInjector or load(http.get('https://raw.githubusercontent.com/kepler155c/opus/master/sys/apis/injector.lua').readAll())() local injector = _G.requireInjector or load(_G.http.get('https://raw.githubusercontent.com/kepler155c/opus/master/sys/apis/injector.lua').readAll())()
injector() injector()
local Event = require('event') local Event = require('event')
local History = require('history') local History = require('history')
local Peripheral = require('peripheral')
local UI = require('ui') local UI = require('ui')
local Util = require('util') local Util = require('util')

View File

@ -128,6 +128,7 @@ function UI.VerticalTabBar:setParent()
c.x = 1 c.x = 1
c.y = k + 1 c.y = k + 1
c.ox, c.oy = c.x, c.y c.ox, c.oy = c.x, c.y
c.ow = 8
c.width = 8 c.width = 8
end end
end end

View File

@ -20,11 +20,7 @@ local overviewId
local tabsDirty = false local tabsDirty = false
local closeInd = Util.getVersion() >= 1.76 and '\215' or '*' local closeInd = Util.getVersion() >= 1.76 and '\215' or '*'
multishell.term = term.current() --deprecated multishell.term = parentTerm --deprecated
-- redirect kernel output to a window
kernel.window = window.create(parentTerm, 1, 2, w, h - 1, false)
kernel.terminal = kernel.window
local config = { local config = {
standard = { standard = {
@ -156,6 +152,7 @@ function multishell.hideTab(tabId)
local tab = kernel.find(tabId) local tab = kernel.find(tabId)
if tab then if tab then
tab.hidden = true tab.hidden = true
kernel.lower(tab.uid)
redrawMenu() redrawMenu()
end end
end end
@ -224,6 +221,7 @@ kernel.hook('multishell_redraw', function()
local currentTab = kernel.routines[1] local currentTab = kernel.routines[1]
for _,tab in pairs(kernel.routines) do for _,tab in pairs(kernel.routines) do
tab.title = tab.env._APP_TITLE or tab.title
if tab.hidden and tab ~= currentTab then if tab.hidden and tab ~= currentTab then
tab.width = 0 tab.width = 0
else else

View File

@ -330,7 +330,7 @@ end
local tArgs = { ... } local tArgs = { ... }
if #tArgs > 0 then if #tArgs > 0 then
local env = setmetatable(Util.shallowCopy(sandboxEnv), { __index = _G }) local env = setmetatable(Util.shallowCopy(sandboxEnv), { __index = _G })
return run(_ENV, ...) -- maybe _ENV return run(env, ...)
end end
local Config = require('config') local Config = require('config')

View File

@ -10,9 +10,9 @@ local os = _G.os
local read = _G.read local read = _G.read
local term = _G.term local term = _G.term
local args = Util.args({ ... }) local options, args = Util.args({ ... })
local remoteId = tonumber(table.remove(args.remainder, 1)) local remoteId = tonumber(table.remove(args, 1) or '')
if not remoteId then if not remoteId then
print('Enter host ID') print('Enter host ID')
remoteId = tonumber(read()) remoteId = tonumber(read())
@ -22,8 +22,8 @@ if not remoteId then
error('Syntax: telnet [-title TITLE] ID [PROGRAM]') error('Syntax: telnet [-title TITLE] ID [PROGRAM]')
end end
if args.title then if options.title then
multishell.setTitle(multishell.getCurrent(), args.title) multishell.setTitle(multishell.getCurrent(), options.title)
end end
print('connecting...') print('connecting...')
@ -43,7 +43,7 @@ socket:write({
width = w, width = w,
height = h, height = h,
isColor = ct.isColor(), isColor = ct.isColor(),
program = args.remainder, program = args,
}) })
Event.addRoutine(function() Event.addRoutine(function()
@ -61,10 +61,10 @@ end)
ct.clear() ct.clear()
ct.setCursorPos(1, 1) ct.setCursorPos(1, 1)
local filter = Util.transpose({ local filter = Util.transpose {
'char', 'paste', 'key', 'key_up', 'terminate', 'char', 'paste', 'key', 'key_up', 'terminate',
'mouse_scroll', 'mouse_click', 'mouse_drag', 'mouse_up', 'mouse_scroll', 'mouse_click', 'mouse_drag', 'mouse_up',
}) }
while true do while true do
local e = { os.pullEventRaw() } local e = { os.pullEventRaw() }

View File

@ -5,43 +5,81 @@ local http = _G.http
local os = _G.os local os = _G.os
local shell = _ENV.shell local shell = _ENV.shell
local term = _G.term local term = _G.term
local window = _G.window
local w, h = term.getSize() local BRANCH = 'develop-1.8'
term.setTextColor(colors.white) local GIT_REPO = 'kepler155c/opus/' .. BRANCH
if term.isColor() then
term.setBackgroundColor(colors.black)
term.clear()
local opus = {
'fffff00',
'ffff07000',
'ff00770b00 4444',
'ff077777444444444',
'f07777744444444444',
'f0000777444444444',
'070000111744444',
'777770000',
'7777000000',
'70700000000',
'077000000000',
}
for k,line in ipairs(opus) do
term.setCursorPos((w - 18) / 2, k + (h - #opus) / 2)
term.blit(string.rep(' ', #line), string.rep('a', #line), line)
end
end
term.setCursorPos((w - 18) / 2, h)
term.write('Loading Opus...')
term.setCursorPos(w, h)
local GIT_REPO = 'kepler155c/opus/develop-1.8'
local BASE = 'https://raw.githubusercontent.com/' .. GIT_REPO local BASE = 'https://raw.githubusercontent.com/' .. GIT_REPO
local sandboxEnv = setmetatable({ }, { __index = _G }) local sandboxEnv = setmetatable({ }, { __index = _G })
for k,v in pairs(_ENV) do for k,v in pairs(_ENV) do
sandboxEnv[k] = v sandboxEnv[k] = v
end end
sandboxEnv.multishell = _ENV.multishell or { } sandboxEnv.multishell = { }
_G.debug = function() end
local terminal = term.current()
local w, h = term.getSize()
local kernelWindow = window.create(terminal, 1, 1, w, h, false)
term.redirect(kernelWindow)
local splashWindow
local function showStatus(status, ...)
local str = string.format(status, ...)
print(str)
splashWindow.setCursorPos(1, h)
splashWindow.clearLine()
splashWindow.setCursorPos((w - #str) / 2, h)
splashWindow.write(str)
os.sleep(.1)
end
local function splash()
splashWindow = window.create(terminal, 1, 1, w, h, false)
splashWindow.setTextColor(colors.white)
if splashWindow.isColor() then
splashWindow.setBackgroundColor(colors.black)
splashWindow.clear()
local opus = {
'fffff00',
'ffff07000',
'ff00770b00 4444',
'ff077777444444444',
'f07777744444444444',
'f0000777444444444',
'070000111744444',
'777770000',
'7777000000',
'70700000000',
'077000000000',
}
for k,line in ipairs(opus) do
splashWindow.setCursorPos((w - 18) / 2, k + (h - #opus) / 2)
splashWindow.blit(string.rep(' ', #line), string.rep('a', #line), line)
end
end
splashWindow.setVisible(true)
return splashWindow
end
local function setLabel()
-- Default label
if not os.getComputerLabel() then
showStatus('Setting computer label')
local id = os.getComputerID()
if _G.turtle then
os.setComputerLabel('turtle_' .. id)
elseif _G.pocket then
os.setComputerLabel('pocket_' .. id)
elseif _G.commands then
os.setComputerLabel('command_' .. id)
else
os.setComputerLabel('computer_' .. id)
end
end
end
local function makeEnv() local function makeEnv()
local env = setmetatable({ }, { __index = _G }) local env = setmetatable({ }, { __index = _G })
@ -51,7 +89,6 @@ local function makeEnv()
return env return env
end end
-- os.run doesn't provide return values :(
local function run(file, ...) local function run(file, ...)
local s, m = loadfile(file, makeEnv()) local s, m = loadfile(file, makeEnv())
if s then if s then
@ -77,107 +114,113 @@ local function runUrl(file, ...)
error('Failed to download ' .. url) error('Failed to download ' .. url)
end end
_G.debug = function() end local function createUserEnvironment(Util)
showStatus('Creating user environment')
-- Install require shim if not fs.exists('usr/apps') then
if fs.exists('sys/apis/injector.lua') then fs.makeDir('usr/apps')
_G.requireInjector = run('sys/apis/injector.lua') end
else if not fs.exists('usr/autorun') then
-- not local, run the file system directly from git fs.makeDir('usr/autorun')
_G.requireInjector = runUrl('/sys/apis/injector.lua') end
runUrl('sys/extensions/vfs.lua') if not fs.exists('usr/etc/fstab') then
Util.writeFile('usr/etc/fstab', 'usr gitfs kepler155c/opus-apps/' .. BRANCH)
-- install file system
fs.mount('', 'gitfs', GIT_REPO)
end
_G.requireInjector()
local Util = require('util')
-- Default label
if not os.getComputerLabel() then
local id = os.getComputerID()
if _G.turtle then
os.setComputerLabel('turtle_' .. id)
elseif _G.pocket then
os.setComputerLabel('pocket_' .. id)
elseif _G.commands then
os.setComputerLabel('command_' .. id)
else
os.setComputerLabel('computer_' .. id)
end end
end end
-- user environment local function createShellEnvironment(Util)
if not fs.exists('usr/apps') then showStatus('Creating shell environment')
fs.makeDir('usr/apps')
end if not fs.exists('usr/config/shell') then
if not fs.exists('usr/autorun') then Util.writeTable('usr/config/shell', {
fs.makeDir('usr/autorun') aliases = shell.aliases(),
end path = 'usr/apps:sys/apps:' .. shell.path(),
if not fs.exists('usr/etc/fstab') then lua_path = '/sys/apis:/usr/apis',
Util.writeFile('usr/etc/fstab', 'usr gitfs kepler155c/opus-apps/develop-1.8') })
end end
if not fs.exists('usr/config/shell') then
Util.writeTable('usr/config/shell', { local config = Util.readTable('usr/config/shell')
aliases = shell.aliases(), if config.aliases then
path = 'usr/apps:sys/apps:' .. shell.path(), for k in pairs(shell.aliases()) do
lua_path = '/sys/apis:/usr/apis', shell.clearAlias(k)
}) end
for k,v in pairs(config.aliases) do
shell.setAlias(k, v)
end
end
shell.setPath(config.path)
sandboxEnv.LUA_PATH = config.lua_path
end end
-- shell environment local function loadExtensions(Util)
local config = Util.readTable('usr/config/shell') local dir = 'sys/extensions'
if config.aliases then for _,file in ipairs(fs.list(dir)) do
for k in pairs(shell.aliases()) do showStatus('Loading ' .. file)
shell.clearAlias(k) local s, m = Util.run(makeEnv(), 'sys/apps/shell', fs.combine(dir, file))
end if not s then
for k,v in pairs(config.aliases) do error(m)
shell.setAlias(k, v) end
end end
end end
shell.setPath(config.path)
sandboxEnv.LUA_PATH = config.lua_path
Util.run(makeEnv(), 'sys/kernel.lua')
-- extensions
local dir = 'sys/extensions'
for _,file in ipairs(fs.list(dir)) do
local s, m = Util.run(makeEnv(), 'sys/apps/shell', fs.combine(dir, file))
if not s then
error(m)
end
end
-- install user file systems
fs.loadTab('usr/etc/fstab')
local args = { ... } local args = { ... }
if args[1] then
term.setBackgroundColor(colors.black)
term.clear()
term.setCursorPos(1, 1)
end
local cterm = term.current() splash()
local s, m = pcall(function()
showStatus('Loading Opus OS...')
args[1] = args[1] or 'sys/apps/multishell' -- Install require shim
local routine = kernel.newRoutine({ if fs.exists('sys/apis/injector.lua') then
path = 'sys/apps/shell', _G.requireInjector = run('sys/apis/injector.lua')
args = args else
}) -- not local, run the file system directly from git
kernel.run(routine) _G.requireInjector = runUrl('sys/apis/injector.lua')
local s, m = pcall(kernel.start) runUrl('sys/extensions/vfs.lua')
-- install file system
fs.mount('', 'gitfs', GIT_REPO)
end
_G.requireInjector()
local Util = require('util')
setLabel()
createUserEnvironment(Util)
createShellEnvironment(Util)
showStatus('Reticulating splines')
Util.run(makeEnv(), 'sys/kernel.lua')
loadExtensions(Util)
showStatus('Mounting file systems')
fs.loadTab('usr/etc/fstab')
splashWindow.setVisible(false)
if args[1] then
kernelWindow.setVisible(true)
end
--term.clear()
--term.redirect(terminal)
_G.kernel.run(_G.kernel.newRoutine({
path = 'sys/apps/shell',
args = args[1] and args or { 'sys/apps/multishell' },
terminal = terminal,
}))
end)
term.redirect(cterm)
term.setBackgroundColor(colors.black)
term.setTextColor(colors.white)
term.clear()
term.setCursorPos(1, 1)
if not s then if not s then
print('\nCrash detected\n') splashWindow.setVisible(false)
_G.printError(m) kernelWindow.setVisible(true)
print('\nError loading Opus OS\n')
_G.printError(m .. '\n')
else
if _G.kernel.routines[1] then
_G.kernel.start(terminal, kernelWindow)
end
end end
fs.restore() if fs.restore then
fs.restore()
end

View File

@ -167,9 +167,9 @@
[ "2a4d562b1d9a9c90bdede6fac8ce4f7402462b86" ] = { [ "2a4d562b1d9a9c90bdede6fac8ce4f7402462b86" ] = {
title = "Tasks", title = "Tasks",
category = "System", category = "System",
icon = "\0307 \0303\0317__\0307\031 \ icon = "\030f\031f \0315/\
\0303 \ \030f\031f \0315/\\/ \
\0303 ", \030f\0315/\031f ",
run = "Tabs.lua", run = "Tabs.lua",
}, },
[ "114edfc04a1ab03541bdc80ce064f66a7cfcedbb" ] = { [ "114edfc04a1ab03541bdc80ce064f66a7cfcedbb" ] = {
@ -215,9 +215,9 @@
bdc1fd5d3c0f3dcfd55d010426e61bf9451e680d = { bdc1fd5d3c0f3dcfd55d010426e61bf9451e680d = {
title = "Shell", title = "Shell",
category = "Apps", category = "Apps",
icon = "\0304 \030 \ icon = "\030f\0314\151\131\131\131\131\
\0304 \030f\0314> \0310_\031 \ \030f\0314\149\030f\0314> \0310_ \
\0304 \030f \030 ", \030f\0314\149\030f ",
run = "shell", run = "shell",
}, },
[ "131f0b008f44298812221d120d982940609be781" ] = { [ "131f0b008f44298812221d120d982940609be781" ] = {

View File

@ -83,7 +83,9 @@ kernel.hook({ 'mouse_click', 'mouse_up', 'mouse_drag' }, function(event, eventDa
if not mouse.state[button] then if not mouse.state[button] then
return true -- ensure mouse ups are only generated if a mouse down was sent return true -- ensure mouse ups are only generated if a mouse down was sent
end end
mouse.state[button] = nil if event == 'mouse_up' then
mouse.state[button] = nil
end
end end
end) end)

View File

@ -24,6 +24,12 @@ local focusedRoutineEvents = Util.transpose {
'paste', 'terminate', 'paste', 'terminate',
} }
_G.debug = function(pattern, ...)
local oldTerm = term.redirect(kernel.terminal)
Util.print(pattern, ...)
term.redirect(oldTerm)
end
-- any function that runs in a kernel hook does not run in -- any function that runs in a kernel hook does not run in
-- a separate coroutine or have a window. an error in a hook -- a separate coroutine or have a window. an error in a hook
-- function will crash the system. -- function will crash the system.
@ -151,6 +157,13 @@ function kernel.lower(uid)
local routine = Util.find(kernel.routines, 'uid', uid) local routine = Util.find(kernel.routines, 'uid', uid)
if routine and #kernel.routines > 1 then if routine and #kernel.routines > 1 then
if routine == kernel.routines[1] then
local nextRoutine = kernel.routines[2]
if nextRoutine then
kernel.raise(nextRoutine.uid)
end
end
Util.removeByValue(kernel.routines, routine) Util.removeByValue(kernel.routines, routine)
table.insert(kernel.routines, routine) table.insert(kernel.routines, routine)
return true return true
@ -172,12 +185,7 @@ function kernel.event(event, eventData)
local eventHooks = kernel.hooks[event] local eventHooks = kernel.hooks[event]
if eventHooks then if eventHooks then
for i = #eventHooks, 1, -1 do for i = #eventHooks, 1, -1 do
local s, m = pcall(function() stopPropagation = eventHooks[i](event, eventData)
stopPropagation = eventHooks[i](event, eventData)
end)
if not s then
error(m)
end
if stopPropagation then if stopPropagation then
break break
end end
@ -199,10 +207,23 @@ function kernel.event(event, eventData)
end end
end end
function kernel.start() function kernel.start(terminal, kernelWindow)
repeat kernel.window = kernelWindow
local eventData = { os.pullEventRaw() } kernel.terminal = kernel.window
local event = table.remove(eventData, 1)
kernel.event(event, eventData) local s, m = pcall(function()
until event == 'kernel_halt' or not kernel.routines[1] repeat
local eventData = { os.pullEventRaw() }
local event = table.remove(eventData, 1)
kernel.event(event, eventData)
until event == 'kernel_halt' or not kernel.routines[1]
end)
kernel.window.setVisible(true)
if not s then
term.redirect(kernel.window)
print('\nCrash detected\n')
_G.printError(m)
end
term.redirect(terminal)
end end

View File

@ -22,6 +22,7 @@ Event.addRoutine(function()
-- need to prevent multiple shares -- need to prevent multiple shares
if not peripheral then if not peripheral then
print('peripheral: invalid peripheral ' .. uri) print('peripheral: invalid peripheral ' .. uri)
socket:write('Invalid peripheral: ' .. uri)
else else
print('peripheral: proxing ' .. uri) print('peripheral: proxing ' .. uri)
local proxy = { local proxy = {
@ -62,6 +63,11 @@ Event.addRoutine(function()
print('peripheral: lost connection from ' .. socket.dhost) print('peripheral: lost connection from ' .. socket.dhost)
break break
end end
if not _G.device[peripheral.name] then
print('periperal: detached')
socket:close()
break
end
if peripheral[data.fn] then if peripheral[data.fn] then
socket:write({ peripheral[data.fn](table.unpack(data.args)) }) socket:write({ peripheral[data.fn](table.unpack(data.args)) })
end end

View File

@ -1,6 +1,8 @@
local Event = require('event') local Event = require('event')
local Socket = require('socket') local Socket = require('socket')
local fs = _G.fs
local fileUid = 0 local fileUid = 0
local fileHandles = { } local fileHandles = { }
@ -46,10 +48,10 @@ local function sambaConnection(socket)
end end
local ret local ret
local s, m = pcall(function() local s, m = pcall(function()
ret = fn(unpack(msg.args)) ret = fn(unpack(msg.args))
end) end)
if not s and m then if not s and m then
printError('samba: ' .. m) _G.printError('samba: ' .. m)
end end
socket:write({ response = ret }) socket:write({ response = ret })
end end
@ -58,7 +60,6 @@ local function sambaConnection(socket)
end end
Event.addRoutine(function() Event.addRoutine(function()
print('samba: listening on port 139') print('samba: listening on port 139')
while true do while true do
@ -72,11 +73,11 @@ Event.addRoutine(function()
end end
end) end)
Event.on('network_attach', function(e, computer) Event.on('network_attach', function(_, computer)
fs.mount(fs.combine('network', computer.label), 'netfs', computer.id) fs.mount(fs.combine('network', computer.label), 'netfs', computer.id)
end) end)
Event.on('network_detach', function(e, computer) Event.on('network_detach', function(_, computer)
print('samba: detaching ' .. computer.label) print('samba: detaching ' .. computer.label)
fs.unmount(fs.combine('network', computer.label)) fs.unmount(fs.combine('network', computer.label))
end) end)

View File

@ -15,7 +15,6 @@ local gpsLastPoint
local gpsLastRequestTime local gpsLastRequestTime
local function snmpConnection(socket) local function snmpConnection(socket)
while true do while true do
local msg = socket:read() local msg = socket:read()
if not msg then if not msg then
@ -98,7 +97,6 @@ local function snmpConnection(socket)
end end
Event.addRoutine(function() Event.addRoutine(function()
print('snmp: listening on port 161') print('snmp: listening on port 161')
while true do while true do
@ -137,7 +135,6 @@ local info = {
local infoTimer = os.clock() local infoTimer = os.clock()
local function sendInfo() local function sendInfo()
if os.clock() - infoTimer >= 1 then -- don't flood if os.clock() - infoTimer >= 1 then -- don't flood
infoTimer = os.clock() infoTimer = os.clock()
info.label = os.getComputerLabel() info.label = os.getComputerLabel()

View File

@ -2,16 +2,14 @@
Low level socket protocol implementation. Low level socket protocol implementation.
* sequencing * sequencing
* write acknowledgements
* background read buffering * background read buffering
]]-- ]]--
local Event = require('event')
local os = _G.os local os = _G.os
_ENV._APP_TITLE = 'Net transport'
local computerId = os.getComputerID() local computerId = os.getComputerID()
local transport = { local transport = {
timers = { }, timers = { },
sockets = { }, sockets = { },
@ -61,21 +59,18 @@ function transport.close(socket)
transport.sockets[socket.sport] = nil transport.sockets[socket.sport] = nil
end end
print('Net transport started') Event.on('timer', function(_, timerId)
local socket = transport.timers[timerId]
while true do if socket and socket.connected then
local e, timerId, dport, dhost, msg, distance = os.pullEvent() print('transport timeout - closing socket ' .. socket.sport)
socket:close()
transport.timers[timerId] = nil
end
end)
if e == 'timer' then Event.on('modem_message', function(_, _, dport, dhost, msg, distance)
local socket = transport.timers[timerId] if dhost == computerId and msg then
if socket and socket.connected then
debug('transport timeout - closing socket ' .. socket.sport)
socket:close()
transport.timers[timerId] = nil
end
elseif e == 'modem_message' and dhost == computerId and msg then
local socket = transport.sockets[dport] local socket = transport.sockets[dport]
if socket and socket.connected then if socket and socket.connected then
@ -85,6 +80,7 @@ while true do
-- received disconnect from other end -- received disconnect from other end
socket.connected = false socket.connected = false
socket:close() socket:close()
os.queueEvent('transport_' .. socket.sport)
elseif msg.type == 'ACK' then elseif msg.type == 'ACK' then
local ackTimerId = socket.timers[msg.seq] local ackTimerId = socket.timers[msg.seq]
@ -105,7 +101,7 @@ while true do
elseif msg.type == 'DATA' and msg.data then elseif msg.type == 'DATA' and msg.data then
socket.activityTimer = os.clock() socket.activityTimer = os.clock()
if msg.seq ~= socket.rseq then if msg.seq ~= socket.rseq then
debug('transport seq error - closing socket ' .. socket.sport) print('transport seq error - closing socket ' .. socket.sport)
socket:close() socket:close()
else else
socket.rseq = socket.rseq + 1 socket.rseq = socket.rseq + 1
@ -125,4 +121,6 @@ while true do
end end
end end
end end
end end)
print('Net transport started')

View File

@ -2,16 +2,18 @@ local Event = require('event')
local Socket = require('socket') local Socket = require('socket')
local Util = require('util') local Util = require('util')
local os = _G.os
local terminal = _ENV.multishell.term
local function vncHost(socket) local function vncHost(socket)
local methods = { 'blit', 'clear', 'clearLine', 'setCursorPos', 'write', local methods = { 'blit', 'clear', 'clearLine', 'setCursorPos', 'write',
'setTextColor', 'setTextColour', 'setBackgroundColor', 'setTextColor', 'setTextColour', 'setBackgroundColor',
'setBackgroundColour', 'scroll', 'setCursorBlink', } 'setBackgroundColour', 'scroll', 'setCursorBlink', }
socket.term = multishell.term local oldTerm = Util.shallowCopy(terminal)
socket.oldTerm = Util.shallowCopy(socket.term)
for _,k in pairs(methods) do for _,k in pairs(methods) do
socket.term[k] = function(...) terminal[k] = function(...)
if not socket.queue then if not socket.queue then
socket.queue = { } socket.queue = { }
Event.onTimeout(0, function() Event.onTimeout(0, function()
@ -23,7 +25,7 @@ local function vncHost(socket)
f = k, f = k,
args = { ... }, args = { ... },
}) })
socket.oldTerm[k](...) oldTerm[k](...)
end end
end end
@ -35,17 +37,17 @@ local function vncHost(socket)
end end
if data.type == 'shellRemote' then if data.type == 'shellRemote' then
os.queueEvent(unpack(data.event)) os.queueEvent(table.unpack(data.event))
elseif data.type == 'termInfo' then elseif data.type == 'termInfo' then
socket.term.getSize = function() terminal.getSize = function()
return data.width, data.height return data.width, data.height
end end
os.queueEvent('term_resize') os.queueEvent('term_resize')
end end
end end
for k,v in pairs(socket.oldTerm) do for k,v in pairs(oldTerm) do
socket.term[k] = v terminal[k] = v
end end
os.queueEvent('term_resize') os.queueEvent('term_resize')
end end

View File

@ -1,7 +1,10 @@
_G.requireInjector() _G.requireInjector()
--[[
Adds the control-d hotkey to view the kernel log.
]]
local Terminal = require('terminal') local Terminal = require('terminal')
local Util = require('util')
local kernel = _G.kernel local kernel = _G.kernel
local keyboard = _G.device.keyboard local keyboard = _G.device.keyboard
@ -9,19 +12,20 @@ local multishell = _ENV.multishell
local os = _G.os local os = _G.os
local term = _G.term local term = _G.term
_ENV._APP_TITLE = 'Debug' if multishell and multishell.setTitle then
multishell.setTitle(multishell.getCurrent(), 'System Log')
end
term.redirect(Terminal.scrollable(term.current(), 50)) local routine = kernel.getCurrent()
local tabId = multishell.getCurrent()
local previousId local previousId
_G.debug = function(pattern, ...) kernel.window.reposition(1, 2)
local oldTerm = term.current() Terminal.scrollable(kernel.window, 50)
term.redirect(kernel.terminal)
Util.print(pattern, ...) routine.terminal = kernel.window
term.redirect(oldTerm) routine.window = kernel.window
end
term.redirect(routine.window)
kernel.hook('mouse_scroll', function(_, eventData) kernel.hook('mouse_scroll', function(_, eventData)
local dir, y = eventData[1], eventData[3] local dir, y = eventData[1], eventData[3]
@ -38,22 +42,15 @@ kernel.hook('mouse_scroll', function(_, eventData)
end end
end) end)
print('Debug started')
print('Press ^d to activate debug window')
keyboard.addHotkey('control-d', function() keyboard.addHotkey('control-d', function()
local currentId = multishell.getFocus() local current = kernel.getFocused()
if currentId ~= tabId then if current.uid ~= routine.uid then
previousId = currentId previousId = current.uid
multishell.setFocus(tabId) kernel.raise(routine.uid)
elseif previousId then elseif previousId then
multishell.setFocus(previousId) kernel.raise(previousId)
end end
end) end)
os.pullEventRaw('terminate') os.pullEventRaw('terminate')
print('Debug stopped')
_G.debug = function() end
keyboard.removeHotkey('control-d') keyboard.removeHotkey('control-d')

View File

@ -5,6 +5,7 @@ local Util = require('util')
local device = _G.device local device = _G.device
local fs = _G.fs local fs = _G.fs
local multishell = _ENV.multishell
local network = _G.network local network = _G.network
local os = _G.os local os = _G.os
local printError = _G.printError local printError = _G.printError
@ -13,7 +14,9 @@ if not device.wireless_modem then
return return
end end
_ENV._APP_TITLE = 'Net Daemon' if multishell and multishell.setTitle then
multishell.setTitle(multishell.getCurrent(), 'Net Daemon')
end
print('Net daemon started') print('Net daemon started')