Closed jgriegershs closed 2 weeks ago
1) File Names in SSH are defined to assume the use of the /
character as a directory separator. https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.2 Thus the use of path.Base
in this case is the correct operation.
2) The SSH_FXP_STAT is defined to return on success the SSH_FXP_ATTRS packet, which contains only attributes and no filename. If you want to get the real filename of any particular path use the RealPath()
https://pkg.go.dev/github.com/pkg/sftp#Client.RealPath call.
If your Windows host is not transcoding native filepaths to some form of /
encoding, then it is not acting in a standards compliant way. Let us know which one it is, and we can then consider changes that could increase compatibility. But we’re always going to stick as closely to the standard as we can.
You could also use filepath.ToSlash()
before sending any filenames. Windows accepts C:/temp/my-file
as a filename just as much as using a backslash.
You could also use
filepath.ToSlash()
before sending any filenames. Windows acceptsC:/temp/my-file
as a filename just as much as using a backslash.
I will try this for the remote OSs, thank you for the quick response. I'll be back 😊.
Normalizing all paths with filepath.ToSlash()
did the trick (even "slashing" the results of filepath.WalkDir()
and filepath.Rel
is needed on Windows).
Thanks!
Problem
When retrieving the file name of a file on a remote Windows machine like:
remoteFileName
will be"c:\temp\my-file"
instead of the expectedmy-file
.This is due to
path.Base("path")
calls in thestat
implementations, e.g.: https://github.com/pkg/sftp/blob/c8fe1f69640c3d92b05e1d7f0072addd6ece3ed2/client.go#L420The name info does not come from the remote SFTP server, but is determined locally, expecting Unix paths.
Solution Proposal
I don't know the SFTP protocol in depth, maybe the file name can be determine on the remote machine.
My current workaround is to determine the remote OS (either Linux or Windows) by retrieving the remote working dir with
Getwd()
and checking for the prefix/home/
. Based on that info, eitherpath.Base()
orfilepath.Base()
is being used for determining the file name (the code gets executed on a Windows machine, sofilepath.Base()
will return the correct file name when the remote path belongs to a Windows machine).What do you think?