private byte[] OpenDir(uint requestId, string directoryPath) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_OPENDIR, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(_encoding.GetBytes(directoryPath)); return WaitHandle(packet, requestId); }
/// <summary> /// Set permissions of the file or directory. /// </summary> /// <param name="path">Path.</param> /// <param name="permissions">Permissions to set.</param> /// <exception cref="SFTPClientErrorException">Operation failed.</exception> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status</exception> /// <exception cref="Exception">An exception which was thrown while processing the response.</exception> public void SetPermissions(string path, int permissions) { CheckStatus(); uint requestId = ++_requestId; byte[] pathData = _encoding.GetBytes(path); SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_SETSTAT, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(pathData) .WriteUInt32(SSH_FILEXFER_ATTR_PERMISSIONS) .WriteUInt32((uint)permissions & 0xfffu /* 07777 */); TransmitPacketAndWaitForStatusOK(requestId, packet); }
private void CloseHandle(uint requestId, byte[] handle) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_CLOSE, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(handle); TransmitPacketAndWaitForStatusOK(requestId, packet); }
private void TransmitPacketAndWaitForStatusOK(uint requestId, SFTPPacket packet) { bool result = false; _eventHandler.ClearResponseBuffer(); Transmit(packet); _eventHandler.WaitResponse( (packetType, dataReader) => { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { if (exception.Code == SFTPStatusCode.SSH_FX_OK) { result = true; // Ok, received SSH_FX_OK return true; // processed } else { throw exception; } } } return false; // ignored }, _protocolTimeout ); // sanity check if (!Volatile.Read(ref result)) { throw new SFTPClientException("Missing SSH_FXP_STATUS"); } }
/// <summary> /// Rename file or directory. /// </summary> /// <param name="oldPath">Old path.</param> /// <param name="newPath">New path.</param> /// <exception cref="SFTPClientErrorException">Operation failed.</exception> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status</exception> /// <exception cref="Exception">An exception which was thrown while processing the response.</exception> public void Rename(string oldPath, string newPath) { CheckStatus(); uint requestId = ++_requestId; byte[] oldPathData = _encoding.GetBytes(oldPath); byte[] newPathData = _encoding.GetBytes(newPath); SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_RENAME, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(oldPathData) .WriteAsString(newPathData); TransmitPacketAndWaitForStatusOK(requestId, packet); }
private byte[] ReadFile(uint requestId, byte[] handle, ulong offset, int length) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_READ, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(handle) .WriteUInt64(offset) .WriteInt32(length); byte[] data = null; bool[] result = new bool[] { false }; lock (_channelReceiver.ResponseNotifier) { Transmit(packet); _channelReceiver.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { if (exception.Code == SFTPStatusCode.SSH_FX_EOF) { data = null; // EOF result[0] = true; // OK, received SSH_FX_EOF return true; // processed } else { throw exception; } } } else if (packetType == SFTPPacketType.SSH_FXP_DATA) { uint id = dataReader.ReadUInt32(); if (id == requestId) { data = dataReader.ReadByteString(); result[0] = true; // OK, received SSH_FXP_DATA return true; // processed } } return false; // ignored }, _protocolTimeout); } // sanity check if (!result[0]) throw new SFTPClientException("Missing SSH_FXP_DATA"); return data; }
private void TransmitPacketAndWaitForStatusOK(uint requestId, SFTPPacket packet) { bool[] result = new bool[] { false }; lock (_channelReceiver.ResponseNotifier) { Transmit(packet); _channelReceiver.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { if (exception.Code == SFTPStatusCode.SSH_FX_OK) { result[0] = true; // Ok, received SSH_FX_OK return true; // processed } else { throw exception; } } } return false; // ignored }, _protocolTimeout); } // sanity check if (!result[0]) throw new SFTPClientException("Missing SSH_FXP_STATUS"); }
private void WriteFile(uint requestId, byte[] handle, ulong offset, byte[] buff, int length) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_WRITE, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(handle) .WriteUInt64(offset) .WriteAsString(buff, 0, length); TransmitPacketAndWaitForStatusOK(requestId, packet); }
/// <summary> /// Get file informations. /// </summary> /// <param name="path">File path.</param> /// <param name="lstat">Specifies to use lstat. Symbolic link is not followed and informations about the symbolic link are returned.</param> /// <returns>File attribute informations</returns> /// <exception cref="SFTPClientErrorException">Operation failed.</exception> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status</exception> /// <exception cref="Exception">An exception which was thrown while processing the response.</exception> public SFTPFileAttributes GetFileInformations(string path, bool lstat) { CheckStatus(); uint requestId = ++_requestId; byte[] pathData = _encoding.GetBytes(path); SFTPPacket packet = new SFTPPacket(lstat ? SFTPPacketType.SSH_FXP_LSTAT : SFTPPacketType.SSH_FXP_STAT, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(pathData); bool[] result = new bool[] { false }; SFTPFileAttributes attributes = null; lock (_channelReceiver.ResponseNotifier) { Transmit(packet); _channelReceiver.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { throw exception; } } else if (packetType == SFTPPacketType.SSH_FXP_ATTRS) { uint id = dataReader.ReadUInt32(); if (id == requestId) { attributes = ReadFileAttributes(dataReader); result[0] = true; // Ok, received SSH_FXP_ATTRS return true; // processed } } return false; // ignored }, _protocolTimeout); } // sanity check if (!result[0]) throw new SFTPClientException("Missing SSH_FXP_ATTRS"); return attributes; }
private ICollection<SFTPFileInfo> ReadDir(uint requestId, byte[] handle) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_READDIR) .WriteUInt32(requestId) .WriteAsString(handle); List<SFTPFileInfo> fileList = new List<SFTPFileInfo>(); bool result = false; _eventHandler.ClearResponseBuffer(); Transmit(packet); _eventHandler.WaitResponse( (packetType, dataReader) => { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { if (exception.Code == SFTPStatusCode.SSH_FX_EOF) { result = true; return true; // processed } else { throw exception; } } } else if (packetType == SFTPPacketType.SSH_FXP_NAME) { uint id = dataReader.ReadUInt32(); if (id == requestId) { uint count = (uint)dataReader.ReadInt32(); // use Encoding object with replacement fallback Encoding encoding = Encoding.GetEncoding( _encoding.CodePage, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback); for (int i = 0; i < count; i++) { SFTPFileInfo fileInfo = ReadFileInfo(dataReader, encoding); fileList.Add(fileInfo); } result = true; // OK, received SSH_FXP_NAME return true; // processed } } return false; // ignored }, _protocolTimeout ); // sanity check if (!Volatile.Read(ref result)) { throw new SFTPClientException("Missing SSH_FXP_NAME"); } return fileList; }
private int ReadFile(uint requestId, byte[] handle, ulong offset, int length, byte[] buffer) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_READ) .WriteUInt32(requestId) .WriteAsString(handle) .WriteUInt64(offset) .WriteInt32(length); int? readLength = null; _eventHandler.ClearResponseBuffer(); Transmit(packet); _eventHandler.WaitResponse( (packetType, dataReader) => { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { if (exception.Code == SFTPStatusCode.SSH_FX_EOF) { readLength = 0; return true; // processed } else { throw exception; } } } else if (packetType == SFTPPacketType.SSH_FXP_DATA) { uint id = dataReader.ReadUInt32(); if (id == requestId) { readLength = dataReader.ReadByteStringInto(buffer); return true; // processed } } return false; // ignored }, _protocolTimeout ); // sanity check Thread.MemoryBarrier(); if (!readLength.HasValue) { throw new SFTPClientException("Missing SSH_FXP_DATA"); } return readLength.Value; }
/// <summary> /// Initialize /// </summary> /// <remarks> /// Send SSH_FXP_INIT and receive SSH_FXP_VERSION. /// </remarks> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status</exception> /// <exception cref="Exception">An exception which was thrown while processing the response.</exception> public void Init() { WaitReady(); CheckStatus(); SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_INIT) .WriteInt32(SFTP_VERSION); bool result = false; _eventHandler.ClearResponseBuffer(); Transmit(packet); _eventHandler.WaitResponse( (packetType, dataReader) => { if (packetType == SFTPPacketType.SSH_FXP_VERSION) { int version = dataReader.ReadInt32(); Debug.WriteLine("SFTP: SSH_FXP_VERSION => " + version); result = true; // OK, received SSH_FXP_VERSION while (dataReader.RemainingDataLength > 4) { string extensionText = dataReader.ReadUTF8String(); Debug.WriteLine("SFTP: SSH_FXP_VERSION => " + extensionText); } return true; // processed } return false; // ignored }, _protocolTimeout ); // sanity check if (!Volatile.Read(ref result)) { throw new SFTPClientException("Missing SSH_FXP_VERSION"); } }
/// <summary> /// Gets canonical path. /// </summary> /// <param name="path">Path to be canonicalized.</param> /// <returns>Canonical path.</returns> /// <exception cref="SFTPClientErrorException">Operation failed.</exception> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status.</exception> public string GetRealPath(string path) { CheckStatus(); uint requestId = ++_requestId; byte[] pathData = _encoding.GetBytes(path); SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_REALPATH) .WriteUInt32(requestId) .WriteAsString(pathData); bool result = false; string realPath = null; _eventHandler.ClearResponseBuffer(); Transmit(packet); _eventHandler.WaitResponse( (packetType, dataReader) => { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { throw exception; } } else if (packetType == SFTPPacketType.SSH_FXP_NAME) { uint id = dataReader.ReadUInt32(); if (id == requestId) { uint count = (uint)dataReader.ReadInt32(); if (count > 0) { // use Encoding object with replacement fallback Encoding encoding = Encoding.GetEncoding( _encoding.CodePage, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback); SFTPFileInfo fileInfo = ReadFileInfo(dataReader, encoding); realPath = fileInfo.FileName; } result = true; // OK, received SSH_FXP_NAME return true; // processed } } return false; // ignored }, _protocolTimeout ); // sanity check if (!Volatile.Read(ref result)) { throw new SFTPClientException("Missing SSH_FXP_NAME"); } return realPath; }
/// <summary> /// Get file informations. /// </summary> /// <param name="path">File path.</param> /// <param name="lstat">Specifies to use lstat. Symbolic link is not followed and informations about the symbolic link are returned.</param> /// <returns>File attribute informations</returns> /// <exception cref="SFTPClientErrorException">Operation failed.</exception> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status</exception> /// <exception cref="Exception">An exception which was thrown while processing the response.</exception> public SFTPFileAttributes GetFileInformations(string path, bool lstat) { CheckStatus(); uint requestId = ++_requestId; byte[] pathData = _encoding.GetBytes(path); SFTPPacket packet = new SFTPPacket(lstat ? SFTPPacketType.SSH_FXP_LSTAT : SFTPPacketType.SSH_FXP_STAT) .WriteUInt32(requestId) .WriteAsString(pathData); bool result = false; SFTPFileAttributes attributes = null; _eventHandler.ClearResponseBuffer(); Transmit(packet); _eventHandler.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { throw exception; } } else if (packetType == SFTPPacketType.SSH_FXP_ATTRS) { uint id = dataReader.ReadUInt32(); if (id == requestId) { attributes = ReadFileAttributes(dataReader); result = true; // Ok, received SSH_FXP_ATTRS return true; // processed } } return false; // ignored }, _protocolTimeout ); // sanity check if (!Volatile.Read(ref result)) { throw new SFTPClientException("Missing SSH_FXP_ATTRS"); } return attributes; }
private byte[] OpenFile(uint requestId, string filePath, uint flags) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_OPEN, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(_encoding.GetBytes(filePath)) .WriteUInt32(flags) .WriteUInt32(0); // attribute flag return WaitHandle(packet, requestId); }
/// <summary> /// Gets canonical path. /// </summary> /// <param name="path">Path to be canonicalized.</param> /// <returns>Canonical path.</returns> /// <exception cref="SFTPClientErrorException">Operation failed.</exception> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status.</exception> public string GetRealPath(string path) { CheckStatus(); uint requestId = ++_requestId; byte[] pathData = _encoding.GetBytes(path); SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_REALPATH, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(pathData); bool[] result = new bool[] { false }; string realPath = null; lock (_channelReceiver.ResponseNotifier) { Transmit(packet); _channelReceiver.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { throw exception; } } else if (packetType == SFTPPacketType.SSH_FXP_NAME) { uint id = dataReader.ReadUInt32(); if (id == requestId) { uint count = (uint)dataReader.ReadInt32(); if (count > 0) { // use Encoding object with replacement fallback Encoding encoding = Encoding.GetEncoding( _encoding.CodePage, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback); SFTPFileInfo fileInfo = ReadFileInfo(dataReader, encoding); realPath = fileInfo.FileName; } result[0] = true; // OK, received SSH_FXP_NAME return true; // processed } } return false; // ignored }, _protocolTimeout); } // sanity check if (!result[0]) throw new SFTPClientException("Missing SSH_FXP_NAME"); return realPath; }
private ICollection<SFTPFileInfo> ReadDir(uint requestId, byte[] handle) { SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_READDIR, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(handle); List<SFTPFileInfo> fileList = new List<SFTPFileInfo>(); bool[] result = new bool[] { false }; lock (_channelReceiver.ResponseNotifier) { Transmit(packet); _channelReceiver.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) { if (exception.Code == SFTPStatusCode.SSH_FX_EOF) { result[0] = true; return true; // processed } else { throw exception; } } } else if (packetType == SFTPPacketType.SSH_FXP_NAME) { uint id = dataReader.ReadUInt32(); if (id == requestId) { uint count = (uint)dataReader.ReadInt32(); // use Encoding object with replacement fallback Encoding encoding = Encoding.GetEncoding( _encoding.CodePage, EncoderFallback.ReplacementFallback, DecoderFallback.ReplacementFallback); for (int i = 0; i < count; i++) { SFTPFileInfo fileInfo = ReadFileInfo(dataReader, encoding); fileList.Add(fileInfo); } result[0] = true; // OK, received SSH_FXP_NAME return true; // processed } } return false; // ignored }, _protocolTimeout); } // sanity check if (!result[0]) throw new SFTPClientException("Missing SSH_FXP_NAME"); return fileList; }
/// <summary> /// Initialize /// </summary> /// <remarks> /// Send SSH_FXP_INIT and receive SSH_FXP_VERSION. /// </remarks> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status</exception> /// <exception cref="Exception">An exception which was thrown while processing the response.</exception> public void Init() { WaitReady(); CheckStatus(); SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_INIT, (uint)_channel.RemoteChannelID) .WriteInt32(SFTP_VERSION); bool[] result = new bool[] { false }; lock (_channelReceiver.ResponseNotifier) { Transmit(packet); _channelReceiver.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_VERSION) { int version = dataReader.ReadInt32(); Debug.WriteLine("SFTP: SSH_FXP_VERSION => " + version); result[0] = true; // OK, received SSH_FXP_VERSION while (dataReader.RemainingDataLength > 4) { string extensionText = dataReader.ReadUTF8String(); Debug.WriteLine("SFTP: SSH_FXP_VERSION => " + extensionText); } return true; // processed } return false; // ignored }, _protocolTimeout); } // sanity check if (!result[0]) throw new SFTPClientException("Missing SSH_FXP_VERSION"); }
private void Transmit(SFTPPacket packet) { ((SSH2Connection)_channel.Connection).Transmit(packet); }
/// <summary> /// Remove file. /// </summary> /// <param name="path">File path to remove.</param> /// <exception cref="SFTPClientErrorException">Operation failed.</exception> /// <exception cref="SFTPClientTimeoutException">Timeout has occured.</exception> /// <exception cref="SFTPClientInvalidStatusException">Invalid status</exception> /// <exception cref="Exception">An exception which was thrown while processing the response.</exception> public void RemoveFile(string path) { CheckStatus(); uint requestId = ++_requestId; byte[] pathData = _encoding.GetBytes(path); SFTPPacket packet = new SFTPPacket(SFTPPacketType.SSH_FXP_REMOVE, (uint)_channel.RemoteChannelID) .WriteUInt32(requestId) .WriteAsString(pathData); TransmitPacketAndWaitForStatusOK(requestId, packet); }
private byte[] WaitHandle(SFTPPacket requestPacket, uint requestId) { byte[] handle = null; lock (_channelReceiver.ResponseNotifier) { Transmit(requestPacket); _channelReceiver.WaitResponse( delegate(SFTPPacketType packetType, SSHDataReader dataReader) { if (packetType == SFTPPacketType.SSH_FXP_STATUS) { SFTPClientErrorException exception = SFTPClientErrorException.Create(dataReader); if (exception.ID == requestId) throw exception; } else if (packetType == SFTPPacketType.SSH_FXP_HANDLE) { uint id = dataReader.ReadUInt32(); if (id == requestId) { handle = dataReader.ReadByteString(); return true; // processed } } return false; // ignored }, _protocolTimeout); } // sanity check if (handle == null) throw new SFTPClientException("Missing SSH_FXP_HANDLE"); return handle; }
private void Transmit(SFTPPacket packet) { _channel.Send(packet.GetImage()); }