class Net::SCP

def start_command(mode, local, remote, options={}, &callback)

(See Net::SCP::Upload and Net::SCP::Download).
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