opus/sys/modules/opus/fs/netfs.lua

166 lines
3.0 KiB
Lua

local Socket = require('opus.socket')
local synchronized = require('opus.sync').sync
local fs = _G.fs
local netfs = { }
local function remoteCommand(node, msg)
for _ = 1, 2 do
if not node.socket then
node.socket = Socket.connect(node.id, 139)
end
if not node.socket then
error('netfs: Unable to establish connection to ' .. node.id)
fs.unmount(node.mountPoint)
return
end
local ret
synchronized(node.socket, function()
node.socket:write(msg)
ret = node.socket:read(1)
end)
if ret then
return ret.response
end
node.socket:close()
node.socket = nil
end
error('netfs: Connection failed', 2)
end
local methods = { 'delete', 'exists', 'getFreeSpace', 'makeDir', 'list', 'listEx', 'attributes' }
local function resolve(node, dir)
-- TODO: Wrong ! (does not support names with dashes)
dir = dir:gsub(node.mountPoint, '', 1)
return fs.combine(node.source, dir)
end
for _,m in pairs(methods) do
netfs[m] = function(node, dir)
dir = resolve(node, dir)
return remoteCommand(node, {
fn = m,
args = { dir },
})
end
end
function netfs.mount(_, id, source)
if not id or not tonumber(id) then
error('ramfs syntax: computerId [directory]')
end
return {
id = tonumber(id),
nodes = { },
source = source or '',
}
end
function netfs.getDrive()
return 'net'
end
function netfs.complete(node, partial, dir, includeFiles, includeSlash)
dir = resolve(node, dir)
return remoteCommand(node, {
fn = 'complete',
args = { partial, dir, includeFiles, includeSlash },
})
end
function netfs.copy(node, s, t)
s = resolve(node, s)
t = resolve(node, t)
return remoteCommand(node, {
fn = 'copy',
args = { s, t },
})
end
function netfs.isDir(node, dir)
if dir == node.mountPoint and node.source == '' then
return true
end
return remoteCommand(node, {
fn = 'isDir',
args = { resolve(node, dir) },
})
end
function netfs.isReadOnly(node, dir)
if dir == node.mountPoint and node.source == '' then
return false
end
return remoteCommand(node, {
fn = 'isReadOnly',
args = { resolve(node, dir) },
})
end
function netfs.getSize(node, dir)
if dir == node.mountPoint and node.source == '' then
return 0
end
return remoteCommand(node, {
fn = 'getSize',
args = { resolve(node, dir) },
})
end
function netfs.find(node, spec)
spec = resolve(node, spec)
local list = remoteCommand(node, {
fn = 'find',
args = { spec },
})
for k,f in ipairs(list) do
list[k] = fs.combine(node.mountPoint, f)
end
return list
end
function netfs.move(node, s, t)
s = resolve(node, s)
t = resolve(node, t)
return remoteCommand(node, {
fn = 'move',
args = { s, t },
})
end
function netfs.open(node, fn, fl)
fn = resolve(node, fn)
local vfh = remoteCommand(node, {
fn = 'open',
args = { fn, fl },
})
if vfh then
vfh.node = node
for _,m in ipairs(vfh.methods) do
vfh[m] = function(...)
return remoteCommand(node, {
fn = 'fileOp',
args = { vfh.fileUid, m, ... },
})
end
end
end
return vfh
end
return netfs