Contains SFTP file attributes.
        protected void Arrange()
        {
            var random = new Random();
            _path = random.Next().ToString(CultureInfo.InvariantCulture);
            _handle = new[] { (byte)random.Next(byte.MinValue, byte.MaxValue) };
            _fileAttributes = SftpFileAttributes.Empty;
            _bufferSize = (uint)random.Next(0, 1000);
            _readBufferSize = (uint)random.Next(0, 1000);
            _writeBufferSize = (uint)random.Next(0, 1000);

            _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);

            var sequence = new MockSequence();
            _sftpSessionMock.InSequence(sequence)
                .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                .Returns(_handle);
            _sftpSessionMock.InSequence(sequence).Setup(p => p.RequestFStat(_handle)).Returns(_fileAttributes);
            _sftpSessionMock.InSequence(sequence)
                .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                .Returns(_readBufferSize);
            _sftpSessionMock.InSequence(sequence)
                .Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
                .Returns(_writeBufferSize);
            _sftpSessionMock.InSequence(sequence)
                .Setup(p => p.IsOpen)
                .Returns(true);
            _sftpSessionMock.InSequence(sequence)
                .Setup(p => p.RequestClose(_handle));

            _sftpFileStream = new SftpFileStream(_sftpSessionMock.Object, _path, FileMode.Create, FileAccess.Write, (int)_bufferSize);
        }
Example #2
0
        internal SftpContextStream(SftpSession session, string path, FileMode mode, FileAccess access,
            SftpFileAttributes attributes)
        {
            Flags flags = Flags.None;

            switch (access)
            {
                case FileAccess.Read:
                    flags = Flags.Read;
                    break;
                case FileAccess.Write:
                    flags = Flags.Write;
                    break;
                case FileAccess.ReadWrite:
                    flags = Flags.Read | Flags.Write;
                    break;
            }

            switch (mode)
            {
                case FileMode.Append:
                    flags |= Flags.Append;
                    break;
                case FileMode.Create:
                    if (attributes == null)
                    {
                        flags |= Flags.CreateNew;
                    }
                    else
                    {
                        flags |= Flags.Truncate;
                    }
                    break;
                case FileMode.CreateNew:
                    flags |= Flags.CreateNew;
                    break;
                case FileMode.Open:
                    break;
                case FileMode.OpenOrCreate:
                    flags |= Flags.CreateNewOrOpen;
                    break;
                case FileMode.Truncate:
                    flags |= Flags.Truncate;
                    break;
            }

            _session = session;

            _handle = _session.RequestOpen(path, flags);

            _attributes = attributes ?? _session.RequestFStat(_handle);

            if (access.HasFlag(FileAccess.Write))
            {
                _writeBuffer = new byte[WRITE_BUFFER_SIZE];
                _writeMode = true;
            }

            _position = mode != FileMode.Append ? 0 : _attributes.Size;
        }
Example #3
0
 public void GroupCanWriteTest()
 {
     SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
     bool expected = false; // TODO: Initialize to an appropriate value
     bool actual;
     target.GroupCanWrite = expected;
     actual = target.GroupCanWrite;
     Assert.AreEqual(expected, actual);
     Assert.Inconclusive("Verify the correctness of this test method.");
 }
Example #4
0
 public void GroupIdTest()
 {
     SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
     int expected = 0; // TODO: Initialize to an appropriate value
     int actual;
     target.GroupId = expected;
     actual = target.GroupId;
     Assert.AreEqual(expected, actual);
     Assert.Inconclusive("Verify the correctness of this test method.");
 }
Example #5
0
 public void LastAccessTimeTest()
 {
     SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
     DateTime expected = new DateTime(); // TODO: Initialize to an appropriate value
     DateTime actual;
     target.LastAccessTime = expected;
     actual = target.LastAccessTime;
     Assert.AreEqual(expected, actual);
     Assert.Inconclusive("Verify the correctness of this test method.");
 }
Example #6
0
        public void Release()
        {
            _attributes = null;

            if (_stream != null)
            {
                _stream.Close();
                _stream = null;
            }
            GC.SuppressFinalize(this);
        }
        public void Init()
        {
            var random = new Random();

            _protocolVersion = (uint)random.Next(0, int.MaxValue);
            _requestId = (uint)random.Next(0, int.MaxValue);
            _handle = new byte[random.Next(1, 10)];
            random.NextBytes(_handle);
            _attributes = SftpFileAttributes.Empty;
            _attributesBytes = _attributes.GetBytes();
        }
        public void Init()
        {
            var random = new Random();

            _protocolVersion = (uint)random.Next(0, int.MaxValue);
            _requestId = (uint)random.Next(0, int.MaxValue);
            _encoding = Encoding.Unicode;
            _path = random.Next().ToString(CultureInfo.InvariantCulture);
            _pathBytes = _encoding.GetBytes(_path);
            _attributes = SftpFileAttributes.Empty;
            _attributesBytes = _attributes.GetBytes();
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SftpFile"/> class.
        /// </summary>
        /// <param name="sftpSession">The SFTP session.</param>
        /// <param name="fullName">Full path of the directory or file.</param>
        /// <param name="attributes">Attributes of the directory or file.</param>
        internal SftpFile(SftpSession sftpSession, string fullName, SftpFileAttributes attributes)
        {
            if (attributes == null)
                throw new ArgumentNullException("attributes");

            if (fullName == null)
                throw new ArgumentNullException("fullName");

            this._sftpSession = sftpSession;
            this.Attributes = attributes;

            this.Name = fullName.Substring(fullName.LastIndexOf('/') + 1);

            this.FullName = fullName;
        }
Example #10
0
        protected SftpFileAttributes ReadAttributes()
        {

            var flag = this.ReadUInt32();

            long size = -1;
            int userId = -1;
            int groupId = -1;
            uint permissions = 0;
            var accessTime = DateTime.MinValue;
            var modifyTime = DateTime.MinValue;
            IDictionary<string, string> extensions = null;

            if ((flag & 0x00000001) == 0x00000001)   //  SSH_FILEXFER_ATTR_SIZE
            {
                size = (long)this.ReadUInt64();
            }

            if ((flag & 0x00000002) == 0x00000002)   //  SSH_FILEXFER_ATTR_UIDGID
            {
                userId = (int)this.ReadUInt32();

                groupId = (int)this.ReadUInt32();
            }

            if ((flag & 0x00000004) == 0x00000004)   //  SSH_FILEXFER_ATTR_PERMISSIONS
            {
                permissions = this.ReadUInt32();
            }

            if ((flag & 0x00000008) == 0x00000008)   //  SSH_FILEXFER_ATTR_ACMODTIME
            {
                var time = this.ReadUInt32();
                accessTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
                time = this.ReadUInt32();
                modifyTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
            }

            if ((flag & 0x80000000) == 0x80000000)   //  SSH_FILEXFER_ATTR_ACMODTIME
            {
                var extendedCount = this.ReadUInt32();
                extensions = this.ReadExtensionPair();
            }
            var attributes = new SftpFileAttributes(accessTime, modifyTime, size, userId, groupId, permissions, extensions);

            return attributes;
        }
Example #11
0
        protected SftpFileAttributes ReadAttributes()
        {
            var flag = this.ReadUInt32();

            long size        = -1;
            int  userId      = -1;
            int  groupId     = -1;
            uint permissions = 0;
            var  accessTime  = DateTime.MinValue;
            var  modifyTime  = DateTime.MinValue;
            IDictionary <string, string> extensions = null;

            if ((flag & 0x00000001) == 0x00000001)   //  SSH_FILEXFER_ATTR_SIZE
            {
                size = (long)this.ReadUInt64();
            }

            if ((flag & 0x00000002) == 0x00000002)   //  SSH_FILEXFER_ATTR_UIDGID
            {
                userId = (int)this.ReadUInt32();

                groupId = (int)this.ReadUInt32();
            }

            if ((flag & 0x00000004) == 0x00000004)   //  SSH_FILEXFER_ATTR_PERMISSIONS
            {
                permissions = this.ReadUInt32();
            }

            if ((flag & 0x00000008) == 0x00000008)   //  SSH_FILEXFER_ATTR_ACMODTIME
            {
                var time = this.ReadUInt32();
                accessTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
                time       = this.ReadUInt32();
                modifyTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
            }

            if ((flag & 0x80000000) == 0x80000000)   //  SSH_FILEXFER_ATTR_ACMODTIME
            {
                var extendedCount = this.ReadUInt32();
                extensions = this.ReadExtensionPair();
            }
            var attributes = new SftpFileAttributes(accessTime, modifyTime, size, userId, groupId, permissions, extensions);

            return(attributes);
        }
        protected void Arrange()
        {
            _random = new Random();
            _path = _random.Next().ToString(CultureInfo.InvariantCulture);
            _handle = new[] {(byte) _random.Next(byte.MinValue, byte.MaxValue)};
            _fileAttributes = SftpFileAttributes.Empty;
            _bufferSize = (uint) _random.Next(1, 1000);
            _readBufferSize = (uint) _random.Next(0, 1000);
            _writeBufferSize = (uint) _random.Next(500, 1000);
            _data = new byte[(_writeBufferSize  * 2) + 15];
            _random.NextBytes(_data);
            _offset = _random.Next(1, 5);
            // to get multiple SSH_FXP_WRITE messages (and verify the offset is updated correctly), we make sure
            // the number of bytes to write is at least two times the write buffer size; we write a few extra bytes to
            // ensure the buffer is not empty after the writes so we can verify whether Length, Dispose and Flush
            // flush the buffer
            _count = ((int) _writeBufferSize*2) + _random.Next(1, 5);

            _expectedWrittenByteCount = (2 * _writeBufferSize);
            _expectedBufferedByteCount = (int)(_count - _expectedWrittenByteCount);
            _expectedBufferedBytes = _data.Take(_offset + (int)_expectedWrittenByteCount, _expectedBufferedByteCount);

            _sftpSessionMock = new Mock<ISftpSession>(MockBehavior.Strict);

            _sequence = new MockSequence();
            _sftpSessionMock.InSequence(_sequence)
                .Setup(p => p.RequestOpen(_path, Flags.Write | Flags.Truncate, true))
                .Returns(_handle);
            _sftpSessionMock.InSequence(_sequence).Setup(p => p.RequestFStat(_handle)).Returns(_fileAttributes);
            _sftpSessionMock.InSequence(_sequence)
                .Setup(p => p.CalculateOptimalReadLength(_bufferSize))
                .Returns(_readBufferSize);
            _sftpSessionMock.InSequence(_sequence)
                .Setup(p => p.CalculateOptimalWriteLength(_bufferSize, _handle))
                .Returns(_writeBufferSize);
            _sftpSessionMock.InSequence(_sequence)
                .Setup(p => p.IsOpen)
                .Returns(true);
            _sftpSessionMock.InSequence(_sequence)
                .Setup(p => p.RequestWrite(_handle, 0, _data, _offset, (int) _writeBufferSize, It.IsAny<AutoResetEvent>(), null));
            _sftpSessionMock.InSequence(_sequence)
                .Setup(p => p.RequestWrite(_handle, _writeBufferSize, _data, _offset + (int) _writeBufferSize, (int)_writeBufferSize, It.IsAny<AutoResetEvent>(), null));

            _sftpFileStream = new SftpFileStream(_sftpSessionMock.Object, _path, FileMode.Create, FileAccess.Write, (int) _bufferSize);
        }
Example #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SftpFile"/> class.
        /// </summary>
        /// <param name="sftpSession">The SFTP session.</param>
        /// <param name="fullName">Full path of the directory or file.</param>
        /// <param name="attributes">Attributes of the directory or file.</param>
        /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception>
        internal SftpFile(ISftpSession sftpSession, string fullName, SftpFileAttributes attributes)
        {
            if (sftpSession == null)
                throw new SshConnectionException("Client not connected.");

            if (attributes == null)
                throw new ArgumentNullException("attributes");

            if (fullName == null)
                throw new ArgumentNullException("fullName");

            _sftpSession = sftpSession;
            Attributes = attributes;

            Name = fullName.Substring(fullName.LastIndexOf('/') + 1);

            FullName = fullName;
        }
Example #14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SftpFile"/> class.
        /// </summary>
        /// <param name="sftpSession">The SFTP session.</param>
        /// <param name="fullName">Full path of the directory or file.</param>
        /// <param name="attributes">Attributes of the directory or file.</param>
        /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception>
        internal SftpFile(SftpSession sftpSession, string fullName, SftpFileAttributes attributes)
        {
            if (attributes == null)
            {
                throw new ArgumentNullException("attributes");
            }

            if (fullName == null)
            {
                throw new ArgumentNullException("fullName");
            }

            this._sftpSession = sftpSession;
            this.Attributes   = attributes;

            this.Name = fullName.Substring(fullName.LastIndexOf('/') + 1);

            this.FullName = fullName;
        }
Example #15
0
        /// <summary>
        /// Performs SSH_FXP_SETSTAT request.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="attributes">The attributes.</param>
        public void RequestSetStat(string path, SftpFileAttributes attributes)
        {
            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpSetStatRequest(this.NextRequestId, path, attributes,
                                                     (response) =>
                {
                    if (response.StatusCode == StatusCodes.Ok)
                    {
                        wait.Set();
                    }
                    else
                    {
                        ThrowSftpException(response);
                    }
                });

                this.SendRequest(request);

                this.WaitHandle(wait, this._operationTimeout);
            }
        }
Example #16
0
        /// <summary>
        /// Performs SSH_FXP_FSETSTAT request.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <param name="attributes">The attributes.</param>
        internal void RequestFSetStat(byte[] handle, SftpFileAttributes attributes)
        {
            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpFSetStatRequest(this.NextRequestId, handle, attributes,
                                                      (response) =>
                {
                    if (response.StatusCode == StatusCodes.Ok)
                    {
                        wait.Set();
                    }
                    else
                    {
                        this.ThrowSftpException(response);
                    }
                });

                this.SendRequest(request);

                this.WaitHandle(wait, this._operationTimeout);
            }
        }
Example #17
0
        /// <summary>
        /// Performs SSH_FXP_SETSTAT request.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="attributes">The attributes.</param>
        public void RequestSetStat(string path, SftpFileAttributes attributes)
        {
            SshException exception = null;

            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpSetStatRequest(this.ProtocolVersion, this.NextRequestId, path, this.Encoding, attributes,
                                                     (response) =>
                {
                    exception = this.GetSftpException(response);
                    wait.Set();
                });

                this.SendRequest(request);

                this.WaitHandle(wait, this._operationTimeout);
            }

            if (exception != null)
            {
                throw exception;
            }
        }
Example #18
0
        /// <summary>
        /// Performs SSH_FXP_FSETSTAT request.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <param name="attributes">The attributes.</param>
        internal void RequestFSetStat(byte[] handle, SftpFileAttributes attributes)
        {
            SshException exception = null;

            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpFSetStatRequest(this.ProtocolVersion, this.NextRequestId, handle, attributes,
                                                      (response) =>
                {
                    exception = this.GetSftpException(response);
                    wait.Set();
                });

                this.SendRequest(request);

                this.WaitOnHandle(wait, this._operationTimeout);
            }

            if (exception != null)
            {
                throw exception;
            }
        }
Example #19
0
        /// <summary>
        /// Performs SSH_FXP_FSETSTAT request.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <param name="attributes">The attributes.</param>
        public void RequestFSetStat(byte[] handle, SftpFileAttributes attributes)
        {
            SshException exception = null;

            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpFSetStatRequest(ProtocolVersion, NextRequestId, handle, attributes,
                                                      response =>
                {
                    exception = GetSftpException(response);
                    wait.Set();
                });

                SendRequest(request);

                WaitOnHandle(wait, OperationTimeout);
            }

            if (exception != null)
            {
                throw exception;
            }
        }
Example #20
0
        /// <summary>
        /// Performs SSH_FXP_FSTAT request.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <param name="nullOnError">if set to <c>true</c> returns null instead of throwing an exception.</param>
        /// <returns>
        /// File attributes
        /// </returns>
        internal SftpFileAttributes RequestFStat(byte[] handle, bool nullOnError = false)
        {
            SftpFileAttributes attributes = null;

            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpFStatRequest(this.NextRequestId, handle,
                                                   (response) =>
                {
                    attributes = response.Attributes;
                    wait.Set();
                },
                                                   (response) =>
                {
                    this.ThrowSftpException(response);
                });

                this.SendRequest(request);

                this.WaitHandle(wait, this._operationTimeout);
            }

            return(attributes);
        }
Example #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SftpFile"/> class.
        /// </summary>
        /// <param name="sftpSession">The SFTP session.</param>
        /// <param name="fullName">Full path of the directory or file.</param>
        /// <param name="attributes">Attributes of the directory or file.</param>
        /// <exception cref="ArgumentNullException"><paramref name="sftpSession"/> or <paramref name="fullName"/> is null.</exception>
        internal SftpFile(ISftpSession sftpSession, string fullName, SftpFileAttributes attributes)
        {
            if (sftpSession == null)
            {
                throw new SshConnectionException("Client not connected.");
            }

            if (attributes == null)
            {
                throw new ArgumentNullException("attributes");
            }

            if (fullName == null)
            {
                throw new ArgumentNullException("fullName");
            }

            _sftpSession = sftpSession;
            Attributes   = attributes;

            Name = fullName.Substring(fullName.LastIndexOf('/') + 1);

            FullName = fullName;
        }
Example #22
0
        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A byte offset relative to the <paramref name="origin"/> parameter.</param>
        /// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin"/> indicating the reference point used to obtain the new position.</param>
        /// <returns>
        /// The new position within the current stream.
        /// </returns>
        /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
        /// <exception cref="T:System.NotSupportedException">The stream does not support seeking, such as if the stream is constructed from a pipe or console output. </exception>
        /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
        public override long Seek(long offset, SeekOrigin origin)
        {
            long newPosn = -1;

            // Lock down the file stream while we do this.
            lock (_lock)
            {
                CheckSessionIsOpen();

                if (!CanSeek)
                    throw new NotSupportedException("Seek is not supported.");

                // Don't do anything if the position won't be moving.
                if (origin == SeekOrigin.Begin && offset == _position)
                {
                    return offset;
                }
                if (origin == SeekOrigin.Current && offset == 0)
                {
                    return _position;
                }

                _attributes = _session.RequestFStat(_handle);

                // The behaviour depends upon the read/write mode.
                if (_bufferOwnedByWrite)
                {
                    // Flush the write buffer and then seek.
                    FlushWriteBuffer();

                    switch (origin)
                    {
                        case SeekOrigin.Begin:
                            newPosn = offset;
                            break;
                        case SeekOrigin.Current:
                            newPosn = _position + offset;
                            break;
                        case SeekOrigin.End:
                            newPosn = _attributes.Size - offset;
                            break;
                    }

                    if (newPosn == -1)
                    {
                        throw new EndOfStreamException("End of stream.");
                    }
                    _position = newPosn;
                    _serverFilePosition = (ulong)newPosn;
                }
                else
                {
                    // Determine if the seek is to somewhere inside
                    // the current read buffer bounds.
                    if (origin == SeekOrigin.Begin)
                    {
                        newPosn = _position - _bufferPosition;
                        if (offset >= newPosn && offset <
                                (newPosn + _bufferLen))
                        {
                            _bufferPosition = (int)(offset - newPosn);
                            _position = offset;
                            return _position;
                        }
                    }
                    else if (origin == SeekOrigin.Current)
                    {
                        newPosn = _position + offset;
                        if (newPosn >= (_position - _bufferPosition) &&
                           newPosn < (_position - _bufferPosition + _bufferLen))
                        {
                            _bufferPosition =
                                (int)(newPosn - (_position - _bufferPosition));
                            _position = newPosn;
                            return _position;
                        }
                    }

                    // Abandon the read buffer.
                    _bufferPosition = 0;
                    _bufferLen = 0;

                    // Seek to the new position.
                    switch (origin)
                    {
                        case SeekOrigin.Begin:
                            newPosn = offset;
                            break;
                        case SeekOrigin.Current:
                            newPosn = _position + offset;
                            break;
                        case SeekOrigin.End:
                            newPosn = _attributes.Size - offset;
                            break;
                    }

                    if (newPosn < 0)
                    {
                        throw new EndOfStreamException();
                    }

                    _position = newPosn;
                }
                return _position;
            }
        }
Example #23
0
        internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync)
        {
            // Validate the parameters.
            if (session == null)
                throw new SshConnectionException("Client not connected.");

            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            if (mode < FileMode.CreateNew || mode > FileMode.Append)
            {
                throw new ArgumentOutOfRangeException("mode");
            }

            Timeout = TimeSpan.FromSeconds(30);
            Name = path;

            // Initialize the object state.
            _session = session;
            _ownsHandle = true;
            _isAsync = useAsync;
            _bufferPosition = 0;
            _bufferLen = 0;
            _bufferOwnedByWrite = false;
            _canRead = ((access & FileAccess.Read) != 0);
            _canSeek = true;
            _canWrite = ((access & FileAccess.Write) != 0);
            _position = 0;
            _serverFilePosition = 0;

            var flags = Flags.None;

            switch (access)
            {
                case FileAccess.Read:
                    flags |= Flags.Read;
                    break;
                case FileAccess.Write:
                    flags |= Flags.Write;
                    break;
                case FileAccess.ReadWrite:
                    flags |= Flags.Read;
                    flags |= Flags.Write;
                    break;
            }

            switch (mode)
            {
                case FileMode.Append:
                    flags |= Flags.Append;
                    break;
                case FileMode.Create:
                    _handle = _session.RequestOpen(path, flags | Flags.Truncate, true);
                    if (_handle == null)
                    {
                        flags |= Flags.CreateNew;
                    }
                    else
                    {
                        flags |= Flags.Truncate;
                    }
                    break;
                case FileMode.CreateNew:
                    flags |= Flags.CreateNew;
                    break;
                case FileMode.Open:
                    break;
                case FileMode.OpenOrCreate:
                    flags |= Flags.CreateNewOrOpen;
                    break;
                case FileMode.Truncate:
                    flags |= Flags.Truncate;
                    break;
            }

            if (_handle == null)
                _handle = _session.RequestOpen(path, flags);

            _attributes = _session.RequestFStat(_handle);

            // instead of using the specified buffer size as is, we use it to calculate a buffer size
            // that ensures we always receive or send the max. number of bytes in a single SSH_FXP_READ
            // or SSH_FXP_WRITE message

            _readBufferSize = (int)session.CalculateOptimalReadLength((uint)bufferSize);
            _readBuffer = new byte[_readBufferSize];
            _writeBufferSize = (int)session.CalculateOptimalWriteLength((uint)bufferSize, _handle);
            _writeBuffer = new byte[_writeBufferSize];

            if (mode == FileMode.Append)
            {
                _position = _attributes.Size;
                _serverFilePosition = (ulong)_attributes.Size;
            }
        }
Example #24
0
 public void SetPermissionsTest()
 {
     SftpFileAttributes target = new SftpFileAttributes(); // TODO: Initialize to an appropriate value
     short mode = 0; // TODO: Initialize to an appropriate value
     target.SetPermissions(mode);
     Assert.Inconclusive("A method that does not return a value cannot be verified.");
 }
Example #25
0
        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A byte offset relative to the <paramref name="origin"/> parameter.</param>
        /// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin"/> indicating the reference point used to obtain the new position.</param>
        /// <returns>
        /// The new position within the current stream.
        /// </returns>
        /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
        /// <exception cref="T:System.NotSupportedException">The stream does not support seeking, such as if the stream is constructed from a pipe or console output. </exception>
        /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
        public override long Seek(long offset, SeekOrigin origin)
        {
            long newPosn = -1;

            // Lock down the file stream while we do this.
            lock (_lock)
            {
                CheckSessionIsOpen();

                if (!CanSeek)
                {
                    throw new NotSupportedException("Seek is not supported.");
                }

                // Don't do anything if the position won't be moving.
                if (origin == SeekOrigin.Begin && offset == _position)
                {
                    return(offset);
                }
                if (origin == SeekOrigin.Current && offset == 0)
                {
                    return(_position);
                }

                _attributes = _session.RequestFStat(_handle);

                // The behaviour depends upon the read/write mode.
                if (_bufferOwnedByWrite)
                {
                    // Flush the write buffer and then seek.
                    FlushWriteBuffer();

                    switch (origin)
                    {
                    case SeekOrigin.Begin:
                        newPosn = offset;
                        break;

                    case SeekOrigin.Current:
                        newPosn = _position + offset;
                        break;

                    case SeekOrigin.End:
                        newPosn = _attributes.Size - offset;
                        break;
                    }

                    if (newPosn == -1)
                    {
                        throw new EndOfStreamException("End of stream.");
                    }
                    _position           = newPosn;
                    _serverFilePosition = (ulong)newPosn;
                }
                else
                {
                    // Determine if the seek is to somewhere inside
                    // the current read buffer bounds.
                    if (origin == SeekOrigin.Begin)
                    {
                        newPosn = _position - _bufferPosition;
                        if (offset >= newPosn && offset <
                            (newPosn + _bufferLen))
                        {
                            _bufferPosition = (int)(offset - newPosn);
                            _position       = offset;
                            return(_position);
                        }
                    }
                    else if (origin == SeekOrigin.Current)
                    {
                        newPosn = _position + offset;
                        if (newPosn >= (_position - _bufferPosition) &&
                            newPosn < (_position - _bufferPosition + _bufferLen))
                        {
                            _bufferPosition =
                                (int)(newPosn - (_position - _bufferPosition));
                            _position = newPosn;
                            return(_position);
                        }
                    }

                    // Abandon the read buffer.
                    _bufferPosition = 0;
                    _bufferLen      = 0;

                    // Seek to the new position.
                    switch (origin)
                    {
                    case SeekOrigin.Begin:
                        newPosn = offset;
                        break;

                    case SeekOrigin.Current:
                        newPosn = _position + offset;
                        break;

                    case SeekOrigin.End:
                        newPosn = _attributes.Size - offset;
                        break;
                    }

                    if (newPosn < 0)
                    {
                        throw new EndOfStreamException();
                    }

                    _position = newPosn;
                }
                return(_position);
            }
        }
Example #26
0
        /// <summary>
        /// Performs SSH_FXP_FSETSTAT request.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <param name="attributes">The attributes.</param>
        public void RequestFSetStat(byte[] handle, SftpFileAttributes attributes)
        {
            SshException exception = null;

            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpFSetStatRequest(ProtocolVersion, NextRequestId, handle, attributes,
                    response =>
                        {
                            exception = GetSftpException(response);
                            wait.Set();
                        });

                SendRequest(request);

                WaitOnHandle(wait, OperationTimeout);
            }

            if (exception != null)
            {
                throw exception;
            }
        }
Example #27
0
        protected void Write(SftpFileAttributes attributes)
        {
            if (attributes == null)
            {
                this.Write((uint)0);
                return;
            }
            else
            {
                UInt32 flag = 0;

                if (attributes.Size > -1)
                {
                    flag |= 0x00000001;
                }

                if (attributes.UserId > -1 && attributes.GroupId > -1)
                {
                    flag |= 0x00000002;
                }

                if (attributes.Permissions > 0)
                {
                    flag |= 0x00000004;
                }

                if (attributes.LastAccessTime > DateTime.MinValue && attributes.LastWriteTime > DateTime.MinValue)
                {
                    flag |= 0x00000008;
                }

                if (attributes.Extensions != null)
                {
                    flag |= 0x80000000;
                }

                this.Write(flag);

                if (attributes.Size > -1)
                {
                    this.Write((UInt64)attributes.Size);
                }

                if (attributes.UserId > -1 && attributes.GroupId > -1)
                {
                    this.Write((UInt32)attributes.UserId);
                    this.Write((UInt32)attributes.GroupId);
                }

                if (attributes.Permissions > 0)
                {
                    this.Write(attributes.Permissions);
                }

                if (attributes.LastAccessTime > DateTime.MinValue && attributes.LastWriteTime > DateTime.MinValue)
                {
                    uint time = (uint)(attributes.LastAccessTime.ToFileTime() / 10000000 - 11644473600);
                    this.Write(time);
                    time = (uint)(attributes.LastWriteTime.ToFileTime() / 10000000 - 11644473600);
                    this.Write(time);
                }

                if (attributes.Extensions != null)
                {
                    this.Write(attributes.Extensions);
                }
            }
        }
Example #28
0
        protected void Write(SftpFileAttributes attributes)
        {
            if (attributes == null)
            {
                this.Write((uint)0);
                return;
            }

            UInt32 flag = 0;

            if (attributes.IsSizeChanged && attributes.IsRegularFile)
            {
                flag |= 0x00000001;
            }

            if (attributes.IsUserIdChanged || attributes.IsGroupIdChanged)
            {
                flag |= 0x00000002;
            }

            if (attributes.IsPermissionsChanged)
            {
                flag |= 0x00000004;
            }

            if (attributes.IsLastAccessTimeChanged || attributes.IsLastWriteTimeChanged)
            {
                flag |= 0x00000008;
            }

            if (attributes.IsExtensionsChanged)
            {
                flag |= 0x80000000;
            }

            this.Write(flag);

            if (attributes.IsSizeChanged && attributes.IsRegularFile)
            {
                this.Write((UInt64)attributes.Size);
            }

            if (attributes.IsUserIdChanged || attributes.IsGroupIdChanged)
            {
                this.Write((UInt32)attributes.UserId);
                this.Write((UInt32)attributes.GroupId);
            }

            if (attributes.IsPermissionsChanged)
            {
                this.Write(attributes.Permissions);
            }

            if (attributes.IsLastAccessTimeChanged || attributes.IsLastWriteTimeChanged)
            {
                var time = (uint)(attributes.LastAccessTime.ToFileTime() / 10000000 - 11644473600);
                this.Write(time);
                time = (uint)(attributes.LastWriteTime.ToFileTime() / 10000000 - 11644473600);
                this.Write(time);
            }

            if (attributes.IsExtensionsChanged)
            {
                this.Write(attributes.Extensions);
            }
        }
Example #29
0
 public SftpContext(SftpFileAttributes attributes)
 {
     _attributes = attributes;
 }
Example #30
0
 public SftpContext(SftpFileAttributes attributes, bool aDeleteOnCloseWorkaround)
 {
     _attributes = attributes;
     this.deleteOnCloseWorkaround = aDeleteOnCloseWorkaround;
 }
Example #31
0
 public SftpContext(SftpSession session, string path, FileMode mode, FileAccess access,
                 SftpFileAttributes attributes)
 {
     _stream = new SftpContextStream(session, path, mode, access, attributes);
 }
        /// <summary>
        /// Performs SSH_FXP_SETSTAT request.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="attributes">The attributes.</param>
        internal void RequestSetStat(string path, SftpFileAttributes attributes)
        {
            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpSetStatRequest(this.NextRequestId, path, attributes,
                    (response) =>
                    {
                        if (response.StatusCode == StatusCodes.Ok)
                        {
                            wait.Set();
                        }
                        else
                        {
                            this.ThrowSftpException(response);
                        }
                    });

                this.SendRequest(request);

                this.WaitHandle(wait, this._operationTimeout);
            }
        }
        internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync)
        {
            // Validate the parameters.
            if (session == null)
                throw new SshConnectionException("Client not connected.");

            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (bufferSize <= 0 || bufferSize > 16 * 1024)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            if (mode < FileMode.CreateNew || mode > FileMode.Append)
            {
                throw new ArgumentOutOfRangeException("mode");
            }

            this.Timeout = TimeSpan.FromSeconds(30);
            this.Name = path;

            // Initialize the object state.
            this._session = session;
            this._access = access;
            this._ownsHandle = true;
            this._isAsync = useAsync;
            this._path = path;
            this._bufferSize = bufferSize;
            this._buffer = new byte[bufferSize];
            this._bufferPosn = 0;
            this._bufferLen = 0;
            this._bufferOwnedByWrite = false;
            this._canSeek = true;
            this._position = 0;
            this._serverFilePosition = 0;
            this._session.Disconnected += Session_Disconnected;

            var flags = Flags.None;

            switch (access)
            {
                case FileAccess.Read:
                    flags |= Flags.Read;
                    break;
                case FileAccess.Write:
                    flags |= Flags.Write;
                    break;
                case FileAccess.ReadWrite:
                    flags |= Flags.Read;
                    flags |= Flags.Write;
                    break;
                default:
                    break;
            }

            switch (mode)
            {
                case FileMode.Append:
                    flags |= Flags.Append;
                    break;
                case FileMode.Create:
                    this._handle = this._session.RequestOpen(path, flags | Flags.Truncate, true);
                    if (this._handle == null)
                    {
                        flags |= Flags.CreateNew;
                    }
                    else
                    {
                        flags |= Flags.Truncate;
                    }
                    break;
                case FileMode.CreateNew:
                    flags |= Flags.CreateNew;
                    break;
                case FileMode.Open:
                    break;
                case FileMode.OpenOrCreate:
                    flags |= Flags.CreateNewOrOpen;
                    break;
                case FileMode.Truncate:
                    flags |= Flags.Truncate;
                    break;
                default:
                    break;
            }

            if (this._handle == null)
                this._handle = this._session.RequestOpen(this._path, flags);

            this._attributes = this._session.RequestFStat(this._handle);

            if (mode == FileMode.Append)
            {
                this._position = this._attributes.Size;
                this._serverFilePosition = (ulong)this._attributes.Size;
            }
        }
Example #34
0
        internal SftpFileStream(SftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync)
        {
            // Validate the parameters.
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            if (mode < FileMode.CreateNew || mode > FileMode.Append)
            {
                throw new ArgumentOutOfRangeException("mode");
            }

            this.Timeout = TimeSpan.FromSeconds(30);
            this.Name    = path;

            // Initialize the object state.
            this._session            = session;
            this._access             = access;
            this._ownsHandle         = true;
            this._isAsync            = useAsync;
            this._path               = path;
            this._bufferSize         = bufferSize;
            this._buffer             = new byte[bufferSize];
            this._bufferPosn         = 0;
            this._bufferLen          = 0;
            this._bufferOwnedByWrite = false;
            this._canSeek            = true;
            this._position           = 0;

            var flags = Flags.None;

            switch (access)
            {
            case FileAccess.Read:
                flags |= Flags.Read;
                break;

            case FileAccess.Write:
                flags |= Flags.Write;
                break;

            case FileAccess.ReadWrite:
                flags |= Flags.Read;
                flags |= Flags.Write;
                break;

            default:
                break;
            }

            switch (mode)
            {
            case FileMode.Append:
                flags |= Flags.Append;
                break;

            case FileMode.Create:
                this._handle = this._session.RequestOpen(path, flags | Flags.Truncate, true);
                if (this._handle == null)
                {
                    flags |= Flags.CreateNew;
                }
                else
                {
                    flags |= Flags.Truncate;
                }
                break;

            case FileMode.CreateNew:
                flags |= Flags.CreateNew;
                break;

            case FileMode.Open:
                break;

            case FileMode.OpenOrCreate:
                flags |= Flags.CreateNewOrOpen;
                break;

            case FileMode.Truncate:
                flags |= Flags.Truncate;
                break;

            default:
                break;
            }

            if (this._handle == null)
            {
                this._handle = this._session.RequestOpen(this._path, flags);
            }

            this._attributes = this._session.RequestFStat(this._handle);

            if (mode == FileMode.Append)
            {
                this._position = this._attributes.Size;
            }
        }
Example #35
0
        protected void Write(SftpFileAttributes attributes)
        {
            if (attributes == null)
            {
                this.Write((uint)0);
                return;
            }

            UInt32 flag = 0;

            if (attributes.IsSizeChanged && attributes.IsRegularFile)
            {
                flag |= 0x00000001;
            }

            if (attributes.IsUserIdChanged|| attributes.IsGroupIdChanged)
            {
                flag |= 0x00000002;
            }

            if (attributes.IsPermissionsChanged)
            {
                flag |= 0x00000004;
            }

            if (attributes.IsLastAccessTimeChanged || attributes.IsLastWriteTimeChanged)
            {
                flag |= 0x00000008;
            }

            if (attributes.IsExtensionsChanged)
            {
                flag |= 0x80000000;
            }

            this.Write(flag);

            if (attributes.IsSizeChanged && attributes.IsRegularFile)
            {
                this.Write((UInt64)attributes.Size);
            }

            if (attributes.IsUserIdChanged|| attributes.IsGroupIdChanged)
            {
                this.Write((UInt32)attributes.UserId);
                this.Write((UInt32)attributes.GroupId);
            }

            if (attributes.IsPermissionsChanged)
            {
                this.Write(attributes.Permissions);
            }

            if (attributes.IsLastAccessTimeChanged || attributes.IsLastWriteTimeChanged)
            {
                var time = (uint)(attributes.LastAccessTime.ToFileTime() / 10000000 - 11644473600);
                this.Write(time);
                time = (uint)(attributes.LastWriteTime.ToFileTime() / 10000000 - 11644473600);
                this.Write(time);
            }

            if (attributes.IsExtensionsChanged)
            {
                this.Write(attributes.Extensions);
            }
        }
Example #36
0
        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A byte offset relative to the <paramref name="origin"/> parameter.</param>
        /// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin"/> indicating the reference point used to obtain the new position.</param>
        /// <returns>
        /// The new position within the current stream.
        /// </returns>
        /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
        ///
        /// <exception cref="T:System.NotSupportedException">The stream does not support seeking, such as if the stream is constructed from a pipe or console output. </exception>
        ///
        /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
        public override long Seek(long offset, SeekOrigin origin)
        {
            long newPosn = -1;

            // Bail out if this stream is not capable of seeking.
            if (!this._canSeek)
            {
                throw new NotSupportedException("Seek is not supported.");
            }

            // Lock down the file stream while we do this.
            lock (this._lock)
            {
                // Bail out if the handle is invalid.
                if (this._handle == null)
                {
                    throw new ObjectDisposedException("Stream is closed.");
                }

                // Don't do anything if the position won't be moving.
                if (origin == SeekOrigin.Begin && offset == this._position)
                {
                    return(offset);
                }
                else if (origin == SeekOrigin.Current && offset == 0)
                {
                    return(this._position);
                }

                this._attributes = this._session.RequestFStat(this._handle);

                // The behaviour depends upon the read/write mode.
                if (this._bufferOwnedByWrite)
                {
                    // Flush the write buffer and then seek.
                    this.FlushWriteBuffer();

                    switch (origin)
                    {
                    case SeekOrigin.Begin:
                        newPosn = offset;
                        break;

                    case SeekOrigin.Current:
                        newPosn = this._position + offset;
                        break;

                    case SeekOrigin.End:
                        newPosn = this._attributes.Size - offset;
                        break;

                    default:
                        break;
                    }

                    if (newPosn == -1)
                    {
                        throw new EndOfStreamException("End of stream.");
                    }
                    this._position = newPosn;
                }
                else
                {
                    // Determine if the seek is to somewhere inside
                    // the current read buffer bounds.
                    if (origin == SeekOrigin.Begin)
                    {
                        newPosn = this._position - this._bufferPosn;
                        if (offset >= newPosn && offset <
                            (newPosn + this._bufferLen))
                        {
                            this._bufferPosn = (int)(offset - newPosn);
                            this._position   = offset;
                            return(this._position);
                        }
                    }
                    else if (origin == SeekOrigin.Current)
                    {
                        newPosn = this._position + offset;
                        if (newPosn >= (this._position - this._bufferPosn) &&
                            newPosn < (this._position - this._bufferPosn + this._bufferLen))
                        {
                            this._bufferPosn =
                                (int)(newPosn - (this._position - this._bufferPosn));
                            this._position = newPosn;
                            return(this._position);
                        }
                    }

                    // Abandon the read buffer.
                    this._bufferPosn = 0;
                    this._bufferLen  = 0;

                    // Seek to the new position.
                    switch (origin)
                    {
                    case SeekOrigin.Begin:
                        newPosn = offset;
                        break;

                    case SeekOrigin.Current:
                        newPosn = this._position + offset;
                        break;

                    case SeekOrigin.End:
                        newPosn = this._attributes.Size - offset;
                        break;

                    default:
                        break;
                    }

                    if (newPosn < 0)
                    {
                        throw new EndOfStreamException();
                    }

                    this._position = newPosn;
                }
                return(this._position);
            }
        }
Example #37
0
        /// <summary>
        /// Sets the specified <see cref="SftpFileAttributes"/> of the file on the specified path.
        /// </summary>
        /// <param name="path">The path to the file.</param>
        /// <param name="fileAttributes">The desired <see cref="SftpFileAttributes"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <b>null</b>.</exception>
        public void SetAttributes(string path, SftpFileAttributes fileAttributes)
        {
            var fullPath = this._sftpSession.GetCanonicalPath(path);

            this._sftpSession.RequestSetStat(fullPath, fileAttributes);
        }
Example #38
0
        internal SftpFileStream(ISftpSession session, string path, FileMode mode, FileAccess access, int bufferSize, bool useAsync)
        {
            // Validate the parameters.
            if (session == null)
            {
                throw new SshConnectionException("Client not connected.");
            }

            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }
            if (access < FileAccess.Read || access > FileAccess.ReadWrite)
            {
                throw new ArgumentOutOfRangeException("access");
            }
            if (mode < FileMode.CreateNew || mode > FileMode.Append)
            {
                throw new ArgumentOutOfRangeException("mode");
            }

            Timeout = TimeSpan.FromSeconds(30);
            Name    = path;

            // Initialize the object state.
            _session            = session;
            _ownsHandle         = true;
            _isAsync            = useAsync;
            _bufferPosition     = 0;
            _bufferLen          = 0;
            _bufferOwnedByWrite = false;
            _canRead            = ((access & FileAccess.Read) != 0);
            _canSeek            = true;
            _canWrite           = ((access & FileAccess.Write) != 0);
            _position           = 0;
            _serverFilePosition = 0;

            var flags = Flags.None;

            switch (access)
            {
            case FileAccess.Read:
                flags |= Flags.Read;
                break;

            case FileAccess.Write:
                flags |= Flags.Write;
                break;

            case FileAccess.ReadWrite:
                flags |= Flags.Read;
                flags |= Flags.Write;
                break;
            }

            switch (mode)
            {
            case FileMode.Append:
                flags |= Flags.Append;
                break;

            case FileMode.Create:
                _handle = _session.RequestOpen(path, flags | Flags.Truncate, true);
                if (_handle == null)
                {
                    flags |= Flags.CreateNew;
                }
                else
                {
                    flags |= Flags.Truncate;
                }
                break;

            case FileMode.CreateNew:
                flags |= Flags.CreateNew;
                break;

            case FileMode.Open:
                break;

            case FileMode.OpenOrCreate:
                flags |= Flags.CreateNewOrOpen;
                break;

            case FileMode.Truncate:
                flags |= Flags.Truncate;
                break;
            }

            if (_handle == null)
            {
                _handle = _session.RequestOpen(path, flags);
            }

            _attributes = _session.RequestFStat(_handle);

            _readBufferSize  = (int)session.CalculateOptimalReadLength((uint)bufferSize);
            _readBuffer      = new byte[_readBufferSize];
            _writeBufferSize = (int)session.CalculateOptimalWriteLength((uint)bufferSize, _handle);
            _writeBuffer     = new byte[_writeBufferSize];

            if (mode == FileMode.Append)
            {
                _position           = _attributes.Size;
                _serverFilePosition = (ulong)_attributes.Size;
            }
        }
Example #39
0
        /// <summary>
        /// Sets the specified <see cref="SftpFileAttributes"/> of the file on the specified path.
        /// </summary>
        /// <param name="path">The path to the file.</param>
        /// <param name="fileAttributes">The desired <see cref="SftpFileAttributes"/>.</param>
        /// <exception cref="ArgumentNullException"><paramref name="path"/> is <b>null</b>.</exception>
        /// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
        public void SetAttributes(string path, SftpFileAttributes fileAttributes)
        {
            CheckDisposed();

            if (_sftpSession == null)
                throw new SshConnectionException("Client not connected.");

            var fullPath = _sftpSession.GetCanonicalPath(path);

            _sftpSession.RequestSetStat(fullPath, fileAttributes);
        }
Example #40
0
        /// <summary>
        /// Performs SSH_FXP_FSETSTAT request.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <param name="attributes">The attributes.</param>
        public void RequestFSetStat(byte[] handle, SftpFileAttributes attributes)
        {
            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpFSetStatRequest(this.NextRequestId, handle, attributes,
                    (response) =>
                    {
                        if (response.StatusCode == StatusCodes.Ok)
                        {
                            wait.Set();
                        }
                        else
                        {
                            ThrowSftpException(response);
                        }
                    });

                this.SendRequest(request);

                this.WaitHandle(wait, this._operationTimeout);
            }
        }
        /// <summary>
        /// Sets the position within the current stream.
        /// </summary>
        /// <param name="offset">A byte offset relative to the <paramref name="origin"/> parameter.</param>
        /// <param name="origin">A value of type <see cref="T:System.IO.SeekOrigin"/> indicating the reference point used to obtain the new position.</param>
        /// <returns>
        /// The new position within the current stream.
        /// </returns>
        /// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
        ///   
        /// <exception cref="T:System.NotSupportedException">The stream does not support seeking, such as if the stream is constructed from a pipe or console output. </exception>
        ///   
        /// <exception cref="T:System.ObjectDisposedException">Methods were called after the stream was closed. </exception>
        public override long Seek(long offset, SeekOrigin origin)
        {
            long newPosn = -1;

            // Bail out if this stream is not capable of seeking.
            if (!this._canSeek)
            {
                throw new NotSupportedException("Seek is not supported.");
            }

            // Lock down the file stream while we do this.
            lock (this._lock)
            {
                // Bail out if the handle is invalid.
                if (this._handle == null)
                {
                    throw new ObjectDisposedException("Stream is closed.");
                }

                // Don't do anything if the position won't be moving.
                if (origin == SeekOrigin.Begin && offset == this._position)
                {
                    return offset;
                }
                else if (origin == SeekOrigin.Current && offset == 0)
                {
                    return this._position;
                }

                this._attributes = this._session.RequestFStat(this._handle);

                // The behaviour depends upon the read/write mode.
                if (this._bufferOwnedByWrite)
                {
                    // Flush the write buffer and then seek.
                    this.FlushWriteBuffer();

                    switch (origin)
                    {
                        case SeekOrigin.Begin:
                            newPosn = offset;
                            break;
                        case SeekOrigin.Current:
                            newPosn = this._position + offset;
                            break;
                        case SeekOrigin.End:
                            newPosn = this._attributes.Size - offset;
                            break;
                        default:
                            break;
                    }

                    if (newPosn == -1)
                    {
                        throw new EndOfStreamException("End of stream.");
                    }
                    this._position = newPosn;
                    this._serverFilePosition = (ulong)newPosn;
                }
                else
                {
                    // Determine if the seek is to somewhere inside
                    // the current read buffer bounds.
                    if (origin == SeekOrigin.Begin)
                    {
                        newPosn = this._position - this._bufferPosn;
                        if (offset >= newPosn && offset <
                                (newPosn + this._bufferLen))
                        {
                            this._bufferPosn = (int)(offset - newPosn);
                            this._position = offset;
                            return this._position;
                        }
                    }
                    else if (origin == SeekOrigin.Current)
                    {
                        newPosn = this._position + offset;
                        if (newPosn >= (this._position - this._bufferPosn) &&
                           newPosn < (this._position - this._bufferPosn + this._bufferLen))
                        {
                            this._bufferPosn =
                                (int)(newPosn - (this._position - this._bufferPosn));
                            this._position = newPosn;
                            return this._position;
                        }
                    }

                    // Abandon the read buffer.
                    this._bufferPosn = 0;
                    this._bufferLen = 0;

                    // Seek to the new position.
                    switch (origin)
                    {
                        case SeekOrigin.Begin:
                            newPosn = offset;
                            break;
                        case SeekOrigin.Current:
                            newPosn = this._position + offset;
                            break;
                        case SeekOrigin.End:
                            newPosn = this._attributes.Size - offset;
                            break;
                        default:
                            break;
                    }

                    if (newPosn < 0)
                    {
                        throw new EndOfStreamException();
                    }

                    this._position = newPosn;
                }
                return this._position;
            }
        }
Example #42
0
 private void CacheAddAttr(string path, SftpFileAttributes attributes, DateTimeOffset expiration)
 {
     LogFSActionSuccess("CacheSetAttr", path, null, "Expir:{1} Size:{0}", attributes.Size, expiration);
     _cache.Add(_volumeLabel+"A:"+path, attributes, expiration);
 }
Example #43
0
        /// <summary>
        /// Performs SSH_FXP_SETSTAT request.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="attributes">The attributes.</param>
        internal void RequestSetStat(string path, SftpFileAttributes attributes)
        {
            SshException exception = null;

            using (var wait = new AutoResetEvent(false))
            {
                var request = new SftpSetStatRequest(this.ProtocolVersion, this.NextRequestId, path, this.Encoding, attributes,
                    (response) =>
                    {
                        exception = this.GetSftpException(response);
                        wait.Set();
                    });

                this.SendRequest(request);

                this.WaitHandle(wait, this._operationTimeout);
            }

            if (exception != null)
            {
                throw exception;
            }
        }
Example #44
0
 private bool GroupRightsSameAsOwner(SftpFileAttributes attributes)
 {
     return (attributes.GroupCanWrite == attributes.OwnerCanWrite)
             && (attributes.GroupCanRead == attributes.OwnerCanRead)
             && (attributes.GroupCanExecute == attributes.OwnerCanExecute);
 }
Example #45
0
 private bool UserCanWrite(SftpFileAttributes attributes)
 {
     return _userId <= 0 || (attributes.OwnerCanWrite && attributes.UserId == _userId ||
                              (attributes.GroupCanWrite && _userGroups.Contains(attributes.GroupId) ||
                               attributes.OthersCanWrite));
 }
Example #46
0
 protected SftpFileAttributes ReadAttributes()
 {
     return(SftpFileAttributes.FromBytes(DataStream));
 }