Fix handling of SftpFileAttributes

Now only attributes that changed will be updated
Fix error with changing permission for directory
This commit is contained in:
olegkap_cp
2012-12-28 01:01:05 +00:00
parent c9ae7f44fd
commit cd3b0ca17a
4 changed files with 64 additions and 30 deletions
@@ -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<SftpStatusResponse> statusAction)
@@ -20,7 +20,7 @@ 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, SftpFileAttributes.Empty, handleAction, statusAction)
: this(requestId, fileName, flags, new SftpFileAttributes(), handleAction, statusAction)
{
}
@@ -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<string, string> _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); }
}
/// <summary>
/// Gets or sets the time the current file or directory was last accessed.
/// </summary>
@@ -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);
/// <summary>
/// Gets the empty SftpFileAttributes instance.
/// </summary>
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<string, string> 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;
}
/// <summary>
@@ -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);
@@ -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);
}