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 example0o644gives read and write permissions for the owner, and read permissions for everyone else, or0o400makes 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
:datafield 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.