aboutsummaryrefslogtreecommitdiff
path: root/lua/extregs/ssh.lua
blob: 8102434b3bd427d4b6b24c2cca3e073fefedbf8f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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