mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-10-29 07:07:02 +08:00
Refactor SFTP to prepare for multiple SFTP version support and add suport for versions 0 thru 3
This commit is contained in:
@@ -16,8 +16,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string NewPath { get; private set; }
|
||||
|
||||
public PosixRenameRequest(uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public PosixRenameRequest(uint protocolVersion, uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.OldPath = oldPath;
|
||||
this.NewPath = newPath;
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public byte[] Handle { get; private set; }
|
||||
|
||||
public SftpCloseRequest(uint requestId, byte[] handle, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpCloseRequest(uint protocolVersion, uint requestId, byte[] handle, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Handle = handle;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public SftpFileAttributes Attributes { get; private set; }
|
||||
|
||||
public SftpFSetStatRequest(uint requestId, byte[] handle, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpFSetStatRequest(uint protocolVersion, uint requestId, byte[] handle, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Handle = handle;
|
||||
this.Attributes = attributes;
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public byte[] Handle { get; private set; }
|
||||
|
||||
public SftpFStatRequest(uint requestId, byte[] handle, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpFStatRequest(uint protocolVersion, uint requestId, byte[] handle, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Handle = handle;
|
||||
this.SetAction(attrsAction);
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public SftpLStatRequest(uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpLStatRequest(uint protocolVersion, uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.SetAction(attrsAction);
|
||||
|
||||
@@ -17,15 +17,15 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public SftpFileAttributes Attributes { get; private set; }
|
||||
|
||||
public SftpMkDirRequest(uint requestId, string path, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpMkDirRequest(uint protocolVersion, uint requestId, string path, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.Attributes = new SftpFileAttributes();
|
||||
}
|
||||
|
||||
public SftpMkDirRequest(uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpMkDirRequest(uint protocolVersion, uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.Attributes = attributes;
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public SftpOpenDirRequest(uint requestId, string path, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpOpenDirRequest(uint protocolVersion, uint requestId, string path, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.SetAction(handleAction);
|
||||
|
||||
@@ -19,13 +19,13 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public SftpFileAttributes Attributes { get; private set; }
|
||||
|
||||
public SftpOpenRequest(uint requestId, string fileName, Flags flags, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
|
||||
: this(requestId, fileName, flags, new SftpFileAttributes(), handleAction, statusAction)
|
||||
public SftpOpenRequest(uint protocolVersion, uint requestId, string fileName, Flags flags, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
|
||||
: this(protocolVersion, requestId, fileName, flags, new SftpFileAttributes(), handleAction, statusAction)
|
||||
{
|
||||
}
|
||||
|
||||
public SftpOpenRequest(uint requestId, string fileName, Flags flags, SftpFileAttributes attributes, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpOpenRequest(uint protocolVersion, uint requestId, string fileName, Flags flags, SftpFileAttributes attributes, Action<SftpHandleResponse> handleAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Filename = fileName;
|
||||
this.Flags = flags;
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public byte[] Handle { get; private set; }
|
||||
|
||||
public SftpReadDirRequest(uint requestId, byte[] handle, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpReadDirRequest(uint protocolVersion, uint requestId, byte[] handle, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Handle = handle;
|
||||
this.SetAction(nameAction);
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public SftpReadLinkRequest(uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpReadLinkRequest(uint protocolVersion, uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.SetAction(nameAction);
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public UInt32 Length { get; private set; }
|
||||
|
||||
public SftpReadRequest(uint requestId, byte[] handle, UInt64 offset, UInt32 length, Action<SftpDataResponse> dataAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpReadRequest(uint protocolVersion, uint requestId, byte[] handle, UInt64 offset, UInt32 length, Action<SftpDataResponse> dataAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Handle = handle;
|
||||
this.Offset = offset;
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public SftpRealPathRequest(uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpRealPathRequest(uint protocolVersion, uint requestId, string path, Action<SftpNameResponse> nameAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
if (nameAction == null)
|
||||
throw new ArgumentNullException("name");
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Filename { get; private set; }
|
||||
|
||||
public SftpRemoveRequest(uint requestId, string filename, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpRemoveRequest(uint protocolVersion, uint requestId, string filename, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Filename = filename;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string NewPath { get; private set; }
|
||||
|
||||
public SftpRenameRequest(uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpRenameRequest(uint protocolVersion, uint requestId, string oldPath, string newPath, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.OldPath = oldPath;
|
||||
this.NewPath = newPath;
|
||||
|
||||
@@ -17,10 +17,13 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
private Action<SftpNameResponse> _nameAction;
|
||||
|
||||
public uint RequestId { get; private set; }
|
||||
|
||||
public uint ProtocolVersion { get; private set; }
|
||||
|
||||
public SftpRequest(uint requestId, Action<SftpStatusResponse> statusAction)
|
||||
public SftpRequest(uint protocolVersion, uint requestId, Action<SftpStatusResponse> statusAction)
|
||||
{
|
||||
this.RequestId = requestId;
|
||||
this.ProtocolVersion = protocolVersion;
|
||||
this._statusAction = statusAction;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public SftpRmDirRequest(uint requestId, string path, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpRmDirRequest(uint protocolVersion, uint requestId, string path, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public SftpFileAttributes Attributes { get; private set; }
|
||||
|
||||
public SftpSetStatRequest(uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpSetStatRequest(uint protocolVersion, uint requestId, string path, SftpFileAttributes attributes, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.Attributes = attributes;
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public SftpStatRequest(uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpStatRequest(uint protocolVersion, uint requestId, string path, Action<SftpAttrsResponse> attrsAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.SetAction(attrsAction);
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string ExistingPath { get; set; }
|
||||
|
||||
public SftpSymLinkRequest(uint requestId, string newLinkPath, string existingPath, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpSymLinkRequest(uint protocolVersion, uint requestId, string newLinkPath, string existingPath, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.NewLinkPath = newLinkPath;
|
||||
this.ExistingPath = existingPath;
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public byte[] Data { get; private set; }
|
||||
|
||||
public SftpWriteRequest(uint requestId, byte[] handle, UInt64 offset, byte[] data, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public SftpWriteRequest(uint protocolVersion, uint requestId, byte[] handle, UInt64 offset, byte[] data, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Handle = handle;
|
||||
this.Offset = offset;
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace Renci.SshNet.Sftp.Requests
|
||||
|
||||
public string Path { get; private set; }
|
||||
|
||||
public StatVfsRequest(uint requestId, string path, Action<SftpExtendedReplyResponse> extendedAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(requestId, statusAction)
|
||||
public StatVfsRequest(uint protocolVersion, uint requestId, string path, Action<SftpExtendedReplyResponse> extendedAction, Action<SftpStatusResponse> statusAction)
|
||||
: base(protocolVersion, requestId, statusAction)
|
||||
{
|
||||
this.Path = path;
|
||||
this.SetAction(extendedAction);
|
||||
|
||||
@@ -14,6 +14,11 @@ namespace Renci.SshNet.Sftp.Responses
|
||||
|
||||
public SftpFileAttributes Attributes { get; private set; }
|
||||
|
||||
public SftpAttrsResponse(uint protocolVersion)
|
||||
: base(protocolVersion)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadData()
|
||||
{
|
||||
base.LoadData();
|
||||
|
||||
@@ -16,6 +16,11 @@ namespace Renci.SshNet.Sftp.Responses
|
||||
|
||||
public bool IsEof { get; set; }
|
||||
|
||||
public SftpDataResponse(uint protocolVersion)
|
||||
: base(protocolVersion)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadData()
|
||||
{
|
||||
base.LoadData();
|
||||
|
||||
@@ -11,5 +11,10 @@ namespace Renci.SshNet.Sftp.Responses
|
||||
{
|
||||
get { return SftpMessageTypes.ExtendedReply; }
|
||||
}
|
||||
|
||||
public SftpExtendedReplyResponse(uint protocolVersion)
|
||||
: base(protocolVersion)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@ namespace Renci.SshNet.Sftp.Responses
|
||||
|
||||
public byte[] Handle { get; private set; }
|
||||
|
||||
public SftpHandleResponse(uint protocolVersion)
|
||||
: base(protocolVersion)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadData()
|
||||
{
|
||||
base.LoadData();
|
||||
|
||||
@@ -16,9 +16,10 @@ namespace Renci.SshNet.Sftp.Responses
|
||||
|
||||
public KeyValuePair<string, SftpFileAttributes>[] Files { get; private set; }
|
||||
|
||||
public SftpNameResponse()
|
||||
public SftpNameResponse(uint protocolVersion)
|
||||
: base(protocolVersion)
|
||||
{
|
||||
this.Files = new KeyValuePair<string,SftpFileAttributes>[0];
|
||||
this.Files = new KeyValuePair<string, SftpFileAttributes>[0];
|
||||
}
|
||||
|
||||
protected override void LoadData()
|
||||
|
||||
@@ -9,6 +9,13 @@ namespace Renci.SshNet.Sftp.Responses
|
||||
{
|
||||
public uint ResponseId { get; private set; }
|
||||
|
||||
public uint ProtocolVersion { get; private set; }
|
||||
|
||||
public SftpResponse(uint protocolVersion)
|
||||
{
|
||||
this.ProtocolVersion = protocolVersion;
|
||||
}
|
||||
|
||||
protected override void LoadData()
|
||||
{
|
||||
base.LoadData();
|
||||
|
||||
@@ -12,19 +12,28 @@ namespace Renci.SshNet.Sftp.Responses
|
||||
get { return SftpMessageTypes.Status; }
|
||||
}
|
||||
|
||||
public SftpStatusResponse(uint protocolVersion)
|
||||
: base(protocolVersion)
|
||||
{
|
||||
}
|
||||
|
||||
public StatusCodes StatusCode { get; private set; }
|
||||
|
||||
public string ErrorMessage { get; private set; }
|
||||
|
||||
public string Language { get; private set; }
|
||||
|
||||
|
||||
protected override void LoadData()
|
||||
{
|
||||
base.LoadData();
|
||||
|
||||
|
||||
this.StatusCode = (StatusCodes)this.ReadUInt32();
|
||||
|
||||
if (this.ProtocolVersion < 3)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.IsEndOfData)
|
||||
{
|
||||
this.ErrorMessage = this.ReadString();
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
{
|
||||
public SftpFileSytemInformation Information { get; private set; }
|
||||
|
||||
public StatVfsResponse()
|
||||
: base(0)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadData()
|
||||
{
|
||||
base.LoadData();
|
||||
|
||||
@@ -9,11 +9,11 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
internal abstract class SftpMessage : SshData
|
||||
{
|
||||
public new static SftpMessage Load(byte[] data)
|
||||
public new static SftpMessage Load(uint protocolVersion, byte[] data)
|
||||
{
|
||||
var messageType = (SftpMessageTypes)data.FirstOrDefault();
|
||||
|
||||
return Load(data, messageType);
|
||||
return Load(protocolVersion, data, messageType);
|
||||
}
|
||||
|
||||
protected override int ZeroReaderIndex
|
||||
@@ -152,7 +152,7 @@ namespace Renci.SshNet.Sftp
|
||||
}
|
||||
}
|
||||
|
||||
private static SftpMessage Load(byte[] data, SftpMessageTypes messageType)
|
||||
private static SftpMessage Load(uint protocolVersion, byte[] data, SftpMessageTypes messageType)
|
||||
{
|
||||
SftpMessage message = null;
|
||||
|
||||
@@ -162,22 +162,22 @@ namespace Renci.SshNet.Sftp
|
||||
message = new SftpVersionResponse();
|
||||
break;
|
||||
case SftpMessageTypes.Status:
|
||||
message = new SftpStatusResponse();
|
||||
message = new SftpStatusResponse(protocolVersion);
|
||||
break;
|
||||
case SftpMessageTypes.Data:
|
||||
message = new SftpDataResponse();
|
||||
message = new SftpDataResponse(protocolVersion);
|
||||
break;
|
||||
case SftpMessageTypes.Handle:
|
||||
message = new SftpHandleResponse();
|
||||
message = new SftpHandleResponse(protocolVersion);
|
||||
break;
|
||||
case SftpMessageTypes.Name:
|
||||
message = new SftpNameResponse();
|
||||
message = new SftpNameResponse(protocolVersion);
|
||||
break;
|
||||
case SftpMessageTypes.Attrs:
|
||||
message = new SftpAttrsResponse();
|
||||
message = new SftpAttrsResponse(protocolVersion);
|
||||
break;
|
||||
case SftpMessageTypes.ExtendedReply:
|
||||
message = new SftpExtendedReplyResponse();
|
||||
message = new SftpExtendedReplyResponse(protocolVersion);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Message type '{0}' is not supported.", messageType));
|
||||
|
||||
@@ -15,6 +15,10 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
internal class SftpSession : SubsystemSession
|
||||
{
|
||||
private const int MAXIMUM_SUPPORTED_VERSION = 3;
|
||||
|
||||
private const int MINIMUM_SUPPORTED_VERSION = 0;
|
||||
|
||||
private Dictionary<uint, SftpRequest> _requests = new Dictionary<uint, SftpRequest>();
|
||||
|
||||
private List<byte> _data = new List<byte>(16 * 1024);
|
||||
@@ -29,7 +33,7 @@ namespace Renci.SshNet.Sftp
|
||||
/// <summary>
|
||||
/// Gets SFTP protocol version.
|
||||
/// </summary>
|
||||
public int ProtocolVersion { get; private set; }
|
||||
public uint ProtocolVersion { get; private set; }
|
||||
|
||||
private long _requestId;
|
||||
/// <summary>
|
||||
@@ -164,11 +168,14 @@ namespace Renci.SshNet.Sftp
|
||||
|
||||
protected override void OnChannelOpen()
|
||||
{
|
||||
this.SendMessage(new SftpInitRequest(3));
|
||||
this.SendMessage(new SftpInitRequest(MAXIMUM_SUPPORTED_VERSION));
|
||||
|
||||
this.WaitHandle(this._sftpVersionConfirmed, this._operationTimeout);
|
||||
|
||||
this.ProtocolVersion = 3;
|
||||
if (this.ProtocolVersion > MAXIMUM_SUPPORTED_VERSION || this.ProtocolVersion < MINIMUM_SUPPORTED_VERSION)
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Server SFTP version {0} is not supported.", this.ProtocolVersion));
|
||||
}
|
||||
|
||||
// Resolve current directory
|
||||
this.WorkingDirectory = this.RequestRealPath(".").First().Key;
|
||||
@@ -202,21 +209,16 @@ namespace Renci.SshNet.Sftp
|
||||
this._data.RemoveRange(0, packetLength);
|
||||
|
||||
// Load SFTP Message and handle it
|
||||
var response = SftpMessage.Load(packetData);
|
||||
var response = SftpMessage.Load(this.ProtocolVersion, packetData);
|
||||
|
||||
try
|
||||
{
|
||||
var versionResponse = response as SftpVersionResponse;
|
||||
if (versionResponse != null)
|
||||
{
|
||||
if (versionResponse.Version == 3)
|
||||
{
|
||||
this._sftpVersionConfirmed.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Server SFTP version {0} is not supported.", versionResponse.Version));
|
||||
}
|
||||
this.ProtocolVersion = versionResponse.Version;
|
||||
|
||||
this._sftpVersionConfirmed.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -270,7 +272,7 @@ namespace Renci.SshNet.Sftp
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpOpenRequest(this.NextRequestId, path, flags,
|
||||
var request = new SftpOpenRequest(this.ProtocolVersion, this.NextRequestId, path, flags,
|
||||
(response) =>
|
||||
{
|
||||
handle = response.Handle;
|
||||
@@ -304,7 +306,7 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpCloseRequest(this.NextRequestId, handle,
|
||||
var request = new SftpCloseRequest(this.ProtocolVersion, this.NextRequestId, handle,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -336,7 +338,7 @@ namespace Renci.SshNet.Sftp
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpReadRequest(this.NextRequestId, handle, offset, length,
|
||||
var request = new SftpReadRequest(this.ProtocolVersion, this.NextRequestId, handle, offset, length,
|
||||
(response) =>
|
||||
{
|
||||
data = response.Data;
|
||||
@@ -371,7 +373,7 @@ namespace Renci.SshNet.Sftp
|
||||
/// <param name="wait">The wait event handle if needed.</param>
|
||||
internal void RequestWrite(byte[] handle, UInt64 offset, byte[] data, EventWaitHandle wait, Action<SftpStatusResponse> writeCompleted = null)
|
||||
{
|
||||
var request = new SftpWriteRequest(this.NextRequestId, handle, offset, data,
|
||||
var request = new SftpWriteRequest(this.ProtocolVersion, this.NextRequestId, handle, offset, data,
|
||||
(response) =>
|
||||
{
|
||||
if (writeCompleted != null)
|
||||
@@ -409,7 +411,7 @@ namespace Renci.SshNet.Sftp
|
||||
SftpFileAttributes attributes = null;
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpLStatRequest(this.NextRequestId, path,
|
||||
var request = new SftpLStatRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
attributes = response.Attributes;
|
||||
@@ -441,7 +443,7 @@ namespace Renci.SshNet.Sftp
|
||||
SftpFileAttributes attributes = null;
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpFStatRequest(this.NextRequestId, handle,
|
||||
var request = new SftpFStatRequest(this.ProtocolVersion, this.NextRequestId, handle,
|
||||
(response) =>
|
||||
{
|
||||
attributes = response.Attributes;
|
||||
@@ -469,7 +471,7 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpSetStatRequest(this.NextRequestId, path, attributes,
|
||||
var request = new SftpSetStatRequest(this.ProtocolVersion, this.NextRequestId, path, attributes,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -497,7 +499,7 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpFSetStatRequest(this.NextRequestId, handle, attributes,
|
||||
var request = new SftpFSetStatRequest(this.ProtocolVersion, this.NextRequestId, handle, attributes,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -528,7 +530,7 @@ namespace Renci.SshNet.Sftp
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpOpenDirRequest(this.NextRequestId, path,
|
||||
var request = new SftpOpenDirRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
handle = response.Handle;
|
||||
@@ -565,7 +567,7 @@ namespace Renci.SshNet.Sftp
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpReadDirRequest(this.NextRequestId, handle,
|
||||
var request = new SftpReadDirRequest(this.ProtocolVersion, this.NextRequestId, handle,
|
||||
(response) =>
|
||||
{
|
||||
result = response.Files;
|
||||
@@ -599,7 +601,7 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpRemoveRequest(this.NextRequestId, path,
|
||||
var request = new SftpRemoveRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -626,7 +628,7 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpMkDirRequest(this.NextRequestId, path,
|
||||
var request = new SftpMkDirRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -653,7 +655,7 @@ namespace Renci.SshNet.Sftp
|
||||
{
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpRmDirRequest(this.NextRequestId, path,
|
||||
var request = new SftpRmDirRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -684,7 +686,7 @@ namespace Renci.SshNet.Sftp
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpRealPathRequest(this.NextRequestId, path,
|
||||
var request = new SftpRealPathRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
result = response.Files;
|
||||
@@ -724,7 +726,7 @@ namespace Renci.SshNet.Sftp
|
||||
SftpFileAttributes attributes = null;
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpStatRequest(this.NextRequestId, path,
|
||||
var request = new SftpStatRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
attributes = response.Attributes;
|
||||
@@ -757,9 +759,13 @@ namespace Renci.SshNet.Sftp
|
||||
/// <param name="newPath">The new path.</param>
|
||||
internal void RequestRename(string oldPath, string newPath)
|
||||
{
|
||||
if (this.ProtocolVersion < 2)
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_RENAME operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
|
||||
}
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpRenameRequest(this.NextRequestId, oldPath, newPath,
|
||||
var request = new SftpRenameRequest(this.ProtocolVersion, this.NextRequestId, oldPath, newPath,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -786,11 +792,16 @@ namespace Renci.SshNet.Sftp
|
||||
/// <returns></returns>
|
||||
internal KeyValuePair<string, SftpFileAttributes>[] RequestReadLink(string path, bool nullOnError = false)
|
||||
{
|
||||
if (this.ProtocolVersion < 3)
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_READLINK operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
|
||||
}
|
||||
|
||||
KeyValuePair<string, SftpFileAttributes>[] result = null;
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpReadLinkRequest(this.NextRequestId, path,
|
||||
var request = new SftpReadLinkRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
result = response.Files;
|
||||
@@ -824,9 +835,14 @@ namespace Renci.SshNet.Sftp
|
||||
/// <param name="targetpath">The targetpath.</param>
|
||||
internal void RequestSymLink(string linkpath, string targetpath)
|
||||
{
|
||||
if (this.ProtocolVersion < 3)
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_SYMLINK operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
|
||||
}
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new SftpSymLinkRequest(this.NextRequestId, linkpath, targetpath,
|
||||
var request = new SftpSymLinkRequest(this.ProtocolVersion, this.NextRequestId, linkpath, targetpath,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -852,9 +868,14 @@ namespace Renci.SshNet.Sftp
|
||||
/// <param name="newPath">The new path.</param>
|
||||
internal void RequestPosixRename(string oldPath, string newPath)
|
||||
{
|
||||
if (this.ProtocolVersion < 3)
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_EXTENDED operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
|
||||
}
|
||||
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new PosixRenameRequest(this.NextRequestId, oldPath, newPath,
|
||||
var request = new PosixRenameRequest(this.ProtocolVersion, this.NextRequestId, oldPath, newPath,
|
||||
(response) =>
|
||||
{
|
||||
if (response.StatusCode == StatusCodes.Ok)
|
||||
@@ -881,10 +902,15 @@ namespace Renci.SshNet.Sftp
|
||||
/// <returns></returns>
|
||||
internal SftpFileSytemInformation RequestStatVfs(string path, bool nullOnError = false)
|
||||
{
|
||||
if (this.ProtocolVersion < 3)
|
||||
{
|
||||
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "SSH_FXP_EXTENDED operation is not supported in {0} version that server operates in.", this.ProtocolVersion));
|
||||
}
|
||||
|
||||
SftpFileSytemInformation information = null;
|
||||
using (var wait = new AutoResetEvent(false))
|
||||
{
|
||||
var request = new StatVfsRequest(this.NextRequestId, path,
|
||||
var request = new StatVfsRequest(this.ProtocolVersion, this.NextRequestId, path,
|
||||
(response) =>
|
||||
{
|
||||
information = response.OfType<StatVfsResponse>().Information;
|
||||
|
||||
@@ -1448,7 +1448,7 @@ namespace Renci.SshNet
|
||||
this._sftpSession.Connect();
|
||||
|
||||
// Resolve current running version
|
||||
this.ProtocolVersion = this._sftpSession.ProtocolVersion;
|
||||
this.ProtocolVersion = (int)this._sftpSession.ProtocolVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user