Fix SFTP TODO items and some bug while downloading file.

This commit is contained in:
olegkap_cp
2010-09-10 14:51:17 +00:00
parent 26ecfd0ec9
commit 4e26ff3954
5 changed files with 86 additions and 62 deletions
@@ -62,7 +62,7 @@ namespace Renci.SshClient.Channels
this.SendMessage(new InitMessage
{
Version = 6,
Version = 3,
});
var versionMessage = this.ReceiveMessage<VersionMessage>();
@@ -128,7 +128,7 @@ namespace Renci.SshClient.Channels
while ((data = this.RemoteRead(handle, offset, bufferSize)) != null)
{
var fileData = data.GetSshBytes().ToArray();
destination.Write(fileData, 0, (int)bufferSize);
destination.Write(fileData, 0, fileData.Length);
destination.Flush();
offset += (ulong)fileData.Length;
}
@@ -216,6 +216,7 @@ namespace Renci.SshClient.Channels
this._channelRequestSuccessWaitHandle.Set();
}
protected override void OnChannelData(string data)
{
base.OnChannelData(data);
@@ -243,8 +244,15 @@ namespace Renci.SshClient.Channels
this._packetData = null;
// TODO: Handle SSH_FXP_STATUS here
// TODO: Validate message request id is correct
if (sftpMessage.RequestId != null)
{
if (sftpMessage.RequestId != this._requestId)
{
throw new InvalidOperationException("Invalid request id.");
}
this._requestId++;
}
this._responseMessage = sftpMessage;
@@ -302,7 +310,7 @@ namespace Renci.SshClient.Channels
private void SendMessage(SftpMessage sftpMessage)
{
sftpMessage.RequestId = this._requestId++;
sftpMessage.RequestId = this._requestId;
var message = new SftpDataMessage
{
ChannelNumber = this.ServerChannelNumber,
@@ -465,7 +473,18 @@ namespace Renci.SshClient.Channels
});
var status = this.ReceiveMessage<StatusMessage>();
// TODO: If close is fails wait a litle a try to close it again, in case server fluashed data into the file during close
var attempts = 0;
// If close is fails wait a litle a try to close it again, in case server flushed data into the file during close
while (status.StatusCode != StatusCodes.Ok && attempts++ < this.Session.ConnectionInfo.RetryAttempts)
{
Thread.Sleep(50);
status = this.ReceiveMessage<StatusMessage>();
}
if (status.StatusCode != StatusCodes.Ok)
{
throw new InvalidOperationException(string.Format("File handle cannot be closed after {0} attempts.", attempts));
}
}
private Attributes GetRemoteFileAttributes(string filename)
@@ -9,19 +9,19 @@ namespace Renci.SshClient.Common
public string FullName { get; set; }
public DateTime CreationTime { get; set; }
public DateTime? CreationTime { get; set; }
public DateTime LastAccessTime { get; set; }
public DateTime? LastAccessTime { get; set; }
public DateTime LastModifyTime { get; set; }
public DateTime? LastModifyTime { get; set; }
public ulong Size { get; set; }
public ulong? Size { get; set; }
public uint UserId { get; set; }
public uint? UserId { get; set; }
public uint GroupId { get; set; }
public uint? GroupId { get; set; }
public uint Permissions { get; set; }
public uint? Permissions { get; set; }
public IDictionary<string, string> Extentions { get; set; }
@@ -5,19 +5,17 @@ namespace Renci.SshClient.Messages.Sftp
{
internal class Attributes
{
public UInt32 Flag { get; set; }
public ulong? Size { get; set; }
public ulong Size { get; set; }
public uint? UserId { get; set; }
public uint UserId { get; set; }
public uint? GroupId { get; set; }
public uint GroupId { get; set; }
public uint? Permissions { get; set; }
public uint Permissions { get; set; }
public DateTime? AccessTime { get; set; }
public DateTime AccessTime { get; set; }
public DateTime ModifyTime { get; set; }
public DateTime? ModifyTime { get; set; }
public IDictionary<string, string> Extentions { get; set; }
}
@@ -72,33 +72,27 @@ namespace Renci.SshClient.Messages.Sftp
protected Attributes ReadAttributes()
{
var attributes = new Attributes();
attributes.Flag = this.ReadUInt32();
var isSize = (attributes.Flag & 0x00000001) == 0x00000001; //SSH_FILEXFER_ATTR_SIZE 0x00000001
var isUidGid = (attributes.Flag & 0x00000002) == 0x00000002; //SSH_FILEXFER_ATTR_UIDGID 0x00000002
var isPermissions = (attributes.Flag & 0x00000004) == 0x00000004; //SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
var isAccessModifyTime = (attributes.Flag & 0x00000008) == 0x00000008; //SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
var flag = this.ReadUInt32();
var isExtended = (attributes.Flag & 0x80000000) == 0x80000000; //SSH_FILEXFER_ATTR_EXTENDED 0x80000000
if (isSize)
if ((flag & 0x00000001) == 0x00000001) // SSH_FILEXFER_ATTR_SIZE
{
attributes.Size = this.ReadUInt64();
}
if (isUidGid)
if ((flag & 0x00000002) == 0x00000002) // SSH_FILEXFER_ATTR_UIDGID
{
attributes.UserId = this.ReadUInt32();
attributes.GroupId = this.ReadUInt32();
}
if (isPermissions)
if ((flag & 0x00000004) == 0x00000004) // SSH_FILEXFER_ATTR_PERMISSIONS
{
attributes.Permissions = this.ReadUInt32();
}
if (isAccessModifyTime)
if ((flag & 0x00000008) == 0x00000008) // SSH_FILEXFER_ATTR_ACMODTIME
{
var time = this.ReadUInt32();
attributes.AccessTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
@@ -106,7 +100,7 @@ namespace Renci.SshClient.Messages.Sftp
attributes.ModifyTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
}
if (isExtended)
if ((flag & 0x80000000) == 0x80000000) // SSH_FILEXFER_ATTR_ACMODTIME
{
var extendedCount = this.ReadUInt32();
attributes.Extentions = this.ReadExtensionPair();
@@ -117,7 +111,6 @@ namespace Renci.SshClient.Messages.Sftp
protected void Write(Attributes attributes)
{
// TODO: Complete attribute serialization, at this point we pass no attributes
if (attributes == null)
{
this.Write((uint)0);
@@ -125,42 +118,60 @@ namespace Renci.SshClient.Messages.Sftp
}
else
{
// TODO: Need to be tested
throw new NotImplementedException();
UInt32 flag = 0;
var isSize = (attributes.Flag & 0x00000001) == 0x00000001; //SSH_FILEXFER_ATTR_SIZE 0x00000001
var isUidGid = (attributes.Flag & 0x00000002) == 0x00000002; //SSH_FILEXFER_ATTR_UIDGID 0x00000002
var isPermissions = (attributes.Flag & 0x00000004) == 0x00000004; //SSH_FILEXFER_ATTR_PERMISSIONS 0x00000004
var isAccessModifyTime = (attributes.Flag & 0x00000008) == 0x00000008; //SSH_FILEXFER_ATTR_ACMODTIME 0x00000008
var isExtended = (attributes.Flag & 0x80000000) == 0x80000000; //SSH_FILEXFER_ATTR_EXTENDED 0x80000000
if (isSize)
if (attributes.Size.HasValue)
{
this.Write(attributes.Size);
flag |= 0x00000001;
}
if (isUidGid)
if (attributes.UserId.HasValue && attributes.GroupId.HasValue)
{
this.Write(attributes.UserId);
this.Write(attributes.GroupId);
flag |= 0x00000002;
}
if (isPermissions)
if (attributes.Permissions.HasValue)
{
this.Write(attributes.Permissions);
flag |= 0x00000004;
}
if (isAccessModifyTime)
if (attributes.AccessTime.HasValue && attributes.ModifyTime.HasValue)
{
uint time = (uint)(attributes.AccessTime.ToFileTime() - 11644473600) / 10000000;
flag |= 0x00000008;
}
if (attributes.Extentions != null)
{
flag |= 0x80000000;
}
this.Write(flag);
if (attributes.Size.HasValue)
{
this.Write(attributes.Size.Value);
}
if (attributes.UserId.HasValue && attributes.GroupId.HasValue)
{
this.Write(attributes.UserId.Value);
this.Write(attributes.GroupId.Value);
}
if (attributes.Permissions.HasValue)
{
this.Write(attributes.Permissions.Value);
}
if (attributes.AccessTime.HasValue && attributes.ModifyTime.HasValue)
{
uint time = (uint)(attributes.AccessTime.Value.ToFileTime() / 10000000 - 11644473600);
this.Write(time);
time = (uint)(attributes.ModifyTime.ToFileTime() - 11644473600) / 10000000;
time = (uint)(attributes.ModifyTime.Value.ToFileTime() / 10000000 - 11644473600);
this.Write(time);
}
if (isExtended)
if (attributes.Extentions != null)
{
this.Write(attributes.Extentions);
}
@@ -47,21 +47,17 @@
this.ErrorMessage = this.ReadString();
this.Language = this.ReadString();
}
// TODO: Load error specific data
}
protected override void SaveData()
{
base.SaveData();
this.Write((uint)this.StatusCode);
if (this.StatusCode == StatusCodes.Ok)
if (!string.IsNullOrEmpty(this.ErrorMessage))
{
// No more data need to be written
return;
this.Write(this.ErrorMessage);
this.Write(this.Language);
}
this.Write(this.ErrorMessage);
this.Write(this.Language);
// TODO: Save error specific data
}
}
}