class Net::SCP
def start_command(mode, local, remote, options={}, &callback)
sets up a state machine to use to process the upload or download.
it (see #scp_command). It then sets up the necessary callbacks, and
Opens a new SSH channel and executes the necessary SCP command over
def start_command(mode, local, remote, options={}, &callback) session.open_channel do |channel| if options[:shell] escaped_file = shellescape(remote).gsub(/'/) { |m| "'\\''" } command = "#{options[:shell]} -c '#{scp_command(mode, options)} #{escaped_file}'" else command = "#{scp_command(mode, options)} #{shellescape remote}" end channel.exec(command) do |ch, success| if success channel[:local ] = local channel[:remote ] = remote channel[:options ] = options.dup channel[:callback] = callback channel[:buffer ] = Net::SSH::Buffer.new channel[:state ] = "#{mode}_start" channel[:stack ] = [] channel[:error_string] = '' channel.on_close { |ch2| send("#{channel[:state]}_state", channel); raise Net::SCP::Error, "SCP did not finish successfully (#{channel[:exit]}): #{channel[:error_string]}" if channel[:exit] != 0 } channel.on_data { |ch2, data| channel[:buffer].append(data) } channel.on_extended_data { |ch2, type, data| debug { data.chomp } } channel.on_request("exit-status") { |ch2, data| channel[:exit] = data.read_long } channel.on_process { send("#{channel[:state]}_state", channel) } else channel.close raise Net::SCP::Error, "could not exec scp on the remote host" end end end end