diff --git a/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpMkDirRequest.cs b/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpMkDirRequest.cs index 9e3b6d09..567f2ad3 100644 --- a/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpMkDirRequest.cs +++ b/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpMkDirRequest.cs @@ -21,7 +21,7 @@ namespace Renci.SshNet.Sftp.Requests : base(requestId, statusAction) { this.Path = path; - this.Attributes = SftpFileAttributes.Empty; + this.Attributes = new SftpFileAttributes(); } public SftpMkDirRequest(uint requestId, string path, SftpFileAttributes attributes, Action statusAction) diff --git a/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpOpenRequest.cs b/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpOpenRequest.cs index b8fc5d61..63e63116 100644 --- a/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpOpenRequest.cs +++ b/Renci.SshClient/Renci.SshNet/Sftp/Requests/SftpOpenRequest.cs @@ -20,7 +20,7 @@ namespace Renci.SshNet.Sftp.Requests public SftpFileAttributes Attributes { get; private set; } public SftpOpenRequest(uint requestId, string fileName, Flags flags, Action handleAction, Action statusAction) - : this(requestId, fileName, flags, SftpFileAttributes.Empty, handleAction, statusAction) + : this(requestId, fileName, flags, new SftpFileAttributes(), handleAction, statusAction) { } diff --git a/Renci.SshClient/Renci.SshNet/Sftp/SftpFileAttributes.cs b/Renci.SshClient/Renci.SshNet/Sftp/SftpFileAttributes.cs index 87556a99..f485608f 100644 --- a/Renci.SshClient/Renci.SshNet/Sftp/SftpFileAttributes.cs +++ b/Renci.SshClient/Renci.SshNet/Sftp/SftpFileAttributes.cs @@ -60,6 +60,49 @@ namespace Renci.SshNet.Sftp private bool _isGroupIDBitSet; private bool _isStickyBitSet; + private DateTime _originalLastAccessTime; + private DateTime _originalLastWriteTime; + private long _originalSize; + private int _originalUserId; + private int _originalGroupId; + private uint _originalPermissions; + private IDictionary _originalExtensions; + + internal bool IsLastAccessTimeChanged + { + get { return this._originalLastAccessTime != this.LastAccessTime; } + } + + internal bool IsLastWriteTimeChanged + { + get { return this._originalLastWriteTime != this.LastWriteTime; } + } + + internal bool IsSizeChanged + { + get { return this._originalSize != this.Size; } + } + + internal bool IsUserIdChanged + { + get { return this._originalUserId != this.UserId; } + } + + internal bool IsGroupIdChanged + { + get { return this._originalGroupId != this.GroupId; } + } + + internal bool IsPermissionsChanged + { + get { return this._originalPermissions != this.Permissions; } + } + + internal bool IsExtensionsChanged + { + get { return this._originalExtensions != null && this.Extensions != null && !this._originalExtensions.SequenceEqual(this.Extensions); } + } + /// /// Gets or sets the time the current file or directory was last accessed. /// @@ -304,7 +347,6 @@ namespace Renci.SshNet.Sftp return permission; } - private set { this._isBitFiledsBitSet = ((value & S_IFMT) == S_IFMT); @@ -349,27 +391,19 @@ namespace Renci.SshNet.Sftp } } - private static SftpFileAttributes _empty = new SftpFileAttributes(DateTime.MinValue, DateTime.MinValue, -1, -1, -1, 0, null); - /// - /// Gets the empty SftpFileAttributes instance. - /// - public static SftpFileAttributes Empty + internal SftpFileAttributes() { - get - { - return SftpFileAttributes._empty; - } } internal SftpFileAttributes(DateTime lastAccessTime, DateTime lastWriteTime, long size, int userId, int groupId, uint permissions, IDictionary extensions) { - this.LastAccessTime = lastAccessTime; - this.LastWriteTime = lastWriteTime; - this.Size = size; - this.UserId = userId; - this.GroupId = groupId; - this.Permissions = permissions; - this.Extensions = extensions; + this.LastAccessTime = this._originalLastAccessTime = lastAccessTime; + this.LastWriteTime = this._originalLastWriteTime = lastWriteTime; + this.Size = this._originalSize = size; + this.UserId = this._originalUserId = userId; + this.GroupId = this._originalGroupId = groupId; + this.Permissions = this._originalPermissions = permissions; + this.Extensions = this._originalExtensions = extensions; } /// @@ -383,7 +417,7 @@ namespace Renci.SshNet.Sftp throw new ArgumentOutOfRangeException("mode"); } - var modeBytes = mode.ToString(CultureInfo.InvariantCulture).PadLeft(3,'0').ToArray(); + var modeBytes = mode.ToString(CultureInfo.InvariantCulture).PadLeft(3, '0').ToArray(); var permission = (modeBytes[0] & 0x0F) * 8 * 8 + (modeBytes[1] & 0x0F) * 8 + (modeBytes[2] & 0x0F); diff --git a/Renci.SshClient/Renci.SshNet/Sftp/SftpMessage.cs b/Renci.SshClient/Renci.SshNet/Sftp/SftpMessage.cs index dfaf20dd..522dc073 100644 --- a/Renci.SshClient/Renci.SshNet/Sftp/SftpMessage.cs +++ b/Renci.SshClient/Renci.SshNet/Sftp/SftpMessage.cs @@ -94,50 +94,50 @@ namespace Renci.SshNet.Sftp { UInt32 flag = 0; - if (attributes.Size > -1) + if (attributes.IsSizeChanged && attributes.IsRegularFile) { flag |= 0x00000001; } - if (attributes.UserId > -1 && attributes.GroupId > -1) + if (attributes.IsUserIdChanged|| attributes.IsGroupIdChanged) { flag |= 0x00000002; } - if (attributes.Permissions > 0) + if (attributes.IsPermissionsChanged) { flag |= 0x00000004; } - if (attributes.LastAccessTime > DateTime.MinValue && attributes.LastWriteTime > DateTime.MinValue) + if (attributes.IsLastAccessTimeChanged || attributes.IsLastWriteTimeChanged) { flag |= 0x00000008; } - if (attributes.Extensions != null) + if (attributes.IsExtensionsChanged) { flag |= 0x80000000; } this.Write(flag); - if (attributes.Size > -1) + if (attributes.IsSizeChanged && attributes.IsRegularFile) { this.Write((UInt64)attributes.Size); } - if (attributes.UserId > -1 && attributes.GroupId > -1) + if (attributes.IsUserIdChanged|| attributes.IsGroupIdChanged) { this.Write((UInt32)attributes.UserId); this.Write((UInt32)attributes.GroupId); } - if (attributes.Permissions > 0) + if (attributes.IsPermissionsChanged) { this.Write(attributes.Permissions); } - if (attributes.LastAccessTime > DateTime.MinValue && attributes.LastWriteTime > DateTime.MinValue) + if (attributes.IsLastAccessTimeChanged || attributes.IsLastWriteTimeChanged) { uint time = (uint)(attributes.LastAccessTime.ToFileTime() / 10000000 - 11644473600); this.Write(time); @@ -145,7 +145,7 @@ namespace Renci.SshNet.Sftp this.Write(time); } - if (attributes.Extensions != null) + if (attributes.IsExtensionsChanged) { this.Write(attributes.Extensions); }