forked from TrueCloudLab/rclone
vendor: update all dependencies
This commit is contained in:
parent
17b4058ee9
commit
abb9f89f65
443 changed files with 32118 additions and 18237 deletions
187
vendor/github.com/pkg/sftp/client.go
generated
vendored
187
vendor/github.com/pkg/sftp/client.go
generated
vendored
|
@ -15,12 +15,18 @@ import (
|
|||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// InternalInconsistency indicates the packets sent and the data queued to be
|
||||
// written to the file don't match up. It is an unusual error and usually is
|
||||
// caused by bad behavior server side or connection issues. The error is
|
||||
// limited in scope to the call where it happened, the client object is still
|
||||
// OK to use as long as the connection is still open.
|
||||
var InternalInconsistency = errors.New("internal inconsistency")
|
||||
var (
|
||||
// ErrInternalInconsistency indicates the packets sent and the data queued to be
|
||||
// written to the file don't match up. It is an unusual error and usually is
|
||||
// caused by bad behavior server side or connection issues. The error is
|
||||
// limited in scope to the call where it happened, the client object is still
|
||||
// OK to use as long as the connection is still open.
|
||||
ErrInternalInconsistency = errors.New("internal inconsistency")
|
||||
// InternalInconsistency alias for ErrInternalInconsistency.
|
||||
//
|
||||
// Deprecated: please use ErrInternalInconsistency
|
||||
InternalInconsistency = ErrInternalInconsistency
|
||||
)
|
||||
|
||||
// A ClientOption is a function which applies configuration to a Client.
|
||||
type ClientOption func(*Client) error
|
||||
|
@ -45,6 +51,30 @@ func MaxPacketChecked(size int) ClientOption {
|
|||
}
|
||||
}
|
||||
|
||||
// UseFstat sets whether to use Fstat or Stat when File.WriteTo is called
|
||||
// (usually when copying files).
|
||||
// Some servers limit the amount of open files and calling Stat after opening
|
||||
// the file will throw an error From the server. Setting this flag will call
|
||||
// Fstat instead of Stat which is suppose to be called on an open file handle.
|
||||
//
|
||||
// It has been found that that with IBM Sterling SFTP servers which have
|
||||
// "extractability" level set to 1 which means only 1 file can be opened at
|
||||
// any given time.
|
||||
//
|
||||
// If the server you are working with still has an issue with both Stat and
|
||||
// Fstat calls you can always open a file and read it until the end.
|
||||
//
|
||||
// Another reason to read the file until its end and Fstat doesn't work is
|
||||
// that in some servers, reading a full file will automatically delete the
|
||||
// file as some of these mainframes map the file to a message in a queue.
|
||||
// Once the file has been read it will get deleted.
|
||||
func UseFstat(value bool) ClientOption {
|
||||
return func(c *Client) error {
|
||||
c.useFstat = value
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// MaxPacketUnchecked sets the maximum size of the payload, measured in bytes.
|
||||
// It accepts sizes larger than the 32768 bytes all servers should support.
|
||||
// Only use a setting higher than 32768 if your application always connects to
|
||||
|
@ -155,12 +185,17 @@ type Client struct {
|
|||
maxPacket int // max packet size read or written.
|
||||
nextid uint32
|
||||
maxConcurrentRequests int
|
||||
useFstat bool
|
||||
}
|
||||
|
||||
// Create creates the named file mode 0666 (before umask), truncating it if it
|
||||
// already exists. If successful, methods on the returned File can be used for
|
||||
// I/O; the associated file descriptor has mode O_RDWR. If you need more
|
||||
// control over the flags/mode used to open the file see client.OpenFile.
|
||||
//
|
||||
// Note that some SFTP servers (eg. AWS Transfer) do not support opening files
|
||||
// read/write at the same time. For those services you will need to use
|
||||
// `client.OpenFile(os.O_WRONLY|os.O_CREATE|os.O_TRUNC)`.
|
||||
func (c *Client) Create(path string) (*File, error) {
|
||||
return c.open(path, flags(os.O_RDWR|os.O_CREATE|os.O_TRUNC))
|
||||
}
|
||||
|
@ -183,8 +218,8 @@ func (c *Client) recvVersion() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if typ != ssh_FXP_VERSION {
|
||||
return &unexpectedPacketErr{ssh_FXP_VERSION, typ}
|
||||
if typ != sshFxpVersion {
|
||||
return &unexpectedPacketErr{sshFxpVersion, typ}
|
||||
}
|
||||
|
||||
version, _ := unmarshalUint32(data)
|
||||
|
@ -222,7 +257,7 @@ func (c *Client) ReadDir(p string) ([]os.FileInfo, error) {
|
|||
break
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_NAME:
|
||||
case sshFxpName:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return nil, &unexpectedIDErr{id, sid}
|
||||
|
@ -239,7 +274,7 @@ func (c *Client) ReadDir(p string) ([]os.FileInfo, error) {
|
|||
}
|
||||
attrs = append(attrs, fileInfoFromStat(attr, path.Base(filename)))
|
||||
}
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
// TODO(dfc) scope warning!
|
||||
err = normaliseError(unmarshalStatus(id, data))
|
||||
done = true
|
||||
|
@ -263,14 +298,14 @@ func (c *Client) opendir(path string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_HANDLE:
|
||||
case sshFxpHandle:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return "", &unexpectedIDErr{id, sid}
|
||||
}
|
||||
handle, _ := unmarshalString(data)
|
||||
return handle, nil
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return "", normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return "", unimplementedPacketErr(typ)
|
||||
|
@ -289,14 +324,14 @@ func (c *Client) Stat(p string) (os.FileInfo, error) {
|
|||
return nil, err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_ATTRS:
|
||||
case sshFxpAttrs:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return nil, &unexpectedIDErr{id, sid}
|
||||
}
|
||||
attr, _ := unmarshalAttrs(data)
|
||||
return fileInfoFromStat(attr, path.Base(p)), nil
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return nil, normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return nil, unimplementedPacketErr(typ)
|
||||
|
@ -315,14 +350,14 @@ func (c *Client) Lstat(p string) (os.FileInfo, error) {
|
|||
return nil, err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_ATTRS:
|
||||
case sshFxpAttrs:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return nil, &unexpectedIDErr{id, sid}
|
||||
}
|
||||
attr, _ := unmarshalAttrs(data)
|
||||
return fileInfoFromStat(attr, path.Base(p)), nil
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return nil, normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return nil, unimplementedPacketErr(typ)
|
||||
|
@ -340,7 +375,7 @@ func (c *Client) ReadLink(p string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_NAME:
|
||||
case sshFxpName:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return "", &unexpectedIDErr{id, sid}
|
||||
|
@ -351,13 +386,32 @@ func (c *Client) ReadLink(p string) (string, error) {
|
|||
}
|
||||
filename, _ := unmarshalString(data) // ignore dummy attributes
|
||||
return filename, nil
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return "", normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return "", unimplementedPacketErr(typ)
|
||||
}
|
||||
}
|
||||
|
||||
// Link creates a hard link at 'newname', pointing at the same inode as 'oldname'
|
||||
func (c *Client) Link(oldname, newname string) error {
|
||||
id := c.nextID()
|
||||
typ, data, err := c.sendPacket(sshFxpHardlinkPacket{
|
||||
ID: id,
|
||||
Oldpath: oldname,
|
||||
Newpath: newname,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch typ {
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
}
|
||||
}
|
||||
|
||||
// Symlink creates a symbolic link at 'newname', pointing at target 'oldname'
|
||||
func (c *Client) Symlink(oldname, newname string) error {
|
||||
id := c.nextID()
|
||||
|
@ -370,7 +424,7 @@ func (c *Client) Symlink(oldname, newname string) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -390,7 +444,7 @@ func (c *Client) setstat(path string, flags uint32, attrs interface{}) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -404,7 +458,7 @@ func (c *Client) Chtimes(path string, atime time.Time, mtime time.Time) error {
|
|||
Mtime uint32
|
||||
}
|
||||
attrs := times{uint32(atime.Unix()), uint32(mtime.Unix())}
|
||||
return c.setstat(path, ssh_FILEXFER_ATTR_ACMODTIME, attrs)
|
||||
return c.setstat(path, sshFileXferAttrACmodTime, attrs)
|
||||
}
|
||||
|
||||
// Chown changes the user and group owners of the named file.
|
||||
|
@ -414,12 +468,12 @@ func (c *Client) Chown(path string, uid, gid int) error {
|
|||
GID uint32
|
||||
}
|
||||
attrs := owner{uint32(uid), uint32(gid)}
|
||||
return c.setstat(path, ssh_FILEXFER_ATTR_UIDGID, attrs)
|
||||
return c.setstat(path, sshFileXferAttrUIDGID, attrs)
|
||||
}
|
||||
|
||||
// Chmod changes the permissions of the named file.
|
||||
func (c *Client) Chmod(path string, mode os.FileMode) error {
|
||||
return c.setstat(path, ssh_FILEXFER_ATTR_PERMISSIONS, uint32(mode))
|
||||
return c.setstat(path, sshFileXferAttrPermissions, uint32(mode))
|
||||
}
|
||||
|
||||
// Truncate sets the size of the named file. Although it may be safely assumed
|
||||
|
@ -427,7 +481,7 @@ func (c *Client) Chmod(path string, mode os.FileMode) error {
|
|||
// the SFTP protocol does not specify what behavior the server should do when setting
|
||||
// size greater than the current size.
|
||||
func (c *Client) Truncate(path string, size int64) error {
|
||||
return c.setstat(path, ssh_FILEXFER_ATTR_SIZE, uint64(size))
|
||||
return c.setstat(path, sshFileXferAttrSize, uint64(size))
|
||||
}
|
||||
|
||||
// Open opens the named file for reading. If successful, methods on the
|
||||
|
@ -455,14 +509,14 @@ func (c *Client) open(path string, pflags uint32) (*File, error) {
|
|||
return nil, err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_HANDLE:
|
||||
case sshFxpHandle:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return nil, &unexpectedIDErr{id, sid}
|
||||
}
|
||||
handle, _ := unmarshalString(data)
|
||||
return &File{c: c, path: path, handle: handle}, nil
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return nil, normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return nil, unimplementedPacketErr(typ)
|
||||
|
@ -482,7 +536,7 @@ func (c *Client) close(handle string) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -499,14 +553,14 @@ func (c *Client) fstat(handle string) (*FileStat, error) {
|
|||
return nil, err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_ATTRS:
|
||||
case sshFxpAttrs:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return nil, &unexpectedIDErr{id, sid}
|
||||
}
|
||||
attr, _ := unmarshalAttrs(data)
|
||||
return attr, nil
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return nil, normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return nil, unimplementedPacketErr(typ)
|
||||
|
@ -530,7 +584,7 @@ func (c *Client) StatVFS(path string) (*StatVFS, error) {
|
|||
|
||||
switch typ {
|
||||
// server responded with valid data
|
||||
case ssh_FXP_EXTENDED_REPLY:
|
||||
case sshFxpExtendedReply:
|
||||
var response StatVFS
|
||||
err = binary.Read(bytes.NewReader(data), binary.BigEndian, &response)
|
||||
if err != nil {
|
||||
|
@ -540,8 +594,8 @@ func (c *Client) StatVFS(path string) (*StatVFS, error) {
|
|||
return &response, nil
|
||||
|
||||
// the resquest failed
|
||||
case ssh_FXP_STATUS:
|
||||
return nil, errors.New(fxp(ssh_FXP_STATUS).String())
|
||||
case sshFxpStatus:
|
||||
return nil, errors.New(fxp(sshFxpStatus).String())
|
||||
|
||||
default:
|
||||
return nil, unimplementedPacketErr(typ)
|
||||
|
@ -562,7 +616,7 @@ func (c *Client) Remove(path string) error {
|
|||
switch err.Code {
|
||||
// some servers, *cough* osx *cough*, return EPERM, not ENODIR.
|
||||
// serv-u returns ssh_FX_FILE_IS_A_DIRECTORY
|
||||
case ssh_FX_PERMISSION_DENIED, ssh_FX_FAILURE, ssh_FX_FILE_IS_A_DIRECTORY:
|
||||
case sshFxPermissionDenied, sshFxFailure, sshFxFileIsADirectory:
|
||||
return c.RemoveDirectory(path)
|
||||
}
|
||||
}
|
||||
|
@ -579,7 +633,7 @@ func (c *Client) removeFile(path string) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -597,7 +651,7 @@ func (c *Client) RemoveDirectory(path string) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -616,7 +670,7 @@ func (c *Client) Rename(oldname, newname string) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -636,7 +690,7 @@ func (c *Client) PosixRename(oldname, newname string) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -653,7 +707,7 @@ func (c *Client) realpath(path string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_NAME:
|
||||
case sshFxpName:
|
||||
sid, data := unmarshalUint32(data)
|
||||
if sid != id {
|
||||
return "", &unexpectedIDErr{id, sid}
|
||||
|
@ -664,7 +718,7 @@ func (c *Client) realpath(path string) (string, error) {
|
|||
}
|
||||
filename, _ := unmarshalString(data) // ignore attributes
|
||||
return filename, nil
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return "", normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return "", unimplementedPacketErr(typ)
|
||||
|
@ -690,7 +744,7 @@ func (c *Client) Mkdir(path string) error {
|
|||
return err
|
||||
}
|
||||
switch typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
return normaliseError(unmarshalStatus(id, data))
|
||||
default:
|
||||
return unimplementedPacketErr(typ)
|
||||
|
@ -845,14 +899,14 @@ func (f *File) Read(b []byte) (int, error) {
|
|||
}
|
||||
delete(reqs, reqID)
|
||||
switch res.typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
if firstErr.err == nil || req.offset < firstErr.offset {
|
||||
firstErr = offsetErr{
|
||||
offset: req.offset,
|
||||
err: normaliseError(unmarshalStatus(reqID, res.data)),
|
||||
}
|
||||
}
|
||||
case ssh_FXP_DATA:
|
||||
case sshFxpData:
|
||||
l, data := unmarshalUint32(data)
|
||||
n := copy(req.b, data[:l])
|
||||
read += n
|
||||
|
@ -884,15 +938,26 @@ func (f *File) Read(b []byte) (int, error) {
|
|||
// maximise throughput for transferring the entire file (especially
|
||||
// over high latency links).
|
||||
func (f *File) WriteTo(w io.Writer) (int64, error) {
|
||||
fi, err := f.c.Stat(f.path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
var fileSize uint64
|
||||
if f.c.useFstat {
|
||||
fileStat, err := f.c.fstat(f.handle)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fileSize = fileStat.Size
|
||||
|
||||
} else {
|
||||
fi, err := f.c.Stat(f.path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
fileSize = uint64(fi.Size())
|
||||
}
|
||||
|
||||
inFlight := 0
|
||||
desiredInFlight := 1
|
||||
offset := f.offset
|
||||
writeOffset := offset
|
||||
fileSize := uint64(fi.Size())
|
||||
// see comment on same line in Read() above
|
||||
ch := make(chan result, f.c.maxConcurrentRequests+1)
|
||||
type inflightRead struct {
|
||||
|
@ -934,7 +999,7 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
|
||||
if inFlight == 0 {
|
||||
if firstErr.err == nil && len(pendingWrites) > 0 {
|
||||
return copied, InternalInconsistency
|
||||
return copied, ErrInternalInconsistency
|
||||
}
|
||||
break
|
||||
}
|
||||
|
@ -952,11 +1017,11 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
}
|
||||
delete(reqs, reqID)
|
||||
switch res.typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
if firstErr.err == nil || req.offset < firstErr.offset {
|
||||
firstErr = offsetErr{offset: req.offset, err: normaliseError(unmarshalStatus(reqID, res.data))}
|
||||
}
|
||||
case ssh_FXP_DATA:
|
||||
case sshFxpData:
|
||||
l, data := unmarshalUint32(data)
|
||||
if req.offset == writeOffset {
|
||||
nbytes, err := w.Write(data)
|
||||
|
@ -1071,7 +1136,7 @@ func (f *File) Write(b []byte) (int, error) {
|
|||
continue
|
||||
}
|
||||
switch res.typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
id, _ := unmarshalUint32(res.data)
|
||||
err := normaliseError(unmarshalStatus(id, res.data))
|
||||
if err != nil && firstErr == nil {
|
||||
|
@ -1139,7 +1204,7 @@ func (f *File) ReadFrom(r io.Reader) (int64, error) {
|
|||
continue
|
||||
}
|
||||
switch res.typ {
|
||||
case ssh_FXP_STATUS:
|
||||
case sshFxpStatus:
|
||||
id, _ := unmarshalUint32(res.data)
|
||||
err := normaliseError(unmarshalStatus(id, res.data))
|
||||
if err != nil && firstErr == nil {
|
||||
|
@ -1218,11 +1283,11 @@ func normaliseError(err error) error {
|
|||
switch err := err.(type) {
|
||||
case *StatusError:
|
||||
switch err.Code {
|
||||
case ssh_FX_EOF:
|
||||
case sshFxEOF:
|
||||
return io.EOF
|
||||
case ssh_FX_NO_SUCH_FILE:
|
||||
case sshFxNoSuchFile:
|
||||
return os.ErrNotExist
|
||||
case ssh_FX_OK:
|
||||
case sshFxOk:
|
||||
return nil
|
||||
default:
|
||||
return err
|
||||
|
@ -1260,24 +1325,24 @@ func flags(f int) uint32 {
|
|||
var out uint32
|
||||
switch f & os.O_WRONLY {
|
||||
case os.O_WRONLY:
|
||||
out |= ssh_FXF_WRITE
|
||||
out |= sshFxfWrite
|
||||
case os.O_RDONLY:
|
||||
out |= ssh_FXF_READ
|
||||
out |= sshFxfRead
|
||||
}
|
||||
if f&os.O_RDWR == os.O_RDWR {
|
||||
out |= ssh_FXF_READ | ssh_FXF_WRITE
|
||||
out |= sshFxfRead | sshFxfWrite
|
||||
}
|
||||
if f&os.O_APPEND == os.O_APPEND {
|
||||
out |= ssh_FXF_APPEND
|
||||
out |= sshFxfAppend
|
||||
}
|
||||
if f&os.O_CREATE == os.O_CREATE {
|
||||
out |= ssh_FXF_CREAT
|
||||
out |= sshFxfCreat
|
||||
}
|
||||
if f&os.O_TRUNC == os.O_TRUNC {
|
||||
out |= ssh_FXF_TRUNC
|
||||
out |= sshFxfTrunc
|
||||
}
|
||||
if f&os.O_EXCL == os.O_EXCL {
|
||||
out |= ssh_FXF_EXCL
|
||||
out |= sshFxfExcl
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue