go-scp icon indicating copy to clipboard operation
go-scp copied to clipboard

Add support for "-p" option, to copy permissions, modification time, access time

Open dxjones opened this issue 2 years ago • 5 comments

The command line version of scp includes a -p option to preserve file permissions, modification time, access time.

go-scp is incomplete because it does not support this option. For copying local files to a remote server, it is possible use os.Stat() and pass the file permissions, but that doesn't preserve mtime/atime, and nothing can be preserved copying in the other direction (remote to local).

Clearly the SCP protocol supports -p, so it this functionality can be added to go-scp.

dxjones avatar Jul 10 '22 18:07 dxjones

Thanks for your issue.

Your proposal makes a lot of sense and seems like it is something that has plenty of use cases. In the short term, I do not have the time to work on it myself, but I would welcome any contributions.

bramvdbogaerde avatar Jul 10 '22 18:07 bramvdbogaerde

Can you recommend any good references for the SCP protocol? What URLs did you use when developing go-scp ? I am willing to take a look at how the protocol supports the "-p" option, and take a crack at writing a new function scp.CopyFromRemotePreserveMode()

Thanks, --David Jones

On Sun, Jul 10, 2022 at 2:10 PM Bram Vandenbogaerde < @.***> wrote:

Thanks for your issue.

Your proposal makes a lot of sense and seems like it is something that has plenty of use cases. In the short term, I do not have the time to work on it myself, but I would welcome any contributions.

— Reply to this email directly, view it on GitHub https://github.com/bramvdbogaerde/go-scp/issues/63#issuecomment-1179773930, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACAWUD5EPGIHIOJ2BGUQVDVTMG2XANCNFSM53FLTU5A . You are receiving this because you authored the thread.Message ID: @.***>

dxjones avatar Jul 10 '22 18:07 dxjones

Dear David,

Thanks for your help. Adding "-v" (verbose mode) to any SCP command already reveals quite a lot about how the protocol works.

Here I send a file using the following command:

scp -v -p ask-pattern.rkt bram@HOST:~

Trace:

debug1: Sending command: scp -v -p -t ~/
File mtime 1657283010 atime 1657283011
Sending file timestamps: T1657283010 0 1657283011 0
Sink: T1657283010 0 1657283011 0
Sending file modes: C0644 375 ask-pattern.rkt
Sink: C0644 375 ask-pattern.rkt
ask-pattern.rkt                                                        100%  375     8.6KB/s   00:00

The trace above reveals that before sending the information of the file (C message: permissions, size and name) a timestamp message (starting with T) is sent that has the following format:

T<mtime> 0 <atime> 0

where mtime = modification time and atime = access time (as defined by POSIX), there seems to be no way to add ctime(creation time).

More information about these messages can be found here [1].

Diving into the code the go-scp library, it seems these messages will need to be sent before line 168 in client.go.

Hope this helps.

Regards,

[1] https://web.archive.org/web/20090806212235/http://blogs.sun.com/janp/entry/how_the_scp_protocol_works

bramvdbogaerde avatar Jul 10 '22 21:07 bramvdbogaerde

Thanks for the info.

By the way, is there a known issue with the program hanging when trying copy a non-existent remote file?

err = client.CopyFromRemote(context.Background(), f, path)

The above line works as expected when the remote file exists, but it never returns when the file does not exist.

I could possibly force the function to return with a timeout, but that shouldn't be necessary.

Amu I the only one who has encountered this bug? Am I calling the function wrong?

Thanks --David Jones

On Sun, Jul 10, 2022 at 5:31 PM Bram Vandenbogaerde < @.***> wrote:

Dear David,

Thanks for your help. Adding "-v" (verbose mode) to any SCP command already reveals quite a lot about how the protocol works.

Here I send a file using the following command:

scp -v -p ask-pattern.rkt @.***:~

Trace:

debug1: Sending command: scp -v -p -t ~/ File mtime 1657283010 atime 1657283011 Sending file timestamps: T1657283010 0 1657283011 0 Sink: T1657283010 0 1657283011 0 Sending file modes: C0644 375 ask-pattern.rkt Sink: C0644 375 ask-pattern.rkt ask-pattern.rkt 100% 375 8.6KB/s 00:00

The trace above reveals that before sending the information of the file (C message: permissions, size and name) a timestamp message (starting with T) is sent that has the following format:

T 0 0

where mtime = modification time and atime = access time (as defined by POSIX), there seems to be no way to add ctime(creation time).

More information about these messages can be found here https://web.archive.org/web/20090806212235/http://blogs.sun.com/janp/entry/how_the_scp_protocol_works [1].

Diving into the code the go-scp library, it seems these messages will need to be sent before li

[1] https://web.archive.org/web/20090806212235/http://blogs.sun.com/janp/entry/how_the_scp_protocol_works

— Reply to this email directly, view it on GitHub https://github.com/bramvdbogaerde/go-scp/issues/63#issuecomment-1179803607, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACAWUHRLTGVTTG52MAN5SDVTM6MPANCNFSM53FLTU5A . You are receiving this because you authored the thread.Message ID: @.***>

dxjones avatar Jul 11 '22 01:07 dxjones

Regarding the scenario of a non-existing file that you just described: there is a test in our test suite that checks just that, so it should work fine and return an error in case the file does not exist.

Could you compare your test code with the code here in the test named TestFileNotFound, maybe there is something that has been overlooked.

Thanks.

bramvdbogaerde avatar Jul 11 '22 15:07 bramvdbogaerde