SparkleShare/SharpSSH/SshShell.cs
2010-07-15 20:41:37 +01:00

257 lines
7.5 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.IO;
using Tamir.SharpSsh.jsch;
using Tamir.Streams;
using System.Text;
using System.Text.RegularExpressions;
/*
* SshShell.cs
*
* Copyright (c) 2006 Tamir Gal, http://www.tamirgal.com, All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
*
* 3. The names of the authors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
* *OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**/
namespace Tamir.SharpSsh
{
/// <summary>
/// Summary description for SshShell.
/// </summary>
public class SshShell : SshBase
{
private Stream m_sshIO = null;
private Regex m_expectPattern;
private bool m_removeTerminalChars = false;
private bool m_redirectToConsole = false;
private static string escapeCharsPattern = "\\[[0-9;?]*[^0-9;]";
public SshShell(string host, string user, string password)
: base(host, user, password)
{
Init();
}
public SshShell(string host, string user)
: base(host, user)
{
Init();
}
protected void Init()
{
ExpectPattern = "";
m_removeTerminalChars = false;
}
protected override void OnChannelReceived()
{
base.OnChannelReceived ();
if(m_redirectToConsole)
{
SetStream(Console.OpenStandardInput(), Console.OpenStandardOutput());
}
else
{
m_sshIO = GetStream();
}
}
protected override string ChannelType
{
get { return "shell"; }
}
public Stream IO
{
get
{
// if(m_sshIO == null)
// {
// m_sshIO = GetStream();
// }
return m_sshIO;
}
}
public void WriteLine(string data)
{
Write( data+"\r" );
}
public void Write(string data)
{
Write( Encoding.Default.GetBytes( data ) );
}
/// <summary>
/// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
/// </summary>
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream. </param>
public virtual void Write(byte[] buffer)
{
Write(buffer, 0, buffer.Length);
}
/// <summary>
/// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written.
/// </summary>
/// <param name="buffer">An array of bytes. This method copies count bytes from buffer to the current stream. </param>
/// <param name="offset">The zero-based byte offset in buffer at which to begin copying bytes to the current stream.</param>
/// <param name="count">The number of bytes to be written to the current stream. </param>
public virtual void Write(byte[] buffer, int offset, int count)
{
IO.Write(buffer, offset, count);
IO.Flush();
}
/// <summary>
/// Creates a new I/O stream of communication with this SSH shell connection
/// </summary>
public Stream GetStream()
{
return new CombinedStream(m_channel.getInputStream(), m_channel.getOutputStream());;
}
public void SetStream(Stream inputStream, Stream outputStream)
{
m_channel.setInputStream(inputStream);
m_channel.setOutputStream(outputStream);
}
public void SetStream(Stream s)
{
SetStream(s, s);
}
public void RedirectToConsole()
{
m_redirectToConsole = true;
}
public virtual bool ShellOpened
{
get
{
if(m_channel != null)
{
return !m_channel.isClosed();
}
return false;
}
}
public virtual bool ShellConnected
{
get
{
if(m_channel != null)
{
return m_channel.isConnected();
}
return false;
}
}
/// <summary>
/// Gets or sets a value indicating wether this Steam sould remove the terminal emulation's escape sequence characters from the response String.
/// </summary>
public bool RemoveTerminalEmulationCharacters
{
get{return m_removeTerminalChars;}
set{m_removeTerminalChars=value;}
}
/// <summary>
/// A regular expression pattern string to match when reading the resonse using the ReadResponse() method. The default prompt value is "\n" which makes the ReadRespons() method return one line of response.
/// </summary>
public string ExpectPattern
{
get{return m_expectPattern.ToString();}
set{m_expectPattern = new Regex(value, RegexOptions.Singleline);}
}
/// <summary>
/// Reads a response string from the SSH channel. This method will block until the pattern in the 'Prompt' property is matched in the response.
/// </summary>
/// <returns>A response string from the SSH server.</returns>
public string Expect()
{
return Expect(m_expectPattern);
}
/// <summary>
/// Reads a response string from the SSH channel. This method will block until the pattern in the 'Prompt' property is matched in the response.
/// </summary>
/// <returns>A response string from the SSH server.</returns>
public string Expect(string pattern)
{
return Expect( new Regex( pattern, RegexOptions.Singleline ));
}
/// <summary>
/// Reads a response string from the SSH channel. This method will block until the pattern in the 'Prompt' property is matched in the response.
/// </summary>
/// <returns>A response string from the SSH server.</returns>
public string Expect(Regex pattern)
{
int readCount;
StringBuilder resp = new StringBuilder();
byte[] buff = new byte[1024];
Match match;
do
{
readCount = IO.Read(buff, 0, buff.Length);
if(readCount == -1) break;
string tmp = System.Text.Encoding.Default.GetString(buff, 0, readCount);
resp.Append( tmp, 0, readCount);
string s = resp.ToString();
match = pattern.Match( s );
}while(!match.Success);
string result = resp.ToString();
if(RemoveTerminalEmulationCharacters)
result = HandleTerminalChars(result);
return result;
}
/// <summary>
/// Removes escape sequence characters from the input string.
/// </summary>
public static string HandleTerminalChars(string str)
{
str = str.Replace("(B)0", "");
str = Regex.Replace(str, escapeCharsPattern, "");
str = str.Replace(((char)15).ToString(), "");
str = Regex.Replace(str, ((char)27)+"=*", "");
//str = Regex.Replace(str, "\\s*\r\n", "\r\n");
return str;
}
}
}