1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-03 15:15:25 +02:00

Support shell output parsing in ssh connections

This commit is contained in:
Martin Oberhuber 2006-08-08 16:57:55 +00:00
parent a604bc4c50
commit b5e8fe024d
14 changed files with 798 additions and 7 deletions

View file

@ -4,6 +4,7 @@ bin.includes = META-INF/,\
about.ini,\
about.mappings,\
about.properties,\
patterns.dat,\
plugin.properties,\
readme.txt,\
eclipse32.png

View file

@ -0,0 +1,283 @@
################################################################################
# Copyright (c) 2006 IBM Corporation. All rights reserved.
# This program and the accompanying materials are made available under the terms
# of the Eclipse Public License v1.0 which accompanies this distribution, and is
# available at http://www.eclipse.org/legal/epl-v10.html
#
# Initial Contributors:
# The following IBM employees contributed to the Remote System Explorer
# component that contains this file: David McKnight, Kushal Munir,
# Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
# Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
#
# Contributors:
# Martin Oberhuber (Wind River) - Adapted from RSE services.local/patterns.dat
################################################################################
#
# parse command line output.
#
# CLICK THIS LINE TO EDIT THIS FILE (PATTERNS.DAT). (When viewing from the Output view)
command: grep -n.*
grep file line pattern =([\w,.,/,(,),\\,\-,\+,\d]*):(\d*):.*
command: grep -.*n.*
grep file line pattern =([\w,.,/,(,),\\,\-,\+,\d]*):(\d*):.*
command: grep .*
grep file pattern =([\w,.,/,(,)\\,\-,\+,\d]*):.*
command: pwd
directory file pattern=([\w,.,/,(,),\\,\-,\+,\d,:]*)
command: nmake.*
error pattern=NMAKE : .*
error file line pattern =([\w,.,\-,\+,(,),\\,:]*)\((\d*):(\d*)\) : error EDC.*
error file pattern =[\w,.,\-,\+,(,),\\,:]*\(([\w,.,/,\\]*)\) : error LNK.*
error file line pattern=([\w,.,/,\-,\+,(,),\\]*):(\d*):\d*\) : error .*
warning file line pattern=([\w,.,/,\-,\+,(,),\\]*)\((\d*):\d*\) : warning .*
informational file line pattern=([\w,.,/,\-,\+,(,),\\]*)\((\d*):\d*\) : informational .*
command: make.*
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(S\).*
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\",, line (\d*)\.\d*: \d*-\d* \(E\).*
warning file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
informational file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
warning file line pattern =([\w,.,/,(,),\-,\+,\\]*):(\d*): warning: .*
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):\d*: warning: .*
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
informational file pattern =([\w,.,/,\\,\-,\+,(,)]*):.*
informational file line pattern =In file included from ([\w,.,/,\\,\-,\+,(,)]*):(\d*):
#iseries c compiler
error file line pattern=[\w,.,/,\\]* Line \d* \"([\w,.,/,\\]*)\", line (\d*)\.\d*: .*
error file line pattern=([\w,.,/,\\]*) Line (\d*)\s.*
#makefile errors
error file line pattern=\"([\w,\.,/,(,),\-,\+,\\]*)\", line (\d*): make:.*
#xlc Options warnings
warning pattern=\(W\) Option .*
#c89 errors
error file line pattern=ERROR CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
warning file line pattern=WARNING CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
informational pattern=CBC\d*\(I\) .*
command: gmake.*
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(S\).*
warning file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
informational file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
warning file line pattern =([\w,.,/,(,),\-,\+,\\]*):(\d*): warning: .*
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):\d*: warning: .*
informational file line pattern =In file included from ([\w,.,/,\\,\-,\+,(,)]*):(\d*):
# ixlc compiler
error file line pattern=[\w,.,/,\\]* Line \d* \"([\w,.,/,\\]*)\", line (\d*)\.\d*: .*
error file line pattern=([\w,.,/,\\]*) Line (\d*)\s.*
# icc compiler
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*),\s(\d*)\.\d*:\s.*
error file line pattern =\"([\w,.,/,\\,\-,\+,(,)]*)\",\sline\s(\d*)\.\d*:\s.*
#generic
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
command: gcc\s.*
error file line pattern=\"([\w,.,/,\\,\-,\+,(,)]*)\", line (\d*)\.\d*: \d*-\d* \(S\).*
warning file line pattern=\"([\w,.,/,\\,\-,\+,(,)]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
informational file line pattern=\"([\w,.,/,\\,\-,\+,(,)]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*): warning: .*
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):\d*: warning: .*
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
informational file pattern =([\w,.,/,\\,\-,\+,(,)]*):.*
informational file line pattern =In file included from ([\w,.,/,\\,\-,\+,(,)]*):(\d*):
command: cc\s.*
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
command: CC\s.*
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
command: c89.*
error file line pattern=ERROR CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
warning file line pattern=WARNING CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
informational pattern=CBC\d*\(I\) .*
command: icc.*
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*),\s(\d*)\.\d*:\s.*
error file line pattern =\"([\w,.,/,\\,\-,\+,(,)]*)\",\sline\s(\d*)\.\d*:\s.*
command: javac.*
warning file line pattern=([\w,.,/,\\,\-,\+,(,),:]*):(\d*): warning.*
error file line pattern=([\w,.,/,\\,\-,\+,(,),:]*):(\d*):.*
command: .*bat\s.*
error file line pattern=\[javac\]\s([\w,.,/,\\,:]*):(\d*):.*
error file line pattern=file:([\w,.,/,\\,:]*):(\d*):.*
command: dir.*
directory file pattern=\d{2}/\d{2}/\d*\s*\d{2}:\d{2}\s[a,p,AM,PM]+\s*<DIR>\s*([\w,.,/,\\,\s,\-,\+,\d]*).*
directory file pattern=.*<DIR>\s*([\w,.,/,\\,\s,\-,\+,\d]*).*
file file pattern=\d{2}/\d{2}/\d*\s*\d{2}:\d{2}\s[a,p,AM,PM]+\s*[\d,,]*\s*([\w,.,/,\\,\s,\-,\+,\d]*).*
directory file pattern=[\d,/,\\,.,-]+.\s*\d{2}[:,.]\d{2}.\s*<DIR>\s*([\w,.,/,\\,\s,\-,\+,\d]*)
file file pattern=[\d,/,\\,.,-]+.\s*\d{2}[:,.]\d{2}.\s*[\d,,,.]*\s*([\w,.,/,\\,\s,\-,\+,\d]*)
command: ls -l.*
file file pattern=-[-,r,w,x]+\s.*\s[\d{4},\d{2}:\d{2}]+,\s([\w,.,/,(,),\\,\-,\+\s,\d]*)
file file pattern=l[-,r,w,x]+\s.*\s[\d{4},\d{2}:\d{2}]+,\s([\w,.,/,(,),\\,\-,\+\s,\d]*)\s->\s[\w,.,/,(,),\\,\-,\+\s,\d]*
file file pattern=-.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)
file file pattern=-.* \d{4} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)
file file pattern=l.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)\s->\s[\w,.,/,(,),\\,\-,\+\s,\d]*
file file pattern=l.* \d{4} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)\s->\s[\w,.,/,(,),\\,\-,\+\s,\d]*
directory file pattern=d.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
directory file pattern=d.*\d{4} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)
command: ls -a.*
file file pattern=-.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
file file pattern=-.* \d{4} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
directory file pattern=d.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
directory file pattern=d.*\d{4} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
command: ls
file file pattern=([\w,\d,.,(,),\-,\+\s]+)
command: ls\s.*
file file pattern=([\w,\d,.,(,),\-,\+\s]+)
command: .*
prompt file pattern=([\w,.,/,(,),\\,\-,\+,\d,:,\s]*)>.*
command: find .*
file file pattern=([\w,.,/,\\,(,),\-]+)
command: env
pathenvvar file pattern=PATH\=(.*)
libpathenvvar file pattern=LIBPATH\=(.*)
libpathenvvar file pattern=LIB\=(.*)
envvar pattern=[\w\d]+\=.*
command: ps
process pattern=[\s]*[\d]+\s.*
command: ps .*
process pattern=[\s]*[\d]+\s.*
command: xl[C,c].*
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\",, line (\d*)\.\d*: \d*-\d* \(S\).*
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(E\).*
warning file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
informational file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
command: ixlc.*
error file line pattern=([\w,.,/,\\]*) Line (\d*)\s.*
error file line pattern=[\w,.,/,\\]* Line \d* \"([\w,.,/,\\]*)\", line (\d*)\.\d*: .*
command: cat.*patterns.*
warning file pattern=# .*(PATTERNS.DAT).*
Output pattern=command: .*
#statement pattern=#.*
statement pattern=.* pattern.*=.*
# special for autoconf
command: ./bootstrap.sc.*
error file line pattern=aclocal: ([\w,.,/,\\]*): (\d*):.*
warning file line pattern=([\w,.,/,\\]*):(\d*):.*
command: ./configure.*
error file line pattern=./(configure): line (\d*): .*
# How Patterns Work
# -----------------
#
# Patterns are used by the Output View to allow lines that contain file names and
# perhaps line numbers to be clicked to cause the file location to be opened in an Editor.
# A line in this file can be 1 of 3 things:
# 1. An empty line or a comment line (denoted by a # in column 1)
# 2. The start of a command description (denoted by a 'command:' at the beginning of the line)
# 3. A pattern description.
# A formal description of the syntax of this file is included at the bottom of this file.
#
#
# Command Descriptions
# --------------------
#
# A Command Description consists of 2 things: A regular expression that describes the
# command invocation, and a list of Pattern Descriptions. The regular expression
# is used to determine what set of Pattern Descriptons to use when parsing command output.
# For example, if you type the command 'gmake clean', the Command Descriptions are checked and
# .*make.* would match that command. Therefore the Pattern Descriptions for .*make.* would
# be used to parse the output of the 'gmake clean'.
# Note: The first Command Description that is found to match the command is used, so make
# sure you put the most specific patterns first. For example, if the nmake.* Command
# Description appeared after .*make.*, then 'nmake install' would be matched by the .*make.*
# Command Descripton, which is probably not what was intended.
#
#
# Pattern Descriptions
# --------------------
#
# A Pattern Description has the following form:
# <obj-name> <match-info> "pattern="<reg-ex>
#
# where:
# <obj-name>: The type of object that will be created in the Output View if
# a line of output matches this pattern.
#
# <match-info>: This is some combination of the words "file" and "line" or nothing
# at all. This is used to define how the backreferences in the
# regular expression are to be interpreted. So "file line" means
# that the first back-reference is a file, and the second is a
# line number. This may seem unnecessary, but we added this capability
# in the event that future releases support other types of information
# that may be useful, such as column info (once we support it).
#
# <reg-ex>: A regular expression that describes a line of output. Backreferences
# are used to store (instead of just match) the filename and line
# number. To store a filename use the backreference ([\w,.,/,\\]*), and
# to store a line number, use (\d*)
#
#
# Note: The patterns are checked against command output and only exact matches are dealt with
# So as an example, if you forget the .* (match everything) at the end of a pattern,
# the match will fail if there are trailing characters in the output not accounted for by
# the pattern
#
#
# Pattern File Syntax
# -------------------
#
# The pattern file syntax should be easy to grasp by looking at the ones
# above, but for those of you who like formal grammars, here it is:
#
# patterns-file:
# commands
#
# commands:
# command
# commands new-line command
#
# command:
# "command:" reg-ex new-line patterns
#
# patterns:
# pattern
# patterns new-line pattern
#
# pattern:
# command-name match-list "pattern=" reg-ex
#
# command-name:
# String that denotes what type of object will be created if some output matches this pattern
#
# match-list:
# file-or-line
# match-list space file-or-line
#
# file-or-line:
# "file" | "line"
#
# reg-ex:
# A regular expression
#
# new-line:
# The new-line character \n
#
# space:
# The space character

View file

@ -15,8 +15,12 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleContext;
@ -61,7 +65,19 @@ public class Activator extends Plugin {
public static Activator getDefault() {
return plugin;
}
/**
* Logs an throwable to the log for this plugin.
* @param t the Throwable to be logged.
*/
public void logException(Throwable t) {
ILog log = getLog();
String id = getBundle().getSymbolicName();
String message = NLS.bind(SshServiceResources.SshPlugin_Unexpected_Exception, t.getClass().getName(), t.getLocalizedMessage());
IStatus status = new Status(IStatus.ERROR, id, 0, message, t);
log.log(status);
}
//<tracing code>----------------------------------------------------
private static Boolean fTracingOn = null;

View file

@ -16,6 +16,8 @@ import org.eclipse.osgi.util.NLS;
public class SshServiceResources extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.rse.services.ssh.SshServiceResources"; //$NON-NLS-1$
public static String SshPlugin_Unexpected_Exception;
public static String SftpFileService_Description;
public static String SftpFileService_Error_JschSessionLost;

View file

@ -9,6 +9,8 @@
# Martin Oberhuber (Wind River) - initial API and implementation
################################################################################
SshPlugin_Unexpected_Exception=Unexpected {0}: {1}
SftpFileService_Name=Ssh / Sftp File Service
SftpFileService_Description=Access a remote file system via Ssh / Sftp protocol
SftpFileService_Error_JschSessionLost=jsch session lost

View file

@ -0,0 +1,60 @@
/********************************************************************************
* Copyright (c) 2001, 2006 IBM Corporation and International Business Machines Corporation. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Initial Contributors:
* The following IBM employees contributed to the Remote System Explorer
* component that contains this file: David McKnight, Kushal Munir,
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Martin Oberhuber (WindRiver) - adapted from services.local
********************************************************************************/
package org.eclipse.rse.services.ssh.shell;
import java.util.ArrayList;
import java.util.regex.Pattern;
public class CommandPattern
{
private Pattern _pattern;
private ArrayList _outputPatterns;
public CommandPattern(Pattern theCommandPattern)
{
_pattern = theCommandPattern;
_outputPatterns = new ArrayList();
}
public void addOutputPattern(OutputPattern op)
{
_outputPatterns.add(op);
}
public boolean matchCommand(String theLine)
{
return _pattern.matcher(theLine).matches();
}
public ParsedOutput matchLine(String theLine)
{
int patterns = _outputPatterns.size();
ParsedOutput matchedOutput;
OutputPattern curPattern;
for (int i = 0; i < patterns; i++)
{
curPattern = (OutputPattern) _outputPatterns.get(i);
matchedOutput = curPattern.matchLine(theLine);
if (matchedOutput != null)
return matchedOutput;
}
return null;
}
}

View file

@ -0,0 +1,98 @@
/********************************************************************************
* Copyright (c) 2001, 2006 IBM Corporation and International Business Machines Corporation. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Initial Contributors:
* The following IBM employees contributed to the Remote System Explorer
* component that contains this file: David McKnight, Kushal Munir,
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Martin Oberhuber (WindRiver) - adapted from services.local
********************************************************************************/
package org.eclipse.rse.services.ssh.shell;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class OutputPattern
{
private Pattern _pattern;
private String _objType;
private ArrayList _matchOrder;
public OutputPattern(String objType, String matchOrder, Pattern thePattern)
{
_objType = objType;
_pattern = thePattern;
_matchOrder = new ArrayList();
//Here we add a dummy first element to the ArrayList, to mimick how the PatternMatcher stores it's
//matches (starting with group 1).
_matchOrder.add(null);
int index = 0;
int nextSpace = 0;
//Walk the matchOrder string parsing out words and adding them to _matchOrder...Could use StringTokenizer
//but this seem much simpler.
while ((nextSpace = matchOrder.indexOf(" ", index)) > 0) //$NON-NLS-1$
{
_matchOrder.add(matchOrder.substring(index, nextSpace).toLowerCase());
index = nextSpace;
while ((index < matchOrder.length()) && (matchOrder.charAt(index) == ' '))
index++;
}
_matchOrder.add(matchOrder.substring(index, matchOrder.length()).toLowerCase());
}
public ParsedOutput matchLine(String theLine)
{
Matcher matcher = null;
try
{
matcher = _pattern.matcher(theLine);
if (!matcher.matches())
return null;
}
catch (StringIndexOutOfBoundsException e)
{
//Getting an exception here, when theLine is an empty line for some patterns..should probably investigate,
//but for now we'll just handle it...
return null;
}
String fileString = ""; //$NON-NLS-1$
String lineString = ""; //$NON-NLS-1$
//Groups start at 1 (group 0 is the entire match).
for (int i = 1; i < _matchOrder.size(); i++)
{
String mStr = (String)_matchOrder.get(i);
if (mStr.equals("file")) //$NON-NLS-1$
fileString = matcher.group(i);
else if (mStr.equals("line")) //$NON-NLS-1$
lineString = matcher.group(i);
}
int line = 1;
if (lineString.length() > 0)
{
try
{
line = Integer.parseInt(lineString);
}
catch (NumberFormatException e)
{
}
}
return new ParsedOutput(_objType, theLine, fileString, line, 1);
}
}

View file

@ -0,0 +1,38 @@
/********************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Initial Contributors:
* The following IBM employees contributed to the Remote System Explorer
* component that contains this file: David McKnight, Kushal Munir,
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Martin Oberhuber (WindRiver) - adapted from services.local
********************************************************************************/
package org.eclipse.rse.services.ssh.shell;
//This is just a convenience object for storing information parsed out of a line of output.
public class ParsedOutput
{
public String type;
public String text;
public String file;
public int line;
public int col;
public ParsedOutput (String theType, String theText, String theFile, int theLine, int theColumn)
{
type = theType;
text = theText;
file = theFile;
line = theLine;
col = theColumn;
}
}

View file

@ -0,0 +1,121 @@
/********************************************************************************
* Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Initial Contributors:
* The following IBM employees contributed to the Remote System Explorer
* component that contains this file: David McKnight, Kushal Munir,
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Martin Oberhuber (WindRiver) - adapted from services.local
********************************************************************************/
package org.eclipse.rse.services.ssh.shell;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Pattern;
import org.osgi.framework.Bundle;
import org.eclipse.rse.services.ssh.Activator;
public class Patterns {
private ArrayList _theCommands;
private String _currentCommand;
public Patterns() {
_theCommands = new ArrayList();
parsePatterns();
}
private void parsePatterns() {
Bundle bundle = Activator.getDefault().getBundle();
URL patterns = bundle.getEntry("/patterns.dat"); //$NON-NLS-1$
if (patterns != null) {
try {
InputStream in = patterns.openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
_theCommands.clear();
String curLine;
CommandPattern curCommand = null;
while ((curLine = reader.readLine()) != null) {
curLine = curLine.trim();
// Skip the current line if it is empty or starts with a #
if ((curLine.length() == 0) || (curLine.charAt(0) == '#')) {
continue;
}
// Check if this line is the start of a new command section
if (curLine.startsWith("command")) { //$NON-NLS-1$
int colon = curLine.indexOf(":"); //$NON-NLS-1$
// Check that there is something after the colon
if (colon == (curLine.length() - 1)) {
continue;
}
Pattern thePattern = Pattern.compile(curLine.substring(colon + 1, curLine.length()).trim());
curCommand = new CommandPattern(thePattern);
_theCommands.add(curCommand);
}
// If we get here, the line must be an output pattern
else {
int firstSpace = curLine.indexOf(" "); //$NON-NLS-1$
int patternWord = curLine.indexOf("pattern"); //$NON-NLS-1$
int firstEquals = curLine.indexOf("="); //$NON-NLS-1$
if ((firstEquals == -1) || (firstEquals == (curLine.length() - 1))) {
continue;
}
String objType = curLine.substring(0, firstSpace);
String matchOrder = curLine.substring(firstSpace + 1, patternWord).trim();
String patternString = curLine.substring(firstEquals + 1, curLine.length());
Pattern thePattern = Pattern.compile(patternString.trim());
if (curCommand != null) {
curCommand.addOutputPattern(new OutputPattern(objType, matchOrder, thePattern));
}
}
}
in.close();
} catch (IOException e) {
Activator.getDefault().logException(e);
}
}
}
public void refresh(String theCommand) {
_currentCommand = theCommand;
parsePatterns();
}
public void update(String theCommand) {
_currentCommand = theCommand;
}
public ParsedOutput matchLine(String theLine) {
CommandPattern curCommand;
ParsedOutput matchedOutput = null;
int commands = _theCommands.size();
if (_currentCommand != null)
{
for (int i = 0; i < commands; i++)
{
curCommand = (CommandPattern) _theCommands.get(i);
if (curCommand.matchCommand(_currentCommand))
{
matchedOutput = curCommand.matchLine(theLine);
}
if (matchedOutput != null)
{
return matchedOutput;
}
}
}
return null;
}
}

View file

@ -20,6 +20,7 @@ import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.IProgressMonitor;
@ -66,7 +67,10 @@ public class SshHostShell extends AbstractHostShell implements IHostShell {
PrintWriter outputWriter = new PrintWriter(outputStream);
fShellWriter = new SshShellWriterThread(outputWriter);
fChannel.connect();
if (initialWorkingDirectory!=null && initialWorkingDirectory.length()>0 && !initialWorkingDirectory.equals(".")) { //$NON-NLS-1$
if (initialWorkingDirectory!=null && initialWorkingDirectory.length()>0
&& !initialWorkingDirectory.equals(".") //$NON-NLS-1$
&& !initialWorkingDirectory.equals("Command Shell") //$NON-NLS-1$ //FIXME workaround for bug 153047
) {
writeToShell("cd "+initialWorkingDirectory); //$NON-NLS-1$
}
} catch(Exception e) {

View file

@ -20,9 +20,6 @@ package org.eclipse.rse.services.ssh.shell;
import java.io.BufferedReader;
import java.io.IOException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.rse.services.shells.AbstractHostShellOutputReader;
import org.eclipse.rse.services.shells.IHostShell;
import org.eclipse.rse.services.shells.IHostShellOutputReader;
@ -142,8 +139,7 @@ public class SshShellOutputReader extends AbstractHostShellOutputReader
//FIXME it's dangerous to return null here since this will end
//our reader thread completely... the exception could just be
//temporary, and we should keep running!
Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.getDefault().getBundle().getSymbolicName(), 0, "IOException in SshShellOutputReader", e));
//e.printStackTrace();
Activator.getDefault().logException(e);
return null;
}
}

View file

@ -12,6 +12,7 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.rse.connectorservice.ssh,
org.eclipse.rse.services.ssh,
org.eclipse.rse.subsystems.shells.core,
org.eclipse.rse.subsystems.files.core,
org.eclipse.rse.shells.ui,
org.eclipse.rse.ui
Eclipse-LazyStart: true

View file

@ -0,0 +1,161 @@
/********************************************************************************
* Copyright (c) 2006 IBM Corporation. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Initial Contributors:
* The following IBM employees contributed to the Remote System Explorer
* component that contains this file: David McKnight, Kushal Munir,
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
*
* Contributors:
* Martin Oberhuber (Wind River) - Adapted from LocalServiceCommandShell
********************************************************************************/
package org.eclipse.rse.subsystems.shells.ssh;
import java.util.ArrayList;
import java.util.regex.Pattern;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.rse.core.subsystems.ISubSystem;
import org.eclipse.rse.internal.subsystems.shells.servicesubsystem.OutputRefreshJob;
import org.eclipse.rse.internal.subsystems.shells.subsystems.RemoteError;
import org.eclipse.rse.internal.subsystems.shells.subsystems.RemoteOutput;
import org.eclipse.rse.services.shells.IHostShell;
import org.eclipse.rse.services.shells.IHostShellChangeEvent;
import org.eclipse.rse.services.ssh.shell.ParsedOutput;
import org.eclipse.rse.services.ssh.shell.Patterns;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
import org.eclipse.rse.subsystems.shells.core.model.ISystemOutputRemoteTypes;
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem;
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteOutput;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ServiceCommandShell;
public class SshServiceCommandShell extends ServiceCommandShell implements ISystemOutputRemoteTypes
{
private Patterns _patterns;
private String _curCommand;
private String _workingDir;
private IRemoteFileSubSystem _fs;
public SshServiceCommandShell(IRemoteCmdSubSystem cmdSS, IHostShell hostShell)
{
super(cmdSS, hostShell);
_patterns = new Patterns();
_patterns.update("cmd"); //$NON-NLS-1$
ISubSystem[] sses = cmdSS.getHost().getSubSystems();
for (int i = 0; i < sses.length; i++)
{
if (sses[i] instanceof IRemoteFileSubSystem)
{
_fs = (IRemoteFileSubSystem)sses[i];
}
}
}
public Object getContext()
{
String workingDir = _workingDir;
if (workingDir != null && workingDir.length() > 0)
{
try
{
return _fs.getRemoteFileObject(workingDir);
}
catch (Exception e)
{
}
}
return null;
}
public void shellOutputChanged(IHostShellChangeEvent event)
{
Object[] lines = event.getLines();
boolean gotCommand = false;
ArrayList outputs = new ArrayList(lines.length);
for (int i = 0; i < lines.length; i++)
{
String line = (String)lines[i];
if (line.endsWith(getPromptCommand())) {
continue; //ignore our synthetic prompt command
}
ParsedOutput parsedMsg = null;
if (!gotCommand && line.equals(_curCommand)) {
gotCommand = true;
} else {
try {
parsedMsg = _patterns.matchLine(line);
}
catch (Throwable e) {
e.printStackTrace();
}
}
RemoteOutput output = null;
String type = "stdout"; //$NON-NLS-1$
if (parsedMsg != null) {
type = parsedMsg.type;
}
if (event.isError()) {
output = new RemoteError(this, type);
}
else {
output = new RemoteOutput(this, type);
}
output.setText(line);
if (parsedMsg != null)
{
String file = parsedMsg.file;
if (type.equals("prompt")) //$NON-NLS-1$
{
_workingDir = file;
output.setAbsolutePath(_workingDir);
}
else if(_workingDir!=null)
{
IPath p = new Path(_workingDir).append(file);
output.setAbsolutePath(p.toString());
}
else
{
output.setAbsolutePath(file);
}
}
addOutput(output);
outputs.add(output);
}
if (_lastRefreshJob == null || _lastRefreshJob.isComplete())
{
IRemoteOutput[] remoteOutputs = (IRemoteOutput[])outputs.toArray(new IRemoteOutput[outputs.size()]);
_lastRefreshJob = new OutputRefreshJob(this, remoteOutputs, false);
_lastRefreshJob.schedule();
}
}
private static final Pattern cdCommands = Pattern.compile("\\A\\s*(cd|chdir|ls)\\b"); //$NON-NLS-1$
protected String getPromptCommand() {
return "echo $PWD'>'"; //$NON-NLS-1$
}
public void writeToShell(String cmd)
{
_curCommand = cmd;
_patterns.update(cmd);
if (cdCommands.matcher(cmd).find()) {
cmd += "\r\n" + getPromptCommand(); //$NON-NLS-1$
}
super.writeToShell(cmd);
}
}

View file

@ -21,9 +21,12 @@ import org.eclipse.rse.connectorservice.ssh.SshConnectorServiceManager;
import org.eclipse.rse.core.subsystems.IConnectorService;
import org.eclipse.rse.core.subsystems.ISubSystem;
import org.eclipse.rse.model.IHost;
import org.eclipse.rse.services.shells.IHostShell;
import org.eclipse.rse.services.shells.IShellService;
import org.eclipse.rse.services.ssh.ISshService;
import org.eclipse.rse.services.ssh.shell.SshShellService;
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IServiceCommandShell;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystem;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystemConfiguration;
@ -72,4 +75,9 @@ public class SshShellSubSystemConfiguration extends
return ISshService.class;
}
public IServiceCommandShell createRemoteCommandShell(IRemoteCmdSubSystem cmdSS, IHostShell hostShell)
{
return new SshServiceCommandShell(cmdSS, hostShell);
}
}