1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

integration of Martin's ssh services

This commit is contained in:
David McKnight 2006-05-09 18:14:47 +00:00
parent c4f9cd45b1
commit 08d25895ba
46 changed files with 2326 additions and 0 deletions

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.rse.connectorservice.ssh</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,19 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ssh Plug-in
Bundle-SymbolicName: org.eclipse.rse.connectorservice.ssh; singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: org.eclipse.rse.connectorservice.ssh.Activator
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.rse.services,
org.eclipse.rse.core,
org.eclipse.rse.ui,
com.jcraft.jsch,
org.eclipse.team.cvs.ssh,
org.eclipse.team.cvs.ssh2,
org.eclipse.team.cvs.ui,
org.eclipse.rse.services.ssh
Eclipse-LazyStart: true
Export-Package: org.eclipse.rse.connectorservice.ssh

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -0,0 +1,16 @@
################################################################################
# Copyright (c) 2006 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 - initial API and implementation
################################################################################
plugin.name = Ssh Connector Service Plugin
SshSystemName=SSH Only
SshSystemDescription=Connection for SSH access to remote hosts

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2006 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 - initial API and implementation
-->
<?eclipse version="3.1"?>
<plugin>
<extension point="org.eclipse.rse.core.systemTypes">
<systemType id="org.eclipse.rse.systemtype.ssh"
name="SSH Only"
description="%SshSystemDescription">
<property name="icon" value="icons/full/obj16/systemcommands_obj.gif"/>
<property name="iconLive" value="icons/full/obj16/systemcommandslive_obj.gif"/>
</systemType>
</extension>
</plugin>

View file

@ -0,0 +1,61 @@
package org.eclipse.rse.connectorservice.ssh;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.rse.connectorservice.ssh";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path.
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}

View file

@ -0,0 +1,23 @@
/*******************************************************************************
* Copyright (c) 2006 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.connectorservice.ssh;
/**
* Markup Interface for subsystems using the SshConnectorService.
*
* By implementing this interface, subsystems can be recognized
* as being able to share a single ssh connector service between
* multiple different subsystems.
*/
public interface ISshSubSystem {
}

View file

@ -0,0 +1,273 @@
/*******************************************************************************
* Copyright (c) 2006 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
*******************************************************************************/
package org.eclipse.rse.connectorservice.ssh;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.rse.core.subsystems.AbstractConnectorService;
import org.eclipse.rse.model.IHost;
import org.eclipse.rse.services.files.IFileService;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.internal.ccvs.ssh2.CVSSSH2Plugin;
import org.eclipse.team.internal.ccvs.ssh2.ISSHContants;
import org.eclipse.team.internal.ccvs.ui.UserValidationDialog;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.UserInfo;
import org.eclipse.rse.services.ssh.ISshSessionProvider;
/**
* Create SSH connections.
*/
public class SshConnectorService extends AbstractConnectorService implements ISshSessionProvider
{
private static final int SSH_DEFAULT_PORT = 22;
private static JSch jsch=new JSch();
private Session session;
// protected SftpFileService _sftpFileService;
public SshConnectorService(IHost host) {
//TODO the port parameter doesnt really make sense here since
//it will be overridden when the subsystem initializes (through
//setPort() on our base class -- I assume the port is meant to
//be a local port.
super("SSH Connector Service", "SSH Connector Service Description", host, 0);
// _sftpFileService = new SftpFileService(this);
}
//----------------------------------------------------------------------
// <copied from org.eclipse.team.cvs.ssh2>
//----------------------------------------------------------------------
private static String current_ssh_home = null;
private static String current_pkeys = ""; //$NON-NLS-1$
static String SSH_HOME_DEFAULT = null;
static {
String ssh_dir_name = ".ssh"; //$NON-NLS-1$
// Windows doesn't like files or directories starting with a dot.
if (Platform.getOS().equals(Platform.OS_WIN32)) {
ssh_dir_name = "ssh"; //$NON-NLS-1$
}
SSH_HOME_DEFAULT = System.getProperty("user.home"); //$NON-NLS-1$
if (SSH_HOME_DEFAULT != null) {
SSH_HOME_DEFAULT = SSH_HOME_DEFAULT + java.io.File.separator + ssh_dir_name;
}
}
static void loadSshPrefs()
{
IPreferenceStore store = CVSSSH2Plugin.getDefault().getPreferenceStore();
String ssh_home = store.getString(ISSHContants.KEY_SSH2HOME);
String pkeys = store.getString(ISSHContants.KEY_PRIVATEKEY);
try {
if (ssh_home.length() == 0)
ssh_home = SSH_HOME_DEFAULT;
if (current_ssh_home == null || !current_ssh_home.equals(ssh_home)) {
loadKnownHosts(ssh_home);
current_ssh_home = ssh_home;
}
if (!current_pkeys.equals(pkeys)) {
java.io.File file;
String[] pkey = pkeys.split(","); //$NON-NLS-1$
String[] _pkey = current_pkeys.split(","); //$NON-NLS-1$
current_pkeys = ""; //$NON-NLS-1$
for (int i = 0; i < pkey.length; i++) {
file = new java.io.File(pkey[i]);
if (!file.isAbsolute()) {
file = new java.io.File(ssh_home, pkey[i]);
}
if (file.exists()) {
boolean notyet = true;
for (int j = 0; j < _pkey.length; j++) {
if (pkey[i].equals(_pkey[j])) {
notyet = false;
break;
}
}
if (notyet)
jsch.addIdentity(file.getPath());
if (current_pkeys.length() == 0) {
current_pkeys = pkey[i];
} else {
current_pkeys += ("," + pkey[i]); //$NON-NLS-1$
}
}
}
}
} catch (Exception e) {
}
}
static void loadKnownHosts(String ssh_home){
try {
java.io.File file;
file=new java.io.File(ssh_home, "known_hosts"); //$NON-NLS-1$
jsch.setKnownHosts(file.getPath());
} catch (Exception e) {
}
}
//----------------------------------------------------------------------
// </copied from org.eclipse.team.cvs.ssh2>
//----------------------------------------------------------------------
protected void internalConnect(IProgressMonitor monitor) throws Exception
{
//TODO Set known hosts and identities from Preferences
//We could share the preferences from ssh2, or use RSE
//ConnectorService Properties / Server Launcher Properties
//jsch.setKnownHosts("/home/foo/.ssh/known_hosts");
loadSshPrefs();
String host = getHostName();
String user = getUserId();
session=jsch.getSession(user, host, SSH_DEFAULT_PORT);
session.setPassword(getPasswordInformation().getPassword());
//session.setPassword("your password");
// username and password will be given via UserInfo interface.
UserInfo ui=new MyUserInfo(user);
session.setUserInfo(ui);
//java.util.Hashtable config=new java.util.Hashtable();
//config.put("StrictHostKeyChecking", "no");
//session.setConfig(config);
session.connect(3000); // making connection with timeout.
//now also connect the sftpFileService. It's not very nice to force
//the connector service know about the file service, and connect it
//so early -- lazy connect inside the sftpFileService would be better.
//But the FileServiceSubsystem only calls internalConnect() on the
//connector service, and doesn't try to connect the file service
//individually.
//TODO: From the API point of view, it might be better if the file
//service had a connect() method and could decide itself if and how
//it wants to use the connector service.
//Or could we ensure that the FileService is instanciated only once
//it needs to be connected? - Currently this is not the case (it is
//instanciated very early by the subsystem).
// _sftpFileService.connect();
}
public void internalDisconnect(IProgressMonitor monitor)
{
//TODO: Check, Is disconnect being called because the network (connection) went down?
//TODO: Fire communication event (aboutToDisconnect) -- see DStoreConnectorService.internalDisconnect()
//TODO: Wrap exception in an InvocationTargetException -- see DStoreConnectorService.internalDisconnect()
// _sftpFileService.disconnect();
session.disconnect();
}
//TODO avoid having jsch type "Session" in the API.
//Could be done by instanciating SshShellService and SshFileService here,
//and implementing IShellService getShellService()
//and IFileService getFileService().
public Session getSession() {
return session;
}
/*
public IFileService getFileService() {
return _sftpFileService;
}
*/
private static Display getStandardDisplay() {
Display display = Display.getCurrent();
if( display==null ) {
display = Display.getDefault();
}
return display;
}
private static class MyUserInfo implements UserInfo {
String fPassphrase;
String fPassword;
final String fUser;
public MyUserInfo(String user) {
fUser = user;
}
public String getPassword() {
return fPassword;
}
public boolean promptYesNo(final String str) {
//need to switch to UI thread for prompting
final boolean[] retval = new boolean[1];
getStandardDisplay().syncExec(new Runnable() {
public void run() {
retval[0] = MessageDialog.openQuestion(null, "Warning", str);
}
});
return retval[0];
}
private String promptString(final String message) {
final String[] retval = new String[1];
getStandardDisplay().syncExec(new Runnable() {
public void run() {
//TODO Write our own UserValidationDialog instead of re-using the internal one from team.ssh
UserValidationDialog uvd = new UserValidationDialog(null, null,
fUser, message);
uvd.setUsernameMutable(false);
if (uvd.open() == uvd.OK) {
retval[0] = uvd.getPassword();
} else {
retval[0] = null;
}
}
});
return retval[0];
}
public String getPassphrase() {
return fPassphrase;
}
public boolean promptPassphrase(String message) {
fPassphrase = promptString(message);
return (fPassphrase!=null);
}
public boolean promptPassword(final String message) {
fPassword = promptString(message);
return (fPassphrase!=null);
}
public void showMessage(final String message) {
getStandardDisplay().syncExec(new Runnable() {
public void run() {
MessageDialog.openInformation(null, "Info", message);
}
});
}
}
public boolean isConnected() {
return (session!=null && session.isConnected());
}
public boolean hasRemoteServerLauncherProperties() {
return false;
}
public boolean supportsRemoteServerLaunching() {
return false;
}
public boolean supportsServerLaunchProperties() {
return false;
}
}

View file

@ -0,0 +1,66 @@
/********************************************************************************
* 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 LocalConnectorServiceManager.
********************************************************************************/
package org.eclipse.rse.connectorservice.ssh;
import org.eclipse.rse.core.subsystems.AbstractConnectorServiceManager;
import org.eclipse.rse.core.subsystems.IConnectorService;
import org.eclipse.rse.core.subsystems.ISubSystem;
import org.eclipse.rse.model.IHost;
/**
* ConnectorService manager class.
*
* The job of this manager is to manage and return IConnectorService
* objects. It ensures there is only ever one per unique SystemConnection,
* so that both the file and cmd subsystems can share the same
* ConnectorService object.
*/
public class SshConnectorServiceManager extends AbstractConnectorServiceManager {
private static SshConnectorServiceManager fInstance;
private SshConnectorServiceManager() {
super();
}
/**
* Return singleton instance of this class
*/
public static SshConnectorServiceManager getInstance()
{
if (fInstance == null)
fInstance = new SshConnectorServiceManager();
return fInstance;
}
/* (non-Javadoc)
* @see org.eclipse.rse.core.subsystems.AbstractConnectorServiceManager#createConnectorService(org.eclipse.rse.model.IHost)
*/
public IConnectorService createConnectorService(IHost host) {
IConnectorService service = new SshConnectorService(host);
return service;
}
public boolean sharesSystem(ISubSystem otherSubSystem) {
return (otherSubSystem instanceof ISshSubSystem);
}
public Class getSubSystemCommonInterface(ISubSystem subsystem) {
return ISshSubSystem.class;
}
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.rse.services.ssh</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %plugin.name
Bundle-SymbolicName: org.eclipse.rse.services.ssh;singleton:=true
Bundle-Version: 0.0.2
Bundle-Activator: org.eclipse.rse.services.ssh.Activator
Bundle-Vendor: Eclipse.org
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.rse.services,
com.jcraft.jsch,
org.eclipse.team.cvs.ui,
org.eclipse.team.cvs.ssh2
Eclipse-LazyStart: true
Export-Package: org.eclipse.rse.services.ssh,
org.eclipse.rse.services.ssh.files,
org.eclipse.rse.services.ssh.shell

View file

@ -0,0 +1,28 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>About</title>
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>May 2, 2006</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="/">http://www.eclipse.org</a>.</p>
</body>
</html>

View file

@ -0,0 +1,10 @@
bin.includes = .classpath,\
.project,\
about.html,\
build.properties,\
icons/,\
META-INF/,\
plugin.properties,\
plugin.xml,\
readme.txt,\
src/

View file

@ -0,0 +1,66 @@
Readme for RSE ssh service
--------------------------
The RSE ssh plugin allows to connect the RSE Remote Command View to
a remote host through the secure shell (ssh) protocol.
This plugin is meant as a proof-of-concept. The code does not have
product quality yet, and there are lots of open issues (marked as
TODO in the code). But it is functional for setting up an ssh shell
connection.
__Requirements:__
The ssh service plugin has been tested with RSE M2 candidate
(CVS HEAD as of May 09, 2006) and Eclipse 3.2 RC3.
The Eclipse Platform Team / CVS feature is needed for the
com.jcraft.jsh plugin and the org.eclipse.team.cvs.ui plugin.
__Installation:__
You need an Eclipse PDE Workspace with RSE.
Then, choose File > Import > Existing Projects > Archive File,
to import the ssh service archive.
__Usage:__
* Start RSE, create a new system of type "SSH Only".
* If you store your ssh private keys in a non-standard place, use
Window > Preferences > Team > CVS > SSh2 Connection Method > General
to set the ssh home directory, and private key types to be used.
* Select the "Shells" node and choose Contextmenu > Launch Shell.
* Enter your username on the remote system. For the password, just
enter anything (this is not checked, since ssh has its own method
of acquiring password information).
* When asked to accept remote host authenticity, press OK.
* Enter the correct password for ssh on the remote system (this is only
necessary if you are not using a private key).
__Known Limitations:__
* Symbolic Links are not resolved (readlink not supported by jsch-0.1.28)
* Ssh passwords can not be stored (no key ring; use private keys instead)
* Ssh timeouts are not observed (no automatic reconnect)
- after auto-logout, shell just doesnt react to input any more
* Password and passphrase internal handling has not been checked for
security against malicious reading from other Eclipse plugins.
__Known Issues:__
* A dummy password must be entered on initial connect (can be saved)
* After some time, the connection may freeze and need to be
disconnected.
* Command service should be provided in addition to the remote shell service.
* Extremely long remote command output may lead to an Exception
due to memory exhaustion (ArrayIndexOutOfBoundsException)
* "Break" can not be sent to the remote system in order to cancel
long-running jobs on the remote side.
* Moving files with a space in the name doesn't currently work.
Renaming them works though.
* Copy&paste, or drag&drop of remote files remotely does'nt currently work.
* The plugin currently uses some "internal" classes from the
org.eclipse.team.cvs.ui plugin. This needs to be cleaned up.
* For other internal coding issues, see TODO items in the code.
__Changelog:__
v0.2:
* Re-use Team/CVS/ssh2 preferences for ssh2 home and private keys specification
Allows to do the ssh login without password if private/public key are set up.
* Key management from Team/CVS/ssh2 Preferences can also be used
* Add sftp files subsystem
* Fix status after disconnect operation
* Update about.html

View file

@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright (c) 2006 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.services.ssh;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The main plugin class to be used in the desktop.
*/
public class Activator extends AbstractUIPlugin {
//The shared instance.
private static Activator plugin;
/**
* The constructor.
*/
public Activator() {
plugin = this;
}
/**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
super.start(context);
// make sure files.ui is activated
// org.eclipse.rse.files.ui.Activator.getDefault();
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
plugin = null;
}
/**
* Returns the shared instance.
*
* @return the shared instance.
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path.
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.rse.services.ssh", path);
}
}

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2006 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.services.ssh;
/**
* Markup Interface for services using the SshConnectorService.
*
* By implementing this interface, services can be recognized
* 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 {
}

View file

@ -0,0 +1,8 @@
package org.eclipse.rse.services.ssh;
import com.jcraft.jsch.Session;
public interface ISshSessionProvider
{
public Session getSession();
}

View file

@ -0,0 +1,451 @@
/*******************************************************************************
* Copyright (c) 2006 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.services.ssh.files;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.rse.services.clientserver.NamePatternMatcher;
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
import org.eclipse.rse.services.files.AbstractFileService;
import org.eclipse.rse.services.files.IFileService;
import org.eclipse.rse.services.files.IHostFile;
import org.eclipse.rse.services.ssh.ISshService;
import org.eclipse.rse.services.ssh.ISshSessionProvider;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpProgressMonitor;
public class SftpFileService extends AbstractFileService implements IFileService, ISshService
{
//private SshConnectorService fConnector;
private ISshSessionProvider fSessionProvider;
private ChannelSftp fChannelSftp;
private String fUserHome;
// public SftpFileService(SshConnectorService conn) {
// fConnector = conn;
// }
public SftpFileService(ISshSessionProvider sessionProvider) {
fSessionProvider = sessionProvider;
}
public String getName() {
return "Ssh / Sftp File Service";
}
public String getDescription() {
return "Access a remote file system via Ssh / Sftp protocol";
}
public void connect() throws Exception {
Session session = fSessionProvider.getSession();
Channel channel=session.openChannel("sftp"); //$NON-NLS-1$
channel.connect();
fChannelSftp=(ChannelSftp)channel;
fUserHome = fChannelSftp.pwd();
}
public void disconnect() {
fChannelSftp.disconnect();
fChannelSftp = null;
}
public IHostFile getFile(IProgressMonitor monitor, String remoteParent, String fileName)
{
//TODO getFile() must return a dummy even for non-existent files,
//or the move() operation will fail. This needs to be described in
//the API docs.
SftpHostFile node = null;
SftpATTRS attrs = null;
try {
attrs = fChannelSftp.stat(remoteParent+'/'+fileName);
} catch(Exception e) {}
if (attrs!=null) {
node = makeHostFile(remoteParent, fileName, attrs);
} else {
node = new SftpHostFile(remoteParent, fileName, false, false, false, 0, 0);
node.setExists(false);
}
return node;
}
public boolean isConnected() {
return fChannelSftp.isConnected();
}
protected IHostFile[] internalFetch(IProgressMonitor monitor, String parentPath, String fileFilter, int fileType)
{
if (fileFilter == null) {
fileFilter = "*"; //$NON-NLS-1$
}
NamePatternMatcher filematcher = new NamePatternMatcher(fileFilter, true, true);
List results = new ArrayList();
try {
java.util.Vector vv=fChannelSftp.ls(parentPath);
for(int ii=0; ii<vv.size(); ii++) {
Object obj=vv.elementAt(ii);
if(obj instanceof ChannelSftp.LsEntry){
ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry)obj;
String fileName = lsEntry.getFilename();
if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
//don't show the trivial names
continue;
}
if (filematcher.matches(fileName)) {
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
if (isRightType(fileType, node)) {
results.add(node);
}
}
}
}
} catch(Exception e) {
//TODO throw new SystemMessageException.
//We get a "2: No such file" exception when we try to get contents
//of a symbolic link that turns out to point to a file rather than
//a directory. In this case, the result is probably expected.
//We should try to classify symbolic links as "file" or "dir" correctly.
e.printStackTrace();
}
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
}
private static SftpHostFile makeHostFile(String parentPath, String fileName, SftpATTRS attrs) {
SftpHostFile node = new SftpHostFile(parentPath, fileName, attrs.isDir(), false, attrs.isLink(), attrs.getMTime(), attrs.getSize());
if (attrs.getExtended()!=null) {
node.setExtendedData(attrs.getExtended());
}
return node;
}
public String getSeparator() {
return "/"; //$NON-NLS-1$
}
public boolean upload(IProgressMonitor monitor, File localFile, String remoteParent, String remoteFile, boolean isBinary, String srcEncoding, String hostEncoding)
{
//TODO what to do with isBinary?
try {
SftpProgressMonitor sftpMonitor=new MyProgressMonitor(monitor);
int mode=ChannelSftp.OVERWRITE;
String dst = remoteParent;
if( remoteFile!=null ) {
if (!dst.endsWith("/")) { //$NON-NLS-1$
dst += '/';
}
dst += remoteFile;
}
fChannelSftp.put(localFile.getAbsolutePath(), dst, sftpMonitor, mode);
}
catch (Exception e) {
//TODO See download
//e.printStackTrace();
//throw new RemoteFileIOException(e);
return false;
}
return true;
}
public static class MyProgressMonitor implements SftpProgressMonitor
{
IProgressMonitor fMonitor;
public MyProgressMonitor(IProgressMonitor monitor) {
fMonitor = monitor;
}
public void init(int op, String src, String dest, long max){
String desc = ((op==SftpProgressMonitor.PUT)?
"put" : "get")+": "+src; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
//TODO avoid cast from long to int
fMonitor.beginTask(desc, (int)max);
}
public boolean count(long count){
fMonitor.worked((int)count);
return !(fMonitor.isCanceled());
}
public void end(){
fMonitor.done();
}
};
public boolean upload(IProgressMonitor monitor, InputStream stream, String remoteParent, String remoteFile, boolean isBinary, String hostEncoding) throws SystemMessageException
{
//TODO hack for now
try
{
BufferedInputStream bis = new BufferedInputStream(stream);
File tempFile = File.createTempFile("ftp", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
FileOutputStream os = new FileOutputStream(tempFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int readCount;
while( (readCount = bis.read(buffer)) > 0)
{
bos.write(buffer, 0, readCount);
}
bos.close();
upload(monitor, tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding); //$NON-NLS-1$
}
catch (Exception e) {
//TODO See download
//e.printStackTrace();
//throw new RemoteFileIOException(e);
return false;
}
return true;
}
public boolean download(IProgressMonitor monitor, String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding) throws SystemMessageException
{
try {
if (!localFile.exists()) {
File localParentFile = localFile.getParentFile();
if (!localParentFile.exists()) {
localParentFile.mkdirs();
}
//localFile.createNewFile();
}
//TODO Ascii/binary?
String remotePath = remoteParent+'/'+remoteFile;
int mode=ChannelSftp.OVERWRITE;
MyProgressMonitor sftpMonitor = new MyProgressMonitor(monitor);
fChannelSftp.get(remotePath, localFile.getAbsolutePath(), sftpMonitor, mode);
}
catch (Exception e) {
//TODO handle exception properly: happens e.g. when trying to download a symlink.
//Messages from Jsch are mostly not useful, especially when the server version is
//<=3 (e.g. "4: Failure"). therefore it is better for now to just return false.
//e.printStackTrace();
//throw new RemoteFileIOException(e);
return false;
}
return true;
}
public IHostFile getUserHome() {
//TODO assert: this is only called after we are connected
int lastSlash = fUserHome.lastIndexOf('/');
String name = fUserHome.substring(lastSlash + 1);
String parent = fUserHome.substring(0, lastSlash);
return getFile(null, parent, name);
}
public IHostFile[] getRoots(IProgressMonitor monitor) {
IHostFile root = new SftpHostFile("/", "/", true, true, false, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$
return new IHostFile[] { root };
}
// TODO
/********************************************************
*
* The following APIs need to be implemented
*
********************************************************/
public IHostFile createFile(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException
{
IHostFile result = null;
try {
String fullPath = remoteParent + '/' + fileName;
OutputStream os = fChannelSftp.put(fullPath);
os.close();
SftpATTRS attrs = fChannelSftp.stat(fullPath);
result = makeHostFile(remoteParent, fileName, attrs);
} catch (Exception e) {
e.printStackTrace();
// DKM commenting out because services don't know about this class
// throw new RemoteFileIOException(e);
}
return result;
}
public IHostFile createFolder(IProgressMonitor monitor, String remoteParent, String folderName) throws SystemMessageException
{
IHostFile result = null;
try {
String fullPath = remoteParent + '/' + folderName;
fChannelSftp.mkdir(fullPath);
SftpATTRS attrs = fChannelSftp.stat(fullPath);
result = makeHostFile(remoteParent, folderName, attrs);
} catch (Exception e) {
e.printStackTrace();
// DKM commenting out because services don't know about this class
//throw new RemoteFileIOException(e);
}
return result;
}
public boolean delete(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException
{
boolean ok=false;
try {
String fullPath = remoteParent + '/' + fileName;
SftpATTRS attrs = fChannelSftp.stat(fullPath);
if (attrs==null) {
//doesn't exist, nothing to do
} else if (attrs.isDir()) {
fChannelSftp.rmdir(fullPath);
} else {
fChannelSftp.rm(fullPath);
}
ok=true;
} catch (Exception e) {
e.printStackTrace();
// DKM commenting out because services don't know about this class
//throw new RemoteFileIOException(e);
}
return ok;
}
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName) throws SystemMessageException
{
boolean ok=false;
try {
String fullPathOld = remoteParent + '/' + oldName;
String fullPathNew = remoteParent + '/' + newName;
fChannelSftp.rename(fullPathOld, fullPathNew);
ok=true;
} catch (Exception e) {
e.printStackTrace();
// DKM commenting out because services don't know about this class
//throw new RemoteFileIOException(e);
}
return ok;
}
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName, IHostFile oldFile) throws SystemMessageException {
// TODO dont know how to update
return rename(monitor, remoteParent, oldName, newName);
}
private boolean progressWorked(IProgressMonitor monitor, int work) {
boolean cancelRequested = false;
if (monitor!=null) {
monitor.worked(work);
cancelRequested = monitor.isCanceled();
}
return cancelRequested;
}
public int runCommand(IProgressMonitor monitor, String command) throws SystemMessageException
{
int result = -1;
if (monitor!=null) {
monitor.beginTask(command, 20);
}
Channel channel = null;
try {
channel=fSessionProvider.getSession().openChannel("exec"); //$NON-NLS-1$
((ChannelExec)channel).setCommand(command);
//No user input
channel.setInputStream(null);
//TODO capture error output for exception
((ChannelExec)channel).setErrStream(System.err);
InputStream in=channel.getInputStream();
channel.connect();
byte[] tmp=new byte[1024];
while(!channel.isClosed()){
if( progressWorked(monitor,1) ) {
break;
}
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
//System.out.print(new String(tmp, 0, i));
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
result = channel.getExitStatus();
} catch(Exception e) {
// DKM
// not visible to this plugin
// throw new RemoteFileIOException(e);
} finally {
if (monitor!=null) {
monitor.done();
}
if (channel!=null) {
channel.disconnect();
}
}
return result;
}
public boolean move(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName) throws SystemMessageException
{
// move is not supported by sftp directly. Use the ssh shell instead.
// TODO check if newer versions of sftp support move directly
// TODO Interpret some error messages like "command not found" (use ren instead of mv on windows)
String fullPathOld = srcParent + '/' + srcName;
String fullPathNew = tgtParent + '/' + tgtName;
//TODO quote pathes if necessary
int rv = runCommand(monitor, "mv "+fullPathOld+' '+fullPathNew); //$NON-NLS-1$
return (rv==0);
}
public boolean copy(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName) throws SystemMessageException {
// move is not supported by sftp directly. Use the ssh shell instead.
// TODO check if newer versions of sftp support move directly
// TODO Interpret some error messages like "command not found" (use (x)copy instead of cp on windows)
String fullPathOld = srcParent + '/' + srcName; //$NON-NLS-1$
String fullPathNew = tgtParent + '/' + tgtName; //$NON-NLS-1$
//TODO quote pathes if necessary
int rv = runCommand(monitor, "cp "+fullPathOld+' '+fullPathNew); //$NON-NLS-1$
return (rv==0);
}
public boolean copyBatch(IProgressMonitor monitor, String[] srcParents, String[] srcNames, String tgtParent) throws SystemMessageException
{
boolean ok = true;
for (int i = 0; i < srcParents.length; i++)
{
ok = ok && copy(monitor, srcParents[i], srcNames[i], tgtParent, srcNames[i]);
}
return ok;
}
public void initService(IProgressMonitor monitor) {
try
{
connect();
}
catch (Exception e)
{
}
}
public void uninitService(IProgressMonitor monitor) {
disconnect();
}
public boolean isCaseSensitive() {
//TODO find out whether remote is case sensitive or not
return true;
}
}

View file

@ -0,0 +1,153 @@
/********************************************************************************
* Copyright (c) 2005, 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 FTPHostFile.
********************************************************************************/
package org.eclipse.rse.services.ssh.files;
import java.io.File;
import org.eclipse.rse.services.clientserver.archiveutils.ArchiveHandlerManager;
import org.eclipse.rse.services.files.IHostFile;
public class SftpHostFile implements IHostFile {
private String fName;
private String fParentPath;
private boolean fIsDirectory = false;
private boolean fIsRoot = false;
private boolean fIsArchive = false;
private boolean fExists = true;
private long fLastModified = 0;
private long fSize = 0;
private boolean fIsLink = false;
private String[] fExtended = null;
//TODO just re-use or extend FTPHostFile instead of copying here?
public SftpHostFile(String parentPath, String name, boolean isDirectory, boolean isRoot, boolean isLink, long lastModified, long size) {
fParentPath = parentPath;
fName = name;
fIsDirectory = isDirectory;
fIsRoot = isRoot;
fLastModified = lastModified;
fSize = size;
fIsLink = isLink;
fIsArchive = internalIsArchive();
}
public String getName() {
return fName;
}
public boolean isHidden() {
String name = getName();
return name.charAt(0) == '.';
}
public String getParentPath() {
return fParentPath;
}
public boolean isDirectory() {
return fIsDirectory;
}
public boolean isFile() {
return !(fIsDirectory || fIsRoot || fIsLink);
}
public boolean isRoot() {
return fIsRoot;
}
public void setExists(boolean b) {
fExists = b;
}
public boolean exists() {
return fExists;
}
public String getAbsolutePath() {
if (isRoot()) {
return getName();
} else {
StringBuffer path = new StringBuffer(getParentPath());
if (!fParentPath.endsWith("/"))
{
path.append('/');
}
path.append(getName());
return path.toString();
}
}
public long getSize() {
return fSize;
}
public long getModifiedDate() {
return fLastModified;
}
public void renameTo(String newAbsolutePath) {
int i = newAbsolutePath.lastIndexOf("/");
if (i == -1) {
fName = newAbsolutePath;
}
else {
fParentPath = newAbsolutePath.substring(0, i);
fName = newAbsolutePath.substring(i+1);
}
fIsArchive = internalIsArchive();
}
protected boolean internalIsArchive() {
return ArchiveHandlerManager.getInstance().isArchive(new File(getAbsolutePath()))
&& !ArchiveHandlerManager.isVirtual(getAbsolutePath());
}
public boolean isArchive() {
return fIsArchive;
}
public boolean isLink() {
return fIsLink;
}
/** Extended data: name:value pairs */
public void setExtendedData(String[] extended) {
fExtended = extended;
}
public String[] getExtendedData() {
return fExtended;
}
public String getClassification() {
//TODO: isExecutable(), shellscript vs. binary
String result;
if (isLink()) {
//TODO: read symbolic link target and its type to provide e.g. "symbolic link(directory):/export4/opt
result = "symbolic link"; //$NON-NLS-1$
} else if (isFile()) {
result = "file"; //$NON-NLS-1$
} else if (isDirectory()) {
result = "directory"; //$NON-NLS-1$
} else {
result = "unknown"; //default-fallback //$NON-NLS-1$
}
return result;
}
}

View file

@ -0,0 +1,87 @@
/********************************************************************************
* 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 LocalHostShell.
********************************************************************************/
package org.eclipse.rse.services.ssh.shell;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import org.eclipse.rse.services.shells.AbstractHostShell;
import org.eclipse.rse.services.shells.IHostShellOutputReader;
import org.eclipse.rse.services.ssh.ISshSessionProvider;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.Session;
/**
* A Shell subsystem for SSH.
*/
public class SshHostShell extends AbstractHostShell {
private ISshSessionProvider fSessionProvider;
private Channel fChannel;
private SshShellOutputReader fStdoutHandler;
private SshShellOutputReader fStderrHandler;
private PrintWriter fStdinHandler;
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(fChannel instanceof ChannelShell) {
// ((ChannelShell)fChannel).setPty(false);
//}
fStdoutHandler = new SshShellOutputReader(this, new BufferedReader(new InputStreamReader(fChannel.getInputStream())), false);
fStderrHandler = new SshShellOutputReader(this, null,true);
fStdinHandler = new PrintWriter(fChannel.getOutputStream());
fChannel.connect();
} catch(Exception e) {
//TODO Forward exception to RSE properly
e.printStackTrace();
}
}
public boolean isActive() {
return !fChannel.isEOF();
}
public void writeToShell(String command) {
fStdinHandler.println(command);
fStdinHandler.flush();
}
public IHostShellOutputReader getStandardOutputReader() {
return fStdoutHandler;
}
public IHostShellOutputReader getStandardErrorReader() {
return fStderrHandler;
}
public void exit() {
fChannel.disconnect();
}
}

View file

@ -0,0 +1,126 @@
/********************************************************************************
* 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 LocalShellOutputReader.
* Martin Oberhuber (Wind River) - Added vt100 escape sequence ignoring.
********************************************************************************/
package org.eclipse.rse.services.ssh.shell;
import java.io.BufferedReader;
import java.io.IOException;
import org.eclipse.rse.services.shells.AbstractHostShellOutputReader;
import org.eclipse.rse.services.shells.IHostShell;
import org.eclipse.rse.services.shells.IHostShellOutputReader;
/**
* 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;
public SshShellOutputReader(IHostShell hostShell, BufferedReader reader,
boolean isErrorReader) {
super(hostShell, isErrorReader);
fReader = reader;
}
protected Object 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();
int ch;
int lastch = 0;
boolean done = false;
while (!done && !isFinished()) {
try {
ch = fReader.read();
switch (ch) {
case -1:
if (theLine.length() == 0) // End of Reader
return null;
done = true;
break;
case 65535:
if (theLine.length() == 0) // Check why I keep getting this!!!
return null;
done = true;
break;
case 10:
done = true; // Newline
break;
case 9:
//TODO Count characters and insert as many as needed to do a real tab
theLine.append(" "); // Tab //$NON-NLS-1$
break;
case 13:
break; // Carriage Return
default:
char tch = (char) ch;
if (!Character.isISOControl(tch)) {
theLine.append(tch); // Any other character
} else if (ch == 27) {
// Escape: ignore next char too
int nch = (char)fReader.read();
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();
} while (Character.isDigit((char)nch) || nch == ';');
}
}
}
boolean ready = fReader.ready();
//TODO Get rid of this to support UNIX and Mac? -- It appears that
//due to vt100 emulation we get CRLF even for UNIX connections.
if (ch == 10 && lastch == 13) {
return theLine.toString();
}
lastch = ch;
// 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 (!ready) {
// wait to make sure
try {
Thread.sleep(_waitIncrement);
} catch (InterruptedException e) {
}
if (!fReader.ready()) {
if (done) {
return theLine.toString().trim();
} else {
done = true;
}
}
}
} catch (IOException e) {
return null;
}
}
return theLine.toString();
}
}

View file

@ -0,0 +1,96 @@
/********************************************************************************
* 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 LocalShellService.
********************************************************************************/
package org.eclipse.rse.services.ssh.shell;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.rse.services.clientserver.messages.SystemMessage;
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.ISshSessionProvider;
import com.jcraft.jsch.Session;
/**
* A Shell Services for ssh.
* Adapted from LocalShellService.
*/
public class SshShellService implements ISshService, IShellService {
private static final String SHELL_INVOCATION = ">";
private ISshSessionProvider fSessionProvider;
public SshShellService(ISshSessionProvider sessionProvider) {
fSessionProvider = sessionProvider;
}
//TODO abstract base class should handle default encodings
public IHostShell launchShell(IProgressMonitor monitor,
String initialWorkingDirectory, String[] environment) {
String defaultEncoding = System.getProperty("file.encoding"); //$NON-NLS-1$
return launchShell(monitor, initialWorkingDirectory, defaultEncoding, environment);
}
public IHostShell launchShell(IProgressMonitor monitor,
String initialWorkingDirectory, String encoding,
String[] environment) {
SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, SHELL_INVOCATION, encoding, environment);
return hostShell;
}
//TODO abstract base class should handle default encodings
public IHostShell runCommand(IProgressMonitor monitor,
String initialWorkingDirectory, String command, String[] environment) {
String defaultEncoding = System.getProperty("file.encoding"); //$NON-NLS-1$
return runCommand(monitor, initialWorkingDirectory, command, defaultEncoding, environment);
}
//TODO command is ignored by SshHostShell for now (just like DStoreHostShell).
public IHostShell runCommand(IProgressMonitor monitor,
String initialWorkingDirectory, String command, String encoding,
String[] environment) {
SshHostShell hostShell = new SshHostShell(fSessionProvider, initialWorkingDirectory, command, encoding, environment);
return hostShell;
}
public String[] getHostEnvironment() {
//TODO getHostEnvironment is not yet implemented for ssh (needs running remote command and parsing)
return new String[0];
}
public String getName() {
//TODO Externalize Strings
return "SSH Shell Service";
}
public String getDescription() {
return "SSH Shell Service Description";
}
public void initService(IProgressMonitor monitor) {
// nothing to do
}
public void uninitService(IProgressMonitor monitor) {
// nothing to do
}
public SystemMessage getMessage(String messageID) {
return null;
}
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.rse.subsystems.files.ssh</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ssh Plug-in
Bundle-SymbolicName: org.eclipse.rse.subsystems.files.ssh; singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: org.eclipse.rse.subsystems.files.ssh.Activator
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.rse.services,
org.eclipse.rse.connectorservice.ssh,
org.eclipse.rse.services.ssh,
org.eclipse.rse.core,
org.eclipse.rse.subsystems.files.core,
com.jcraft.jsch,
org.eclipse.rse.ui
Eclipse-LazyStart: true
Export-Package: org.eclipse.rse.subsystems.files.ssh

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

View file

@ -0,0 +1,15 @@
################################################################################
# Copyright (c) 2006 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 - initial API and implementation
################################################################################
plugin.name = Ssh Files Plugin
SshFileSubsystemName=Sftp Files
SshFileSubsystemDescription=Show Sftp Files on remote host.

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2006 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 - initial API and implementation
-->
<?eclipse version="3.1"?>
<plugin>
<extension
point="org.eclipse.rse.ui.subsystemConfiguration">
<configuration
systemTypes="Linux;Unix;AIX;SSH Only"
name="%SshFileSubsystemName"
description="%SshFileSubsystemDescription"
iconlive="icons/full/obj16/systemfileslive_obj.gif"
icon="icons/full/obj16/systemfiles_obj.gif"
category="files"
class="org.eclipse.rse.subsystems.files.ssh.SftpFileSubSystemConfiguration"
vendor="Wind River Systems, Inc."
id="ssh.files">
</configuration>
</extension>
</plugin>

View file

@ -0,0 +1,61 @@
package org.eclipse.rse.subsystems.files.ssh;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.rse.subsystems.files.ssh";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path.
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}

View file

@ -0,0 +1,63 @@
/********************************************************************************
* 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 FTPFileAdapter.
********************************************************************************/
package org.eclipse.rse.subsystems.files.ssh;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.rse.services.files.IHostFile;
import org.eclipse.rse.services.ssh.files.SftpHostFile;
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
import org.eclipse.rse.subsystems.files.core.subsystems.IHostFileToRemoteFileAdapter;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileContext;
import org.eclipse.rse.ui.ISystemPreferencesConstants;
import org.eclipse.rse.ui.RSEUIPlugin;
public class SftpFileAdapter implements IHostFileToRemoteFileAdapter {
public IRemoteFile[] convertToRemoteFiles(FileServiceSubSystem ss, IRemoteFileContext context, IRemoteFile parent, IHostFile[] nodes) {
boolean showHidden = RSEUIPlugin.getDefault().getPreferenceStore().getBoolean(ISystemPreferencesConstants.SHOWHIDDEN);
List results = new ArrayList();
for (int i = 0; i < nodes.length; i++) {
SftpHostFile node = (SftpHostFile)nodes[i];
if (showHidden || !node.isHidden()) {
IRemoteFile remoteFile = new SftpRemoteFile(ss, context, parent, node);
results.add(remoteFile);
ss.cacheRemoteFile(remoteFile);
}
}
return (IRemoteFile[])results.toArray(new IRemoteFile[results.size()]);
}
public IRemoteFile convertToRemoteFile(FileServiceSubSystem ss, IRemoteFileContext context, IRemoteFile parent, String name, boolean isDirectory, boolean isRoot) {
return null;
}
public IRemoteFile convertToRemoteFile(FileServiceSubSystem ss, IRemoteFileContext context, IRemoteFile parent, IHostFile node) {
IRemoteFile file = new SftpRemoteFile(ss, context, parent, (SftpHostFile)node);
ss.cacheRemoteFile(file);
return file;
}
public IRemoteFile convertToRemoteFile(FileServiceSubSystem ss, IRemoteFileContext context, IRemoteFile parent, Object object) {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -0,0 +1,118 @@
/*******************************************************************************
* Copyright (c) 2006 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.subsystems.files.ssh;
import org.eclipse.rse.connectorservice.ssh.SshConnectorService;
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.internal.subsystems.files.core.ILanguageUtilityFactory;
import org.eclipse.rse.model.IHost;
import org.eclipse.rse.services.clientserver.SystemSearchString;
import org.eclipse.rse.services.files.IFileService;
import org.eclipse.rse.services.search.IHostSearchResultConfiguration;
import org.eclipse.rse.services.search.IHostSearchResultSet;
import org.eclipse.rse.services.search.ISearchService;
import org.eclipse.rse.services.ssh.ISshService;
import org.eclipse.rse.services.ssh.ISshSessionProvider;
import org.eclipse.rse.services.ssh.files.SftpFileService;
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystemConfiguration;
import org.eclipse.rse.subsystems.files.core.subsystems.IHostFileToRemoteFileAdapter;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
import com.jcraft.jsch.Session;
public class SftpFileSubSystemConfiguration extends FileServiceSubSystemConfiguration {
protected IHostFileToRemoteFileAdapter _hostFileAdapter;
public SftpFileSubSystemConfiguration() {
super();
setIsUnixStyle(true);
}
public boolean isFactoryFor(Class subSystemType) {
boolean isFor = FileServiceSubSystem.class.equals(subSystemType);
return isFor;
}
public boolean supportsArchiveManagement() {
return false;
}
public ISubSystem createSubSystemInternal(IHost host) {
SshConnectorService connectorService = (SshConnectorService)getConnectorService(host);
ISubSystem subsys = new FileServiceSubSystem(host, connectorService, getFileService(host), getHostFileAdapter(), getSearchService(host));
return subsys;
}
public boolean supportsFileTypes() {
return false;
}
public boolean supportsSearch() {
return false;
}
public boolean supportsEnvironmentVariablesPropertyPage() {
return false;
}
public boolean supportsFilters() {
return true;
}
public IConnectorService getConnectorService(IHost host) {
return SshConnectorServiceManager.getInstance().getConnectorService(host, getServiceImplType());
}
public void setConnectorService(IHost host, IConnectorService connectorService) {
SshConnectorServiceManager.getInstance().setConnectorService(host, getServiceImplType(), connectorService);
}
public IFileService createFileService(IHost host) {
SshConnectorService connectorService = (SshConnectorService)getConnectorService(host);
//return connectorService.getFileService();
//TODO We have to get the file service from the connector service in order to make
//sure the connector service can connect it when required. It might be better to
//create a new instance here, and have it connect lazily on demand instead.
//In fact, due to ssh timeouts, it might be necessary that we can re-connect
//on demand on any operation anyway.
return new SftpFileService((ISshSessionProvider)connectorService);
}
public ISearchService createSearchService(IHost host) {
// no search service supported for ssh/sftp at moment
return null;
}
public IHostFileToRemoteFileAdapter getHostFileAdapter() {
if (_hostFileAdapter == null) {
_hostFileAdapter = new SftpFileAdapter();
}
return _hostFileAdapter;
}
public IHostSearchResultConfiguration createSearchConfiguration(IHost host, IHostSearchResultSet resultSet, Object searchTarget, SystemSearchString searchString) {
return null;
}
public ILanguageUtilityFactory getLanguageUtilityFactory(IRemoteFileSubSystem ss) {
return null;
}
public Class getServiceImplType() {
return ISshService.class;
}
}

View file

@ -0,0 +1,47 @@
/********************************************************************************
* Copyright (c) 2005, 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 FTPRemoteFile.
********************************************************************************/
package org.eclipse.rse.subsystems.files.ssh;
import org.eclipse.rse.services.ssh.files.SftpHostFile;
import org.eclipse.rse.subsystems.files.core.servicesubsystem.AbstractRemoteFile;
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileContext;
public class SftpRemoteFile extends AbstractRemoteFile {
public SftpRemoteFile(FileServiceSubSystem ss, IRemoteFileContext context, IRemoteFile parent, SftpHostFile hostFile) {
super(ss, context, parent, hostFile);
}
public SftpHostFile getSftpHostFile() {
return (SftpHostFile)getHostFile();
}
public boolean isVirtual() {
return false;
}
public String getCanonicalPath() {
return getAbsolutePath();
}
public String getClassification() {
return getSftpHostFile().getClassification();
}
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.rse.subsystems.shells.ssh</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Ssh Plug-in
Bundle-SymbolicName: org.eclipse.rse.subsystems.shells.ssh; singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: org.eclipse.rse.subsystems.shells.ssh.Activator
Bundle-Localization: plugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.rse.services,
org.eclipse.rse.connectorservice.ssh,
org.eclipse.rse.services.ssh,
org.eclipse.rse.ui,
org.eclipse.rse.core,
org.eclipse.rse.subsystems.shells.core,
com.jcraft.jsch
Eclipse-LazyStart: true
Export-Package: org.eclipse.rse.subsystems.shells.ssh

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

View file

@ -0,0 +1,17 @@
################################################################################
# Copyright (c) 2006 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 - initial API and implementation
################################################################################
plugin.name = Ssh Shells Plugin
SshShellSubsystemName=Shells
SshShellSubsystemDescription=This configuration allows you to work with shells and commands on remote systems using the Secure Shell (ssh) protocol.

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2006 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 - initial API and implementation
-->
<?eclipse version="3.1"?>
<plugin>
<extension
point="org.eclipse.rse.ui.subsystemConfiguration">
<configuration
systemTypes="Linux;Unix;AIX;SSH Only"
name="%SshShellSubsystemName"
description="%SshShellSubsystemDescription"
iconlive="icons/full/obj16/systemcommandslive_obj.gif"
icon="icons/full/obj16/systemcommands_obj.gif"
category="shells"
class="org.eclipse.rse.subsystems.shells.ssh.SshShellSubSystemConfiguration"
vendor="Wind River Systems, Inc."
id="ssh.shells">
</configuration>
</extension>
</plugin>

View file

@ -0,0 +1,61 @@
package org.eclipse.rse.subsystems.shells.ssh;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.rse.subsystems.shells.ssh";
// The shared instance
private static Activator plugin;
/**
* The constructor
*/
public Activator() {
plugin = this;
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path.
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}

View file

@ -0,0 +1,82 @@
/********************************************************************************
* 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 template for ssh service.
********************************************************************************/
package org.eclipse.rse.subsystems.shells.ssh;
import org.eclipse.rse.connectorservice.ssh.SshConnectorService;
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.internal.model.Host;
import org.eclipse.rse.model.IHost;
import org.eclipse.rse.services.shells.IShellService;
import org.eclipse.rse.services.ssh.ISshService;
import org.eclipse.rse.services.ssh.ISshSessionProvider;
import org.eclipse.rse.services.ssh.shell.SshShellService;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystem;
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystemConfiguration;
public class SshShellSubSystemConfiguration extends
ShellServiceSubSystemConfiguration {
public SshShellSubSystemConfiguration() {
super();
}
public boolean supportsCommands() {
//TODO support commands in SshShellService.runCommand()
return false;
}
/* (non-Javadoc)
* @see org.eclipse.rse.core.subsystems.SubSystemConfiguration#isFactoryFor(java.lang.Class)
*/
public boolean isFactoryFor(Class subSystemType) {
boolean isFor = ShellServiceSubSystem.class.equals(subSystemType);
return isFor;
}
/**
* Instantiate and return an instance of OUR subystem.
* Do not populate it yet though!
* @see org.eclipse.rse.core.subsystems.impl.SubSystemFactoryImpl#createSubSystemInternal(Host)
*/
public ISubSystem createSubSystemInternal(IHost host)
{
SshConnectorService connectorService = (SshConnectorService)getConnectorService(host);
ISubSystem subsys = new ShellServiceSubSystem(host, connectorService, createShellService(host));
return subsys;
}
public IShellService createShellService(IHost host) {
SshConnectorService cserv = (SshConnectorService)getConnectorService(host);
return new SshShellService((ISshSessionProvider)cserv);
}
public IConnectorService getConnectorService(IHost host) {
return SshConnectorServiceManager.getInstance().getConnectorService(host, ISshService.class);
}
public void setConnectorService(IHost host,
IConnectorService connectorService) {
SshConnectorServiceManager.getInstance().setConnectorService(host, ISshService.class, connectorService);
}
public Class getServiceImplType() {
return ISshService.class;
}
}