forked from TrueCloudLab/rclone
parent
3ef9f6f016
commit
8ec57d145e
267 changed files with 15430 additions and 10511 deletions
51
vendor/github.com/pkg/sftp/client.go
generated
vendored
51
vendor/github.com/pkg/sftp/client.go
generated
vendored
|
@ -495,7 +495,7 @@ func (c *Client) Remove(path string) error {
|
|||
// 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:
|
||||
return c.removeDirectory(path)
|
||||
return c.RemoveDirectory(path)
|
||||
}
|
||||
}
|
||||
return err
|
||||
|
@ -518,7 +518,8 @@ func (c *Client) removeFile(path string) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *Client) removeDirectory(path string) error {
|
||||
// RemoveDirectory removes a directory path.
|
||||
func (c *Client) RemoveDirectory(path string) error {
|
||||
id := c.nextID()
|
||||
typ, data, err := c.sendPacket(sshFxpRmdirPacket{
|
||||
ID: id,
|
||||
|
@ -652,7 +653,7 @@ func (f *File) Read(b []byte) (int, error) {
|
|||
inFlight := 0
|
||||
desiredInFlight := 1
|
||||
offset := f.offset
|
||||
ch := make(chan result, 1)
|
||||
ch := make(chan result, 2)
|
||||
type inflightRead struct {
|
||||
b []byte
|
||||
offset uint64
|
||||
|
@ -751,7 +752,7 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
offset := f.offset
|
||||
writeOffset := offset
|
||||
fileSize := uint64(fi.Size())
|
||||
ch := make(chan result, 1)
|
||||
ch := make(chan result, 2)
|
||||
type inflightRead struct {
|
||||
b []byte
|
||||
offset uint64
|
||||
|
@ -778,16 +779,21 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
|
||||
var copied int64
|
||||
for firstErr.err == nil || inFlight > 0 {
|
||||
for inFlight < desiredInFlight && firstErr.err == nil {
|
||||
b := make([]byte, f.c.maxPacket)
|
||||
sendReq(b, offset)
|
||||
offset += uint64(f.c.maxPacket)
|
||||
if offset > fileSize {
|
||||
desiredInFlight = 1
|
||||
if firstErr.err == nil {
|
||||
for inFlight+len(pendingWrites) < desiredInFlight {
|
||||
b := make([]byte, f.c.maxPacket)
|
||||
sendReq(b, offset)
|
||||
offset += uint64(f.c.maxPacket)
|
||||
if offset > fileSize {
|
||||
desiredInFlight = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if inFlight == 0 {
|
||||
if firstErr.err == nil && len(pendingWrites) > 0 {
|
||||
return copied, errors.New("internal inconsistency")
|
||||
}
|
||||
break
|
||||
}
|
||||
select {
|
||||
|
@ -816,6 +822,8 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
nbytes, err := w.Write(data)
|
||||
copied += int64(nbytes)
|
||||
if err != nil {
|
||||
// We will never receive another DATA with offset==writeOffset, so
|
||||
// the loop will drain inFlight and then exit.
|
||||
firstErr = offsetErr{offset: req.offset + uint64(nbytes), err: err}
|
||||
break
|
||||
}
|
||||
|
@ -830,8 +838,16 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
desiredInFlight++
|
||||
}
|
||||
writeOffset += uint64(nbytes)
|
||||
for pendingData, ok := pendingWrites[writeOffset]; ok; pendingData, ok = pendingWrites[writeOffset] {
|
||||
for {
|
||||
pendingData, ok := pendingWrites[writeOffset]
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
// Give go a chance to free the memory.
|
||||
delete(pendingWrites, writeOffset)
|
||||
nbytes, err := w.Write(pendingData)
|
||||
// Do not move writeOffset on error so subsequent iterations won't trigger
|
||||
// any writes.
|
||||
if err != nil {
|
||||
firstErr = offsetErr{offset: writeOffset + uint64(nbytes), err: err}
|
||||
break
|
||||
|
@ -841,14 +857,12 @@ func (f *File) WriteTo(w io.Writer) (int64, error) {
|
|||
break
|
||||
}
|
||||
writeOffset += uint64(nbytes)
|
||||
inFlight--
|
||||
}
|
||||
} else {
|
||||
// Don't write the data yet because
|
||||
// this response came in out of order
|
||||
// and we need to wait for responses
|
||||
// for earlier segments of the file.
|
||||
inFlight++ // Pending writes should still be considered inFlight.
|
||||
pendingWrites[req.offset] = data
|
||||
}
|
||||
default:
|
||||
|
@ -884,7 +898,8 @@ func (f *File) Write(b []byte) (int, error) {
|
|||
inFlight := 0
|
||||
desiredInFlight := 1
|
||||
offset := f.offset
|
||||
ch := make(chan result, 1)
|
||||
// chan must have a buffer of max value of (desiredInFlight - inFlight)
|
||||
ch := make(chan result, 2)
|
||||
var firstErr error
|
||||
written := len(b)
|
||||
for len(b) > 0 || inFlight > 0 {
|
||||
|
@ -947,7 +962,8 @@ func (f *File) ReadFrom(r io.Reader) (int64, error) {
|
|||
inFlight := 0
|
||||
desiredInFlight := 1
|
||||
offset := f.offset
|
||||
ch := make(chan result, 1)
|
||||
// chan must have a buffer of max value of (desiredInFlight - inFlight)
|
||||
ch := make(chan result, 2)
|
||||
var firstErr error
|
||||
read := int64(0)
|
||||
b := make([]byte, f.c.maxPacket)
|
||||
|
@ -1081,10 +1097,7 @@ func unmarshalStatus(id uint32, data []byte) error {
|
|||
return &unexpectedIDErr{id, sid}
|
||||
}
|
||||
code, data := unmarshalUint32(data)
|
||||
msg, data, err := unmarshalStringSafe(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
msg, data, _ := unmarshalStringSafe(data)
|
||||
lang, _, _ := unmarshalStringSafe(data)
|
||||
return &StatusError{
|
||||
Code: code,
|
||||
|
|
5
vendor/github.com/pkg/sftp/conn.go
generated
vendored
5
vendor/github.com/pkg/sftp/conn.go
generated
vendored
|
@ -14,6 +14,8 @@ type conn struct {
|
|||
io.Reader
|
||||
io.WriteCloser
|
||||
sync.Mutex // used to serialise writes to sendPacket
|
||||
// sendPacketTest is needed to replicate packet issues in testing
|
||||
sendPacketTest func(w io.Writer, m encoding.BinaryMarshaler) error
|
||||
}
|
||||
|
||||
func (c *conn) recvPacket() (uint8, []byte, error) {
|
||||
|
@ -23,6 +25,9 @@ func (c *conn) recvPacket() (uint8, []byte, error) {
|
|||
func (c *conn) sendPacket(m encoding.BinaryMarshaler) error {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
if c.sendPacketTest != nil {
|
||||
return c.sendPacketTest(c, m)
|
||||
}
|
||||
return sendPacket(c, m)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue