示例#1
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);
        }
示例#2
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;
            }
        }
示例#3
0
文件: SftpFile.cs 项目: xxdoc/acidmax
        /// <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");
            }

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

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

            this.FullName = fullName;
        }
示例#4
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);
            }
        }
示例#5
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;
            }
        }
示例#6
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);
            }
        }