librarian v0.2.0 SSH.SCP.Send View Source
implements the data transactions involved in unstreamed SCP file transfer to the destination server.
Concretely, the following functions are implemented:
Link to this section Summary
Functions
initializes the sending procedure for SCP.
responds to information returned on the stderr
stream by the
scp -t
command.
responds to information returned on the stdout
stream
by the scp -t
command.
handles the host scp
agent not calling back
postprocesses results sent to the ssh stream.
Link to this section Functions
Specs
init(SSH.Stream.t(), {Path.t(), String.t() | iodata(), integer()}) :: {:ok, SSH.Stream.t()}
initializes the sending procedure for SCP.
Expects the following information:
- the initialized SSH Stream. This will be modified to include our payload.
- a triple of:
{remote_filepath, data_content, permissions}
Permissions should be standard unix permissions scheme, for example0o644
gives read and write permissions for the owner, and read permissions for everyone else, or0o400
makes it read-only and only readable to the owner.
The following tasks are performed:
- As per the SCP protocol, send the control command:
C0<permissions> <size> <remote_filepath>
. - stash the content in the
:data
field of the stream.
Specs
on_stderr(term(), SSH.Stream.t()) :: {[term()], SSH.Stream.t()}
responds to information returned on the stderr
stream by the
scp -t
command.
These strings will be saved to the stream as part of an {:stderr, data}
tuple.
Specs
on_stdout(binary(), SSH.Stream.t()) :: {[term()], SSH.Stream.t()}
responds to information returned on the stdout
stream
by the scp -t
command.
As per the protocol the following binary responses can be expected:
<<0>>
: connection acknowledged, send data.<<0>>
: data packet receieved, send more data.<<1, error_string>>
: some error has occurred.<<2, error_string>>
: some fatal error has occurred.
The stream struct keeps track of what data it has sent via the
:data
field. If this contains data, then that data should be sent.
If the the field contains :finished
, then the available content
has been exhausted.
In general, no data will be emitted by the stream, although nonfatal errors will send an error tuple.
Specs
on_timeout(SSH.Stream.t()) :: {[], SSH.Stream.t()}
handles the host scp
agent not calling back
sometimes, the other side will forget to send a packet. In those
cases, send a <<0>>
packet down the SSH as reminder that we're still
here and need a response.
Specs
reducer([error: term(), stderr: String.t()], :ok | {:error, String.t()}) :: :ok | {:error, String.t()}
postprocesses results sent to the ssh stream.
The ssh stream is mostly used to return error values. We reduce on
that stream as a final step in SSH.send/4
. The two tuples we emit during
stream processing are {:stderr, string}
and {:error, string}
. For an
{:error, string}
value, make that the reduced return value. For
{:stderr, string}
, send it to the process's standard error as a side effect.