AFAIK, the scp protocol isn't documented anywhere else than it the source code of
scp.c, so here is an attempt to an outline of how
When either the source or the destination is a remote machine,
scp will use
ssh to connect and start a
scp program on it: if the copy direction is from the remote to the local, it will be started as
scp -f src (from / source), otherwise it will be started as
scp -t dst (to / sink), and the local
scp will assume the opposite posture.
After this the two scp processes are running on both ends of the scp connection, using it as their stdin/stdout and passing the file data and metadata over it.
Both ends could use the following responses to acknowledge messages or signal some error condition:
"\1%s\n", err_msg: non-fatal error
"\2%s\n", err_msg: fatal error
The transfer starts by the to / sink scp sending a
\0 (OK) ack.
Then the from / source scp will use the following messages:
"C%04o %lld %s\n", mode, size, filename: create a file
this is followed by
size bytes of file data, and an ack (
\0 = OK)
"D%04o 0 %.1024s\n", mode, dirname: start of directory
recursively followed by
T messages, until a
"E\n": end of directory
"T%llu 0 %llu 0\n", mtime, atime: file times
this is sent before the
D messages, if the
-p switch was used.
These messages will have to be ack'ed by the other side before proceding further, including the
C before sending the file data, and the ack sent after it.
D messages above, newlines and other control chars (except
\x7f) in the file/dir name will be escaped as eg.
\^J, but will not be unescaped at the destination; a literal
\^M in the original name will be left as-is.
The difference between fatal and non-fatal errors is not consistent; only
\1 (non-fatal) errors will be generated by either side, but some of them will be considered fatal, and
scp will exit upon sending or receiving them, leaving the other side to hold both pieces. Both sides will exit upon a
\2 (fatal) error or anything unexpected.
Unlike in http, there are no provisions for sending the file data by chunks; if the source
scp is no longer able to read some big file it has started sending after the
C message, it will send up to its
size NUL bytes before the
\1 error message / nak.