Reduce partial methods/classes and streamline API surface across target frameworks

* Make Extensions.DebugPrint(this IEnumerable<byte>) available on all
target frameworks.
* Moved the following extension methods from Extensions.<target
framework>.cs to Extensions.cs:
- IsNullOrWhiteSpace(this string)
- CanRead(this Socket)
- CanWrite(this Socket)
* Removed GetIPAddress(this string) from Extensions.cs, and use
DnsAbstraction.GetHostAddresses(string) instead.
* Make ForwardedPortRemote(uint boundPort, string host, uint port) and
ForwardedPortRemote(string boundHost, uint boundPort, string host, uint
port) constructors available on all target frameworks.
* Eliminated SendData(IChannelSession channel, string command) partial
method from ScpClient.cs.

* Make the following methods on SftpClient available on all target
frameworks:
- SynchronizeDirectories(string, string, string)
- BeginSynchronizeDirectories(string, string, string, AsyncCallback,
object)
- EndSynchronizeDirectories(IAsyncResult)
* Make DnsAbstraction.GetHostAddresses(string) available on all target
frameworks.
* Added SocketAbstraction class.
This commit is contained in:
Gert Driesen
2016-04-04 14:37:09 +02:00
parent 7a8135fd0c
commit b5c7066bde
34 changed files with 361 additions and 542 deletions
@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
@@ -18,7 +18,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<DefineConstants>TRACE;DEBUG;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -26,7 +26,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<DefineConstants>TRACE;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
@@ -53,6 +53,9 @@
<Compile Include="..\Renci.SshNet\Abstractions\ReflectionAbstraction.cs">
<Link>Abstractions\ReflectionAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\SocketAbstraction.cs">
<Link>Abstractions\SocketAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ThreadAbstraction.cs">
<Link>Abstractions\ThreadAbstraction.cs</Link>
</Compile>
@@ -161,9 +164,6 @@
<Compile Include="..\Renci.SshNet\Common\Extensions.cs">
<Link>Common\Extensions.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Common\Extensions.NET.cs">
<Link>Common\Extensions.NET.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Common\HostKeyEventArgs.cs">
<Link>Common\HostKeyEventArgs.cs</Link>
</Compile>
@@ -296,9 +296,6 @@
<Compile Include="..\Renci.SshNet\ForwardedPortRemote.cs">
<Link>ForwardedPortRemote.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\ForwardedPortRemote.NET.cs">
<Link>ForwardedPortRemote.NET.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\HashInfo.cs">
<Link>HashInfo.cs</Link>
</Compile>
@@ -749,9 +746,6 @@
<Compile Include="..\Renci.SshNet\SftpClient.cs">
<Link>SftpClient.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\SftpClient.NET.cs">
<Link>SftpClient.NET.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Sftp\Flags.cs">
<Link>Sftp\Flags.cs</Link>
</Compile>
@@ -942,7 +936,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -46,6 +46,8 @@ namespace Renci.SshNet.Channels
}
break;
} while (receivedTotal < bytesToRead);
read = receivedTotal;
}
partial void InternalSocketSend(byte[] data)
@@ -1,10 +1,8 @@
using System;
using System.Linq;
using System.Net.Sockets;
using System.Threading;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Net;
namespace Renci.SshNet.Common
{
@@ -13,20 +11,6 @@ namespace Renci.SshNet.Common
/// </summary>
internal static partial class Extensions
{
/// <summary>
/// Determines whether [is null or white space] [the specified value].
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// <c>true</c> if [is null or white space] [the specified value]; otherwise, <c>false</c>.
/// </returns>
internal static bool IsNullOrWhiteSpace(this string value)
{
if (string.IsNullOrEmpty(value)) return true;
return value.All(char.IsWhiteSpace);
}
/// <summary>
/// Disposes the specified socket.
/// </summary>
@@ -65,25 +49,5 @@ namespace Renci.SshNet.Common
algorithm.Clear();
}
internal static bool CanRead(this Socket socket)
{
return socket.Connected;
}
internal static bool CanWrite(this Socket socket)
{
return socket.Connected;
}
internal static IPAddress GetIPAddress(this string host)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(host, out ipAddress))
{
throw new ProxyException("Silverlight supports only IP addresses.");
}
return ipAddress;
}
}
}
@@ -1,16 +0,0 @@
using System;
using System.Threading;
namespace Renci.SshNet
{
/// <summary>
/// Provides functionality for remote port forwarding
/// </summary>
public partial class ForwardedPortRemote
{
partial void ExecuteThread(Action action)
{
ThreadPool.QueueUserWorkItem(o => action());
}
}
}
@@ -1,14 +0,0 @@
using System;
using System.Net;
using System.Threading;
namespace Renci.SshNet
{
public partial class KeyboardInteractiveAuthenticationMethod
{
partial void ExecuteThread(Action action)
{
ThreadPool.QueueUserWorkItem((o) => { action(); });
}
}
}
@@ -1,13 +0,0 @@
using System;
using System.Threading;
namespace Renci.SshNet
{
public partial class PasswordAuthenticationMethod
{
partial void ExecuteThread(Action action)
{
ThreadPool.QueueUserWorkItem((o) => { action(); });
}
}
}
@@ -29,7 +29,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Bin\Debug</OutputPath>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;TUNING;FEATURE_HASH_SHA1;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -40,7 +40,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>Bin\Release</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT;TUNING;FEATURE_HASH_SHA1;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
<DefineConstants>TRACE;SILVERLIGHT;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -67,6 +67,18 @@
<Reference Include="System.Net" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Renci.SshNet\Abstractions\DnsAbstraction.cs">
<Link>Abstractions\DnsAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ReflectionAbstraction.cs">
<Link>Abstractions\ReflectionAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\SocketAbstraction.cs">
<Link>Abstractions\SocketAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ThreadAbstraction.cs">
<Link>Abstractions\ThreadAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\AuthenticationMethod.cs">
<Link>AuthenticationMethod.cs</Link>
</Compile>
@@ -867,21 +879,13 @@
</Compile>
<Compile Include="Channels\ChannelDirectTcpip.SilverlightShared.cs" />
<Compile Include="Common\Extensions.SilverlightShared.cs" />
<Compile Include="Shell.SilverlightShared.cs" />
<Compile Include="ShellStream.SilverlightShared.cs" />
<Compile Include="ForwardedPortLocal.SilverlightShared.cs" />
<Compile Include="ForwardedPortRemote.SilverlightShared.cs" />
<Compile Include="KeyboardInteractiveAuthenticationMethod.SilverlightShared.cs" />
<Compile Include="PasswordAuthenticationMethod.SilverlightShared.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\Renci.SshNet\Properties\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="ScpClient.SilverlightShared.cs" />
<Compile Include="Session.SilverlightBrowser.cs" />
<Compile Include="Session.SilverlightShared.cs" />
<Compile Include="SftpClient.SilverlightShared.cs" />
<Compile Include="SshCommand.SilverlightShared.cs" />
</ItemGroup>
<ItemGroup>
<None Include="..\Renci.SshNet.snk">
@@ -895,7 +899,7 @@
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties />
</FlavorProperties>
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -1,16 +0,0 @@
using System.Text;
using Renci.SshNet.Channels;
namespace Renci.SshNet
{
/// <summary>
/// Provides SCP client functionality.
/// </summary>
public partial class ScpClient
{
partial void SendData(IChannelSession channel, string command)
{
channel.SendData(Encoding.UTF8.GetBytes(command));
}
}
}
@@ -5,6 +5,7 @@ using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Renci.SshNet.Abstractions;
using Renci.SshNet.Common;
using Renci.SshNet.Messages.Transport;
@@ -39,7 +40,7 @@ namespace Renci.SshNet
partial void SocketConnect(string host, int port)
{
var timeout = ConnectionInfo.Timeout;
var ipAddress = host.GetIPAddress();
var ipAddress = DnsAbstraction.GetHostAddresses(host)[0];
var ep = new IPEndPoint(ipAddress, port);
_socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
@@ -1,16 +0,0 @@
using System;
using System.Threading;
namespace Renci.SshNet
{
/// <summary>
///
/// </summary>
public partial class SftpClient
{
partial void ExecuteThread(Action action)
{
ThreadPool.QueueUserWorkItem(o => action());
}
}
}
@@ -1,16 +0,0 @@
using System;
using System.Threading;
namespace Renci.SshNet
{
/// <summary>
///
/// </summary>
public partial class Shell
{
partial void ExecuteThread(Action action)
{
ThreadPool.QueueUserWorkItem(o => action());
}
}
}
@@ -1,16 +0,0 @@
using System;
using System.Threading;
namespace Renci.SshNet
{
/// <summary>
///
/// </summary>
public partial class ShellStream
{
partial void ExecuteThread(Action action)
{
ThreadPool.QueueUserWorkItem(o => action());
}
}
}
@@ -1,16 +0,0 @@
using System;
using System.Threading;
namespace Renci.SshNet
{
/// <summary>
/// Represents SSH command that can be executed.
/// </summary>
public partial class SshCommand
{
partial void ExecuteThread(Action action)
{
ThreadPool.QueueUserWorkItem(o => action());
}
}
}
@@ -29,7 +29,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Bin\Debug</OutputPath>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_DNS_SYNC;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -41,7 +41,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>Bin\Release</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_DNS_SYNC;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<DefineConstants>TRACE;SILVERLIGHT;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_POLL;FEATURE_DNS_SYNC;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -75,18 +75,21 @@
<Compile Include="..\Renci.SshNet.Silverlight\ForwardedPortLocal.SilverlightShared.cs">
<Link>ForwardedPortLocal.SilverlightShared.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\ScpClient.SilverlightShared.cs">
<Link>ScpClient.SilverlightShared.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\Session.SilverlightBrowser.cs">
<Link>Session.SilverlightBrowser.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\Session.SilverlightShared.cs">
<Link>Session.SilverlightShared.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\DnsAbstraction.cs">
<Link>Abstractions\DnsAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ReflectionAbstraction.cs">
<Link>Abstractions\ReflectionAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\SocketAbstraction.cs">
<Link>Abstractions\SocketAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ThreadAbstraction.cs">
<Link>Abstractions\ThreadAbstraction.cs</Link>
</Compile>
@@ -908,7 +911,7 @@
<FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
<SilverlightProjectProperties />
</FlavorProperties>
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -24,7 +24,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Bin\Debug</OutputPath>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;WINDOWS_PHONE;TUNING;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
<DefineConstants>TRACE;DEBUG;WINDOWS_PHONE;TUNING;FEATURE_RNG_CSP;FEATURE_STREAM_APM;FEATURE_DEVICEINFORMATION_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -35,7 +35,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>Bin\Release</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE;TUNING;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
<DefineConstants>TRACE;WINDOWS_PHONE;TUNING;FEATURE_RNG_CSP;FEATURE_STREAM_APM;FEATURE_DEVICEINFORMATION_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -44,6 +44,7 @@
<NoWarn>1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Phone" />
<Reference Include="Renci.Security.Cryptography, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Renci.Security.Cryptography.1.0.0\lib\wp71\Renci.Security.Cryptography.dll</HintPath>
<Private>True</Private>
@@ -52,6 +53,18 @@
<Reference Include="System.Net" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Renci.SshNet\Abstractions\DnsAbstraction.cs">
<Link>Abstractions\DnsAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ReflectionAbstraction.cs">
<Link>Abstractions\ReflectionAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\SocketAbstraction.cs">
<Link>Abstractions\SocketAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ThreadAbstraction.cs">
<Link>Abstractions\ThreadAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\AuthenticationMethod.cs">
<Link>AuthenticationMethod.cs</Link>
</Compile>
@@ -280,9 +293,6 @@
<Compile Include="..\Renci.SshNet\KeyboardInteractiveAuthenticationMethod.cs">
<Link>KeyboardInteractiveAuthenticationMethod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\KeyboardInteractiveAuthenticationMethod.SilverlightShared.cs">
<Link>PasswordAuthenticationMethod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\KeyboardInteractiveConnectionInfo.cs">
<Link>KeyboardInteractiveConnectionInfo.cs</Link>
</Compile>
@@ -508,9 +518,6 @@
<Compile Include="..\Renci.SshNet\PasswordAuthenticationMethod.cs">
<Link>PasswordAuthenticationMethod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\PasswordAuthenticationMethod.SilverlightShared.cs">
<Link>PasswordAuthenticationMethod.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\PasswordConnectionInfo.cs">
<Link>PasswordConnectionInfo.cs</Link>
</Compile>
@@ -529,9 +536,6 @@
<Compile Include="..\Renci.SshNet\ScpClient.cs">
<Link>ScpClient.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\ScpClient.SilverlightShared.cs">
<Link>ScpClient.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Algorithm.cs">
<Link>Security\Algorithm.cs</Link>
</Compile>
@@ -691,9 +695,6 @@
<Compile Include="..\Renci.SshNet\SftpClient.cs">
<Link>SftpClient.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\SftpClient.SilverlightShared.cs">
<Link>Session.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Sftp\Flags.cs">
<Link>Sftp\Flags.cs</Link>
</Compile>
@@ -841,6 +842,9 @@
<Compile Include="..\Renci.SshNet\Sftp\SftpSession.cs">
<Link>Sftp\SftpSession.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Sftp\SftpSynchronizeDirectoriesAsyncResult.cs">
<Link>Sftp\SftpSynchronizeDirectoriesAsyncResult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Sftp\SftpUploadAsyncResult.cs">
<Link>Sftp\SftpUploadAsyncResult.cs</Link>
</Compile>
@@ -850,24 +854,15 @@
<Compile Include="..\Renci.SshNet\Shell.cs">
<Link>Shell.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\Shell.SilverlightShared.cs">
<Link>Shell.SilverlightShared.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\ShellStream.cs">
<Link>ShellStream.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\ShellStream.SilverlightShared.cs">
<Link>ShellStream.SilverlightShared.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\SshClient.cs">
<Link>SshClient.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\SshCommand.cs">
<Link>SshCommand.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\SshCommand.SilverlightShared.cs">
<Link>SshCommand.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\SubsystemSession.cs">
<Link>SubsystemSession.cs</Link>
</Compile>
@@ -1,20 +0,0 @@
using System;
namespace Renci.SshNet
{
/// <summary>
/// Provides functionality for local port forwarding
/// </summary>
public partial class ForwardedPortLocal
{
partial void InternalStart()
{
throw new NotImplementedException();
}
partial void InternalStop(TimeSpan timeout)
{
throw new NotImplementedException();
}
}
}
@@ -23,7 +23,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>Bin\Debug</OutputPath>
<DefineConstants>TRACE;DEBUG;SILVERLIGHT;WINDOWS_PHONE;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_DNS_SYNC;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<DefineConstants>TRACE;DEBUG;WINDOWS_PHONE;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_STREAM_APM;FEATURE_DEVICEINFORMATION_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -35,7 +35,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>Bin\Release</OutputPath>
<DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_DNS_SYNC;FEATURE_STREAM_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<DefineConstants>TRACE;SILVERLIGHT;WINDOWS_PHONE;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DEVICEINFORMATION_APM;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_MEMORYSTREAM_GETBUFFER;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;</DefineConstants>
<NoStdLib>true</NoStdLib>
<NoConfig>true</NoConfig>
<ErrorReport>prompt</ErrorReport>
@@ -92,14 +92,20 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Renci.SshNet.Silverlight\Channels\ChannelDirectTcpip.SilverlightShared.cs">
<Link>ChannelDirectTcpip.SilverlightShared.cs</Link>
<Link>Channels\ChannelDirectTcpip.SilverlightShared.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.WindowsPhone\Common\Extensions.WP.cs">
<Link>Common\Extensions.WP.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\DnsAbstraction.cs">
<Link>Abstractions\DnsAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ReflectionAbstraction.cs">
<Link>Abstractions\ReflectionAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\SocketAbstraction.cs">
<Link>Abstractions\SocketAbstraction.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Abstractions\ThreadAbstraction.cs">
<Link>Abstractions\ThreadAbstraction.cs</Link>
</Compile>
@@ -574,9 +580,6 @@
<Compile Include="..\Renci.SshNet\ScpClient.cs">
<Link>ScpClient.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet.Silverlight\ScpClient.SilverlightShared.cs">
<Link>ScpClient.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Security\Algorithm.cs">
<Link>Security\Algorithm.cs</Link>
</Compile>
@@ -883,6 +886,9 @@
<Compile Include="..\Renci.SshNet\Sftp\SftpSession.cs">
<Link>Sftp\SftpSession.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Sftp\SftpSynchronizeDirectoriesAsyncResult.cs">
<Link>Sftp\SftpSynchronizeDirectoriesAsyncResult.cs</Link>
</Compile>
<Compile Include="..\Renci.SshNet\Sftp\SftpUploadAsyncResult.cs">
<Link>Sftp\SftpUploadAsyncResult.cs</Link>
</Compile>
@@ -904,7 +910,6 @@
<Compile Include="..\Renci.SshNet\SubsystemSession.cs">
<Link>SubsystemSession.cs</Link>
</Compile>
<Compile Include="ForwardedPortLocal.SilverlightShared.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\Renci.SshNet\Properties\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
@@ -924,7 +929,7 @@
<Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
<UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
</VisualStudio>
</ProjectExtensions>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+32 -19
View File
@@ -1,4 +1,12 @@
using System.Net;
using System;
using System.Net;
#if FEATURE_DEVICEINFORMATION_APM
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Threading;
using Microsoft.Phone.Net.NetworkInformation;
#endif // FEATURE_DEVICEINFORMATION_APM
namespace Renci.SshNet.Abstractions
{
@@ -19,26 +27,31 @@ namespace Renci.SshNet.Abstractions
#elif FEATURE_DNS_TAP
return Dns.GetHostAddressesAsync(hostNameOrAddress).Result;
#else
#error Retrieving IP addresses for a given host is not implemented.
#endif
}
IPAddress address;
if (IPAddress.TryParse(hostNameOrAddress, out address))
return new [] { address};
/// <summary>
/// Resolves a host name or IP address to an <see cref="IPHostEntry"/> instance.
/// </summary>
/// <param name="hostNameOrAddress">The host name or IP address to resolve.</param>
/// <returns>
/// An <see cref="IPHostEntry"/> instance that contains address information about the host
/// specified in <paramref name="hostNameOrAddress"/>.
/// </returns>
public static IPHostEntry GetHostEntry(string hostNameOrAddress)
{
#if FEATURE_DNS_SYNC
return Dns.GetHostEntry(hostNameOrAddress);
#elif FEATURE_DNS_TAP
return Dns.GetHostEntryAsync(hostNameOrAddress).Result;
#if FEATURE_DEVICEINFORMATION_APM
var resolveCompleted = new ManualResetEvent(false);
NameResolutionResult nameResolutionResult = null;
DeviceNetworkInformation.ResolveHostNameAsync(new DnsEndPoint(hostNameOrAddress, 0), result =>
{
nameResolutionResult = result;
resolveCompleted.Set();
}, null);
// wait until address is resolved
resolveCompleted.WaitOne();
if (nameResolutionResult.NetworkErrorCode == NetworkError.Success)
{
var addresses = new List<IPAddress>(nameResolutionResult.IPEndPoints.Select(p => p.Address).Distinct());
return addresses.ToArray();
}
throw new SocketException((int)nameResolutionResult.NetworkErrorCode);
#else
#error Resolving host name or IP address to an IPHostEntry is not implemented.
throw new NotSupportedException("Resolving hostname to IP address is not supported.");
#endif // FEATURE_DEVICEINFORMATION_APM
#endif
}
}
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
#if FEATURE_REFLECTION_TYPEINFO
using System.Reflection;
#endif // FEATURE_REFLECTION_TYPEINFO
namespace Renci.SshNet.Abstractions
{
@@ -0,0 +1,32 @@
using System.Net.Sockets;
namespace Renci.SshNet.Abstractions
{
internal static class SocketAbstraction
{
public static bool CanRead(Socket socket)
{
if (socket.Connected)
{
#if FEATURE_SOCKET_POLL
return socket.Poll(-1, SelectMode.SelectRead) && socket.Available > 0;
#endif // FEATURE_SOCKET_POLL
}
return false;
}
public static bool CanWrite(Socket socket)
{
if (socket.Connected)
{
#if FEATURE_SOCKET_POLL
return socket.Poll(-1, SelectMode.SelectWrite);
#endif // FEATURE_SOCKET_POLL
}
return false;
}
}
}
-46
View File
@@ -1,46 +0,0 @@
using System.Linq;
using System.Net;
using System.Net.Sockets;
using Renci.SshNet.Abstractions;
namespace Renci.SshNet.Common
{
/// <summary>
/// Collection of different extension method specific for .NET 4.0
/// </summary>
internal static partial class Extensions
{
/// <summary>
/// Determines whether [is null or white space] [the specified value].
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// <c>true</c> if [is null or white space] [the specified value]; otherwise, <c>false</c>.
/// </returns>
internal static bool IsNullOrWhiteSpace(this string value)
{
if (string.IsNullOrEmpty(value)) return true;
return value.All(char.IsWhiteSpace);
}
internal static bool CanRead(this Socket socket)
{
return socket.Connected && socket.Poll(-1, SelectMode.SelectRead) && socket.Available > 0;
}
internal static bool CanWrite(this Socket socket)
{
return socket.Connected && socket.Poll(-1, SelectMode.SelectWrite);
}
internal static IPAddress GetIPAddress(this string host)
{
IPAddress ipAddress;
if (!IPAddress.TryParse(host, out ipAddress))
ipAddress = DnsAbstraction.GetHostAddresses(host).First();
return ipAddress;
}
}
}
+32 -8
View File
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
#if !SILVERLIGHT
using System.Diagnostics;
#endif
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using Renci.SshNet.Abstractions;
using Renci.SshNet.Messages;
using Renci.SshNet.Messages.Connection;
@@ -15,6 +17,20 @@ namespace Renci.SshNet.Common
/// </summary>
internal static partial class Extensions
{
/// <summary>
/// Determines whether [is null or white space] [the specified value].
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// <c>true</c> if [is null or white space] [the specified value]; otherwise, <c>false</c>.
/// </returns>
internal static bool IsNullOrWhiteSpace(this string value)
{
if (string.IsNullOrEmpty(value)) return true;
return value.All(char.IsWhiteSpace);
}
internal static byte[] ToArray(this GlobalRequestName globalRequestName)
{
switch (globalRequestName)
@@ -150,22 +166,20 @@ namespace Renci.SshNet.Common
return IsEqualTo(value, compareList, null);
}
#if SILVERLIGHT
#else
/// <summary>
/// Prints out
/// </summary>
/// <param name="bytes">The bytes.</param>
internal static void DebugPrint(this IEnumerable<byte> bytes)
{
var sb = new StringBuilder();
foreach (var b in bytes)
{
Debug.Write(string.Format(CultureInfo.CurrentCulture, "0x{0:x2}, ", b));
sb.AppendFormat(CultureInfo.CurrentCulture, "0x{0:x2}, ", b);
}
Debug.WriteLine(string.Empty);
Debug.WriteLine(sb.ToString());
}
#endif
/// <summary>
/// Trims the leading zero from bytes array.
@@ -305,5 +319,15 @@ namespace Renci.SshNet.Common
Buffer.BlockCopy(data, offset, taken, 0, length);
return taken;
}
internal static bool CanRead(this Socket socket)
{
return SocketAbstraction.CanRead(socket);
}
internal static bool CanWrite(this Socket socket)
{
return SocketAbstraction.CanWrite(socket);
}
}
}
+1 -1
View File
@@ -26,7 +26,7 @@ namespace Renci.SshNet
var ip = IPAddress.Any;
if (!string.IsNullOrEmpty(BoundHost))
{
ip = BoundHost.GetIPAddress();
ip = DnsAbstraction.GetHostAddresses(BoundHost)[0];
}
var ep = new IPEndPoint(ip, (int) BoundPort);
+1 -1
View File
@@ -22,7 +22,7 @@ namespace Renci.SshNet
partial void InternalStart()
{
var addr = BoundHost.GetIPAddress();
var addr = DnsAbstraction.GetHostAddresses(BoundHost)[0];
var ep = new IPEndPoint(addr, (int) BoundPort);
_listener = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp) {Blocking = true};
@@ -1,39 +0,0 @@
using Renci.SshNet.Abstractions;
namespace Renci.SshNet
{
/// <summary>
/// Provides functionality for remote port forwarding
/// </summary>
public partial class ForwardedPortRemote
{
/// <summary>
/// Initializes a new instance of the <see cref="ForwardedPortRemote"/> class.
/// </summary>
/// <param name="boundPort">The bound port.</param>
/// <param name="host">The host.</param>
/// <param name="port">The port.</param>
/// <example>
/// <code source="..\..\Renci.SshNet.Tests\Classes\ForwardedPortRemoteTest.cs" region="Example SshClient AddForwardedPort Start Stop ForwardedPortRemote" language="C#" title="Remote port forwarding" />
/// </example>
public ForwardedPortRemote(uint boundPort, string host, uint port)
: this(string.Empty, boundPort, host, port)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ForwardedPortRemote"/> class.
/// </summary>
/// <param name="boundHost">The bound host.</param>
/// <param name="boundPort">The bound port.</param>
/// <param name="host">The host.</param>
/// <param name="port">The port.</param>
public ForwardedPortRemote(string boundHost, uint boundPort, string host, uint port)
: this(DnsAbstraction.GetHostEntry(boundHost).AddressList[0],
boundPort,
DnsAbstraction.GetHostEntry(host).AddressList[0],
port)
{
}
}
}
+30 -1
View File
@@ -11,7 +11,7 @@ namespace Renci.SshNet
/// <summary>
/// Provides functionality for remote port forwarding
/// </summary>
public partial class ForwardedPortRemote : ForwardedPort, IDisposable
public class ForwardedPortRemote : ForwardedPort, IDisposable
{
private bool _requestStatus;
@@ -99,6 +99,35 @@ namespace Renci.SshNet
Port = port;
}
/// <summary>
/// Initializes a new instance of the <see cref="ForwardedPortRemote"/> class.
/// </summary>
/// <param name="boundPort">The bound port.</param>
/// <param name="host">The host.</param>
/// <param name="port">The port.</param>
/// <example>
/// <code source="..\..\Renci.SshNet.Tests\Classes\ForwardedPortRemoteTest.cs" region="Example SshClient AddForwardedPort Start Stop ForwardedPortRemote" language="C#" title="Remote port forwarding" />
/// </example>
public ForwardedPortRemote(uint boundPort, string host, uint port)
: this(string.Empty, boundPort, host, port)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ForwardedPortRemote"/> class.
/// </summary>
/// <param name="boundHost">The bound host.</param>
/// <param name="boundPort">The bound port.</param>
/// <param name="host">The host.</param>
/// <param name="port">The port.</param>
public ForwardedPortRemote(string boundHost, uint boundPort, string host, uint port)
: this(DnsAbstraction.GetHostAddresses(boundHost)[0],
boundPort,
DnsAbstraction.GetHostAddresses(host)[0],
port)
{
}
/// <summary>
/// Starts remote port forwarding.
/// </summary>
+3 -5
View File
@@ -18,7 +18,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<DefineConstants>TRACE;DEBUG;TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\Renci.SshNet.xml</DocumentationFile>
@@ -27,7 +27,7 @@
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<DefineConstants>TUNING;FEATURE_RNG_CSP;FEATURE_SOCKET_EAP;FEATURE_SOCKET_POLL;FEATURE_STREAM_APM;FEATURE_DNS_SYNC;FEATURE_THREAD_THREADPOOL;FEATURE_THREAD_SLEEP;FEATURE_HASH_MD5;FEATURE_HASH_SHA1;FEATURE_HASH_SHA256;FEATURE_HASH_SHA384;FEATURE_HASH_SHA512;FEATURE_HASH_RIPEMD160;FEATURE_HMAC_MD5;FEATURE_HMAC_SHA1;FEATURE_HMAC_SHA256;FEATURE_HMAC_SHA384;FEATURE_HMAC_SHA512;FEATURE_HMAC_RIPEMD160;FEATURE_MEMORYSTREAM_GETBUFFER</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Release\Renci.SshNet.xml</DocumentationFile>
@@ -48,6 +48,7 @@
<ItemGroup>
<Compile Include="Abstractions\DnsAbstraction.cs" />
<Compile Include="Abstractions\ReflectionAbstraction.cs" />
<Compile Include="Abstractions\SocketAbstraction.cs" />
<Compile Include="Abstractions\ThreadAbstraction.cs" />
<Compile Include="AuthenticationMethod.cs">
<SubType>Code</SubType>
@@ -88,7 +89,6 @@
<Compile Include="Common\ChannelOpenConfirmedEventArgs.cs" />
<Compile Include="Common\ChannelOpenFailedEventArgs.cs" />
<Compile Include="Common\ChannelRequestEventArgs.cs" />
<Compile Include="Common\Extensions.NET.cs" />
<Compile Include="Common\ProxyException.cs">
<SubType>Code</SubType>
</Compile>
@@ -148,7 +148,6 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="ConnectionInfo.cs" />
<Compile Include="ForwardedPortRemote.NET.cs" />
<Compile Include="HashInfo.cs">
<SubType>Code</SubType>
</Compile>
@@ -179,7 +178,6 @@
<Compile Include="Common\SshDataStream.cs" />
<Compile Include="ExpectAsyncResult.cs" />
<Compile Include="Security\KeyExchangeDiffieHellmanGroupSha1.cs" />
<Compile Include="SftpClient.NET.cs" />
<Compile Include="KeyboardInteractiveAuthenticationMethod.cs">
<SubType>Code</SubType>
</Compile>
-6
View File
@@ -1,5 +1,4 @@
using System;
using System.Text;
using Renci.SshNet.Channels;
using System.IO;
using Renci.SshNet.Common;
@@ -296,10 +295,5 @@ namespace Renci.SshNet
SendConfirmation(channel, 1, string.Format("\"{0}\" is not valid protocol message.", message));
}
}
partial void SendData(IChannelSession channel, string command)
{
channel.SendData(SshData.Utf8.GetBytes(command));
}
}
}
+4 -1
View File
@@ -359,7 +359,10 @@ namespace Renci.SshNet
}
}
partial void SendData(IChannelSession channel, string command);
private void SendData(IChannelSession channel, string command)
{
channel.SendData(SshData.Utf8.GetBytes(command));
}
private void SendData(IChannelSession channel, byte[] buffer, int length)
{
+1 -1
View File
@@ -103,7 +103,7 @@ namespace Renci.SshNet
{
const int socketBufferSize = 2 * MaximumSshPacketSize;
var ipAddress = host.GetIPAddress();
var ipAddress = DnsAbstraction.GetHostAddresses(host)[0];
var timeout = ConnectionInfo.Timeout;
var ep = new IPEndPoint(ipAddress, port);
+2 -2
View File
@@ -1875,7 +1875,7 @@ namespace Renci.SshNet
SocketWriteByte((byte)(ConnectionInfo.Port % 0xFF));
// Send IP
var ipAddress = ConnectionInfo.Host.GetIPAddress();
var ipAddress = DnsAbstraction.GetHostAddresses(ConnectionInfo.Host)[0];
SocketWrite(ipAddress.GetAddressBytes());
// Send username
@@ -1986,7 +1986,7 @@ namespace Renci.SshNet
// Send reserved, must be 0x00
SocketWriteByte(0x00);
var ip = ConnectionInfo.Host.GetIPAddress();
var ip = DnsAbstraction.GetHostAddresses(ConnectionInfo.Host)[0];
// Send address type and address
if (ip.AddressFamily == AddressFamily.InterNetwork)
-167
View File
@@ -1,167 +0,0 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using Renci.SshNet.Common;
using Renci.SshNet.Sftp;
using System.Globalization;
using Renci.SshNet.Abstractions;
namespace Renci.SshNet
{
/// <summary>
/// Implementation of the SSH File Transfer Protocol (SFTP) over SSH.
/// </summary>
public partial class SftpClient
{
#region SynchronizeDirectories
/// <summary>
/// Synchronizes the directories.
/// </summary>
/// <param name="sourcePath">The source path.</param>
/// <param name="destinationPath">The destination path.</param>
/// <param name="searchPattern">The search pattern.</param>
/// <returns>List of uploaded files.</returns>
public IEnumerable<FileInfo> SynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern)
{
return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, null);
}
/// <summary>
/// Begins the synchronize directories.
/// </summary>
/// <param name="sourcePath">The source path.</param>
/// <param name="destinationPath">The destination path.</param>
/// <param name="searchPattern">The search pattern.</param>
/// <param name="asyncCallback">The async callback.</param>
/// <param name="state">The state.</param>
/// <returns>
/// An <see cref="System.IAsyncResult" /> that represents the asynchronous directory synchronization.
/// </returns>
/// <exception cref="System.ArgumentNullException"><paramref name="sourcePath"/> is <c>null</c>.</exception>
/// <exception cref="System.ArgumentException"><paramref name="destinationPath"/> is <c>null</c> or contains only whitespace.</exception>
public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, AsyncCallback asyncCallback, object state)
{
if (sourcePath == null)
throw new ArgumentNullException("sourcePath");
if (destinationPath.IsNullOrWhiteSpace())
throw new ArgumentException("destDir");
var asyncResult = new SftpSynchronizeDirectoriesAsyncResult(asyncCallback, state);
ThreadAbstraction.ExecuteThread(() =>
{
try
{
var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult);
asyncResult.SetAsCompleted(result, false);
}
catch (Exception exp)
{
asyncResult.SetAsCompleted(exp, false);
}
});
return asyncResult;
}
/// <summary>
/// Ends the synchronize directories.
/// </summary>
/// <param name="asyncResult">The async result.</param>
/// <returns>List of uploaded files.</returns>
/// <exception cref="System.ArgumentException">Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.</exception>
public IEnumerable<FileInfo> EndSynchronizeDirectories(IAsyncResult asyncResult)
{
var ar = asyncResult as SftpSynchronizeDirectoriesAsyncResult;
if (ar == null || ar.EndInvokeCalled)
throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
// Wait for operation to complete, then return result or throw exception
return ar.EndInvoke();
}
private IEnumerable<FileInfo> InternalSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, SftpSynchronizeDirectoriesAsyncResult asynchResult)
{
if (destinationPath.IsNullOrWhiteSpace())
throw new ArgumentException("destinationPath");
if (!Directory.Exists(sourcePath))
throw new FileNotFoundException(string.Format("Source directory not found: {0}", sourcePath));
var uploadedFiles = new List<FileInfo>();
var sourceDirectory = new DirectoryInfo(sourcePath);
#if SILVERLIGHT
var sourceFiles = sourceDirectory.EnumerateFiles(searchPattern);
#else
var sourceFiles = sourceDirectory.GetFiles(searchPattern);
#endif
if (sourceFiles == null || !sourceFiles.Any())
return uploadedFiles;
#region Existing Files at The Destination
var destFiles = InternalListDirectory(destinationPath, null);
var destDict = new Dictionary<string, SftpFile>();
foreach (var destFile in destFiles)
{
if (destFile.IsDirectory)
continue;
destDict.Add(destFile.Name, destFile);
}
#endregion
#region Upload the difference
const Flags uploadFlag = Flags.Write | Flags.Truncate | Flags.CreateNewOrOpen;
foreach (var localFile in sourceFiles)
{
var isDifferent = !destDict.ContainsKey(localFile.Name);
if (!isDifferent)
{
var temp = destDict[localFile.Name];
// TODO: Use md5 to detect a difference
//ltang: File exists at the destination => Using filesize to detect the difference
isDifferent = localFile.Length != temp.Length;
}
if (isDifferent)
{
var remoteFileName = string.Format(CultureInfo.InvariantCulture, @"{0}/{1}", destinationPath, localFile.Name);
try
{
using (var file = File.OpenRead(localFile.FullName))
{
InternalUploadFile(file, remoteFileName, uploadFlag, null, null);
}
uploadedFiles.Add(localFile);
if (asynchResult != null)
{
asynchResult.Update(uploadedFiles.Count);
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Failed to upload {0} to {1}", localFile.FullName, remoteFileName), ex);
}
}
}
#endregion
return uploadedFiles;
}
#endregion
}
}
+156 -3
View File
@@ -15,7 +15,7 @@ namespace Renci.SshNet
/// <summary>
/// Implementation of the SSH File Transfer Protocol (SFTP) over SSH.
/// </summary>
public partial class SftpClient : BaseClient
public class SftpClient : BaseClient
{
/// <summary>
/// Holds the <see cref="ISftpSession"/> instance that is used to communicate to the
@@ -233,7 +233,7 @@ namespace Renci.SshNet
BufferSize = 1024 * 32;
}
#endregion
#endregion Constructors
/// <summary>
/// Changes remote directory to path.
@@ -1566,6 +1566,156 @@ namespace Renci.SshNet
//public void SetCreationTime(string path, DateTime creationTime);
//public void SetCreationTimeUtc(string path, DateTime creationTimeUtc);
#endregion // File Methods
#region SynchronizeDirectories
/// <summary>
/// Synchronizes the directories.
/// </summary>
/// <param name="sourcePath">The source path.</param>
/// <param name="destinationPath">The destination path.</param>
/// <param name="searchPattern">The search pattern.</param>
/// <returns>List of uploaded files.</returns>
public IEnumerable<FileInfo> SynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern)
{
return InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, null);
}
/// <summary>
/// Begins the synchronize directories.
/// </summary>
/// <param name="sourcePath">The source path.</param>
/// <param name="destinationPath">The destination path.</param>
/// <param name="searchPattern">The search pattern.</param>
/// <param name="asyncCallback">The async callback.</param>
/// <param name="state">The state.</param>
/// <returns>
/// An <see cref="System.IAsyncResult" /> that represents the asynchronous directory synchronization.
/// </returns>
/// <exception cref="System.ArgumentNullException"><paramref name="sourcePath"/> is <c>null</c>.</exception>
/// <exception cref="System.ArgumentException"><paramref name="destinationPath"/> is <c>null</c> or contains only whitespace.</exception>
public IAsyncResult BeginSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, AsyncCallback asyncCallback, object state)
{
if (sourcePath == null)
throw new ArgumentNullException("sourcePath");
if (destinationPath.IsNullOrWhiteSpace())
throw new ArgumentException("destDir");
var asyncResult = new SftpSynchronizeDirectoriesAsyncResult(asyncCallback, state);
ThreadAbstraction.ExecuteThread(() =>
{
try
{
var result = InternalSynchronizeDirectories(sourcePath, destinationPath, searchPattern, asyncResult);
asyncResult.SetAsCompleted(result, false);
}
catch (Exception exp)
{
asyncResult.SetAsCompleted(exp, false);
}
});
return asyncResult;
}
/// <summary>
/// Ends the synchronize directories.
/// </summary>
/// <param name="asyncResult">The async result.</param>
/// <returns>List of uploaded files.</returns>
/// <exception cref="System.ArgumentException">Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.</exception>
public IEnumerable<FileInfo> EndSynchronizeDirectories(IAsyncResult asyncResult)
{
var ar = asyncResult as SftpSynchronizeDirectoriesAsyncResult;
if (ar == null || ar.EndInvokeCalled)
throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
// Wait for operation to complete, then return result or throw exception
return ar.EndInvoke();
}
private IEnumerable<FileInfo> InternalSynchronizeDirectories(string sourcePath, string destinationPath, string searchPattern, SftpSynchronizeDirectoriesAsyncResult asynchResult)
{
if (destinationPath.IsNullOrWhiteSpace())
throw new ArgumentException("destinationPath");
if (!Directory.Exists(sourcePath))
throw new FileNotFoundException(string.Format("Source directory not found: {0}", sourcePath));
var uploadedFiles = new List<FileInfo>();
var sourceDirectory = new DirectoryInfo(sourcePath);
#if SILVERLIGHT
var sourceFiles = sourceDirectory.EnumerateFiles(searchPattern);
#else
var sourceFiles = sourceDirectory.GetFiles(searchPattern);
#endif
if (sourceFiles == null || !sourceFiles.Any())
return uploadedFiles;
#region Existing Files at The Destination
var destFiles = InternalListDirectory(destinationPath, null);
var destDict = new Dictionary<string, SftpFile>();
foreach (var destFile in destFiles)
{
if (destFile.IsDirectory)
continue;
destDict.Add(destFile.Name, destFile);
}
#endregion
#region Upload the difference
const Flags uploadFlag = Flags.Write | Flags.Truncate | Flags.CreateNewOrOpen;
foreach (var localFile in sourceFiles)
{
var isDifferent = !destDict.ContainsKey(localFile.Name);
if (!isDifferent)
{
var temp = destDict[localFile.Name];
// TODO: Use md5 to detect a difference
//ltang: File exists at the destination => Using filesize to detect the difference
isDifferent = localFile.Length != temp.Length;
}
if (isDifferent)
{
var remoteFileName = string.Format(CultureInfo.InvariantCulture, @"{0}/{1}", destinationPath, localFile.Name);
try
{
using (var file = File.OpenRead(localFile.FullName))
{
InternalUploadFile(file, remoteFileName, uploadFlag, null, null);
}
uploadedFiles.Add(localFile);
if (asynchResult != null)
{
asynchResult.Update(uploadedFiles.Count);
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Failed to upload {0} to {1}", localFile.FullName, remoteFileName), ex);
}
}
}
#endregion
return uploadedFiles;
}
#endregion
/// <summary>
@@ -1665,8 +1815,11 @@ namespace Renci.SshNet
// Call callback to report number of bytes read
if (downloadCallback != null)
{
// copy offset to ensure it's not modified between now and execution of callback
var downloadOffset = offset;
// Execute callback on different thread
ThreadAbstraction.ExecuteThread(() => { downloadCallback(offset); });
ThreadAbstraction.ExecuteThread(() => { downloadCallback(downloadOffset); });
}
data = _sftpSession.RequestRead(handle, offset, optimalReadLength);