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 description for SshShell. /// 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 ) ); } /// /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. /// /// An array of bytes. This method copies count bytes from buffer to the current stream. public virtual void Write(byte[] buffer) { Write(buffer, 0, buffer.Length); } /// /// Writes a sequence of bytes to the current stream and advances the current position within this stream by the number of bytes written. /// /// An array of bytes. This method copies count bytes from buffer to the current stream. /// The zero-based byte offset in buffer at which to begin copying bytes to the current stream. /// The number of bytes to be written to the current stream. public virtual void Write(byte[] buffer, int offset, int count) { IO.Write(buffer, offset, count); IO.Flush(); } /// /// Creates a new I/O stream of communication with this SSH shell connection /// 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; } } /// /// Gets or sets a value indicating wether this Steam sould remove the terminal emulation's escape sequence characters from the response String. /// public bool RemoveTerminalEmulationCharacters { get{return m_removeTerminalChars;} set{m_removeTerminalChars=value;} } /// /// 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. /// public string ExpectPattern { get{return m_expectPattern.ToString();} set{m_expectPattern = new Regex(value, RegexOptions.Singleline);} } /// /// Reads a response string from the SSH channel. This method will block until the pattern in the 'Prompt' property is matched in the response. /// /// A response string from the SSH server. public string Expect() { return Expect(m_expectPattern); } /// /// Reads a response string from the SSH channel. This method will block until the pattern in the 'Prompt' property is matched in the response. /// /// A response string from the SSH server. public string Expect(string pattern) { return Expect( new Regex( pattern, RegexOptions.Singleline )); } /// /// Reads a response string from the SSH channel. This method will block until the pattern in the 'Prompt' property is matched in the response. /// /// A response string from the SSH server. 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; } /// /// Removes escape sequence characters from the input string. /// 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; } } }