local util = require('extregs.util') local storage = require('extregs.storage') local M = {} local function remote_path(path) -- Expand ~/ on the remote system; quote everything else. if path:sub(1, 2) == '~/' then return '"$HOME"/' .. util.shell_quote(path:sub(3)) end return util.shell_quote(path) end function M.get_provider(cfg) assert(type(cfg.path) == 'string' and cfg.path ~= '', 'ssh.path required') local path = remote_path(cfg.path) local function exec(script, input) assert(type(cfg.host) == 'string' and cfg.host:match('^[%w_.%-]+@[%w_.%-]+$'), 'ssh.host must be user@host') -- SSH joins remote argv with spaces: quote the *whole* sh -c argument. return util.system({ 'ssh', '-o', 'BatchMode=yes', cfg.host, 'sh -c ' .. util.shell_quote(script) }, input, 'ssh') end return { read = function() return storage.decode(exec('cat ' .. path)) end, write = function(_, reg) exec('mkdir -p "$(dirname ' .. path .. ')" && cat > ' .. path, storage.encode(reg)) return true end, } end return M