Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public class BaseClientTest_Disconnected_KeepAliveInterval_NotNegativeOne
private BaseClient _client;
private ConnectionInfo _connectionInfo;
private TimeSpan _keepAliveInterval;
private int _keepAliveCount;

[TestInitialize]
public void Setup()
Expand All @@ -38,7 +37,6 @@ private void SetupData()
{
_connectionInfo = new ConnectionInfo("host", "user", new PasswordAuthenticationMethod("user", "pwd"));
_keepAliveInterval = TimeSpan.FromMilliseconds(50d);
_keepAliveCount = 0;
}

private void CreateMocks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public class ClientAuthenticationTest_Success_MultiList_PartialSuccessLimitReach
{
private int _partialSuccessLimit;
private ClientAuthentication _clientAuthentication;
private SshAuthenticationException _actualException;

protected override void SetupData()
{
Expand Down Expand Up @@ -182,4 +181,4 @@ public void AuthenticateOnPublicKeyAuthenticationMethodShouldHaveBeenInvokedTwic
PublicKeyAuthenticationMethodMock.Verify(p => p.Authenticate(SessionMock.Object), Times.Exactly(2));
}
}
}
}
2 changes: 2 additions & 0 deletions src/Renci.SshNet.Tests/Classes/Common/BigIntegerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1506,10 +1506,12 @@ public void DefaultCtorWorks()
Assert.AreEqual("0", a.ToString(), "#4");

a = new BigInteger();
#pragma warning disable CS1718 // Comparison made to same variable
Assert.AreEqual(true, a == a, "#5");

a = new BigInteger();
Assert.AreEqual(false, a < a, "#6");
#pragma warning restore CS1718 // Comparison made to same variable

a = new BigInteger();
Assert.AreEqual(true, a < 10L, "#7");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void ChannelExtendedDataMessageConstructorTest()
[Ignore] // placeholder
public void ChannelExtendedDataMessageConstructorTest1()
{
uint localChannelNumber = 0; // TODO: Initialize to an appropriate value
//uint localChannelNumber = 0; // TODO: Initialize to an appropriate value
//ChannelExtendedDataMessage target = new ChannelExtendedDataMessage(localChannelNumber, null, null);
Assert.Inconclusive("TODO: Implement code to verify target");
}
Expand Down
10 changes: 9 additions & 1 deletion src/Renci.SshNet.Tests/Classes/SftpClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,9 @@ public void SetLastAccessTimeTest()
SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value
string path = string.Empty; // TODO: Initialize to an appropriate value
DateTime lastAccessTime = new DateTime(); // TODO: Initialize to an appropriate value
#pragma warning disable CS0618 // Type or member is obsolete
target.SetLastAccessTime(path, lastAccessTime);
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Inconclusive("A method that does not return a value cannot be verified.");
}

Expand All @@ -957,7 +959,9 @@ public void SetLastAccessTimeUtcTest()
SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value
string path = string.Empty; // TODO: Initialize to an appropriate value
DateTime lastAccessTimeUtc = new DateTime(); // TODO: Initialize to an appropriate value
#pragma warning disable CS0618 // Type or member is obsolete
target.SetLastAccessTimeUtc(path, lastAccessTimeUtc);
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Inconclusive("A method that does not return a value cannot be verified.");
}

Expand All @@ -972,7 +976,9 @@ public void SetLastWriteTimeTest()
SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value
string path = string.Empty; // TODO: Initialize to an appropriate value
DateTime lastWriteTime = new DateTime(); // TODO: Initialize to an appropriate value
#pragma warning disable CS0618 // Type or member is obsolete
target.SetLastWriteTime(path, lastWriteTime);
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Inconclusive("A method that does not return a value cannot be verified.");
}

Expand All @@ -987,7 +993,9 @@ public void SetLastWriteTimeUtcTest()
SftpClient target = new SftpClient(connectionInfo); // TODO: Initialize to an appropriate value
string path = string.Empty; // TODO: Initialize to an appropriate value
DateTime lastWriteTimeUtc = new DateTime(); // TODO: Initialize to an appropriate value
#pragma warning disable CS0618 // Type or member is obsolete
target.SetLastWriteTimeUtc(path, lastWriteTimeUtc);
#pragma warning restore CS0618 // Type or member is obsolete
Assert.Inconclusive("A method that does not return a value cannot be verified.");
}

Expand Down Expand Up @@ -1269,4 +1277,4 @@ private class TestInfo
public SftpDownloadAsyncResult DownloadResult { get; set; }
}
}
}
}
8 changes: 4 additions & 4 deletions src/Renci.SshNet/Sftp/SftpFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ public DateTime LastAccessTimeUtc
{
get
{
return Attributes.LastAccessTime.ToUniversalTime();
return Attributes.LastAccessTimeUtc;
}
set
{
Attributes.LastAccessTime = value.ToLocalTime();
Attributes.LastAccessTimeUtc = value;
}
}

Expand All @@ -117,11 +117,11 @@ public DateTime LastWriteTimeUtc
{
get
{
return Attributes.LastWriteTime.ToUniversalTime();
return Attributes.LastWriteTimeUtc;
}
set
{
Attributes.LastWriteTime = value.ToLocalTime();
Attributes.LastWriteTimeUtc = value;
}
}

Expand Down
106 changes: 89 additions & 17 deletions src/Renci.SshNet/Sftp/SftpFileAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Renci.SshNet.Sftp
/// </summary>
public class SftpFileAttributes
{
#region Bitmask constats
#region Bitmask constants

private const uint S_IFMT = 0xF000; // bitmask for the file type bitfields

Expand Down Expand Up @@ -60,8 +60,8 @@ public class SftpFileAttributes
private bool _isGroupIDBitSet;
private bool _isStickyBitSet;

private readonly DateTime _originalLastAccessTime;
private readonly DateTime _originalLastWriteTime;
private readonly DateTime _originalLastAccessTimeUtc;
private readonly DateTime _originalLastWriteTimeUtc;
private readonly long _originalSize;
private readonly int _originalUserId;
private readonly int _originalGroupId;
Expand All @@ -70,12 +70,12 @@ public class SftpFileAttributes

internal bool IsLastAccessTimeChanged
{
get { return _originalLastAccessTime != LastAccessTime; }
get { return _originalLastAccessTimeUtc != LastAccessTimeUtc; }
}

internal bool IsLastWriteTimeChanged
{
get { return _originalLastWriteTime != LastWriteTime; }
get { return _originalLastWriteTimeUtc != LastWriteTimeUtc; }
}

internal bool IsSizeChanged
Expand Down Expand Up @@ -104,20 +104,58 @@ internal bool IsExtensionsChanged
}

/// <summary>
/// Gets or sets the time the current file or directory was last accessed.
/// Gets or sets the local time the current file or directory was last accessed.
/// </summary>
/// <value>
/// The time that the current file or directory was last accessed.
/// The local time that the current file or directory was last accessed.
/// </value>
public DateTime LastAccessTime { get; set; }
public DateTime LastAccessTime
{
get
{
return ToLocalTime(this.LastAccessTimeUtc);
}

set
{
this.LastAccessTimeUtc = ToUniversalTime(value);
}
}

/// <summary>
/// Gets or sets the local time when the current file or directory was last written to.
/// </summary>
/// <value>
/// The local time the current file was last written.
/// </value>
public DateTime LastWriteTime
{
get
{
return ToLocalTime(this.LastWriteTimeUtc);
}

set
{
this.LastWriteTimeUtc = ToUniversalTime(value);
}
}

/// <summary>
/// Gets or sets the UTC time the current file or directory was last accessed.
/// </summary>
/// <value>
/// The UTC time that the current file or directory was last accessed.
/// </value>
public DateTime LastAccessTimeUtc { get; set; }

/// <summary>
/// Gets or sets the time when the current file or directory was last written to.
/// Gets or sets the UTC time when the current file or directory was last written to.
/// </summary>
/// <value>
/// The time the current file was last written.
/// The UTC time the current file was last written.
/// </value>
public DateTime LastWriteTime { get; set; }
public DateTime LastWriteTimeUtc { get; set; }

/// <summary>
/// Gets or sets the size, in bytes, of the current file.
Expand Down Expand Up @@ -397,8 +435,8 @@ private SftpFileAttributes()

internal SftpFileAttributes(DateTime lastAccessTime, DateTime lastWriteTime, long size, int userId, int groupId, uint permissions, IDictionary<string, string> extensions)
{
LastAccessTime = _originalLastAccessTime = lastAccessTime;
LastWriteTime = _originalLastWriteTime = lastWriteTime;
LastAccessTimeUtc = _originalLastAccessTimeUtc = ToUniversalTime(lastAccessTime);
LastWriteTimeUtc = _originalLastWriteTimeUtc = ToUniversalTime(lastWriteTime);
Size = _originalSize = size;
UserId = _originalUserId = userId;
GroupId = _originalGroupId = groupId;
Expand Down Expand Up @@ -491,9 +529,9 @@ public byte[] GetBytes()

if (IsLastAccessTimeChanged || IsLastWriteTimeChanged)
{
var time = (uint)(LastAccessTime.ToFileTime() / 10000000 - 11644473600);
var time = (uint)(LastAccessTimeUtc.ToFileTimeUtc() / 10000000 - 11644473600);
stream.Write(time);
time = (uint)(LastWriteTime.ToFileTime() / 10000000 - 11644473600);
time = (uint)(LastWriteTimeUtc.ToFileTimeUtc() / 10000000 - 11644473600);
stream.Write(time);
}

Expand Down Expand Up @@ -544,10 +582,12 @@ internal static SftpFileAttributes FromBytes(SshDataStream stream)

if ((flag & 0x00000008) == 0x00000008) // SSH_FILEXFER_ATTR_ACMODTIME
{
// The incoming times are "Unix times", so they're already in UTC. We need to preserve that
// to avoid losing information in a local time conversion during the "fall back" hour in DST.
var time = stream.ReadUInt32();
accessTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
accessTime = DateTime.FromFileTimeUtc((time + 11644473600) * 10000000);
time = stream.ReadUInt32();
modifyTime = DateTime.FromFileTime((time + 11644473600) * 10000000);
modifyTime = DateTime.FromFileTimeUtc((time + 11644473600) * 10000000);
}

if ((flag & 0x80000000) == 0x80000000) // SSH_FILEXFER_ATTR_EXTENDED
Expand All @@ -572,5 +612,37 @@ internal static SftpFileAttributes FromBytes(byte[] buffer)
return FromBytes(stream);
}
}

internal static DateTime ToLocalTime(DateTime value)
{
DateTime result;

if (value == DateTime.MinValue)
{
result = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Local);
}
else
{
result = value.ToLocalTime();
}

return result;
}

internal static DateTime ToUniversalTime(DateTime value)
{
DateTime result;

if (value == DateTime.MinValue)
{
result = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc);
}
else
{
result = value.ToUniversalTime();
}

return result;
}
}
}