Thursday, February 16, 2012

How SCP works !

Interesting article ....

Examples

Now it's time to have some fun. The protocol description might not be that describing like a few simple examples.

single file copy to the remote side

let's have a file test, containing string "hello" and we want to copy it over SCP protocol to /tmp directory.

$ rm -f /tmp/test
$ { echo C0644 6 test; printf "hello\\n"; } | scp -t /tmp
test 100% |\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*| 6 00:00
$ cat /tmp/test
hello

Nice, isn't it? I used printf so that it's clear why we used 6 for the file length. Now something with a directory copy.
recursive directory copy to the remote side

let's have the file test in a directory testdir. Now we want to recursively copy the whole directory to /tmp on the "other side".

$ rm -rf /tmp/testdir
$ { echo D0755 0 testdir; echo C0644 6 test;
printf "hello\\n"; echo E; } | scp -rt /tmp
test 100% |\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*| 6 00:00
$ cat /tmp/testdir/test
hello

Note that we had to use -r option because the directory copy was involved.
copy the directory from the remote side

now the scp program in the pipe will represent the remote side, the producer of the data. As said in the protocol section, the consumer (we) must reply to every protocol message and also to the finished data transfer. Note that this will not create any directory or file since generated protocol messages and data sent are just printed to your terminal - no one reads or interprets them, we just want to see scp's output in the source mode:

$ cd /tmp
$ rm -rf testdir
$ mkdir testdir
$ echo hello > testdir/test
$ printf '\\000\\000\\000\\000\\000\\000' | scp -qprf testdir
T1183832947 0 1183833773 0
D0700 0 testdir
T1183833773 0 1183833762 0
C0600 6 test
hello
E

A little explanation - you don't see data progress bar because of -q option. You see time protocol messages because we asked for them via -p option. And -f means that scp was the producer of the data. Also note that we had to use six '\\0' characters - the first for initializing the transfer, 4 to confirm the messages and 1 for the data transfer. Is that correct? Not exactly because we didn't acknowledged the final E message:

$ echo $?
1

and that's why scp returned failure. If we use 7 binary zeroes everything is fine then:

$ printf '\\000\\000\\000\\000\\000\\000\\000' | scp -qprf testdir
T1183832947 0 1183833956 0
D0700 0 testdir
T1183833773 0 1183833956 0
C0600 6 test
hello
E
$ echo $?
0

sending an error message

The example shows that scp will exit when we reply with binary 2. You can see that even when we send a couple of zeroes after that the scp command doesn't accept them anymore.

$ printf '\\000\\000\\002\\n\\000\\000' | scp -qprf testdir
T1183895689 0 1183899084 0
D0700 0 testdir

No comments: