mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 23:05:47 +02:00
[261478] Removed SshShellService, TelnetShellService and related classes.
This commit is contained in:
parent
37699260b8
commit
ef55e61199
19 changed files with 35 additions and 1189 deletions
|
@ -13,6 +13,5 @@ Bundle-ActivationPolicy: lazy
|
|||
Eclipse-LazyStart: true
|
||||
Export-Package: org.eclipse.rse.internal.services.ssh;x-friends:="org.eclipse.rse.connectorservice.ssh,org.eclipse.rse.subsystems.files.ssh,org.eclipse.rse.subsystems.shells.ssh",
|
||||
org.eclipse.rse.internal.services.ssh.files;x-friends:="org.eclipse.rse.connectorservice.ssh,org.eclipse.rse.subsystems.files.ssh,org.eclipse.rse.subsystems.shells.ssh",
|
||||
org.eclipse.rse.internal.services.ssh.shell;x-friends:="org.eclipse.rse.connectorservice.ssh,org.eclipse.rse.subsystems.files.ssh,org.eclipse.rse.subsystems.shells.ssh",
|
||||
org.eclipse.rse.internal.services.ssh.terminal;x-friends:="org.eclipse.rse.subsystems.shells.ssh"
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.4
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2007 Wind River Systems, Inc.
|
||||
* Copyright (c) 2006, 2009 Wind River Systems, Inc.
|
||||
* 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
* Yu-Fen Kuo (MontaVista) - [170910] Integrate the TM Terminal View with RSE
|
||||
* Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.ssh;
|
||||
|
@ -31,10 +32,6 @@ public class SshServiceResources extends NLS {
|
|||
|
||||
public static String SftpFileService_Name;
|
||||
|
||||
public static String SshShellService_Description;
|
||||
|
||||
public static String SshShellService_Name;
|
||||
|
||||
public static String SshTerminalService_Name;
|
||||
|
||||
public static String SshTerminalService_Description;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
################################################################################
|
||||
# Copyright (c) 2006 Wind River Systems, Inc.
|
||||
# Copyright (c) 2006, 2009 Wind River Systems, Inc. and others.
|
||||
# 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
# Contributors:
|
||||
# Martin Oberhuber (Wind River) - initial API and implementation
|
||||
# Yu-Fen Kuo (MontaVista) - [170910] Integrate the TM Terminal View with RSE
|
||||
# Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
################################################################################
|
||||
|
||||
# NLS_MESSAGEFORMAT_VAR
|
||||
|
@ -22,8 +23,5 @@ SftpFileService_Error_upload_size=Ssh upload: file size mismatch for {0}
|
|||
SftpFileService_Error_download_size=Ssh download: file size mismatch for {0}
|
||||
SftpFileService_Msg_Progress={0,number,integer} KB of {1,number,integer} KB complete ({2,number,percent})
|
||||
|
||||
SshShellService_Name=SSH Shell Service
|
||||
SshShellService_Description=SSH Shell Service Description
|
||||
|
||||
SshTerminalService_Name=SSH Terminal Service
|
||||
SshTerminalService_Description=SSH Terminal Service Description
|
||||
|
|
|
@ -1,208 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 IBM Corporation and others.
|
||||
* 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 LocalHostShell.
|
||||
* David McKnight (IBM) - [191599] Use the remote encoding specified in the host property page
|
||||
* David McKnight (IBM) - [196301] Check that the remote encoding isn't null before using it
|
||||
* Martin Oberhuber (Wind River) - [204744] Honor encoding in SSH command input field
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable
|
||||
* Anna Dushistova (MontaVista) - [258720] SshHostShell fails to run command if initialWorkingDirectory supplied
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.ssh.shell;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Hashtable;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelShell;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
import org.eclipse.rse.internal.services.ssh.ISshSessionProvider;
|
||||
import org.eclipse.rse.services.clientserver.PathUtility;
|
||||
import org.eclipse.rse.services.shells.AbstractHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShellOutputReader;
|
||||
|
||||
/**
|
||||
* A Shell subsystem for SSH.
|
||||
*/
|
||||
public class SshHostShell extends AbstractHostShell implements IHostShell {
|
||||
|
||||
public static final String SHELL_INVOCATION = ">"; //$NON-NLS-1$
|
||||
|
||||
private ISshSessionProvider fSessionProvider;
|
||||
private Channel fChannel;
|
||||
private SshShellOutputReader fStdoutHandler;
|
||||
private SshShellOutputReader fStderrHandler;
|
||||
private SshShellWriterThread fShellWriter;
|
||||
|
||||
public SshHostShell(ISshSessionProvider sessionProvider, String initialWorkingDirectory, String commandToRun, String encoding, String[] environment) {
|
||||
try {
|
||||
fSessionProvider = sessionProvider;
|
||||
fChannel = fSessionProvider.getSession().openChannel("shell"); //$NON-NLS-1$
|
||||
|
||||
////disable pty mode. This works in jsch-0.1.25 and later only.
|
||||
////By default, jsch always creates a vt100 connection sized
|
||||
////80x24 / 640x480 (dimensions can be changed).
|
||||
////I wonder whether jsch could give us a dumb terminal?
|
||||
//if(commandToRun!=null && !commandToRun.equals(SHELL_INVOCATION) & (fChannel instanceof ChannelShell)) {
|
||||
// ((ChannelShell)fChannel).setPty(false);
|
||||
//}
|
||||
|
||||
//Try to set the user environment. On most sshd configurations, this will
|
||||
//not work since in sshd_config, PermitUserEnvironment and AcceptEnv
|
||||
//settings are disabled. Still, it's worth a try.
|
||||
if (environment!=null && environment.length>0 && fChannel instanceof ChannelShell) {
|
||||
Hashtable envTable=new Hashtable();
|
||||
for(int i=0; i<environment.length; i++) {
|
||||
String curStr=environment[i];
|
||||
int curLen=environment[i].length();
|
||||
int idx = curStr.indexOf('=');
|
||||
if (idx>0 && idx<curLen-1) {
|
||||
String key=environment[i].substring(0, idx);
|
||||
String value=environment[i].substring(idx+1, curLen);
|
||||
envTable.put(key, value);
|
||||
}
|
||||
}
|
||||
((ChannelShell)fChannel).setEnv(envTable);
|
||||
}
|
||||
|
||||
if (encoding != null)
|
||||
{
|
||||
fStdoutHandler = new SshShellOutputReader(this, new BufferedReader(new InputStreamReader(fChannel.getInputStream(), encoding)), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// default encoding - same as
|
||||
// System.getProperty("file.encoding")
|
||||
// TODO should try to determine remote encoding if possible
|
||||
fStdoutHandler = new SshShellOutputReader(this, new BufferedReader(new InputStreamReader(fChannel.getInputStream())), false);
|
||||
}
|
||||
fStderrHandler = new SshShellOutputReader(this, null,true);
|
||||
OutputStream outputStream = fChannel.getOutputStream();
|
||||
if (encoding!=null) {
|
||||
//use specified encoding
|
||||
Charset cs = Charset.forName(encoding);
|
||||
PrintWriter outputWriter = new PrintWriter(
|
||||
new OutputStreamWriter(outputStream,cs));
|
||||
fShellWriter = new SshShellWriterThread(outputWriter);
|
||||
} else {
|
||||
PrintWriter outputWriter = new PrintWriter(outputStream);
|
||||
fShellWriter = new SshShellWriterThread(outputWriter);
|
||||
}
|
||||
fChannel.connect();
|
||||
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 "+PathUtility.enQuoteUnix(initialWorkingDirectory)); //$NON-NLS-1$
|
||||
}
|
||||
if (SHELL_INVOCATION.equals(commandToRun)) {
|
||||
writeToShell(getPromptCommand());
|
||||
} else if(commandToRun!=null && commandToRun.length()>0) {
|
||||
writeToShell(commandToRun);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
//TODO [209043] Forward exception to RSE properly
|
||||
e.printStackTrace();
|
||||
if (fShellWriter!=null) {
|
||||
fShellWriter.stopThread();
|
||||
fShellWriter = null;
|
||||
}
|
||||
if (fStderrHandler!=null) {
|
||||
fStderrHandler.interrupt();
|
||||
fStderrHandler = null;
|
||||
}
|
||||
if (fStdoutHandler!=null) {
|
||||
fStdoutHandler.interrupt();
|
||||
fStdoutHandler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to remote system and launch Threads for the shell as needed.
|
||||
*
|
||||
* @param monitor progress monitor for long-running operation
|
||||
*/
|
||||
protected void start(IProgressMonitor monitor)
|
||||
{
|
||||
//TODO Move stuff from constructor to here
|
||||
//TODO Set up environment variables for proper prompting, e.g. like dstore
|
||||
//varTable.put("PS1","$PWD/>");
|
||||
//varTable.put("COLUMNS","256");
|
||||
//alias ls='ls -1'
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
if (fChannel!=null && !fChannel.isEOF()) {
|
||||
return true;
|
||||
}
|
||||
// shell is not active: check for session lost
|
||||
exit();
|
||||
Session session = fSessionProvider.getSession();
|
||||
if (session!=null && !session.isConnected()) {
|
||||
fSessionProvider.handleSessionLost();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Pattern cdCommands = Pattern.compile("\\A\\s*(cd|chdir|ls)\\b"); //$NON-NLS-1$
|
||||
|
||||
public String getPromptCommand() {
|
||||
return "echo $PWD'>'"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void writeToShell(String command) {
|
||||
if (isActive()) {
|
||||
if ("#break".equals(command)) { //$NON-NLS-1$
|
||||
command = "\u0003"; //Unicode 3 == Ctrl+C //$NON-NLS-1$
|
||||
} else if (cdCommands.matcher(command).find()) {
|
||||
command += "\r\n" + getPromptCommand(); //$NON-NLS-1$
|
||||
}
|
||||
if (!fShellWriter.sendCommand(command)) {
|
||||
//exception occurred: terminate writer thread, cancel connection
|
||||
exit();
|
||||
isActive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IHostShellOutputReader getStandardOutputReader() {
|
||||
return fStdoutHandler;
|
||||
}
|
||||
|
||||
public IHostShellOutputReader getStandardErrorReader() {
|
||||
return fStderrHandler;
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
if (fShellWriter!=null) {
|
||||
fShellWriter.stopThread();
|
||||
}
|
||||
if (fChannel!=null) {
|
||||
fChannel.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2007 IBM Corporation and others.
|
||||
* 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 LocalShellOutputReader.
|
||||
* Martin Oberhuber (Wind River) - Added vt100 escape sequence ignoring.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.ssh.shell;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.rse.internal.services.ssh.Activator;
|
||||
import org.eclipse.rse.services.shells.AbstractHostShellOutputReader;
|
||||
import org.eclipse.rse.services.shells.IHostOutput;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShellOutputReader;
|
||||
import org.eclipse.rse.services.shells.SimpleHostOutput;
|
||||
|
||||
/**
|
||||
* Listener to shell output. As io streams through, refresh events are sent out
|
||||
* for the OutputChangeListener to respond to.
|
||||
* VT100 terminal escape sequences are ignored.
|
||||
*/
|
||||
public class SshShellOutputReader extends AbstractHostShellOutputReader
|
||||
implements IHostShellOutputReader {
|
||||
|
||||
protected BufferedReader fReader;
|
||||
private String fPromptChars = ">$%#]"; //Characters we accept as the end of a prompt //$NON-NLS-1$;
|
||||
|
||||
public SshShellOutputReader(IHostShell hostShell, BufferedReader reader,
|
||||
boolean isErrorReader) {
|
||||
super(hostShell, isErrorReader);
|
||||
setName("Ssh ShellOutputReader"+getName()); //$NON-NLS-1$
|
||||
fReader = reader;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
//check for active session and notify lost session if necessary
|
||||
getHostShell().isActive();
|
||||
}
|
||||
|
||||
protected IHostOutput internalReadLine() {
|
||||
if (fReader == null) {
|
||||
//Our workaround sets the stderr reader to null, so we never give any stderr output.
|
||||
//TODO Check if ssh supports some method of having separate stdout and stderr streams
|
||||
return null;
|
||||
}
|
||||
StringBuffer theLine = new StringBuffer();
|
||||
StringBuffer theDebugLine = null;
|
||||
theDebugLine = new StringBuffer();
|
||||
int ch;
|
||||
boolean done = false;
|
||||
while (!done && !isFinished()) {
|
||||
try {
|
||||
ch = fReader.read();
|
||||
switch (ch) {
|
||||
case -1:
|
||||
case 65535:
|
||||
if (theLine.length() == 0) // End of Reader
|
||||
return null;
|
||||
done = true;
|
||||
break;
|
||||
case '\b': //backspace
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
int len = theLine.length()-1;
|
||||
if (len>=0) theLine.deleteCharAt(len);
|
||||
break;
|
||||
case 13:
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
break; // Carriage Return: dont append to the buffer
|
||||
case 10:
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
done = true; // Newline
|
||||
break;
|
||||
case 9:
|
||||
//Tab: we count tabs at column 8
|
||||
//TODO Check: SystemViewRemoteOutputAdapter.translateTabs() also translates
|
||||
//Therefore this special handling here might be unnecessary
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
int tabIndex = theLine.length() % 8;
|
||||
while (tabIndex < 8) {
|
||||
theLine.append(' ');
|
||||
tabIndex++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
char tch = (char) ch;
|
||||
if(theDebugLine!=null) theDebugLine.append(tch);
|
||||
if (!Character.isISOControl(tch)) {
|
||||
theLine.append(tch); // Any other character
|
||||
} else if (ch == 27) {
|
||||
// Escape: ignore next char too
|
||||
int nch = fReader.read();
|
||||
if (theDebugLine!=null) theDebugLine.append((char)nch);
|
||||
if (nch == 91) {
|
||||
//vt100 escape sequence: read until end-of-command (skip digits and semicolon)
|
||||
//e.g. \x1b;13;m --> ignore the entire command, including the trailing m
|
||||
do {
|
||||
nch = fReader.read();
|
||||
if (theDebugLine!=null) theDebugLine.append((char)nch);
|
||||
} while (Character.isDigit((char)nch) || nch == ';');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the BufferedReader is still ready which means
|
||||
// there are more characters
|
||||
// in the Buffer...If not, then we assume it is waiting for
|
||||
// input.
|
||||
if (!done && !fReader.ready()) {
|
||||
// wait to make sure -- max. 500 msec to wait for new chars
|
||||
// if we are not at a CRLF seems to be appropriate for the
|
||||
// Pipes and Threads in ssh.
|
||||
long waitIncrement = 500;
|
||||
// Check if we think we are at a prompt
|
||||
int len = theLine.length()-1;
|
||||
while (len>0 && Character.isSpaceChar(theLine.charAt(len))) {
|
||||
len--;
|
||||
}
|
||||
if (len>=0 && fPromptChars.indexOf(theLine.charAt(len))>=0) {
|
||||
waitIncrement = 5; //wait only 5 msec if we think it's a prompt
|
||||
}
|
||||
try {
|
||||
Thread.sleep(waitIncrement);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
if (!fReader.ready()) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//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().logException(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (theDebugLine!=null) {
|
||||
String debugLine = theDebugLine.toString();
|
||||
debugLine.compareTo(""); //$NON-NLS-1$
|
||||
}
|
||||
return new SimpleHostOutput(theLine.toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,114 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 IBM Corporation and others.
|
||||
* 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 LocalShellService.
|
||||
* Martin Oberhuber (Wind River) - [186128] Move IProgressMonitor last in all API
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
* Martin Oberhuber (Wind River) - [170910] Adopt RSE ITerminalService API for SSH
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.ssh.shell;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
import org.eclipse.rse.internal.services.ssh.ISshService;
|
||||
import org.eclipse.rse.internal.services.ssh.ISshSessionProvider;
|
||||
import org.eclipse.rse.internal.services.ssh.SshServiceResources;
|
||||
import org.eclipse.rse.internal.services.ssh.terminal.SshTerminalService;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.shells.AbstractShellService;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
||||
/**
|
||||
* A Shell Services for ssh.
|
||||
* Adapted from LocalShellService.
|
||||
*/
|
||||
public class SshShellService extends AbstractShellService implements ISshService {
|
||||
|
||||
private final ISshSessionProvider fSessionProvider;
|
||||
private SshTerminalService fRelatedTerminalService;
|
||||
|
||||
public SshShellService(ISshSessionProvider sessionProvider) {
|
||||
fSessionProvider = sessionProvider;
|
||||
}
|
||||
|
||||
public IHostShell launchShell(String initialWorkingDirectory,
|
||||
String encoding, String[] environment,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, SshHostShell.SHELL_INVOCATION, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public IHostShell runCommand(String initialWorkingDirectory,
|
||||
String command, String encoding, String[] environment,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, command, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an RSE ITerminalService related to this Shell Service.
|
||||
*/
|
||||
protected synchronized SshTerminalService getRelatedTerminalService() {
|
||||
if (fRelatedTerminalService == null) {
|
||||
fRelatedTerminalService = new SshTerminalService(getSessionProvider());
|
||||
}
|
||||
return fRelatedTerminalService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt this shell service to different (potentially contributed)
|
||||
* interfaces.
|
||||
*
|
||||
* Asks the adapter manager first whether it got any contributed adapter; if
|
||||
* none is found contributed externally, try to adapt to an
|
||||
* SshTerminalService. That way, clients can easily convert this
|
||||
* IShellService into an ITerminalService:
|
||||
*
|
||||
* <pre>
|
||||
* ITerminalService ts = (ITerminalService) myShellService.getAdapter(ITerminalService.class);
|
||||
* </pre>
|
||||
*
|
||||
* @see IAdaptable
|
||||
* @see PlatformObject#getAdapter(Class)
|
||||
*/
|
||||
public Object getAdapter(Class adapter) {
|
||||
// TODO I'm not sure if this is the right way doing things. First of
|
||||
// all, we're holding on to the created terminal service forever if
|
||||
// we're asked for it, thus needing extra memory.
|
||||
// Second, by asking the adapter manager first, we might get no chance
|
||||
// returning what we think is right.
|
||||
Object o = super.getAdapter(adapter);
|
||||
if (o == null && adapter.isAssignableFrom(SshTerminalService.class)) {
|
||||
return getRelatedTerminalService();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return SshServiceResources.SshShellService_Name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return SshServiceResources.SshShellService_Description;
|
||||
}
|
||||
|
||||
public ISshSessionProvider getSessionProvider() {
|
||||
return fSessionProvider;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2007 Wind River Systems, Inc.
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.ssh.shell;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* The SshShellWriterThread is a Thread used to print commands into
|
||||
* a running ssh shell channel.
|
||||
*
|
||||
* A separate Thread is needed because the PipedInputStream
|
||||
* used by ssh requires that the writing end of the Pipe be
|
||||
* a Thread that remains alive during the entire lifetime
|
||||
* of the shell.
|
||||
*/
|
||||
public class SshShellWriterThread extends Thread
|
||||
{
|
||||
private PrintWriter fOutputWriter;
|
||||
private String fNextCommand;
|
||||
private boolean fIsCancelled;
|
||||
|
||||
|
||||
/**
|
||||
* constructor for ssh shell writer thread
|
||||
* @param outputWriter PrintWriter to write to in separate Thread
|
||||
*/
|
||||
public SshShellWriterThread(PrintWriter outputWriter)
|
||||
{
|
||||
super();
|
||||
fOutputWriter = outputWriter;
|
||||
setName("Ssh ShellWriter"+getName()); //$NON-NLS-1$
|
||||
start();
|
||||
}
|
||||
|
||||
public synchronized boolean isDone()
|
||||
{
|
||||
return fIsCancelled;
|
||||
}
|
||||
|
||||
public synchronized void stopThread()
|
||||
{
|
||||
fIsCancelled = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write command to remote side. Wait until the
|
||||
* thread takes the command (no queueing).
|
||||
* @param command to send
|
||||
* @return boolean true if command was sent ok
|
||||
*/
|
||||
public synchronized boolean sendCommand(String command)
|
||||
{
|
||||
try {
|
||||
//In case multiple commands try to send:
|
||||
//wait until it's our turn
|
||||
while (!fIsCancelled && fNextCommand!=null) {
|
||||
wait();
|
||||
}
|
||||
if (!fIsCancelled) {
|
||||
//Now it's our turn
|
||||
fNextCommand = command;
|
||||
notifyAll();
|
||||
//Wait until our command is processed
|
||||
while (!fIsCancelled && fNextCommand!=null) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
stopThread();
|
||||
}
|
||||
return !fIsCancelled;
|
||||
}
|
||||
|
||||
public synchronized void run()
|
||||
{
|
||||
try {
|
||||
while (!fIsCancelled) {
|
||||
while (fNextCommand==null && !fIsCancelled) {
|
||||
wait();
|
||||
}
|
||||
if (!fIsCancelled) {
|
||||
fOutputWriter.println(fNextCommand);
|
||||
fNextCommand=null;
|
||||
notifyAll();
|
||||
if (fOutputWriter.checkError()) { //flush AND get error
|
||||
stopThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
/* no special handling -> close stream */
|
||||
} finally {
|
||||
stopThread();
|
||||
fOutputWriter.close();
|
||||
fOutputWriter = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc.
|
||||
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
|
||||
* 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
|
||||
|
@ -7,18 +7,16 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
* Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.services.ssh.terminal;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
import org.eclipse.rse.internal.services.ssh.ISshService;
|
||||
import org.eclipse.rse.internal.services.ssh.ISshSessionProvider;
|
||||
import org.eclipse.rse.internal.services.ssh.SshServiceResources;
|
||||
import org.eclipse.rse.internal.services.ssh.shell.SshShellService;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.terminals.AbstractTerminalService;
|
||||
import org.eclipse.rse.services.terminals.ITerminalShell;
|
||||
|
@ -29,7 +27,6 @@ import org.eclipse.rse.services.terminals.ITerminalShell;
|
|||
public class SshTerminalService extends AbstractTerminalService implements ISshService {
|
||||
|
||||
private final ISshSessionProvider fSessionProvider;
|
||||
private SshShellService fRelatedShellService;
|
||||
|
||||
public SshTerminalService(ISshSessionProvider sessionProvider) {
|
||||
fSessionProvider = sessionProvider;
|
||||
|
@ -45,45 +42,6 @@ public class SshTerminalService extends AbstractTerminalService implements ISshS
|
|||
return hostShell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an RSE IShellService related to this Terminal Service.
|
||||
*/
|
||||
protected synchronized SshShellService getRelatedShellService() {
|
||||
if (fRelatedShellService == null) {
|
||||
fRelatedShellService = new SshShellService(getSessionProvider());
|
||||
}
|
||||
return fRelatedShellService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt this terminal service to different (potentially contributed)
|
||||
* interfaces, in order to provide additional functionality.
|
||||
*
|
||||
* Asks the adapter manager first whether it got any contributed adapter; if
|
||||
* none is found contributed externally, try to adapt to an SshShellService.
|
||||
* That way, clients can easily convert this ITerminalService into an
|
||||
* IShellService:
|
||||
*
|
||||
* <pre>
|
||||
* IShellService ss = (IShellService) myTerminalService.getAdapter(IShellService.class);
|
||||
* </pre>
|
||||
*
|
||||
* @see IAdaptable
|
||||
* @see PlatformObject#getAdapter(Class)
|
||||
*/
|
||||
public Object getAdapter(Class adapter) {
|
||||
// TODO I'm not sure if this is the right way doing things. First of
|
||||
// all, we're holding on to the created terminal service forever if
|
||||
// we're asked for it, thus needing extra memory.
|
||||
// Second, by asking the adapter manager first, we might get no chance
|
||||
// returning what we think is right.
|
||||
Object o = super.getAdapter(adapter);
|
||||
if (o==null && adapter.isAssignableFrom(SshShellService.class)) {
|
||||
return getRelatedShellService();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return SshServiceResources.SshTerminalService_Name;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ Require-Bundle: org.eclipse.core.runtime,
|
|||
org.eclipse.rse.services;bundle-version="[3.1.0,4.0.0)",
|
||||
org.apache.commons.net;bundle-version="[1.4.1,2.0.0)"
|
||||
Export-Package: org.eclipse.rse.internal.services.telnet;x-friends:="org.eclipse.rse.connectorservice.telnet,org.eclipse.rse.subsystems.files.telnet,org.eclipse.rse.subsystems.shells.telnet",
|
||||
org.eclipse.rse.internal.services.telnet.shell;x-friends:="org.eclipse.rse.connectorservice.telnet,org.eclipse.rse.subsystems.shells.telnet",
|
||||
org.eclipse.rse.internal.services.telnet.terminal;x-friends:="org.eclipse.rse.subsystems.shells.telnet"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Eclipse-LazyStart: true
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 IBM Corporation and others.
|
||||
* 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 LocalHostShell.
|
||||
* Sheldon D'souza (Celunite) - Adapted from SshHostShell
|
||||
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
|
||||
* David McKnight (IBM) - [191599] Use the remote encoding specified in the host property page
|
||||
* Martin Oberhuber (Wind River) - [194466] Fix shell terminated state when stream is closed
|
||||
* Anna Dushistova (MontaVista) - [258720] SshHostShell fails to run command if initialWorkingDirectory supplied
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.services.telnet.shell;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.net.telnet.TelnetClient;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider;
|
||||
import org.eclipse.rse.services.clientserver.PathUtility;
|
||||
import org.eclipse.rse.services.shells.AbstractHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShellOutputReader;
|
||||
|
||||
public class TelnetHostShell extends AbstractHostShell implements IHostShell {
|
||||
|
||||
public static final String SHELL_INVOCATION = ">"; //$NON-NLS-1$
|
||||
|
||||
private ITelnetSessionProvider fSessionProvider;
|
||||
private TelnetShellOutputReader fStdoutHandler;
|
||||
private TelnetShellOutputReader fStderrHandler;
|
||||
private TelnetShellWriterThread fShellWriter;
|
||||
private TelnetClient fTelnetClient;
|
||||
|
||||
public TelnetHostShell(ITelnetSessionProvider sessionProvider, String initialWorkingDirectory, String commandToRun, String encoding, String[] environment) {
|
||||
try {
|
||||
fSessionProvider = sessionProvider;
|
||||
|
||||
fTelnetClient = fSessionProvider.makeNewTelnetClient(new NullProgressMonitor());
|
||||
|
||||
if (encoding != null)
|
||||
{
|
||||
fStdoutHandler = new TelnetShellOutputReader(this, new BufferedReader(new InputStreamReader(fTelnetClient.getInputStream(), encoding)), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
fStdoutHandler = new TelnetShellOutputReader(this, new BufferedReader(new InputStreamReader(fTelnetClient.getInputStream())), false);
|
||||
}
|
||||
|
||||
fStderrHandler = new TelnetShellOutputReader(this, null,true);
|
||||
OutputStream outputStream = fTelnetClient.getOutputStream();
|
||||
//TODO check if encoding or command to execute needs to be considered
|
||||
//If a command is given, it might be possible to do without a Thread
|
||||
//Charset cs = Charset.forName(encoding);
|
||||
//PrintWriter outputWriter = new PrintWriter(
|
||||
// new BufferedWriter(new OutputStreamWriter(outputStream,cs)));
|
||||
PrintWriter outputWriter = new PrintWriter(outputStream);
|
||||
fShellWriter = new TelnetShellWriterThread(outputWriter);
|
||||
|
||||
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 "+PathUtility.enQuoteUnix(initialWorkingDirectory)); //$NON-NLS-1$
|
||||
}
|
||||
if (SHELL_INVOCATION.equals(commandToRun)) {
|
||||
writeToShell(getPromptCommand());
|
||||
} else if(commandToRun!=null && commandToRun.length()>0) {
|
||||
writeToShell(commandToRun);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
//TODO [209043] Forward exception to RSE properly
|
||||
e.printStackTrace();
|
||||
if (fShellWriter!=null) {
|
||||
fShellWriter.stopThread();
|
||||
fShellWriter = null;
|
||||
}
|
||||
if (fStderrHandler!=null) {
|
||||
fStderrHandler.interrupt();
|
||||
fStderrHandler = null;
|
||||
}
|
||||
if (fStdoutHandler!=null) {
|
||||
fStdoutHandler.interrupt();
|
||||
fStdoutHandler = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getPromptCommand() {
|
||||
return "echo $PWD'>'"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
if (fShellWriter.isAlive()) {
|
||||
fShellWriter.stopThread();
|
||||
}
|
||||
try {
|
||||
//TODO disconnect should better be done via the ConnectorService!!
|
||||
//Because like we do it here, the connector service is not notified!
|
||||
if (fTelnetClient!=null) {
|
||||
synchronized(fTelnetClient) {
|
||||
if (fTelnetClient.isConnected())
|
||||
fTelnetClient.disconnect();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IHostShellOutputReader getStandardOutputReader() {
|
||||
return fStdoutHandler;
|
||||
}
|
||||
|
||||
public IHostShellOutputReader getStandardErrorReader() {
|
||||
return fStderrHandler;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
if (fTelnetClient!=null && fTelnetClient.isConnected() && !fStdoutHandler.isFinished()) {
|
||||
return true;
|
||||
}
|
||||
// shell is not active: check for session lost
|
||||
exit();
|
||||
|
||||
////MOB: Telnet sessions are really independent of each other.
|
||||
////So if one telnet session disconnects, it must not disconnect
|
||||
////the other sessions.
|
||||
//if (fTelnetClient!=null && !fTelnetClient.isConnected()) {
|
||||
// fSessionProvider.handleSessionLost();
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final Pattern cdCommands = Pattern.compile("\\A\\s*(cd|chdir|ls)\\b"); //$NON-NLS-1$
|
||||
|
||||
public void writeToShell(String command) {
|
||||
if (isActive()) {
|
||||
if ("#break".equals(command)) { //$NON-NLS-1$
|
||||
command = "\u0003"; //Unicode 3 == Ctrl+C //$NON-NLS-1$
|
||||
} else if (cdCommands.matcher(command).find()) {
|
||||
command += "\r\n" + getPromptCommand(); //$NON-NLS-1$
|
||||
}
|
||||
if (!fShellWriter.sendCommand(command)) {
|
||||
//exception occurred: terminate writer thread, cancel connection
|
||||
exit();
|
||||
isActive();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2007 IBM Corporation and others.
|
||||
* 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 LocalShellOutputReader.
|
||||
* Martin Oberhuber (Wind River) - Added vt100 escape sequence ignoring.
|
||||
* Sheldon D'souza (Celunite) - Adapted from SshShellOutputReader
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.services.telnet.shell;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.rse.internal.services.telnet.Activator;
|
||||
import org.eclipse.rse.services.shells.AbstractHostShellOutputReader;
|
||||
import org.eclipse.rse.services.shells.IHostOutput;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.SimpleHostOutput;
|
||||
|
||||
public class TelnetShellOutputReader extends AbstractHostShellOutputReader {
|
||||
|
||||
|
||||
protected BufferedReader fReader;
|
||||
private String fPromptChars = ">$%#]"; //$NON-NLS-1$
|
||||
|
||||
public TelnetShellOutputReader(IHostShell hostShell, BufferedReader reader,boolean isErrorReader) {
|
||||
super(hostShell, isErrorReader);
|
||||
setName("Telnet ShellOutputReader"+getName()); //$NON-NLS-1$
|
||||
fReader = reader;
|
||||
}
|
||||
|
||||
protected IHostOutput internalReadLine() {
|
||||
if (fReader == null) {
|
||||
//Our workaround sets the stderr reader to null, so we never give any stderr output.
|
||||
//TODO Check if ssh supports some method of having separate stdout and stderr streams
|
||||
return null;
|
||||
}
|
||||
StringBuffer theLine = new StringBuffer();
|
||||
StringBuffer theDebugLine = null;
|
||||
theDebugLine = new StringBuffer();
|
||||
int ch;
|
||||
boolean done = false;
|
||||
while (!done && !isFinished()) {
|
||||
try {
|
||||
ch = fReader.read();
|
||||
switch (ch) {
|
||||
case -1:
|
||||
case 65535:
|
||||
if (theLine.length() == 0) // End of Reader
|
||||
return null;
|
||||
done = true;
|
||||
break;
|
||||
case '\b': //backspace
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
int len = theLine.length()-1;
|
||||
if (len>=0) theLine.deleteCharAt(len);
|
||||
break;
|
||||
case 13:
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
break; // Carriage Return: dont append to the buffer
|
||||
case 10:
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
done = true; // Newline
|
||||
break;
|
||||
case 9:
|
||||
//Tab: we count tabs at column 8
|
||||
//TODO Check: SystemViewRemoteOutputAdapter.translateTabs() also translates
|
||||
//Therefore this special handling here might be unnecessary
|
||||
if(theDebugLine!=null) theDebugLine.append((char)ch);
|
||||
int tabIndex = theLine.length() % 8;
|
||||
while (tabIndex < 8) {
|
||||
theLine.append(' ');
|
||||
tabIndex++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
char tch = (char) ch;
|
||||
if(theDebugLine!=null) theDebugLine.append(tch);
|
||||
if (!Character.isISOControl(tch)) {
|
||||
theLine.append(tch); // Any other character
|
||||
} else if (ch == 27) {
|
||||
// Escape: ignore next char too
|
||||
int nch = fReader.read();
|
||||
if (theDebugLine!=null) theDebugLine.append((char)nch);
|
||||
if (nch == 91) {
|
||||
//vt100 escape sequence: read until end-of-command (skip digits and semicolon)
|
||||
//e.g. \x1b;13;m --> ignore the entire command, including the trailing m
|
||||
do {
|
||||
nch = fReader.read();
|
||||
if (theDebugLine!=null) theDebugLine.append((char)nch);
|
||||
} while (Character.isDigit((char)nch) || nch == ';');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the BufferedReader is still ready which means
|
||||
// there are more characters
|
||||
// in the Buffer...If not, then we assume it is waiting for
|
||||
// input.
|
||||
if (!done && !fReader.ready()) {
|
||||
// wait to make sure -- max. 500 msec to wait for new chars
|
||||
// if we are not at a CRLF seems to be appropriate for the
|
||||
// Pipes and Threads in ssh.
|
||||
long waitIncrement = 500;
|
||||
// Check if we think we are at a prompt
|
||||
int len = theLine.length()-1;
|
||||
while (len>0 && Character.isSpaceChar(theLine.charAt(len))) {
|
||||
len--;
|
||||
}
|
||||
if (len>=0 && fPromptChars.indexOf(theLine.charAt(len))>=0) {
|
||||
waitIncrement = 5; //wait only 5 msec if we think it's a prompt
|
||||
}
|
||||
try {
|
||||
Thread.sleep(waitIncrement);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
if (!fReader.ready()) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
//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().logException(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (theDebugLine!=null) {
|
||||
String debugLine = theDebugLine.toString();
|
||||
debugLine.compareTo(""); //$NON-NLS-1$
|
||||
}
|
||||
return new SimpleHostOutput(theLine.toString());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 IBM Corporation and others.
|
||||
* 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 LocalShellService.
|
||||
* Sheldon D'souza (Celunite) - Adapted from SshShellService.
|
||||
* Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable
|
||||
* Martin Oberhuber (Wind River) - [226301][api] IShellService should throw SystemMessageException on error
|
||||
* Anna Dushistova (MontaVista) - [246422] Possible bug in TelnetShellService.runCommand()
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.services.telnet.shell;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.rse.internal.services.telnet.ITelnetService;
|
||||
import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider;
|
||||
import org.eclipse.rse.internal.services.telnet.TelnetServiceResources;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.shells.AbstractShellService;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
||||
public class TelnetShellService extends AbstractShellService implements ITelnetService {
|
||||
|
||||
private ITelnetSessionProvider fTelnetSessionProvider;
|
||||
|
||||
public TelnetShellService( ITelnetSessionProvider sessionProvider) {
|
||||
this.fTelnetSessionProvider = sessionProvider;
|
||||
}
|
||||
|
||||
public IHostShell launchShell(String initialWorkingDirectory,
|
||||
String encoding, String[] environment,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
TelnetHostShell hostShell = new TelnetHostShell(fTelnetSessionProvider, initialWorkingDirectory, TelnetHostShell.SHELL_INVOCATION, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public IHostShell runCommand(String initialWorkingDirectory,
|
||||
String command, String encoding, String[] environment,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
TelnetHostShell hostShell = new TelnetHostShell(fTelnetSessionProvider, initialWorkingDirectory, command, encoding, environment);
|
||||
return hostShell;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return TelnetServiceResources.TelnetShellService_Description;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TelnetServiceResources.TelnetShellService_Name;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
|
||||
* 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
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
* Sheldon D'souza (Celunite) - Adapted from SshShellWriterThread
|
||||
* Martin Oberhuber (Wind River) - [187218] Fix error reporting for connect()
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.services.telnet.shell;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.rse.internal.services.telnet.Activator;
|
||||
|
||||
public class TelnetShellWriterThread extends Thread {
|
||||
|
||||
private PrintWriter fOutputWriter;
|
||||
private String fNextCommand;
|
||||
private boolean fIsCancelled;
|
||||
|
||||
|
||||
/**
|
||||
* constructor for ssh shell writer thread
|
||||
* @param outputWriter PrintWriter to write to in separate Thread
|
||||
*/
|
||||
public TelnetShellWriterThread(PrintWriter outputWriter)
|
||||
{
|
||||
super();
|
||||
fOutputWriter = outputWriter;
|
||||
setName("Telnet ShellWriter"+getName()); //$NON-NLS-1$
|
||||
start();
|
||||
}
|
||||
|
||||
public synchronized boolean isDone()
|
||||
{
|
||||
return fIsCancelled;
|
||||
}
|
||||
|
||||
public synchronized void stopThread()
|
||||
{
|
||||
fIsCancelled = true;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write command to remote side. Wait until the
|
||||
* thread takes the command (no queueing).
|
||||
* @param command to send
|
||||
* @return boolean true if command was sent ok
|
||||
*/
|
||||
public synchronized boolean sendCommand(String command)
|
||||
{
|
||||
try {
|
||||
//In case multiple commands try to send:
|
||||
//wait until it's our turn
|
||||
while (!fIsCancelled && fNextCommand!=null) {
|
||||
wait();
|
||||
}
|
||||
if (!fIsCancelled) {
|
||||
//Now it's our turn
|
||||
fNextCommand = command;
|
||||
notifyAll();
|
||||
//Wait until our command is processed
|
||||
while (!fIsCancelled && fNextCommand!=null) {
|
||||
wait();
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
stopThread();
|
||||
}
|
||||
return !fIsCancelled;
|
||||
}
|
||||
|
||||
public synchronized void run()
|
||||
{
|
||||
try {
|
||||
while (!fIsCancelled) {
|
||||
while (fNextCommand==null && !fIsCancelled) {
|
||||
wait();
|
||||
}
|
||||
if (!fIsCancelled) {
|
||||
fOutputWriter.println(fNextCommand);
|
||||
fNextCommand=null;
|
||||
notifyAll();
|
||||
if (fOutputWriter.checkError()) { //flush AND get error
|
||||
stopThread();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(InterruptedException e) {
|
||||
/* no special handling -> close stream */
|
||||
} catch(Exception e) {
|
||||
Activator.getDefault().getLog().log(new Status(IStatus.WARNING,
|
||||
Activator.PLUGIN_ID,
|
||||
e.getLocalizedMessage()!=null ? e.getLocalizedMessage() : e.getClass().getName(),
|
||||
e));
|
||||
} finally {
|
||||
stopThread();
|
||||
// if( fOutputWriter != null )
|
||||
// fOutputWriter.close();
|
||||
fOutputWriter = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others.
|
||||
* 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
|
||||
|
@ -13,15 +13,11 @@
|
|||
|
||||
package org.eclipse.rse.internal.services.telnet.terminal;
|
||||
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
import org.eclipse.rse.internal.services.shells.TerminalShellService;
|
||||
import org.eclipse.rse.internal.services.telnet.ITelnetService;
|
||||
import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider;
|
||||
import org.eclipse.rse.internal.services.telnet.TelnetServiceResources;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.shells.IShellService;
|
||||
import org.eclipse.rse.services.terminals.AbstractTerminalService;
|
||||
import org.eclipse.rse.services.terminals.ITerminalShell;
|
||||
|
||||
|
@ -32,7 +28,6 @@ import org.eclipse.rse.services.terminals.ITerminalShell;
|
|||
public class TelnetTerminalService extends AbstractTerminalService implements ITelnetService {
|
||||
|
||||
private final ITelnetSessionProvider fSessionProvider;
|
||||
private IShellService fRelatedShellService;
|
||||
|
||||
public TelnetTerminalService(ITelnetSessionProvider sessionProvider) {
|
||||
fSessionProvider = sessionProvider;
|
||||
|
@ -48,45 +43,6 @@ public class TelnetTerminalService extends AbstractTerminalService implements IT
|
|||
return hostShell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an RSE IShellService related to this Terminal Service.
|
||||
*/
|
||||
protected synchronized IShellService getRelatedShellService() {
|
||||
if (fRelatedShellService == null) {
|
||||
fRelatedShellService = new TerminalShellService(this);
|
||||
}
|
||||
return fRelatedShellService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapt this terminal service to different (potentially contributed)
|
||||
* interfaces, in order to provide additional functionality.
|
||||
*
|
||||
* Asks the adapter manager first whether it got any contributed adapter; if
|
||||
* none is found contributed externally, try to adapt to an SshShellService.
|
||||
* That way, clients can easily convert this ITerminalService into an
|
||||
* IShellService:
|
||||
*
|
||||
* <pre>
|
||||
* IShellService ss = (IShellService) myTerminalService.getAdapter(IShellService.class);
|
||||
* </pre>
|
||||
*
|
||||
* @see IAdaptable
|
||||
* @see PlatformObject#getAdapter(Class)
|
||||
*/
|
||||
public Object getAdapter(Class adapter) {
|
||||
// TODO I'm not sure if this is the right way doing things. First of
|
||||
// all, we're holding on to the created terminal service forever if
|
||||
// we're asked for it, thus needing extra memory.
|
||||
// Second, by asking the adapter manager first, we might get no chance
|
||||
// returning what we think is right.
|
||||
Object o = super.getAdapter(adapter);
|
||||
if (o==null && adapter.isAssignableFrom(IShellService.class)) {
|
||||
return getRelatedShellService();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return TelnetServiceResources.TelnetShellService_Name;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2007, 2009 Wind River Systems, Inc. and others.
|
||||
* 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
* David McKnight (IBM) - [220547] [api][breaking] SimpleSystemMessage needs to specify a message id and some messages should be shared
|
||||
* Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.services;
|
||||
|
||||
|
@ -31,6 +32,10 @@ public class RSEServicesMessages extends NLS {
|
|||
public static String FILEMSG_FOLDER_NOT_EMPTY_DETAILS;
|
||||
|
||||
|
||||
public static String TerminalShellService_description;
|
||||
public static String TerminalShellService_name;
|
||||
|
||||
|
||||
static {
|
||||
NLS.initializeMessages(BUNDLE_NAME, RSEServicesMessages.class);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2000, 2008 IBM Corporation and others.
|
||||
# Copyright (c) 2000, 2009 IBM Corporation and others.
|
||||
# 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
|
||||
|
@ -9,6 +9,7 @@
|
|||
# IBM Corporation - initial API and implementation
|
||||
# Martin Oberhuber (Wind River) - copy Socket_timeout from team.cvs.core
|
||||
# David McKnight (IBM) - [220547] [api][breaking] SimpleSystemMessage needs to specify a message id and some messages should be shared
|
||||
# Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
###############################################################################
|
||||
|
||||
# NLS_MESSAGEFORMAT_VAR
|
||||
|
@ -28,4 +29,6 @@ FILEMSG_SECURITY_VIOLATION_DETAILS=Message reported from file system: {0}
|
|||
FILEMSG_FOLDER_NOT_EMPTY = Folder is not empty. Cannot delete
|
||||
FILEMSG_FOLDER_NOT_EMPTY_DETAILS = The operation failed. One possible reason is that the folder is not empty
|
||||
|
||||
TerminalShellService_description=Generic shell service
|
||||
TerminalShellService_name=Generic shell service
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 IBM Corporation and others.
|
||||
* Copyright (c) 2006, 2009 IBM Corporation and others.
|
||||
* 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
|
||||
|
@ -19,6 +19,7 @@
|
|||
* Martin Oberhuber (Wind River) - [170910] Adopt RSE ITerminalService API for SSH
|
||||
* Anna Dushistova (MontaVista) - adapted from SshShellService
|
||||
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||
* Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.services.shells;
|
||||
|
||||
|
@ -26,6 +27,7 @@ import org.eclipse.core.runtime.IAdaptable;
|
|||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
import org.eclipse.rse.internal.services.RSEServicesMessages;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.shells.AbstractShellService;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
|
@ -93,4 +95,15 @@ public class TerminalShellService extends AbstractShellService {
|
|||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return RSEServicesMessages.TerminalShellService_name;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return RSEServicesMessages.TerminalShellService_description;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* Martin Oberhuber (Wind River) - Adapted from LocalServiceCommandShell
|
||||
* Martin Oberhuber (Wind River) - [225510][api] Fix OutputRefreshJob API leakage
|
||||
* Anna Dushistova (MontaVista) - [259414][api] refactor the "SSH Shell" to use the generic Terminal->IHostShell converter
|
||||
* Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.shells.ssh;
|
||||
|
@ -28,7 +29,6 @@ import org.eclipse.core.runtime.Path;
|
|||
|
||||
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||
import org.eclipse.rse.internal.services.shells.TerminalServiceHostShell;
|
||||
import org.eclipse.rse.internal.services.ssh.shell.SshHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostOutput;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShellChangeEvent;
|
||||
|
@ -186,10 +186,6 @@ public class SshServiceCommandShell extends ServiceCommandShell
|
|||
if (shell instanceof TerminalServiceHostShell) {
|
||||
return ((TerminalServiceHostShell)shell).getPromptCommand();
|
||||
}
|
||||
//Legacy support for TM <= 3.0 without TerminalServiceHostShell
|
||||
else if (shell instanceof SshHostShell) {
|
||||
return ((SshHostShell)shell).getPromptCommand();
|
||||
}
|
||||
//return something impossible such that nothing is ever matched
|
||||
return "\uffff"; //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2008 IBM Corporation and others.
|
||||
* Copyright (c) 2006, 2009 IBM Corporation and others.
|
||||
* 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
|
||||
|
@ -16,6 +16,7 @@
|
|||
* Sheldon D'souza (Celunite) - Adapted from SshServiceCommandShell
|
||||
* Martin Oberhuber (Wind River) - [225510][api] Fix OutputRefreshJob API leakage
|
||||
* Anna Dushistova (MontaVista) - [240523] [rseterminals] Provide a generic adapter factory that adapts any ITerminalService to an IShellService
|
||||
* Anna Dushistova (MontaVista) - [261478] Remove SshShellService, SshHostShell (or deprecate and schedule for removal in 3.2)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.subsystems.shells.telnet;
|
||||
|
||||
|
@ -27,7 +28,6 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
|||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||
import org.eclipse.rse.internal.services.shells.TerminalServiceHostShell;
|
||||
import org.eclipse.rse.internal.services.telnet.shell.TelnetHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostOutput;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShellChangeEvent;
|
||||
|
@ -180,9 +180,6 @@ public class TelnetServiceCommandShell extends ServiceCommandShell {
|
|||
if (shell instanceof TerminalServiceHostShell) {
|
||||
return ((TerminalServiceHostShell)shell).getPromptCommand();
|
||||
}
|
||||
if (shell instanceof TelnetHostShell) {
|
||||
return ((TelnetHostShell)shell).getPromptCommand();
|
||||
}
|
||||
//return something impossible such that nothing is ever matched
|
||||
return "\uffff"; //$NON-NLS-1$
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue