diff --git a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs index d45ddcd7..44f392aa 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/Channel.cs +++ b/Renci.SshClient/Renci.SshClient/Channels/Channel.cs @@ -1,5 +1,6 @@ using System; using System.Threading; +using Renci.SshClient.Common; using Renci.SshClient.Messages; using Renci.SshClient.Messages.Connection; @@ -11,6 +12,10 @@ namespace Renci.SshClient.Channels private EventWaitHandle _channelWindowAdjustWaitHandle = new AutoResetEvent(false); + private EventWaitHandle _errorOccuredWaitHandle = new ManualResetEvent(false); + + private EventWaitHandle _disconnectedWaitHandle = new ManualResetEvent(false); + private uint _initialWindowSize = 0x100000; private uint _maximumPacketSize = 0x8000; @@ -164,6 +169,8 @@ namespace Renci.SshClient.Channels this._session.ChannelRequestReceived += OnChannelRequest; this._session.ChannelSuccessReceived += OnChannelSuccess; this._session.ChannelFailureReceived += OnChannelFailure; + this._session.ErrorOccured += Session_ErrorOccured; + this._session.Disconnected += Session_Disconnected; } @@ -319,6 +326,16 @@ namespace Renci.SshClient.Channels this._session.WaitHandle(waitHandle); } + private void Session_Disconnected(object sender, EventArgs e) + { + this._disconnectedWaitHandle.Set(); + } + + private void Session_ErrorOccured(object sender, System.IO.ErrorEventArgs e) + { + this._errorOccuredWaitHandle.Set(); + } + #region Channel message event handlers private void OnChannelOpen(object sender, MessageEventArgs e) diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelDataEventArgs.cs b/Renci.SshClient/Renci.SshClient/Common/ChannelDataEventArgs.cs similarity index 89% rename from Renci.SshClient/Renci.SshClient/Channels/ChannelDataEventArgs.cs rename to Renci.SshClient/Renci.SshClient/Common/ChannelDataEventArgs.cs index 3673fdb8..a694198b 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelDataEventArgs.cs +++ b/Renci.SshClient/Renci.SshClient/Common/ChannelDataEventArgs.cs @@ -1,5 +1,4 @@ - -namespace Renci.SshClient.Channels +namespace Renci.SshClient.Common { internal class ChannelDataEventArgs : ChannelEventArgs { diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelEventArgs.cs b/Renci.SshClient/Renci.SshClient/Common/ChannelEventArgs.cs similarity index 84% rename from Renci.SshClient/Renci.SshClient/Channels/ChannelEventArgs.cs rename to Renci.SshClient/Renci.SshClient/Common/ChannelEventArgs.cs index b7d7fc01..528c8155 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelEventArgs.cs +++ b/Renci.SshClient/Renci.SshClient/Common/ChannelEventArgs.cs @@ -1,6 +1,6 @@ using System; -namespace Renci.SshClient.Channels +namespace Renci.SshClient.Common { internal class ChannelEventArgs : EventArgs { diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelOpenFailedEventArgs.cs b/Renci.SshClient/Renci.SshClient/Common/ChannelOpenFailedEventArgs.cs similarity index 90% rename from Renci.SshClient/Renci.SshClient/Channels/ChannelOpenFailedEventArgs.cs rename to Renci.SshClient/Renci.SshClient/Common/ChannelOpenFailedEventArgs.cs index 42802973..993a55c9 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelOpenFailedEventArgs.cs +++ b/Renci.SshClient/Renci.SshClient/Common/ChannelOpenFailedEventArgs.cs @@ -1,4 +1,4 @@ -namespace Renci.SshClient.Channels +namespace Renci.SshClient.Common { internal class ChannelOpenFailedEventArgs : ChannelEventArgs { diff --git a/Renci.SshClient/Renci.SshClient/Channels/ChannelRequestEventArgs.cs b/Renci.SshClient/Renci.SshClient/Common/ChannelRequestEventArgs.cs similarity index 85% rename from Renci.SshClient/Renci.SshClient/Channels/ChannelRequestEventArgs.cs rename to Renci.SshClient/Renci.SshClient/Common/ChannelRequestEventArgs.cs index 832d79dc..cc448fa5 100644 --- a/Renci.SshClient/Renci.SshClient/Channels/ChannelRequestEventArgs.cs +++ b/Renci.SshClient/Renci.SshClient/Common/ChannelRequestEventArgs.cs @@ -1,7 +1,7 @@ using System; using Renci.SshClient.Messages.Connection; -namespace Renci.SshClient.Channels +namespace Renci.SshClient.Common { internal class ChannelRequestEventArgs : EventArgs { diff --git a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj index c00aa13b..a3f2528b 100644 --- a/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj +++ b/Renci.SshClient/Renci.SshClient/Renci.SshClient.csproj @@ -60,10 +60,10 @@ - - - - + + + + diff --git a/Renci.SshClient/Renci.SshClient/Session.cs b/Renci.SshClient/Renci.SshClient/Session.cs index f06442e0..c70aeb3a 100644 --- a/Renci.SshClient/Renci.SshClient/Session.cs +++ b/Renci.SshClient/Renci.SshClient/Session.cs @@ -217,6 +217,16 @@ namespace Renci.SshClient /// The connection info. public ConnectionInfo ConnectionInfo { get; private set; } + public event EventHandler ErrorOccured; + + public event EventHandler Connecting; + + public event EventHandler Connected; + + public event EventHandler Disconnecting; + + public event EventHandler Disconnected; + #region Message events /// @@ -387,6 +397,12 @@ namespace Renci.SshClient if (this.IsConnected) return; + if (this.Connecting != null) + { + // TODO: Create custom ConnectingEventArgs to allow to pass different connection parameters + this.Connecting(this, new EventArgs()); + } + lock (this) { // If connected dont connect again @@ -517,6 +533,12 @@ namespace Renci.SshClient Monitor.Pulse(this); } + + if (this.Connected != null) + { + // TODO: Create custom ConnectingEventArgs to allow to pass different connection parameters + this.Connected(this, new EventArgs()); + } } finally { @@ -531,6 +553,11 @@ namespace Renci.SshClient { this._isDisconnecting = true; + if (this.Disconnecting != null) + { + this.Disconnecting(this, new EventArgs()); + } + this.SendDisconnect(DisconnectReasons.ByApplication, "Connection terminated by the client."); } @@ -936,6 +963,11 @@ namespace Renci.SshClient { this.DisconnectReceived(this, new MessageEventArgs(message)); } + + if (this.Disconnected != null) + { + this.Disconnected(this, new EventArgs()); + } } protected virtual void OnIgnoreReceived(IgnoreMessage message) @@ -1328,9 +1360,7 @@ namespace Renci.SshClient this.SendDisconnect(exp.DisconnectReason, exp.ToString()); } - this._exceptionToThrow = exp; - - this._exceptionWaitHandle.Set(); + this.RaiseError(exp); } catch (Exception exp) { @@ -1338,15 +1368,25 @@ namespace Renci.SshClient this.SendDisconnect(DisconnectReasons.ByApplication, exp.ToString()); - this._exceptionToThrow = exp; - - this._exceptionWaitHandle.Set(); + this.RaiseError(exp); } } this._listenerWaitHandle.Set(); } + private void RaiseError(Exception exp) + { + this._exceptionToThrow = exp; + + this._exceptionWaitHandle.Set(); + + if (this.ErrorOccured != null) + { + this.ErrorOccured(this, new ErrorEventArgs(exp)); + } + } + #region IDisposable Members private bool _disposed = false;