sftp: Can't determine if dir already exists with Mkdir
I’d like to determine if after running a mkdir if a failure is due to the directory already existing. I’ve done:
if status, ok := err.(*sftp.StatusError); ok {
log.Printf("Code: %v, %v", status.Code, status.Error())
if status.Code == ??? {
XXX
}
}
but unfortunately there doesn’t seem to be enough information in StatusError or the Code to determine this. Can it be added?
Thanks!
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 19 (12 by maintainers)
The Mkdir() method as it is currently implemented closely follows the protocol and the openssh implementation (which I consider to be the standard/reference implementation). I think this is generally a good thing and would like to keep it as is.
My idea for using Stat() was that it would be easy for a developer using the library to do the Stat() check themselves and handle things as they deem appropriate. That was why I thought putting it in an example best addressed the issue.
Once a “1.0” version is done I’ll be open to ideas about adding a layer of abstraction on top of the existing code as a more managed/high-level client experience.
I gave this one last look and what you want is just not possible. I looked at openssh’s sftp server mkdir implementation and it doesn’t return the information needed to enable the client to know if the error is due to a directory already existing with the same name. In the case that a the directory already exists it returns a general SSH2_FX_FAILURE. It returns this same error in all these error cases…
EDQUOT - quota limit hit EEXIST - file, directory, sym-link already exists with that name EMLINK - parent directory has to many files ENOMEM - out of memory error ENOSPC - no space on device EROFS - read-only file system error
I got this by comparing all the possible errors returned by the mkdir system call to what the sftp server handles and which SFTP status packets it sends for each error.
So the only way to do what you want is to check the returned status and if it contains the error-code SSH2_FX_FAILURE (type uint32, value 4) then do a client.Stat() call on that path and check the returned os.FileInfo value to see if it is a directory.
This is why I think this could be a documentation issue, because that pattern could be documented and possibly put in an example.
I wonder if we could reuse os.PathErr here, then maybe the os.IsExist helper could be bought into play.
On Sat, Aug 6, 2016 at 8:55 PM, James notifications@github.com wrote: