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); }
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; }
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."); }
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."); }
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."); }
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; }
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 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); }
/// <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; }
/// <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; }
/// <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); } }
/// <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); } }
/// <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; } }
/// <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; } }
/// <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; } }
/// <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); }
/// <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; }
/// <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; } }
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; } }
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."); }
/// <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); } }
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); } } }
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); } }
public SftpContext(SftpFileAttributes attributes) { _attributes = attributes; }
public SftpContext(SftpFileAttributes attributes, bool aDeleteOnCloseWorkaround) { _attributes = attributes; this.deleteOnCloseWorkaround = aDeleteOnCloseWorkaround; }
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; } }
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; } }
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); } }
/// <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); } }
/// <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); }
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; } }
/// <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); }
/// <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; } }
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); }
/// <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; } }
private bool GroupRightsSameAsOwner(SftpFileAttributes attributes) { return (attributes.GroupCanWrite == attributes.OwnerCanWrite) && (attributes.GroupCanRead == attributes.OwnerCanRead) && (attributes.GroupCanExecute == attributes.OwnerCanExecute); }
private bool UserCanWrite(SftpFileAttributes attributes) { return _userId <= 0 || (attributes.OwnerCanWrite && attributes.UserId == _userId || (attributes.GroupCanWrite && _userGroups.Contains(attributes.GroupId) || attributes.OthersCanWrite)); }
protected SftpFileAttributes ReadAttributes() { return(SftpFileAttributes.FromBytes(DataStream)); }