diff --git a/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF index 9c64e74f491..dfda787500e 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF +++ b/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF @@ -13,5 +13,6 @@ 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.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-internal:=true Bundle-RequiredExecutionEnvironment: J2SE-1.4 diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/ISshService.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/ISshService.java index c53b1c67a7f..ee5265ed4b3 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/ISshService.java +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/ISshService.java @@ -1,24 +1,33 @@ /******************************************************************************* - * 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 + * Copyright (c) 2006, 2008 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 + * Martin Oberhuber (Wind River) - [170910] Adopt RSE ITerminalService API for SSH *******************************************************************************/ package org.eclipse.rse.internal.services.ssh; -/** +/** * Markup Interface for services using the SshConnectorService. * * By implementing this interface, services can be recognized - * as operating against an SshConnectorService. The interface + * as operating against an SshConnectorService. The interface * is used as the key in a table for looking up the connector * service when needed. */ public interface ISshService { + /** + * Get the Session Provider that cares for connect / disconnect of an SSH + * Session, and can be used to instantiate new Channels. + * + * @return an SSH Session Provider. + */ + public ISshSessionProvider getSessionProvider(); + } diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.java index af06046b789..77353e75691 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.java +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.java @@ -7,6 +7,7 @@ * * Contributors: * Martin Oberhuber (Wind River) - initial API and implementation + * Yu-Fen Kuo (MontaVista) - [170910] Integrate the TM Terminal View with RSE *******************************************************************************/ package org.eclipse.rse.internal.services.ssh; @@ -33,6 +34,11 @@ public class SshServiceResources extends NLS { public static String SshShellService_Description; public static String SshShellService_Name; + + public static String SshTerminalService_Name; + + public static String SshTerminalService_Description; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, SshServiceResources.class); diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.properties b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.properties index 48ac84520a6..0205d9147b2 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.properties +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/SshServiceResources.properties @@ -7,6 +7,7 @@ # # Contributors: # Martin Oberhuber (Wind River) - initial API and implementation +# Yu-Fen Kuo (MontaVista) - [170910] Integrate the TM Terminal View with RSE ################################################################################ # NLS_MESSAGEFORMAT_VAR @@ -23,3 +24,6 @@ SftpFileService_Msg_Progress={0,number,integer} KB of {1,number,integer} KB comp SshShellService_Name=SSH Shell Service SshShellService_Description=SSH Shell Service Description + +SshTerminalService_Name=SSH Terminal Service +SshTerminalService_Description=SSH Terminal Service Description diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java index 67100fab129..1d01008def6 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/files/SftpFileService.java @@ -25,6 +25,7 @@ * David McKnight (IBM) - [216252] [api][nls] Resource Strings specific to subsystems should be moved from rse.ui into files.ui / shells.ui / processes.ui where possible * Martin Oberhuber (Wind River) - [224799] Fix JSch encoding problems with Arabic filenames * Martin Oberhuber (Wind River) - [226262] Make IService IAdaptable + * Martin Oberhuber (Wind River) - [170910] Adopt RSE ITerminalService API for SSH *******************************************************************************/ package org.eclipse.rse.internal.services.ssh.files; @@ -154,7 +155,7 @@ public class SftpFileService extends AbstractFileService implements ISshService, } //private SshConnectorService fConnector; - private ISshSessionProvider fSessionProvider; + private final ISshSessionProvider fSessionProvider; private ChannelSftp fChannelSftp; private String fUserHome; private Mutex fDirChannelMutex = new Mutex(); @@ -174,6 +175,10 @@ public class SftpFileService extends AbstractFileService implements ISshService, fSessionProvider = sessionProvider; } + public ISshSessionProvider getSessionProvider() { + return fSessionProvider; + } + public void setControlEncoding(String encoding) throws SystemMessageException { try { fChannelSftp.setFilenameEncoding(encoding); diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java index 9fd81e23113..9d168b5b185 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/shell/SshShellService.java @@ -16,15 +16,19 @@ * 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; @@ -35,7 +39,8 @@ import org.eclipse.rse.services.shells.IHostShell; */ public class SshShellService extends AbstractShellService implements ISshService { - private ISshSessionProvider fSessionProvider; + private final ISshSessionProvider fSessionProvider; + private SshTerminalService fRelatedTerminalService; public SshShellService(ISshSessionProvider sessionProvider) { fSessionProvider = sessionProvider; @@ -55,6 +60,45 @@ public class SshShellService extends AbstractShellService implements ISshService 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: + * + *
+ * ITerminalService ts = (ITerminalService) myShellService.getAdapter(ITerminalService.class); + *+ * + * @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; } @@ -63,4 +107,8 @@ public class SshShellService extends AbstractShellService implements ISshService return SshServiceResources.SshShellService_Description; } + public ISshSessionProvider getSessionProvider() { + return fSessionProvider; + } + } diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/terminal/SshTerminalService.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/terminal/SshTerminalService.java new file mode 100644 index 00000000000..5b78226a24e --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/terminal/SshTerminalService.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2008 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.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.internal.services.terminals.AbstractTerminalService; +import org.eclipse.rse.internal.services.terminals.ITerminalShell; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; + +/** + * A Terminal Service for ssh. + */ +public class SshTerminalService extends AbstractTerminalService implements ISshService { + + private final ISshSessionProvider fSessionProvider; + private SshShellService fRelatedShellService; + + public SshTerminalService(ISshSessionProvider sessionProvider) { + fSessionProvider = sessionProvider; + } + + public ISshSessionProvider getSessionProvider() { + return fSessionProvider; + } + + public ITerminalShell launchTerminal(String ptyType, String encoding, String[] environment, String initialWorkingDirectory, String commandToRun, + IProgressMonitor monitor) throws SystemMessageException { + SshTerminalShell hostShell = new SshTerminalShell(getSessionProvider(), ptyType, encoding, environment, initialWorkingDirectory, commandToRun); + 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: + * + *
+ * IShellService ss = (IShellService) myTerminalService.getAdapter(IShellService.class); + *+ * + * @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; + } + + public String getDescription() { + return SshServiceResources.SshTerminalService_Description; + } + +} diff --git a/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/terminal/SshTerminalShell.java b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/terminal/SshTerminalShell.java new file mode 100644 index 00000000000..a8f569305af --- /dev/null +++ b/rse/plugins/org.eclipse.rse.services.ssh/src/org/eclipse/rse/internal/services/ssh/terminal/SshTerminalShell.java @@ -0,0 +1,229 @@ +/******************************************************************************* + * Copyright (c) 2008 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 + * Anna Dushistova (MontaVista) - [170910] Integrate the TM Terminal View with RSE + *******************************************************************************/ + +package org.eclipse.rse.internal.services.ssh.terminal; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.util.Hashtable; + +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.internal.services.terminals.AbstractTerminalShell; +import org.eclipse.rse.internal.services.terminals.ITerminalService; +import org.eclipse.rse.services.clientserver.PathUtility; +import org.eclipse.rse.services.clientserver.messages.SystemMessageException; +import org.eclipse.rse.services.files.RemoteFileException; + +/** + * A remote shell connection supporting Streams for I/O. + */ +public class SshTerminalShell extends AbstractTerminalShell { + + private ISshSessionProvider fSessionProvider; + private Channel fChannel; + private String fEncoding; + private InputStream fInputStream; + private OutputStream fOutputStream; + private Writer fOutputStreamWriter; + private int fWidth = 0; + private int fHeight = 0; + private static String defaultEncoding = new java.io.InputStreamReader(new java.io.ByteArrayInputStream(new byte[0])).getEncoding(); + + /** + * Construct a new Terminal connection. + * + * The SSH channel is immediately connected in the Constructor. + * + * @param sessionProvider SSH session provider + * @param ptyType Terminal type to set, or
null
if not
+ * relevant
+ * @param encoding The default encoding to use for initial command.
+ * @param environment Environment array to set, or null
if
+ * not relevant.
+ * @param initialWorkingDirectory initial directory to open the Terminal in.
+ * Use null
or empty String ("") to start in a
+ * default directory. Empty String will typically start in the
+ * home directory.
+ * @param commandToRun initial command to send.
+ * @throws SystemMessageException in case anything goes wrong. Channels and
+ * Streams are all cleaned up again in this case.
+ * @see ITerminalService
+ */
+ public SshTerminalShell(ISshSessionProvider sessionProvider, String ptyType, String encoding, String[] environment, String initialWorkingDirectory,
+ String commandToRun) throws SystemMessageException {
+ try {
+ fSessionProvider = sessionProvider;
+ fEncoding = encoding;
+ fChannel = fSessionProvider.getSession().openChannel("shell"); //$NON-NLS-1$
+ if (ptyType != null && (fChannel instanceof ChannelShell)) {
+ //By default, jsch always creates a vt100 connection sized
+ //80x24 / 640x480 (dimensions can be changed).
+ ((ChannelShell) fChannel).setPtyType(ptyType);
+ }
+
+ //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+ * EXPERIMENTAL. This class or interface has been added as + * part of a work in progress. There is no guarantee that this API will work or + * that it will remain the same. Please do not use this API without consulting + * with the Target Management + * team. + *
+ * + * @see ITerminalService + * @since org.eclipse.rse.services 3.0 + */ +public abstract class AbstractTerminalService extends AbstractService implements ITerminalService { + + // empty for now, extenders need to implement the launchTerminal() method + // themselves + +} diff --git a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/terminals/ITerminalService.java b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/terminals/ITerminalService.java index a59f441cf78..345f36d6902 100644 --- a/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/terminals/ITerminalService.java +++ b/rse/plugins/org.eclipse.rse.services/src/org/eclipse/rse/internal/services/terminals/ITerminalService.java @@ -13,29 +13,28 @@ package org.eclipse.rse.internal.services.terminals; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.rse.services.AbstractService; import org.eclipse.rse.services.IService; import org.eclipse.rse.services.clientserver.messages.SystemMessageException; /** * Interface for getting Terminal Connections from a remote side, also known as * terminal session with Streams. - * + * * One ITerminalService instance is typically associated with one particular * connection to a (potentially remote) system, such that the ITerminalService * instance can also hold state data about that session, such as connected * state, login and authentication information, configuration data or * environment variables. - * + * * Each * {@link #launchTerminal(String, String, String[], String, String, IProgressMonitor)} * invocation, however, acts as a factory method such that it creates a new * (remote) process and associated {@link ITerminalShell} connection. - * + * * @noimplement This interface is not intended to be implemented by clients. - * Clients must subclass the {@link AbstractService} class rather - * than implementing this interface directly. - * + * Clients must subclass the {@link AbstractTerminalService} class + * rather than implementing this interface directly. + * ** EXPERIMENTAL. This class or interface has been added as * part of a work in progress. There is no guarantee that this API will work or @@ -43,9 +42,9 @@ import org.eclipse.rse.services.clientserver.messages.SystemMessageException; * with the Target Management * team. *
- * + * * @since org.eclipse.rse.services 3.0 - * + * */ public interface ITerminalService extends IService {