Esempio n. 1
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;
            }
        }
Esempio n. 2
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 <c>null</c>.</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;
        }
Esempio n. 3
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);
            }
        }
Esempio n. 4
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;
            }
        }
Esempio n. 5
0
 protected SftpFileAttributes ReadAttributes()
 {
     return(SftpFileAttributes.FromBytes(DataStream));
 }