1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Merge with master.

Change-Id: I5f2295703ff699c143bb51f72087b4cad4eb15b7
Signed-off-by: Greg Watson <g.watson@computer.org>
This commit is contained in:
Greg Watson 2018-03-12 13:09:36 -04:00
parent fb0c709c16
commit 8ef7c04f8f
191 changed files with 10006 additions and 96 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>

View file

@ -1,7 +1,7 @@
eclipse.preferences.version=1 eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.compiler.source=1.7

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: %pluginName Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.remote.console;singleton:=true Bundle-SymbolicName: org.eclipse.remote.console;singleton:=true
Bundle-Version: 1.1.0.qualifier Bundle-Version: 1.2.0.qualifier
Bundle-Activator: org.eclipse.remote.internal.console.Activator Bundle-Activator: org.eclipse.remote.internal.console.Activator
Bundle-Localization: plugin Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-RequiredExecutionEnvironment: JavaSE-1.7

View file

@ -1,27 +0,0 @@
# about.ini
# contains information about a feature
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# "%key" are externalized strings defined in about.properties
# This file does not need to be translated.
# Property "aboutText" contains blurb for "About" dialog (translated)
aboutText=%blurb
# Property "windowImage" contains path to window icon (16x16)
# needed for primary features only
# Property "featureImage" contains path to feature image (32x32)
featureImage=ptp_logo_icon32.png
# Property "aboutImage" contains path to product image (500x330 or 115x164)
# needed for primary features only
# Property "appName" contains name of the application (not translated)
# needed for primary features only
# Property "welcomePage" contains path to welcome page (special XML-based format)
# optional
# Property "welcomePerspective" contains the id of the perspective in which the
# welcome page is to be opened.
# optional

View file

@ -1,6 +0,0 @@
# about.mappings
# contains fill-ins for about.properties
# java.io.Properties file (ISO 8859-1 with "\" escapes)
# This file does not need to be translated.
0=@build@

View file

@ -5,8 +5,4 @@ bin.includes = META-INF/,\
plugin.xml,\ plugin.xml,\
plugin.properties,\ plugin.properties,\
icons/,\ icons/,\
about.html,\ about.html
about.ini,\
about.mappings,\
about.properties,\
ptp_logo_icon32.png

View file

@ -6,11 +6,11 @@
<parent> <parent>
<groupId>org.eclipse.remote</groupId> <groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId> <artifactId>remote-parent</artifactId>
<version>2.1.0-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath> <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent> </parent>
<artifactId>org.eclipse.remote.console</artifactId> <artifactId>org.eclipse.remote.console</artifactId>
<packaging>eclipse-plugin</packaging> <packaging>eclipse-plugin</packaging>
<version>1.1.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</project> </project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View file

@ -0,0 +1,14 @@
package org.eclipse.remote.console;
import org.eclipse.remote.core.IRemoteConnection;
/**
* @since 1.2
*/
public interface ITerminalConsole {
/**
* @return The {@link IRemoteConnection} associated to this {@link ITerminalConsole}
*/
public IRemoteConnection getConnection();
}

View file

@ -31,4 +31,5 @@ public class ConsoleMessages extends NLS {
public static String OPENNING_TERMINAL; public static String OPENNING_TERMINAL;
public static String MAKING_CONNECTION; public static String MAKING_CONNECTION;
public static String DISCONNECTING; public static String DISCONNECTING;
public static String TerminalConsoleConnector_0;
} }

View file

@ -22,3 +22,4 @@ CONNECTING_TO_TERMINAL = Connecting to Command Shell
OPENNING_TERMINAL = Openning Command Shell OPENNING_TERMINAL = Openning Command Shell
MAKING_CONNECTION = Making Connection MAKING_CONNECTION = Making Connection
DISCONNECTING = Disconnecting DISCONNECTING = Disconnecting
TerminalConsoleConnector_0=Command shell not supported on this connection

View file

@ -13,6 +13,7 @@ package org.eclipse.remote.internal.console;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.remote.console.ITerminalConsole;
import org.eclipse.remote.core.IRemoteConnection; import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.tm.internal.terminal.provisional.api.TerminalState; import org.eclipse.tm.internal.terminal.provisional.api.TerminalState;
import org.eclipse.ui.console.AbstractConsole; import org.eclipse.ui.console.AbstractConsole;
@ -20,7 +21,7 @@ import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.part.IPageBookViewPage; import org.eclipse.ui.part.IPageBookViewPage;
import org.eclipse.ui.progress.UIJob; import org.eclipse.ui.progress.UIJob;
public class TerminalConsole extends AbstractConsole { public class TerminalConsole extends AbstractConsole implements ITerminalConsole {
private final String encoding; private final String encoding;
private final TerminalConsoleConnector terminalConnector; private final TerminalConsoleConnector terminalConnector;
private final int index; private final int index;
@ -36,6 +37,7 @@ public class TerminalConsole extends AbstractConsole {
return terminalConnector; return terminalConnector;
} }
@Override
public IRemoteConnection getConnection() { public IRemoteConnection getConnection() {
return terminalConnector.getConnection(); return terminalConnector.getConnection();
} }

View file

@ -141,6 +141,11 @@ public class TerminalConsoleConnector {
} }
} }
if (remoteProcess == null) {
disconnect();
return new Status(IStatus.ERROR, Activator.PLUGIN_ID, ConsoleMessages.TerminalConsoleConnector_0);
}
if (width > 0 || height > 0) { if (width > 0 || height > 0) {
IRemoteProcessTerminalService termService = remoteProcess.getService(IRemoteProcessTerminalService.class); IRemoteProcessTerminalService termService = remoteProcess.getService(IRemoteProcessTerminalService.class);
if (termService != null) { if (termService != null) {

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: %pluginName Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.remote.core;singleton:=true Bundle-SymbolicName: org.eclipse.remote.core;singleton:=true
Bundle-Version: 3.0.0.qualifier Bundle-Version: 4.0.0.qualifier
Bundle-Activator: org.eclipse.remote.internal.core.RemoteCorePlugin Bundle-Activator: org.eclipse.remote.internal.core.RemoteCorePlugin
Bundle-Vendor: %pluginProvider Bundle-Vendor: %pluginProvider
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
@ -19,6 +19,7 @@ Import-Package: org.eclipse.cdt.utils.pty,
org.eclipse.core.filesystem, org.eclipse.core.filesystem,
org.eclipse.core.resources, org.eclipse.core.resources,
org.eclipse.core.runtime, org.eclipse.core.runtime,
org.eclipse.core.runtime.jobs,
org.eclipse.core.runtime.preferences, org.eclipse.core.runtime.preferences,
org.eclipse.debug.core, org.eclipse.debug.core,
org.eclipse.equinox.security.storage, org.eclipse.equinox.security.storage,

View file

@ -6,11 +6,11 @@
<parent> <parent>
<groupId>org.eclipse.remote</groupId> <groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId> <artifactId>remote-parent</artifactId>
<version>2.1.0-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath> <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent> </parent>
<artifactId>org.eclipse.remote.core</artifactId> <artifactId>org.eclipse.remote.core</artifactId>
<version>3.0.0-SNAPSHOT</version> <version>4.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging> <packaging>eclipse-plugin</packaging>
</project> </project>

View file

@ -16,6 +16,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.remote.internal.core.RemoteProcess;
/** /**
* Abstract base class for remote process builders. Implementors can use this class to provide a default implementation of a remote * Abstract base class for remote process builders. Implementors can use this class to provide a default implementation of a remote
@ -195,4 +196,11 @@ public abstract class AbstractRemoteProcessBuilder implements IRemoteProcessBuil
public IRemoteConnection getRemoteConnection() { public IRemoteConnection getRemoteConnection() {
return fConnection; return fConnection;
} }
/**
* @since 4.0
*/
protected IRemoteProcess newRemoteProcess() {
return new RemoteProcess(getRemoteConnection(), this);
}
} }

View file

@ -41,6 +41,13 @@ public interface IRemoteProcessBuilder {
*/ */
public static int FORWARD_X11 = 0x02; public static int FORWARD_X11 = 0x02;
/**
* Flag to request that the supplied environment be apended to the remote environment; otherwise
* it is replaced.
* @since 3.0
*/
public static int APPEND_ENVIRONMENT = 0x03;
/** /**
* Returns this process builder's operating system program and arguments. * Returns this process builder's operating system program and arguments.
* *

View file

@ -51,6 +51,12 @@ public class RemoteConnectionChangeEvent {
*/ */
public static final int CONNECTION_REMOVED = 1 << 5; public static final int CONNECTION_REMOVED = 1 << 5;
/**
* Event indicating the connection attributes had changed.
* @since 4.0
*/
public static final int ATTRIBUTES_CHANGED = 1 << 6;
private final IRemoteConnection connection; private final IRemoteConnection connection;
private final int type; private final int type;

View file

@ -318,6 +318,10 @@ public class RemoteConnectionWorkingCopy implements IRemoteConnectionWorkingCopy
throw new RemoteConnectionException(e); throw new RemoteConnectionException(e);
} }
if (newAttributes.size() > 0 || newSecureAttributes.size() > 0) {
original.fireConnectionChangeEvent(RemoteConnectionChangeEvent.ATTRIBUTES_CHANGED);
}
/* /*
* Reset state for isDirty() * Reset state for isDirty()
*/ */

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.eclipse.remote</groupId> <groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId> <artifactId>remote-parent</artifactId>
<version>2.1.0-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath> <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent> </parent>
@ -20,13 +20,11 @@
<version>${tycho-extras-version}</version> <version>${tycho-extras-version}</version>
<configuration> <configuration>
<outputDirectory>${basedir}/html/reference/api</outputDirectory> <outputDirectory>${basedir}/html/reference/api</outputDirectory>
<!-- TODO: bump tycho-extras version. Excludes option requires >= 0.23
<javadocOptions> <javadocOptions>
<excludes> <excludes>
<exclude>org.eclipse.remote.internal.*</exclude> <exclude>org.eclipse.remote.internal.*</exclude>
</excludes> </excludes>
</javadocOptions> </javadocOptions>
-->
</configuration> </configuration>
<executions> <executions>
<execution> <execution>

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.eclipse.remote</groupId> <groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId> <artifactId>remote-parent</artifactId>
<version>2.1.0-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath> <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent> </parent>

View file

@ -29,7 +29,6 @@ import org.eclipse.remote.core.IRemoteFileService;
import org.eclipse.remote.core.IRemoteProcess; import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.exception.RemoteConnectionException; import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.internal.core.RemoteDebugOptions; import org.eclipse.remote.internal.core.RemoteDebugOptions;
import org.eclipse.remote.internal.core.RemoteProcess;
import org.eclipse.remote.internal.jsch.core.messages.Messages; import org.eclipse.remote.internal.jsch.core.messages.Messages;
import com.jcraft.jsch.Channel; import com.jcraft.jsch.Channel;
@ -182,7 +181,7 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
} }
fChannel.setXForwarding((flags & FORWARD_X11) == FORWARD_X11); fChannel.setXForwarding((flags & FORWARD_X11) == FORWARD_X11);
fChannel.connect(); fChannel.connect();
return new RemoteProcess(getRemoteConnection(), this); return newRemoteProcess();
} catch (RemoteConnectionException e) { } catch (RemoteConnectionException e) {
throw new IOException(e.getMessage()); throw new IOException(e.getMessage());
} catch (JSchException e) { } catch (JSchException e) {

View file

@ -6,7 +6,7 @@
<parent> <parent>
<groupId>org.eclipse.remote</groupId> <groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId> <artifactId>remote-parent</artifactId>
<version>2.1.0-SNAPSHOT</version> <version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath> <relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent> </parent>

View file

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

View file

@ -0,0 +1 @@
/bin

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.remote.proxy.core</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>
<buildCommand>
<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,28 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.remote.proxy.core;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: org.eclipse.remote.internal.proxy.core.Activator
Bundle-Vendor: %pluginProvider
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.remote.internal.proxy.core;x-friends:="org.eclipse.remote.proxy.ui",
org.eclipse.remote.internal.proxy.core.commands;x-friends:="org.eclipse.remote.proxy.ui",
org.eclipse.remote.internal.proxy.core.messages;x-friends:="org.eclipse.remote.proxy.ui"
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package:
com.jcraft.jsch,
org.eclipse.core.filesystem,
org.eclipse.core.filesystem.provider,
org.eclipse.core.runtime,
org.eclipse.core.runtime.jobs,
org.eclipse.jsch.core,
org.eclipse.osgi.util,
org.eclipse.remote.core,
org.eclipse.remote.core.exception,
org.eclipse.remote.internal.core,
org.eclipse.remote.internal.jsch.core,
org.eclipse.remote.proxy.protocol.core,
org.eclipse.remote.proxy.protocol.core.exceptions,
org.osgi.framework

View file

@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
</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">http://www.eclipse.org.</p>
</body>
</html>

View file

@ -0,0 +1,125 @@
installdir="$HOME/.eclipsesettings"
if test ! -d $installdir; then
mkdir $installdir
if test ! -d $installdir; then
echo fail:cannot create $installdir
exit 1
fi
fi
cat > $installdir/bootstrap.sh <<-\EOF
#!/bin/sh
installdir="$HOME/.eclipsesettings"
proxytmp=$installdir/proxy.b64
success=false
cleanup() {
rm -f $installdir/bootstrap.sh
}
trap 'cleanup' EXIT
parent_is_not_orphan () {
parent=`ps -ef|awk '$2=='$$'{print $3}'`
let parent=$parent+0
if [[ $parent -eq 1 ]]; then
return 1
fi
return 0
}
do_check() {
java_vers=`java -version 2>&1`
case "$java_vers" in
*"not found")
echo "fail:could not find a valid java installation"
return
;;
esac
major=`expr "$java_vers" : ".* version \"\([0-9]*\)\.[0-9]*.*\""`
minor=`expr "$java_vers" : ".* version \"[0-9]*\.\([0-9]*\).*\""`
if test "$major" -ge 2 -o "$minor" -ge 8; then
:
else
echo "fail:invalid java version $major.$minor; must be >= 1.8"
return
fi
case "`uname`" in
Linux)
osname="linux";
osarch=`uname -m`;
proxydir=$installdir/proxy;
plugins=$proxydir/plugins;;
Darwin)
osname="macosx";
osarch=`uname -m`;
proxydir=$installdir/Proxy.app;
plugins=$proxydir/Contents/Eclipse/plugins;;
*)
echo fail:system not supported;
return;;
esac
proxy=not_found
if test -d $proxydir; then
bundle="org.eclipse.remote.proxy.server.core_$1.jar"
if test -f $plugins/$bundle; then
proxy=found
else
mv $proxydir $proxydir.pre_$1
fi
fi
echo ok:$proxy/$osname/$osarch
}
do_download() {
dd of=$proxytmp ibs=680 count=$1
IFS= read -r last
echo "$last" >> $proxytmp
base64 --decode < $proxytmp | (cd $installdir && tar zxvf -) > /dev/null 2>&1
if test $? -eq 0; then
echo ok
else
echo fail:download failed
fi
}
#
# Start java in background so we can clean up after connection is dropped. The only way to tell if this
# has happened is to poll if ppid has changed to 1 (i.e. we no longer have a controlling terminal)
#
start_server() {
# enable debugoptions in order to attach a debugger
#debugoptions="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=1044,quiet=y"
# use globbing to find launcher version
java -cp $plugins/org.eclipse.equinox.launcher_1.*.jar \
$debugoptions \
org.eclipse.equinox.launcher.Main \
-application org.eclipse.remote.proxy.server.core.application \
-noExit 0<&0 &
pid=$!
trap 'kill $pid; exit' HUP INT TERM
while parent_is_not_orphan; do
sleep 10
done
kill $pid
}
echo running
while read line arg; do
case $line in
check) do_check $arg;;
download) do_download $arg;;
start) start_server;;
exit) break;;
*) echo fail:unrecognized command:$line; exit 1;;
esac
done
exit 0
EOF
chmod 755 $installdir/bootstrap.sh
exec $installdir/bootstrap.sh

View file

@ -0,0 +1,10 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
plugin.properties,\
about.html,\
bootstrap.sh

View file

@ -1,22 +1,11 @@
############################################################################### ###############################################################################
# Copyright (c) 2005, 2007 IBM Corporation and others. # Copyright (c) 2016 Oak Ridge National Laboratory and others.
# All rights reserved. This program and the accompanying materials # All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0 # are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at # which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html # http://www.eclipse.org/legal/epl-v10.html
# #
# Contributors:
# IBM Corporation - initial API and implementation
############################################################################### ###############################################################################
# NLS_MESSAGEFORMAT_NONE pluginName=Remote Proxy Support
# NLS_ENCODING=UTF-8 pluginProvider=Eclipse PTP
blurb=Remote Services\n\
\n\
Version: {featureVersion}\n\
Build id: {0}\n\
\n\
Copyright (c) 2008 IBM Corporation, and others. All rights reserved.\n\
Visit http://www.eclipse.org/ptp\n

View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
<extension
point="org.eclipse.remote.core.remoteServices">
<connectionType
id="org.eclipse.remote.Proxy"
name="PROXY"
scheme="proxy">
</connectionType>
<connectionService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
service="org.eclipse.remote.core.IRemoteConnectionControlService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
service="org.eclipse.remote.core.IRemoteConnectionPropertyService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
service="org.eclipse.remote.core.IRemoteProcessService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyFileManager$Factory"
service="org.eclipse.remote.core.IRemoteFileService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
service="org.eclipse.remote.core.IRemoteConnectionHostService">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
service="org.eclipse.remote.internal.proxy.core.ProxyConnection">
</connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
service="org.eclipse.remote.core.IRemoteCommandShellService">
</connectionService>
<processService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
service="org.eclipse.remote.core.IRemoteProcessControlService">
</processService>
<processService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
service="org.eclipse.remote.core.IRemoteProcessSignalService">
</processService>
<processService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
service="org.eclipse.remote.core.IRemoteProcessTerminalService">
</processService>
<processService
connectionTypeId="org.eclipse.remote.Proxy"
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
service="org.eclipse.remote.internal.proxy.core.ProxyProcess">
</processService>
</extension>
<extension
id="org.eclipse.remote.proxy.filesystem"
point="org.eclipse.core.filesystem.filesystems">
<filesystem
scheme="proxy">
<run
class="org.eclipse.remote.internal.proxy.core.ProxyFileSystem">
</run>
</filesystem>
</extension>
</plugin>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.remote.proxy.core</artifactId>
<packaging>eclipse-plugin</packaging>
<version>1.0.0-SNAPSHOT</version>
</project>

View file

@ -0,0 +1,116 @@
package org.eclipse.remote.internal.proxy.core;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends Plugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.remote.proxy.core"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Get unique identifier
*
* @return
* @since 5.0
*/
public static String getUniqueIdentifier() {
if (getDefault() == null) {
return PLUGIN_ID;
}
return getDefault().getBundle().getSymbolicName();
}
/**
* Logs the specified status with this plug-in's log.
*
* @param status
* status to log
*/
public static void log(IStatus status) {
getDefault().getLog().log(status);
}
/**
* Logs an internal error with the specified message.
*
* @param message
* the error message to log
*/
public static void log(String message) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, message, null));
}
/**
* Logs an internal error with the specified throwable
*
* @param e
* the exception to be logged
*/
public static void log(Throwable e) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), e));
}
/**
* The constructor
*/
public Activator() {
}
/**
* Return the OSGi service with the given service interface.
*
* @param service service interface
* @return the specified service or null if it's not registered
*/
public static <T> T getService(Class<T> service) {
BundleContext context = plugin.getBundle().getBundleContext();
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
* )
*/
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
* )
*/
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
}

View file

@ -0,0 +1,463 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.remote.core.IRemoteCommandShellService;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionChangeListener;
import org.eclipse.remote.core.IRemoteConnectionControlService;
import org.eclipse.remote.core.IRemoteConnectionHostService;
import org.eclipse.remote.core.IRemoteConnectionPropertyService;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteProcessService;
import org.eclipse.remote.core.RemoteConnectionChangeEvent;
import org.eclipse.remote.core.RemoteServicesUtils;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.internal.proxy.core.commands.ExecCommand;
import org.eclipse.remote.internal.proxy.core.commands.GetCwdCommand;
import org.eclipse.remote.internal.proxy.core.commands.GetEnvCommand;
import org.eclipse.remote.internal.proxy.core.commands.GetPropertiesCommand;
import org.eclipse.remote.internal.proxy.core.messages.Messages;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.StreamChannelManager;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
import com.jcraft.jsch.ChannelShell;
/**
* @since 5.0
*/
public class ProxyConnection implements IRemoteConnectionControlService,
IRemoteConnectionChangeListener, IRemoteProcessService,
IRemoteCommandShellService, IRemoteConnectionHostService,
IRemoteConnectionPropertyService {
// Connection Type ID
public static final String JSCH_ID = "org.eclipse.remote.Proxy"; //$NON-NLS-1$
public static final int DEFAULT_PORT = 22;
public static final int DEFAULT_TIMEOUT = 0;
public static final boolean DEFAULT_USE_PASSWORD = false;
public static final boolean DEFAULT_USE_DEFAULT_SERVER = true;
public static final String DEFAULT_SERVER_COMMAND = "sh .eclipsesettings/proxy.sh"; //$NON-NLS-1$
public static final String HOSTNAME_ATTR = "PROXY_HOSTNAME__ATTR"; //$NON-NLS-1$
public static final String USERNAME_ATTR = "PROXY_USERNAME_ATTR"; //$NON-NLS-1$
public static final String PASSWORD_ATTR = "PROXY_PASSWORD_ATTR"; //$NON-NLS-1$
public static final String PORT_ATTR = "PROXY_PORT_ATTR"; //$NON-NLS-1$
public static final String USE_PASSWORD_ATTR = "PROXY_USE_PASSWORD_ATTR"; //$NON-NLS-1$
public static final String PASSPHRASE_ATTR = "PROXY_PASSPHRASE_ATTR"; //$NON-NLS-1$
public static final String TIMEOUT_ATTR = "PROXY_TIMEOUT_ATTR"; //$NON-NLS-1$
public static final String SERVER_COMMAND_ATTR = "PROXY_SERVER_COMMAND_ATTR"; //$NON-NLS-1$
public static final String USE_DEFAULT_SERVER_ATTR = "PROXY_USE_DEFAULT_SERVER_ATTR"; //$NON-NLS-1$
private String fWorkingDir;
private StreamChannelManager channelMux;
private StreamChannel commandChannel;
private boolean isOpen;
private final IRemoteConnection fRemoteConnection;
private final Map<String, String> fEnv = new HashMap<>();
private final Map<String, String> fProperties = new HashMap<>();
private static final Map<IRemoteConnection, ProxyConnection> connectionMap = new HashMap<>();
public ProxyConnection(IRemoteConnection connection) {
fRemoteConnection = connection;
connection.addConnectionChangeListener(this);
}
@Override
public void connectionChanged(RemoteConnectionChangeEvent event) {
if (event.getType() == RemoteConnectionChangeEvent.CONNECTION_REMOVED) {
synchronized (connectionMap) {
connectionMap.remove(event.getConnection());
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection.Service#getRemoteConnection()
*/
@Override
public IRemoteConnection getRemoteConnection() {
return fRemoteConnection;
}
public static class Factory implements IRemoteConnection.Service.Factory {
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnection.Service.Factory#getService(org.eclipse.remote.core.IRemoteConnection,
* java.lang.Class)
*/
@Override
@SuppressWarnings("unchecked")
public <T extends IRemoteConnection.Service> T getService(IRemoteConnection connection, Class<T> service) {
// This little trick creates an instance of this class for a connection
// then for each interface it implements, it returns the same object.
// This works because the connection caches the service so only one gets created.
// As a side effect, it makes this class a service too which can be used
// by the this plug-in
if (ProxyConnection.class.equals(service)) {
synchronized (connectionMap) {
ProxyConnection conn = connectionMap.get(connection);
if (conn == null) {
conn = new ProxyConnection(connection);
connectionMap.put(connection, conn);
}
return (T) conn;
}
} else if (IRemoteConnectionControlService.class.equals(service)
|| IRemoteConnectionPropertyService.class.equals(service)
|| IRemoteConnectionHostService.class.equals(service)
|| IRemoteProcessService.class.equals(service)
|| IRemoteCommandShellService.class.equals(service)
|| IRemoteConnectionPropertyService.class.equals(service)) {
return (T) connection.getService(ProxyConnection.class);
} else {
return null;
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnectionControlService#close()
*/
@Override
public synchronized void close() {
if (isOpen) {
channelMux.shutdown();
isOpen = false;
fRemoteConnection.fireConnectionChangeEvent(RemoteConnectionChangeEvent.CONNECTION_CLOSED);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnectionControlService#isOpen()
*/
@Override
public boolean isOpen() {
return isOpen;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteConnectionControlService#open(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void open(IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor subMon = SubMonitor.convert(monitor, Messages.ProxyConnection_0, 20);
if (!isOpen) {
ProxyConnectionBootstrap bootstrap = new ProxyConnectionBootstrap();
channelMux = bootstrap.run(getRemoteConnection(), subMon.newChild(10));
new Thread(channelMux, "multiplexer").start(); //$NON-NLS-1$
try {
commandChannel = channelMux.openChannel();
initialize(subMon.newChild(10));
} catch (RemoteConnectionException | IOException e) {
try {
commandChannel.close();
} catch (IOException e1) {
// Ignore
}
channelMux.shutdown();
throw new RemoteConnectionException(e.getMessage());
}
isOpen = true;
fRemoteConnection.fireConnectionChangeEvent(RemoteConnectionChangeEvent.CONNECTION_OPENED);
}
}
private void initialize(IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor subMon = SubMonitor.convert(monitor, 30);
fWorkingDir = getCwd(subMon.newChild(10));
if (subMon.isCanceled()) {
throw new RemoteConnectionException(Messages.ProxyConnection_2);
}
fEnv.putAll(loadEnv(subMon.newChild(10)));
if (subMon.isCanceled()) {
throw new RemoteConnectionException(Messages.ProxyConnection_2);
}
fProperties.putAll(loadProperties(subMon.newChild(10)));
if (subMon.isCanceled()) {
throw new RemoteConnectionException(Messages.ProxyConnection_2);
}
}
private String getCwd(IProgressMonitor monitor) throws RemoteConnectionException {
try {
GetCwdCommand cmd = new GetCwdCommand(this);
return cmd.getResult(monitor);
} catch (ProxyException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
private Map<String, String> loadEnv(IProgressMonitor monitor) throws RemoteConnectionException {
try {
GetEnvCommand cmd = new GetEnvCommand(this);
return cmd.getResult(monitor);
} catch (ProxyException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
private Map<String, String> loadProperties(IProgressMonitor monitor) throws RemoteConnectionException {
try {
GetPropertiesCommand cmd = new GetPropertiesCommand(this);
return cmd.getResult(monitor);
} catch (ProxyException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
public Map<String, String> getEnv() {
return Collections.unmodifiableMap(fEnv);
}
public StreamChannel getCommandChannel() {
return commandChannel;
}
public StreamChannel openChannel() throws IOException {
return channelMux.openChannel();
}
private StringBuffer stdout = new StringBuffer();
private StringBuffer stderr = new StringBuffer();
@SuppressWarnings("unused")
private String executeSshCommand(ChannelShell shell, String command) throws RemoteConnectionException {
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
shell.setOutputStream(stream);
shell.setExtOutputStream(err);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(shell.getOutputStream()));
writer.write(command);
writer.flush();
if (err.size() > 0) {
throw new RemoteConnectionException(err.toString());
}
return stream.toString();
} catch (IOException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
@SuppressWarnings("unused")
private String executeCommand(List<String> command, IProgressMonitor monitor) throws ProxyException {
try {
final StreamChannel chanA = channelMux.openChannel();
final StreamChannel chanB = channelMux.openChannel();
final StreamChannel chanC = channelMux.openChannel();
new Thread("cmd stdin reader") { //$NON-NLS-1$
@Override
public void run() {
byte[] buf = new byte[1024];
int n;
try {
while ((n = chanA.getInputStream().read(buf)) >= 0) {
stdout.append(new String(buf, 0, n));
}
} catch (IOException e) {
// Finish
}
}
}.start();
new Thread("cmd stderr reader") { //$NON-NLS-1$
@Override
public void run() {
byte[] buf = new byte[1024];
int n;
try {
while ((n = chanB.getInputStream().read(buf)) >= 0) {
stderr.append(new String(buf, 0, n));
}
} catch (IOException e) {
// Finish
}
}
}.start();
ExecCommand cmd = new ExecCommand(this, command, getEnv(), getWorkingDirectory(), false, false, chanA.getId(), chanB.getId(), chanC.getId());
cmd.getResult(monitor);
DataInputStream status = new DataInputStream(chanC.getInputStream());
int stat = status.readInt();
if (stat == 0) {
return stdout.toString();
}
return stderr.toString();
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
@Override
public String getEnv(String name) {
return getEnv().get(name);
}
@Override
public IRemoteProcessBuilder getProcessBuilder(List<String> command) {
return new ProxyProcessBuilder(this, command);
}
@Override
public IRemoteProcessBuilder getProcessBuilder(String... command) {
return new ProxyProcessBuilder(this, command);
}
@Override
public String getWorkingDirectory() {
return fWorkingDir;
}
@Override
public void setWorkingDirectory(String path) {
if (RemoteServicesUtils.posixPath(path).isAbsolute()) {
fWorkingDir = path;
}
}
@Override
public IRemoteProcess getCommandShell(int flags) throws IOException {
return new ProxyProcessBuilder(this).start(flags);
}
@Override
public String getHostname() {
return fRemoteConnection.getAttribute(HOSTNAME_ATTR);
}
@Override
public int getPort() {
String portStr = fRemoteConnection.getAttribute(PORT_ATTR);
return !portStr.isEmpty() ? Integer.parseInt(portStr) : DEFAULT_PORT;
}
@Override
public int getTimeout() {
String portStr = fRemoteConnection.getAttribute(TIMEOUT_ATTR);
return !portStr.isEmpty() ? Integer.parseInt(portStr) : DEFAULT_TIMEOUT;
}
@Override
public String getPassphrase() {
return fRemoteConnection.getSecureAttribute(PASSPHRASE_ATTR);
}
@Override
public String getPassword() {
return fRemoteConnection.getSecureAttribute(PASSWORD_ATTR);
}
@Override
public boolean usePassword() {
String str = fRemoteConnection.getAttribute(USE_PASSWORD_ATTR);
return !str.isEmpty() ? Boolean.parseBoolean(str) : DEFAULT_USE_PASSWORD;
}
@Override
public String getUsername() {
return fRemoteConnection.getAttribute(USERNAME_ATTR);
}
@Override
public boolean useLoginShell() {
return false;
}
@Override
public void setHostname(String hostname) {
if (fRemoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) fRemoteConnection;
wc.setAttribute(HOSTNAME_ATTR, hostname);
}
}
@Override
public void setPassphrase(String passphrase) {
if (fRemoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) fRemoteConnection;
wc.setSecureAttribute(PASSPHRASE_ATTR, passphrase);
}
}
@Override
public void setPassword(String password) {
if (fRemoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) fRemoteConnection;
wc.setSecureAttribute(PASSWORD_ATTR, password);
}
}
@Override
public void setPort(int port) {
if (fRemoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) fRemoteConnection;
wc.setAttribute(PORT_ATTR, Integer.toString(port));
}
}
@Override
public void setTimeout(int timeout) {
if (fRemoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) fRemoteConnection;
wc.setAttribute(TIMEOUT_ATTR, Integer.toString(timeout));
}
}
@Override
public void setUseLoginShell(boolean useLogingShell) {
// Not used
}
@Override
public void setUsePassword(boolean usePassword) {
if (fRemoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) fRemoteConnection;
wc.setAttribute(USE_PASSWORD_ATTR, Boolean.toString(usePassword));
}
}
@Override
public void setUsername(String username) {
if (fRemoteConnection instanceof IRemoteConnectionWorkingCopy) {
IRemoteConnectionWorkingCopy wc = (IRemoteConnectionWorkingCopy) fRemoteConnection;
wc.setAttribute(USERNAME_ATTR, username);
}
}
@Override
public String getProperty(String key) {
return fProperties.get(key);
}
}

View file

@ -0,0 +1,321 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.util.Arrays;
import java.util.Base64;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.jsch.core.IJSchService;
import org.eclipse.osgi.util.NLS;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionHostService;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.remote.core.IUserAuthenticatorService;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.internal.jsch.core.JSchUserInfo;
import org.eclipse.remote.internal.proxy.core.messages.Messages;
import org.eclipse.remote.proxy.protocol.core.StreamChannelManager;
import org.osgi.framework.Bundle;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
public class ProxyConnectionBootstrap {
private final IJSchService jSchService;
private Session session;
private ChannelExec exec;
private class Context {
private State state;
private String osName;
private String osArch;
private String errorMessage;
private final SubMonitor monitor;
private final BufferedReader reader;
private final BufferedWriter writer;
public Context(BufferedReader reader, BufferedWriter writer, IProgressMonitor monitor) {
this.reader = reader;
this.writer = writer;
this.monitor = SubMonitor.convert(monitor);
setState(States.INIT);
}
State getState() {
return state;
}
SubMonitor getMonitor() {
return monitor;
}
void setState(State state) {
this.state = state;
}
String getOSName() {
return osName;
}
void setOSName(String osName) {
this.osName = osName;
}
String getOSArch() {
return osArch;
}
void setOSArch(String osArch) {
this.osArch = osArch;
}
void setErrorMessage(String message) {
this.errorMessage = message;
}
String getErrorMessage() {
return errorMessage;
}
}
private interface State {
/**
* @return true to keep processing, false to read more data.
*/
boolean process(Context context) throws IOException;
}
private enum States implements State {
INIT {
@Override
public boolean process(Context context) throws IOException {
context.getMonitor().subTask(Messages.ProxyConnectionBootstrap_0);
String line = context.reader.readLine();
context.getMonitor().worked(1);
if (line.equals("running")) { //$NON-NLS-1$
context.setState(States.CHECK);
return true;
}
return false;
}
},
CHECK {
@Override
public boolean process(Context context) throws IOException {
context.getMonitor().subTask(Messages.ProxyConnectionBootstrap_1);
String bundleName = "org.eclipse.remote.proxy.server.core"; //$NON-NLS-1$
Bundle serverBundle = Platform.getBundle(bundleName);
if (serverBundle == null) {
throw new IOException(NLS.bind(Messages.ProxyConnectionBootstrap_2, bundleName));
}
context.writer.write("check " + serverBundle.getVersion() + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
context.writer.flush();
String line = context.reader.readLine();
while (line != null) {
context.getMonitor().worked(2);
String[] parts = line.split(":"); //$NON-NLS-1$
switch (parts[0]) {
case "ok": //$NON-NLS-1$
String[] status = parts[1].split("/"); //$NON-NLS-1$
context.setOSName(status[1]);
context.setOSArch(status[2]);
context.setState(status[0].equals("found") ? States.START : States.DOWNLOAD); //$NON-NLS-1$
return true;
case "fail": //$NON-NLS-1$
context.setErrorMessage(parts[1]);
System.out.println("fail:"+parts[1]); //$NON-NLS-1$
return false;
case "debug": //$NON-NLS-1$
System.err.println(line);
break;
default:
System.err.println("Invalid response from bootstrap script: " + line); //$NON-NLS-1$
return false;
}
line = context.reader.readLine();
}
return false;
}
},
DOWNLOAD {
@Override
public boolean process(Context context) throws IOException {
context.getMonitor().subTask(Messages.ProxyConnectionBootstrap_3);
String bundleName = "org.eclipse.remote.proxy.server." + context.getOSName() + "." + context.getOSArch(); //$NON-NLS-1$ //$NON-NLS-2$
Bundle serverBundle = Platform.getBundle(bundleName);
if (serverBundle == null) {
throw new IOException(NLS.bind(Messages.ProxyConnectionBootstrap_2, bundleName));
}
URL fileURL = FileLocator.find(serverBundle, new Path("proxy.server.tar.gz"), null); //$NON-NLS-1$
if (fileURL == null) {
return false;
}
File file = new File(FileLocator.toFileURL(fileURL).getFile());
long count = file.length() / 510;
context.writer.write("download " + count + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
context.writer.flush();
context.getMonitor().worked(2);
if (downloadFile(file, context.writer, context.getMonitor().newChild(5))) {
String line = context.reader.readLine();
while (line != null) {
String[] parts = line.split(":"); //$NON-NLS-1$
switch (parts[0]) {
case "ok": //$NON-NLS-1$
context.setState(States.START);
return true;
case "fail": //$NON-NLS-1$
context.setErrorMessage(parts[1]);
System.out.println("fail:"+parts[1]); //$NON-NLS-1$
return false;
case "debug": //$NON-NLS-1$
System.err.println(line);
break;
default:
System.err.println("Invalid response from bootstrap script: " + line); //$NON-NLS-1$
return false;
}
line = context.reader.readLine();
}
}
return false;
}
private boolean downloadFile(File file, BufferedWriter writer, IProgressMonitor monitor) {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
try {
Base64.Encoder encoder = Base64.getEncoder();
FileInputStream in = new FileInputStream(file);
byte[] buf = new byte[510]; // Multiple of 3
int n;
while ((n = in.read(buf)) >= 0) {
if (n < 510) {
writer.write(encoder.encodeToString(Arrays.copyOf(buf, n)) + "\n"); //$NON-NLS-1$
} else {
writer.write(encoder.encodeToString(buf));
}
subMon.setWorkRemaining(8);
}
writer.flush();
in.close();
return true;
} catch (IOException e) {
return false;
}
}
},
START {
@Override
public boolean process(Context context) throws IOException {
context.getMonitor().subTask(Messages.ProxyConnectionBootstrap_4);
context.writer.write("start\n"); //$NON-NLS-1$
context.writer.flush();
return false; // Finished
}
}
}
public ProxyConnectionBootstrap() {
jSchService = Activator.getService(IJSchService.class);
}
public StreamChannelManager run(IRemoteConnection connection, IProgressMonitor monitor) throws RemoteConnectionException {
SubMonitor subMon = SubMonitor.convert(monitor, 20);
try {
final Channel chan = openChannel(connection, subMon.newChild(10));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(chan.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(chan.getInputStream()));
subMon.beginTask(Messages.ProxyConnectionBootstrap_5, 10);
subMon.subTask(Messages.ProxyConnectionBootstrap_9);
URL fileURL = FileLocator.find(Activator.getDefault().getBundle(), new Path("bootstrap.sh"), null); //$NON-NLS-1$
if (fileURL == null) {
throw new RemoteConnectionException(Messages.ProxyConnectionBootstrap_6);
}
File file = new File(FileLocator.toFileURL(fileURL).getFile());
BufferedReader scriptReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String line;
while ((line = scriptReader.readLine()) != null) {
writer.write(line + "\n"); //$NON-NLS-1$
}
scriptReader.close();
writer.flush();
subMon.worked(2);
Context context = new Context(reader, writer, subMon.newChild(8));
while (context.getState().process(context)) {
// do state machine
}
if (context.getState() != States.START) {
context.writer.write("exit\n"); //$NON-NLS-1$
context.writer.flush();
throw new RemoteConnectionException(NLS.bind(Messages.ProxyConnectionBootstrap_7, context.getErrorMessage()));
}
new Thread("server error stream") { //$NON-NLS-1$
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(chan.getExtInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.err.println("server: "+ line); //$NON-NLS-1$
}
} catch (IOException e) {
// Ignore and terminate thread
}
}
}.start();
return new StreamChannelManager(chan.getInputStream(), chan.getOutputStream());
} catch (IOException | CoreException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
private Channel openChannel(IRemoteConnection connection, IProgressMonitor monitor) throws RemoteConnectionException {
IRemoteConnectionWorkingCopy wc = connection.getWorkingCopy();
IRemoteConnectionHostService hostService = wc.getService(IRemoteConnectionHostService.class);
IUserAuthenticatorService authService = wc.getService(IUserAuthenticatorService.class);
try {
session = jSchService.createSession(hostService.getHostname(), hostService.getPort(), hostService.getUsername());
session.setUserInfo(new JSchUserInfo(hostService, authService));
if (hostService.usePassword()) {
session.setConfig("PreferredAuthentications", "password,keyboard-interactive,gssapi-with-mic,publickey"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
session.setConfig("PreferredAuthentications", "publickey,gssapi-with-mic,password,keyboard-interactive"); //$NON-NLS-1$ //$NON-NLS-2$
}
String password = hostService.getPassword();
if (!password.isEmpty()) {
session.setPassword(password);
}
jSchService.connect(session, hostService.getTimeout() * 1000, monitor);
if (monitor.isCanceled()) {
throw new RemoteConnectionException(Messages.ProxyConnectionBootstrap_8);
}
exec = (ChannelExec) session.openChannel("exec"); //$NON-NLS-1$
exec.setCommand("/bin/bash -l"); //$NON-NLS-1$
exec.connect();
return exec;
} catch (JSchException e) {
throw new RemoteConnectionException(e.getMessage());
}
}
}

View file

@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import org.eclipse.remote.core.IRemoteConnectionProviderService;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteConnectionType.Service;
public class ProxyConnectionProviderService implements IRemoteConnectionProviderService {
private IRemoteConnectionType connectionType;
public static class Factory implements IRemoteConnectionType.Service.Factory {
@SuppressWarnings("unchecked")
@Override
public <T extends Service> T getService(IRemoteConnectionType connectionType, Class<T> service) {
if (service.equals(IRemoteConnectionProviderService.class)) {
return (T) new ProxyConnectionProviderService(connectionType);
}
return null;
}
}
public ProxyConnectionProviderService(IRemoteConnectionType connectionType) {
this.connectionType = connectionType;
}
@Override
public void init() {
// Nothing
}
@Override
public IRemoteConnectionType getConnectionType() {
return connectionType;
}
}

View file

@ -0,0 +1,85 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import java.net.URI;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.IPath;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnection.Service;
import org.eclipse.remote.core.IRemoteFileService;
import org.eclipse.remote.core.IRemoteProcessService;
import org.eclipse.remote.core.RemoteServicesUtils;
public class ProxyFileManager implements IRemoteFileService {
private final IRemoteConnection fConnection;
private ProxyFileManager(IRemoteConnection connection) {
fConnection = connection;
}
public static class Factory implements IRemoteFileService.Factory {
@SuppressWarnings("unchecked")
@Override
public <T extends Service> T getService(IRemoteConnection remoteConnection, Class<T> service) {
if (IRemoteFileService.class.equals(service)) {
return (T) new ProxyFileManager(remoteConnection);
}
return null;
}
}
@Override
public IRemoteConnection getRemoteConnection() {
return fConnection;
}
@Override
public String getDirectorySeparator() {
return "/"; //$NON-NLS-1$
}
@Override
public IFileStore getResource(String pathStr) {
IPath path = RemoteServicesUtils.posixPath(pathStr);
if (!path.isAbsolute()) {
path = RemoteServicesUtils.posixPath(getBaseDirectory()).append(path);
}
return ProxyFileStore.getInstance(ProxyFileSystem.getURIFor(fConnection.getName(), path.toString()));
}
@Override
public String getBaseDirectory() {
return fConnection.getService(IRemoteProcessService.class).getWorkingDirectory();
}
@Override
public void setBaseDirectory(String path) {
fConnection.getService(IRemoteProcessService.class).setWorkingDirectory(path);
}
@Override
public String toPath(URI uri) {
return uri.getPath();
}
@Override
public URI toURI(IPath path) {
try {
return ProxyFileSystem.getURIFor(fConnection.getName(), path.toString());
} catch (Exception e) {
return null;
}
}
@Override
public URI toURI(String path) {
return toURI(RemoteServicesUtils.posixPath(path));
}
}

View file

@ -0,0 +1,356 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.provider.FileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteServicesManager;
import org.eclipse.remote.core.RemoteServicesUtils;
import org.eclipse.remote.core.exception.RemoteConnectionException;
import org.eclipse.remote.internal.proxy.core.commands.ChildInfosCommand;
import org.eclipse.remote.internal.proxy.core.commands.DeleteCommand;
import org.eclipse.remote.internal.proxy.core.commands.FetchInfoCommand;
import org.eclipse.remote.internal.proxy.core.commands.GetInputStreamCommand;
import org.eclipse.remote.internal.proxy.core.commands.GetOutputStreamCommand;
import org.eclipse.remote.internal.proxy.core.commands.MkdirCommand;
import org.eclipse.remote.internal.proxy.core.commands.PutInfoCommand;
import org.eclipse.remote.internal.proxy.core.messages.Messages;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ProxyFileStore extends FileStore {
/**
* Public factory method for obtaining ProxyFileStore instances.
*
* @param uri
* URI to get a fileStore for
* @return an ProxyFileStore instance for the URI.
*/
public static ProxyFileStore getInstance(URI uri) {
synchronized (instanceMap) {
ProxyFileStore store = instanceMap.get(uri.toString());
if (store == null) {
store = new ProxyFileStore(uri);
instanceMap.put(uri.toString(), store);
}
return store;
}
}
private static Map<String, ProxyFileStore> instanceMap = new HashMap<String, ProxyFileStore>();
private final IPath fRemotePath;
private final URI fURI;
private ProxyFileStore(URI uri) {
fURI = uri;
fRemotePath = RemoteServicesUtils.posixPath(uri.getPath());
}
private ProxyConnection checkConnection(IProgressMonitor monitor) throws RemoteConnectionException {
IRemoteServicesManager manager = Activator.getService(IRemoteServicesManager.class);
IRemoteConnectionType connectionType = manager.getConnectionType(fURI);
if (connectionType == null) {
throw new RemoteConnectionException(NLS.bind(Messages.ProxyFileStore_0, fURI));
}
try {
IRemoteConnection connection = connectionType.getConnection(fURI);
if (connection == null) {
throw new RemoteConnectionException(NLS.bind(Messages.ProxyFileStore_1, fURI));
}
if (!connection.isOpen()) {
connection.open(monitor);
if (!connection.isOpen()) {
throw new RemoteConnectionException(Messages.ProxyFileStore_2);
}
}
return connection.getService(ProxyConnection.class);
} catch (CoreException e) {
throw new RemoteConnectionException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#childInfos(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileInfo[] childInfos(int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ProxyConnection connection = checkConnection(subMon.newChild(1));
ChildInfosCommand command = new ChildInfosCommand(connection, fRemotePath.toString());
try {
return command.getResult(subMon.newChild(9));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#childNames(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public String[] childNames(int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
IFileInfo[] infos = childInfos(options, subMon.newChild(10));
String[] names = new String[infos.length];
for (int i = 0; i < infos.length; i++) {
names[i] = infos[i].getName();
}
return names;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#delete(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void delete(int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 20);
ProxyConnection connection = checkConnection(subMon.newChild(1));
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(9));
if (!subMon.isCanceled() && info.exists()) {
DeleteCommand command = new DeleteCommand(connection, options, fRemotePath.toString());
try {
command.getResult(subMon.newChild(10));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
subMon.setWorkRemaining(0);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#fetchInfo(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileInfo fetchInfo(int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ProxyConnection connection = checkConnection(subMon.newChild(1));
FetchInfoCommand command = new FetchInfoCommand(connection, fRemotePath.toString());
try {
return command.getResult(subMon.newChild(9));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.filesystem.provider.FileStore#getChild(java.lang.String)
*/
@Override
public IFileStore getChild(String name) {
URI uri = ProxyFileSystem.getURIFor(ProxyFileSystem.getConnectionNameFor(fURI), fRemotePath.append(name).toString());
return getInstance(uri);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#getName()
*/
@Override
public String getName() {
return getNameFromPath(fRemotePath);
}
/**
* Utility routing to get the file name from an absolute path.
*
* @param path
* path to extract file name from
* @return last segment of path, or the full path if it is root
*/
private String getNameFromPath(IPath path) {
if (path.isRoot()) {
return path.toString();
}
return path.lastSegment();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#getParent()
*/
@Override
public IFileStore getParent() {
if (fRemotePath.isRoot()) {
return null;
}
String parentPath = fRemotePath.toString();
if (fRemotePath.segmentCount() > 0) {
parentPath = fRemotePath.removeLastSegments(1).toString();
}
return getInstance(ProxyFileSystem.getURIFor(ProxyFileSystem.getConnectionNameFor(fURI), parentPath));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#mkdir(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public IFileStore mkdir(int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 16);
ProxyConnection connection = checkConnection(subMon.newChild(1));
if ((options & EFS.SHALLOW) == EFS.SHALLOW) {
IFileStore parent = getParent();
if (parent != null && !parent.fetchInfo(EFS.NONE, subMon.newChild(5)).exists()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRITE,
NLS.bind(Messages.ProxyFileStore_3, fRemotePath.toString()), null));
}
if (subMon.isCanceled()) {
return this;
}
}
subMon.setWorkRemaining(10);
try {
MkdirCommand command = new MkdirCommand(connection, options, fRemotePath.toString());
command.getResult(subMon.newChild(5));
} catch (Exception e) {
// Ignore any exceptions
}
if (!subMon.isCanceled()) {
/*
* Check if the result exists and is a directory, throw an exception if neither.
*/
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(5));
if (!subMon.isCanceled()) {
if (!info.exists()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRITE,
NLS.bind(Messages.ProxyFileStore_4, fRemotePath.toString()), null));
}
if (!info.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE,
NLS.bind(Messages.ProxyFileStore_5, fRemotePath.toString()), null));
}
}
}
return this;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#openInputStream(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public InputStream openInputStream(int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 20);
ProxyConnection connection = checkConnection(subMon.newChild(1));
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(9));
if (!subMon.isCanceled()) {
if (!info.exists()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_READ,
NLS.bind(Messages.ProxyFileStore_6, fRemotePath.toString()), null));
}
if (info.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE,
NLS.bind(Messages.ProxyFileStore_7, fRemotePath.toString()), null));
}
GetInputStreamCommand command = new GetInputStreamCommand(connection, options, fRemotePath.toString());
try {
return command.getResult(subMon.newChild(10));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#openOutputStream(int,
* org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 20);
ProxyConnection connection = checkConnection(subMon.newChild(1));
IFileInfo info = fetchInfo(EFS.NONE, subMon.newChild(9));
if (!subMon.isCanceled()) {
if (info.isDirectory()) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), EFS.ERROR_WRONG_TYPE,
NLS.bind(Messages.ProxyFileStore_7, fRemotePath.toString()), null));
}
GetOutputStreamCommand command = new GetOutputStreamCommand(connection, options, fRemotePath.toString());
try {
return command.getResult(subMon.newChild(10));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
return null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.filesystem.provider.FileStore#putInfo(org.eclipse.core
* .filesystem.IFileInfo, int, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void putInfo(IFileInfo info, int options, IProgressMonitor monitor) throws CoreException {
SubMonitor subMon = SubMonitor.convert(monitor, 10);
ProxyConnection connection = checkConnection(subMon.newChild(1));
PutInfoCommand command = new PutInfoCommand(connection, info, options, fRemotePath.toString());
try {
command.getResult(subMon.newChild(9));
} catch (ProxyException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage()));
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileStore#toURI()
*/
@Override
public URI toURI() {
return fURI;
}
}

View file

@ -0,0 +1,112 @@
/********************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory and others.
* 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
********************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import java.net.URI;
import java.net.URISyntaxException;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.provider.FileSystem;
import org.eclipse.core.runtime.IPath;
public class ProxyFileSystem extends FileSystem {
/**
* Return the connection name encoded in the URI.
*
* @param uri
* URI specifying a remote tools connection
* @return name of the connection or null if the URI is invalid
* @since 4.0
*/
public static String getConnectionNameFor(URI uri) {
return uri.getAuthority();
}
/**
* Return an URI uniquely naming a remote tools remote resource.
*
* @param connectionName
* remote tools connection name
* @param path
* absolute path to resource as valid on the remote system
* @return an URI uniquely naming the remote resource.
*/
public static URI getURIFor(String connectionName, String path) {
try {
return new URI("proxy", connectionName, path, null, null); //$NON-NLS-1$
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
/**
* Default constructor.
*/
public ProxyFileSystem() {
super();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.IFileSystem#attributes()
*/
@Override
public int attributes() {
// Attributes supported by JSch IFileService
return EFS.ATTRIBUTE_READ_ONLY | EFS.ATTRIBUTE_EXECUTABLE | EFS.ATTRIBUTE_SYMLINK | EFS.ATTRIBUTE_LINK_TARGET;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileSystem#canDelete()
*/
@Override
public boolean canDelete() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileSystem#canWrite()
*/
@Override
public boolean canWrite() {
return true;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.filesystem.provider.FileSystem#getStore(org.eclipse.core.runtime.IPath)
*/
@Override
public IFileStore getStore(IPath path) {
return EFS.getNullFileSystem().getStore(path);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.filesystem.provider.FileSystem#getStore(java.net.URI)
*/
@Override
public IFileStore getStore(URI uri) {
try {
return ProxyFileStore.getInstance(uri);
} catch (Exception e) {
// Could be an URI format exception
Activator.log(e);
return EFS.getNullFileSystem().getStore(uri);
}
}
}

View file

@ -0,0 +1,211 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessControlService;
import org.eclipse.remote.core.IRemoteProcessSignalService;
import org.eclipse.remote.core.IRemoteProcessTerminalService;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
public class ProxyProcess implements IRemoteProcessControlService, IRemoteProcessTerminalService {
private IRemoteProcess remoteProcess;
private final StreamChannel stdIOChan;
private final StreamChannel stdErrChan;
private final StreamChannel controlChan;
private final DataOutputStream cmdStream;
private final DataInputStream resultStream;
private final Thread cmdThread;
private volatile int exitValue;
private volatile boolean isCompleted;
public static class Factory implements IRemoteProcess.Service.Factory {
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteProcess.Service.Factory#getService(org.eclipse.remote.core.IRemoteProcess,
* java.lang.Class)
*/
@SuppressWarnings("unchecked")
@Override
public <T extends IRemoteProcess.Service> T getService(IRemoteProcess remoteProcess, Class<T> service) {
if (ProxyProcess.class.equals(service)) {
return (T) new ProxyProcess(remoteProcess);
}
if (IRemoteProcessControlService.class.equals(service) || IRemoteProcessSignalService.class.equals(service)
|| IRemoteProcessTerminalService.class.equals(service)) {
return (T) remoteProcess.getService(ProxyProcess.class);
}
return null;
}
}
protected ProxyProcess(IRemoteProcess process) {
remoteProcess = process;
ProxyProcessBuilder builder = (ProxyProcessBuilder)process.getProcessBuilder();
List<StreamChannel> streams = builder.getStreams();
controlChan = streams.get(0);
stdIOChan = streams.get(1);
stdErrChan = streams.size() > 2 ? streams.get(2) : null;
cmdStream = new DataOutputStream(controlChan.getOutputStream());
resultStream = new DataInputStream(controlChan.getInputStream());
isCompleted = false;
exitValue = 0;
cmdThread = new Thread("process result reader") { //$NON-NLS-1$
@Override
public void run() {
try {
exitValue = resultStream.readInt();
} catch (IOException e) {
// Finish
}
isCompleted = true;
try {
stdIOChan.close();
} catch (IOException e1) {
// Ignore
}
try {
if (stdErrChan != null) {
stdErrChan.close();
}
} catch (IOException e1) {
// Ignore
}
try {
controlChan.close();
} catch (IOException e) {
// Ignore
}
}
};
cmdThread.start();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#destroy()
*/
@Override
public void destroy() {
try {
cmdStream.writeByte(Protocol.CONTROL_KILL);
cmdStream.flush();
} catch (IOException e) {
isCompleted = true;
}
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#exitValue()
*/
@Override
public int exitValue() {
if (!isCompleted) {
throw new IllegalThreadStateException();
}
return exitValue;
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#getErrorStream()
*/
@Override
public InputStream getErrorStream() {
if (stdErrChan == null) {
return new InputStream() {
@Override
public int read() throws IOException {
return -1;
}
@Override
public int available() {
return 0;
}
};
}
return stdErrChan.getInputStream();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#getInputStream()
*/
@Override
public InputStream getInputStream() {
return stdIOChan.getInputStream();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#getOutputStream()
*/
@Override
public OutputStream getOutputStream() {
return stdIOChan.getOutputStream();
}
/*
* (non-Javadoc)
*
* @see java.lang.Process#waitFor()
*/
@Override
public int waitFor() throws InterruptedException {
cmdThread.join();
return exitValue;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.RemoteProcess#isCompleted()
*/
@Override
public boolean isCompleted() {
return isCompleted;
}
@Override
public IRemoteProcess getRemoteProcess() {
return remoteProcess;
}
@Override
public void setTerminalSize(int cols, int rows, int pwidth, int pheight) {
try {
cmdStream.writeByte(Protocol.CONTROL_SETTERMINALSIZE);
cmdStream.writeInt(cols);
cmdStream.writeInt(rows);
cmdStream.writeInt(pwidth);
cmdStream.writeInt(pheight);
cmdStream.flush();
} catch (IOException e) {
// Dealt with somewhere else hopefully
}
}
}

View file

@ -0,0 +1,169 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.remote.core.AbstractRemoteProcessBuilder;
import org.eclipse.remote.core.IRemoteFileService;
import org.eclipse.remote.core.IRemoteProcess;
import org.eclipse.remote.core.IRemoteProcessBuilder;
import org.eclipse.remote.internal.proxy.core.commands.ExecCommand;
import org.eclipse.remote.internal.proxy.core.commands.ShellCommand;
import org.eclipse.remote.internal.proxy.core.messages.Messages;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
private final ProxyConnection proxyConnection;
private Map<String, String> remoteEnv;
private List<StreamChannel> streams = new ArrayList<>();
public ProxyProcessBuilder(ProxyConnection connection, List<String> command) {
super(connection.getRemoteConnection(), command);
proxyConnection = connection;
IRemoteFileService fileSvc = proxyConnection.getRemoteConnection().getService(IRemoteFileService.class);
if (fileSvc != null) {
directory(fileSvc.getResource(proxyConnection.getWorkingDirectory()));
}
}
public ProxyProcessBuilder(ProxyConnection connection, String... command) {
this(connection, Arrays.asList(command));
}
/**
* Constructor for creating command shell
* @param connection
*/
public ProxyProcessBuilder(ProxyConnection connection) {
super(connection.getRemoteConnection(), (List<String>)null);
proxyConnection = connection;
redirectErrorStream(true);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.AbstractRemoteProcessBuilder#environment()
*/
@Override
public Map<String, String> environment() {
if (remoteEnv == null) {
remoteEnv = new HashMap<String, String>(proxyConnection.getEnv());
}
return remoteEnv;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.remote.core.AbstractRemoteProcessBuilder#getSupportedFlags
* ()
*/
@Override
public int getSupportedFlags() {
return NONE;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.remote.core.IRemoteProcessBuilder#start(int)
*/
@Override
public IRemoteProcess start(int flags) throws IOException {
final ProxyConnection conn = getRemoteConnection().getService(ProxyConnection.class);
if (conn == null) {
throw new IOException(Messages.ProxyProcessBuilder_0);
}
Job job;
final List<String> cmdArgs = command();
if (cmdArgs != null) {
if (cmdArgs.size() < 1) {
throw new IOException(Messages.ProxyProcessBuilder_1);
}
/*
* If environment has not been touched, then don't send anything
*/
final Map<String, String> env = new HashMap<String, String>();
if (remoteEnv != null) {
env.putAll(remoteEnv);
}
final boolean append = (flags & IRemoteProcessBuilder.APPEND_ENVIRONMENT) != 0 || remoteEnv == null;
streams.add(conn.openChannel());
streams.add(conn.openChannel());
streams.add(conn.openChannel());
job = new Job("process executor") { //$NON-NLS-1$
@Override
protected IStatus run(IProgressMonitor monitor) {
ExecCommand cmd = new ExecCommand(conn, cmdArgs, env, directory().toURI().getPath(), redirectErrorStream(), append,
streams.get(0).getId(), streams.get(1).getId(), streams.get(2).getId());
try {
cmd.getResult(monitor);
} catch (ProxyException e) {
return new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage());
}
return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
}
};
} else {
/*
* Start command shell
*/
streams.add(conn.openChannel());
streams.add(conn.openChannel());
job = new Job("process executor") { //$NON-NLS-1$
@Override
protected IStatus run(IProgressMonitor monitor) {
ShellCommand cmd = new ShellCommand(conn, streams.get(0).getId(), streams.get(1).getId());
try {
cmd.getResult(monitor);
} catch (ProxyException e) {
return new Status(IStatus.ERROR, Activator.getUniqueIdentifier(), e.getMessage());
}
return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS;
}
};
}
job.schedule();
try {
job.join();
} catch (InterruptedException e) {
throw new IOException(e.getMessage());
}
if (!job.getResult().isOK()) {
throw new IOException(job.getResult().getMessage());
}
return newRemoteProcess();
}
public List<StreamChannel> getStreams() {
return streams;
}
}

View file

@ -0,0 +1,84 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.internal.proxy.core.messages.Messages;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public abstract class AbstractCommand<T> implements Callable<T> {
private IProgressMonitor progressMonitor;
private static ExecutorService executors = Executors.newSingleThreadExecutor();
private final ProxyConnection connection;
private Future<T> asyncCmdInThread() throws ProxyException {
return executors.submit(this);
}
public StreamChannel openChannel() throws IOException {
return connection.openChannel();
}
public IProgressMonitor getProgressMonitor() {
return progressMonitor;
}
/**
* Function opens exec channel and then executes the exec operation. If
* run on the main thread it executes it on a separate thread
*/
public T getResult(IProgressMonitor monitor) throws ProxyException {
Future<T> future = null;
progressMonitor = SubMonitor.convert(monitor, 10);
future = asyncCmdInThread();
return waitCmdInThread(future);
}
private T waitCmdInThread(Future<T> future) throws ProxyException {
boolean bInterrupted = Thread.interrupted();
while (!getProgressMonitor().isCanceled()) {
try {
return future.get(100, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
bInterrupted = true;
} catch (TimeoutException e) {
// ignore
} catch (ExecutionException e) {
throw new ProxyException(e.getMessage());
}
getProgressMonitor().worked(1);
}
if (bInterrupted) {
Thread.currentThread().interrupt(); // set current thread flag
}
future.cancel(true);
throw new ProxyException(Messages.AbstractCommand_0);
}
@Override
public abstract T call() throws ProxyException;
public AbstractCommand(ProxyConnection conn) {
this.connection = conn;
}
}

View file

@ -0,0 +1,64 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ChildInfosCommand extends AbstractCommand<IFileInfo[]> {
private final DataOutputStream out;
private final DataInputStream in;
private final String path;
public ChildInfosCommand(ProxyConnection conn, String path) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.path = path;
}
public IFileInfo[] call() throws ProxyException {
try {
final StreamChannel chan = openChannel();
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_CHILDINFOS);
out.writeByte(chan.getId());
out.writeUTF(path);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
DataInputStream resultStream = new DataInputStream(chan.getInputStream());
int length = resultStream.readInt();
SerializableFileInfo sInfo = new SerializableFileInfo();
IFileInfo[] infos = new IFileInfo[length];
for (int i = 0; i < length; i++) {
sInfo.readObject(resultStream);
infos[i] = sInfo.getIFileInfo();
}
chan.close();
return infos;
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class DeleteCommand extends AbstractCommand<Void> {
private final DataOutputStream out;
private final DataInputStream in;
private final int options;
private final String path;
public DeleteCommand(ProxyConnection conn, int options, String path) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.options = options;
this.path = path;
}
public Void call() throws ProxyException {
try {
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_DELETE);
out.writeInt(options);
out.writeUTF(path);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
return null;
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,79 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ExecCommand extends AbstractCommand<Void> {
private final DataOutputStream out;
private final DataInputStream in;
private final List<String> command;
private final Map<String, String> env;
private final String directory;
private final boolean appendEnv;
private final boolean redirect;
private final int cmdChan;
private final int ioChan;
private final int errChan;
public ExecCommand(ProxyConnection conn, List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv,
int cmdChan, int ioChan, int errChan) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.command = command;
this.env = env;
this.directory = directory;
this.redirect = redirect;
this.appendEnv = appendEnv;
this.cmdChan = cmdChan;
this.ioChan = ioChan;
this.errChan = errChan;
}
public Void call() throws ProxyException {
try {
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_EXEC);
out.writeByte(cmdChan);
out.writeByte(ioChan);
out.writeByte(errChan);
out.writeInt(command.size());
for (String arg : command) {
out.writeUTF(arg);
}
out.writeInt(env.size());
for (Map.Entry<String, String> entry : env.entrySet()) {
out.writeUTF(entry.getKey());
out.writeUTF(entry.getValue());
}
out.writeUTF(directory);
out.writeBoolean(redirect);
out.writeBoolean(appendEnv);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
return null;
}
}

View file

@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class FetchInfoCommand extends AbstractCommand<IFileInfo> {
private final DataOutputStream out;
private final DataInputStream in;
private final String path;
public FetchInfoCommand(ProxyConnection conn, String path) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.path = path;
}
public IFileInfo call() throws ProxyException {
try {
final StreamChannel chan = openChannel();
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_FETCHINFO);
out.writeByte(chan.getId());
out.writeUTF(path);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
DataInputStream resultStream = new DataInputStream(chan.getInputStream());
SerializableFileInfo info = new SerializableFileInfo();
info.readObject(resultStream);
chan.close();
return info.getIFileInfo();
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class GetCwdCommand extends AbstractCommand<String> {
private final DataOutputStream out;
private final DataInputStream in;
public GetCwdCommand(ProxyConnection conn) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
}
public String call() throws ProxyException {
try {
final StreamChannel chan = openChannel();
DataInputStream resultStream = new DataInputStream(chan.getInputStream());
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_GETCWD);
out.writeByte(chan.getId());
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
String cwd = resultStream.readUTF();
chan.close();
return cwd;
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class GetEnvCommand extends AbstractCommand<Map<String, String>> {
private final DataOutputStream out;
private final DataInputStream in;
public GetEnvCommand(ProxyConnection conn) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
}
public Map<String, String> call() throws ProxyException {
try {
final StreamChannel chan = openChannel();
DataInputStream resultStream = new DataInputStream(chan.getInputStream());
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_GETENV);
out.writeByte(chan.getId());
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
int len = resultStream.readInt();
Map<String, String> env = new HashMap<String, String>(len);
for (int i = 0; i < len; i++) {
String key = resultStream.readUTF();
String value = resultStream.readUTF();
env.put(key, value);
}
chan.close();
return env;
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class GetInputStreamCommand extends AbstractCommand<InputStream> {
private final DataOutputStream out;
private final DataInputStream in;
private final int options;
private final String path;
public GetInputStreamCommand(ProxyConnection conn, int options, String path) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.options = options;
this.path = path;
}
public InputStream call() throws ProxyException {
try {
StreamChannel chan = openChannel();
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_GETINPUTSTREAM);
out.writeByte(chan.getId());
out.writeInt(options);
out.writeUTF(path);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
return new BufferedInputStream(chan.getInputStream());
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class GetOutputStreamCommand extends AbstractCommand<OutputStream> {
private final DataOutputStream out;
private final DataInputStream in;
private final int options;
private final String path;
public GetOutputStreamCommand(ProxyConnection conn, int options, String path) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.options = options;
this.path = path;
}
public OutputStream call() throws ProxyException {
try {
StreamChannel chan = openChannel();
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_GETOUTPUTSTREAM);
out.writeByte(chan.getId());
out.writeInt(options);
out.writeUTF(path);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
return new BufferedOutputStream(chan.getOutputStream());
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class GetPropertiesCommand extends AbstractCommand<Map<String, String>> {
private final DataOutputStream out;
private final DataInputStream in;
public GetPropertiesCommand(ProxyConnection conn) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
}
public Map<String, String> call() throws ProxyException {
try {
final StreamChannel chan = openChannel();
DataInputStream resultStream = new DataInputStream(chan.getInputStream());
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_GETPROPERTIES);
out.writeByte(chan.getId());
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
int len = resultStream.readInt();
Map<String, String> props = new HashMap<String, String>(len);
for (int i = 0; i < len; i++) {
String key = resultStream.readUTF();
String value = resultStream.readUTF();
props.put(key, value);
}
chan.close();
return props;
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class MkdirCommand extends AbstractCommand<Void> {
private final DataOutputStream out;
private final DataInputStream in;
private final int options;
private final String path;
public MkdirCommand(ProxyConnection conn, int options, String path) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.options = options;
this.path = path;
}
public Void call() throws ProxyException {
try {
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_MKDIR);
out.writeInt(options);
out.writeUTF(path);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
return null;
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,57 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class PutInfoCommand extends AbstractCommand<Void> {
private final DataOutputStream out;
private final DataInputStream in;
private final IFileInfo info;
private final int options;
private final String path;
public PutInfoCommand(ProxyConnection conn, IFileInfo info, int options, String path) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.info = info;
this.options = options;
this.path = path;
}
public Void call() throws ProxyException {
try {
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_PUTINFO);
out.writeInt(options);
out.writeUTF(path);
SerializableFileInfo sInfo = new SerializableFileInfo(info);
sInfo.writeObject(out);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
return null;
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,51 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.core.commands;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ShellCommand extends AbstractCommand<Void> {
private final DataOutputStream out;
private final DataInputStream in;
private final int cmdChan;
private final int ioChan;
public ShellCommand(ProxyConnection conn, int cmdChan, int ioChan) {
super(conn);
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
this.cmdChan = cmdChan;
this.ioChan = ioChan;
}
public Void call() throws ProxyException {
try {
out.writeByte(Protocol.PROTO_COMMAND);
out.writeShort(Protocol.CMD_SHELL);
out.writeByte(cmdChan);
out.writeByte(ioChan);
out.flush();
byte res = in.readByte();
if (res != Protocol.PROTO_OK) {
String errMsg = in.readUTF();
throw new ProxyException(errMsg);
}
} catch (IOException e) {
throw new ProxyException(e.getMessage());
}
return null;
}
}

View file

@ -0,0 +1,115 @@
/**
* Copyright (c) 2013 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
*
* Contributors:
* IBM Corporation - Initial Implementation
*
*/
package org.eclipse.remote.internal.proxy.core.messages;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_ID = "org.eclipse.remote.internal.proxy.core.messages.messages"; //$NON-NLS-1$
public static String AbstractCommand_0;
public static String AbstractRemoteCommand_format1;
public static String AbstractRemoteCommand_format2;
public static String AbstractRemoteCommand_Get_symlink_target;
public static String AbstractRemoteCommand_Operation_cancelled_by_user;
public static String AuthInfo_Authentication_message;
public static String ExecCommand_Exec_command;
public static String GetInputStreamCommand_Receiving;
public static String GetOutputStreamCommand_Sending;
public static String JSchConnection_0;
public static String JSchConnection_Connection_was_cancelled;
public static String JSchConnection_connectionNotOpen;
public static String JSchConnection_Executing_command;
public static String JSchConnection_remote_address_must_be_set;
public static String JSchConnection_remotePort;
public static String JSchConnection_forwarding;
public static String JSchConnection_Remote_host_does_not_support_sftp;
public static String JSchConnection_Unable_to_open_sftp_channel;
public static String JSchConnection_username_must_be_set;
public static String JSchConnectionManager_connection_with_name_exists;
public static String JSchConnectionManager_cannotRemoveOpenConnection;
public static String JSchConnectionManager_invalidConnectionType;
public static String JSchConnectionProxyFactory_failed;
public static String JSchConnectionProxyFactory_ProxyCommandFailed;
public static String JSchConnectionProxyFactory_timedOut;
public static String JSchConnectionProxyFactory_wasCanceled;
public static String JSchProcess_exitValue_exception_msg;
public static String JSchProcessBuilder_Connection_is_not_open;
public static String JschFileStore_Connection_is_not_open;
public static String JschFileStore_File_doesnt_exist;
public static String JschFileStore_Invalid_connection_for_URI;
public static String JschFileStore_Is_a_directory;
public static String JschFileStore_No_remote_services_found_for_URI;
public static String JschFileStore_The_directory_could_not_be_created;
public static String JschFileStore_A_file_of_name_already_exists;
public static String JschFileStore_The_parent_of_directory_does_not_exist;
public static String ProxyCommandShell_0;
public static String ProxyConnection_0;
public static String ProxyConnection_2;
public static String ProxyConnectionBootstrap_0;
public static String ProxyConnectionBootstrap_1;
public static String ProxyConnectionBootstrap_2;
public static String ProxyConnectionBootstrap_3;
public static String ProxyConnectionBootstrap_4;
public static String ProxyConnectionBootstrap_5;
public static String ProxyConnectionBootstrap_6;
public static String ProxyConnectionBootstrap_7;
public static String ProxyConnectionBootstrap_8;
public static String ProxyConnectionBootstrap_9;
public static String ProxyFileStore_0;
public static String ProxyFileStore_1;
public static String ProxyFileStore_2;
public static String ProxyFileStore_3;
public static String ProxyFileStore_4;
public static String ProxyFileStore_5;
public static String ProxyFileStore_6;
public static String ProxyFileStore_7;
public static String ProxyProcessBuilder_0;
public static String ProxyProcessBuilder_1;
static {
// load message values from bundle file
NLS.initializeMessages(BUNDLE_ID, Messages.class);
}
private Messages() {
// cannot create new instance
}
}

View file

@ -0,0 +1,69 @@
###############################################################################
# Copyright (c) 2013 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
#
# Contributors:
# IBM Corporation - initial implementation
###############################################################################
AbstractCommand_0=Operation cancelled by user
AbstractRemoteCommand_format1={0,number,integer} {1} completed
AbstractRemoteCommand_format2={0,number,integer} {1} of {2,number,integer} {3} complete ({4,number,percent})
AbstractRemoteCommand_Get_symlink_target=Get symlink target
AbstractRemoteCommand_Operation_cancelled_by_user=Operation cancelled by user
AuthInfo_Authentication_message=Authentication Message
ExecCommand_Exec_command=Executing command "{0}"
GetInputStreamCommand_Receiving=Receiving {0}:
GetOutputStreamCommand_Sending=Sending {0}:
JSchConnection_0=Connection canceled by user
JSchConnection_Connection_was_cancelled=Connection was cancelled
JSchConnection_connectionNotOpen=Connection is not open
JSchConnection_Executing_command=Executing command "{0}"
JSchConnection_remote_address_must_be_set=Remote address must be set before opening connection
JSchConnection_remotePort=Could not allocate remote port
JSchConnection_forwarding=Setting up remote forwarding
JSchConnection_Remote_host_does_not_support_sftp=Remote host does not support sftp. Remote functionality requires sftp to be enabled
JSchConnection_Unable_to_open_sftp_channel=Unable to open sftp channel: check sftp is enabled on remote host
JSchConnection_username_must_be_set=Username must be set before opening connection
JSchConnectionManager_connection_with_name_exists=A connection with name \"{0}\" already exists
JSchConnectionManager_cannotRemoveOpenConnection=Cannot remove an open connection
JSchConnectionManager_invalidConnectionType=Invalid connection type
JSchConnectionProxyFactory_failed=failed
JSchConnectionProxyFactory_ProxyCommandFailed=Proxy command "{0}" {1} and printed message "{2}"
JSchConnectionProxyFactory_timedOut=timed out
JSchConnectionProxyFactory_wasCanceled=was canceled
JSchProcess_exitValue_exception_msg=process has not exited
JSchProcessBuilder_Connection_is_not_open=Connection is not open
JschFileStore_Connection_is_not_open=Connection is not open
JschFileStore_File_doesnt_exist=File {0} doesn't exist
JschFileStore_Invalid_connection_for_URI=Invalid connection for URI: "{0}"
JschFileStore_Is_a_directory={0} is a directory
JschFileStore_No_remote_services_found_for_URI=No remote services found for URI: "{0}"
JschFileStore_The_directory_could_not_be_created=The directory {0} could not be created
JschFileStore_A_file_of_name_already_exists=A file of name {0} already exists
JschFileStore_The_parent_of_directory_does_not_exist=The parent of directory {0} does not exist
ProxyCommandShell_0=Unable to locate connection for command shell
ProxyConnection_0=Opening connection...
ProxyConnection_2=User canceled opening connection
ProxyConnectionBootstrap_0=Initializing
ProxyConnectionBootstrap_1=Validating environment
ProxyConnectionBootstrap_2=Unable to locate server bundle {0}
ProxyConnectionBootstrap_3=Updating server proxy
ProxyConnectionBootstrap_4=Starting server
ProxyConnectionBootstrap_5=Checking server installation
ProxyConnectionBootstrap_6=Unable to locate bootstrap shell
ProxyConnectionBootstrap_7=Unable to start server: {0}
ProxyConnectionBootstrap_8=User canceled connection open
ProxyConnectionBootstrap_9=Loading bootstrap shell
ProxyFileStore_0=No remote services found for URI {0}
ProxyFileStore_1=Invalid connection for URI {0}
ProxyFileStore_2=Connection is not open
ProxyFileStore_3=The parent of directory {0} does not exist
ProxyFileStore_4=The directory {0} could not be created
ProxyFileStore_5=A file of name {0} already exists
ProxyFileStore_6=File {0} does not exist
ProxyFileStore_7={0} is a directory
ProxyProcessBuilder_0=Unable to located connection for this process
ProxyProcessBuilder_1=No command to run\!

View file

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

View file

@ -0,0 +1 @@
/bin

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.remote.proxy.protocol.core</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>
<buildCommand>
<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,16 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.remote.proxy.protocol.core;singleton:=true
Bundle-Version: 2.0.0.qualifier
Bundle-Activator: org.eclipse.remote.internal.proxy.protocol.core.Activator
Bundle-Vendor: %pluginProvider
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.remote.proxy.protocol.core,
org.eclipse.remote.proxy.protocol.core.exceptions
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.eclipse.core.filesystem,
org.eclipse.core.filesystem.provider,
org.eclipse.core.runtime,
org.osgi.framework

View file

@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
</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">http://www.eclipse.org.</p>
</body>
</html>

View file

@ -0,0 +1,8 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.properties,\
about.html

View file

@ -0,0 +1,11 @@
###############################################################################
# Copyright (c) 2016 Oak Ridge National Laboratory 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
#
###############################################################################
pluginName=Remote Proxy Protocol Support
pluginProvider=Eclipse PTP

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.remote.proxy.protocol.core</artifactId>
<packaging>eclipse-plugin</packaging>
<version>2.0.0-SNAPSHOT</version>
</project>

View file

@ -0,0 +1,116 @@
package org.eclipse.remote.internal.proxy.protocol.core;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends Plugin {
// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.remote.proxy.protocol.core"; //$NON-NLS-1$
// The shared instance
private static Activator plugin;
/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}
/**
* Get unique identifier
*
* @return
* @since 5.0
*/
public static String getUniqueIdentifier() {
if (getDefault() == null) {
return PLUGIN_ID;
}
return getDefault().getBundle().getSymbolicName();
}
/**
* Logs the specified status with this plug-in's log.
*
* @param status
* status to log
*/
public static void log(IStatus status) {
getDefault().getLog().log(status);
}
/**
* Logs an internal error with the specified message.
*
* @param message
* the error message to log
*/
public static void log(String message) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, message, null));
}
/**
* Logs an internal error with the specified throwable
*
* @param e
* the exception to be logged
*/
public static void log(Throwable e) {
log(new Status(IStatus.ERROR, getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), e));
}
/**
* The constructor
*/
public Activator() {
}
/**
* Return the OSGi service with the given service interface.
*
* @param service service interface
* @return the specified service or null if it's not registered
*/
public static <T> T getService(Class<T> service) {
BundleContext context = plugin.getBundle().getBundleContext();
ServiceReference<T> ref = context.getServiceReference(service);
return ref != null ? context.getService(ref) : null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
* )
*/
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
* )
*/
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.proxy.protocol.core;
public class Protocol {
public static final int MAGIC = 0xAFFA;
public final static byte PROTO_COMMAND = 1;
public final static byte PROTO_SHUTDOWN = 2;
public final static byte PROTO_ERROR = 126;
public final static byte PROTO_OK = 0;
public final static short CmdBase = 100;
public final static short CMD_EXEC = CmdBase + 1;
public final static short CMD_SHELL = CmdBase + 2;
public final static short CMD_GETCWD = CmdBase + 3;
public final static short CMD_GETENV = CmdBase + 4;
public final static short CMD_CHILDINFOS = CmdBase + 5;
public final static short CMD_DELETE = CmdBase + 6;
public final static short CMD_FETCHINFO = CmdBase + 7;
public final static short CMD_GETINPUTSTREAM = CmdBase + 8;
public final static short CMD_GETOUTPUTSTREAM = CmdBase + 9;
public final static short CMD_MKDIR = CmdBase + 10;
public final static short CMD_PUTINFO = CmdBase + 11;
public final static short CMD_GETPROPERTIES = CmdBase + 12;
/**
* @since 2.0
*/
public final static byte CONTROL_KILL = 0;
/**
* @since 2.0
*/
public final static byte CONTROL_SETTERMINALSIZE = 1;
}

View file

@ -0,0 +1,90 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.proxy.protocol.core;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.provider.FileInfo;
public class SerializableFileInfo implements Serializable {
private static final long serialVersionUID = -1986643088683154145L;
private IFileInfo info;
public SerializableFileInfo() {
}
public SerializableFileInfo(IFileInfo info) {
setIFileInfo(info);
}
public void setIFileInfo(IFileInfo info) {
this.info = info;
}
public IFileInfo getIFileInfo() {
return info;
}
public void writeObject(DataOutputStream out) throws IOException {
out.writeUTF(info.getName());
boolean symlink = info.getAttribute(EFS.ATTRIBUTE_SYMLINK);
out.writeBoolean(symlink);
if (symlink) {
out.writeUTF(info.getStringAttribute(EFS.ATTRIBUTE_LINK_TARGET));
}
out.writeBoolean(info.exists());
out.writeLong(info.getLastModified());
out.writeLong(info.getLength());
out.writeBoolean(info.isDirectory());
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_GROUP_READ));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_GROUP_WRITE));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_GROUP_EXECUTE));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_OTHER_READ));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_OTHER_WRITE));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_OTHER_EXECUTE));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_OWNER_READ));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_OWNER_WRITE));
out.writeBoolean(info.getAttribute(EFS.ATTRIBUTE_OWNER_EXECUTE));
}
public void readObject(DataInputStream in) throws IOException {
FileInfo newInfo = new FileInfo();
try {
newInfo.setName(in.readUTF());
boolean symlink = in.readBoolean();
newInfo.setAttribute(EFS.ATTRIBUTE_SYMLINK, symlink);
if (symlink) {
newInfo.setStringAttribute(EFS.ATTRIBUTE_LINK_TARGET, in.readUTF());
}
newInfo.setExists(in.readBoolean());
newInfo.setLastModified(in.readLong());
newInfo.setLength(in.readLong());
newInfo.setDirectory(in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_GROUP_READ, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_GROUP_WRITE, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_GROUP_EXECUTE, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_OTHER_READ, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_OTHER_WRITE, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_OTHER_EXECUTE, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_OWNER_READ, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_OWNER_WRITE, in.readBoolean());
newInfo.setAttribute(EFS.ATTRIBUTE_OWNER_EXECUTE, in.readBoolean());
} catch (IOException e) {
newInfo.setError(IFileInfo.IO_ERROR);
}
setIFileInfo(newInfo);
}
}

View file

@ -0,0 +1,365 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*
*******************************************************************************/
package org.eclipse.remote.proxy.protocol.core;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class StreamChannel {
public static final int CAPACITY = 8192;
private class ChannelInputStream extends InputStream {
private final Lock lock = new ReentrantLock();
private final Condition cond = lock.newCondition();
private final StreamChannel channel;
private int currentPos;
private int currentSize;
private boolean connected = true;
private int inputRequestCount;
private byte[] buffer = new byte[CAPACITY];
public ChannelInputStream(StreamChannel channel) {
this.channel = channel;
}
@Override
public synchronized int read() throws IOException {
byte[] b = new byte[1];
if (read(b, 0, 1) != 1) {
return -1;
}
return b[0] & 0xff;
}
@Override
public int available() throws IOException {
lock.lock();
try {
return currentSize - currentPos;
} finally {
lock.unlock();
}
}
public synchronized int read(byte b[], int off, int len) throws IOException {
if (len <= 0) {
return 0;
}
int moreSpace;
lock.lock();
try {
if (currentPos >= currentSize) {
currentPos = currentSize = 0;
} else if (currentPos >= CAPACITY/2) {
System.arraycopy(buffer, currentPos, buffer, 0, currentSize - currentPos);
currentSize -= currentPos;
currentPos = 0;
}
int freeSpace = CAPACITY - currentSize;
moreSpace = Math.max(freeSpace - inputRequestCount, 0);
} finally {
lock.unlock();
}
if (moreSpace > 0) {
mux.sendRequestCmd(StreamChannel.this, moreSpace);
}
lock.lock();
try {
inputRequestCount += moreSpace;
while (currentPos >= currentSize && connected) {
try {
cond.await();
} catch (InterruptedException e) {
}
}
if (!connected && currentPos >= currentSize) {
return -1;
}
int available = currentSize - currentPos;
if (len < available) {
System.arraycopy(buffer, currentPos, b, off, len);
currentPos += len;
return len;
} else {
System.arraycopy(buffer, currentPos, b, off, available);
currentPos = currentSize = 0;
return available;
}
} finally {
lock.unlock();
}
}
@Override
public void close() throws IOException {
channel.closeOutput();
disconnect();
}
void receive(byte[] buf, int len) throws IOException {
lock.lock();
try {
if (currentPos > 0 && (CAPACITY - currentSize) < len) {
System.arraycopy(buffer, currentPos, buffer, 0, currentSize - currentPos);
currentSize -= currentPos;
currentPos = 0;
}
if (CAPACITY - currentSize < len) {
throw new IOException("Receive buffer overflow");
}
System.arraycopy(buf, 0, buffer, currentSize, len);
currentSize += len;
inputRequestCount -= len;
cond.signalAll();
} finally {
lock.unlock();
}
}
void disconnect() {
lock.lock();
try {
connected = false;
cond.signalAll();
} finally {
lock.unlock();
}
}
boolean isConnected() {
lock.lock();
try {
return connected;
} finally {
lock.unlock();
}
}
}
private class ChannelOutputStream extends OutputStream {
private final Lock lock = new ReentrantLock();
private final Condition cond = lock.newCondition();
private final StreamChannel channel;
private int currentPos;
private byte[] buffer = new byte[CAPACITY];
private boolean connected = true;
private int outputRequestCount;
public ChannelOutputStream(StreamChannel channel) {
this.channel = channel;
}
@Override
public synchronized void write(int b) throws IOException {
while (currentPos >= CAPACITY) {
send();
}
buffer[currentPos++] = (byte)b;
}
@Override
public synchronized void flush() throws IOException {
while (currentPos > 0) {
send();
}
}
@Override
public synchronized void write(byte[] b, int off, int len) throws IOException {
if (len <= 0) {
return;
}
if (len <= CAPACITY - currentPos) {
System.arraycopy(b, off, buffer, currentPos, len);
currentPos += len;
return;
}
flush();
int canSend;
while (true) {
lock.lock();
try {
while ((canSend = outputRequestCount) == 0 && connected) {
try {
cond.await();
} catch (InterruptedException e) {
}
}
if (!connected) {
throw new IOException("channel closed");
}
} finally {
lock.unlock();
}
if (canSend < len) {
mux.sendTransmitCmd(StreamChannel.this, b, off, canSend);
off += canSend;
len -= canSend;
lock.lock();
outputRequestCount -= canSend;
lock.unlock();
} else {
mux.sendTransmitCmd(StreamChannel.this, b, off, len);
lock.lock();
outputRequestCount -= len;
lock.unlock();
break;
}
}
}
void send() throws IOException {
int canSend;
lock.lock();
try {
while ((canSend = outputRequestCount) == 0 && connected) {
try {
cond.await();
} catch (InterruptedException e) {
}
}
if (!connected) {
throw new IOException("channel closed");
}
} finally {
lock.unlock();
}
if (canSend < currentPos) {
mux.sendTransmitCmd(StreamChannel.this, buffer, 0, canSend);
currentPos -= canSend;
System.arraycopy(buffer, canSend, buffer, 0, currentPos);
lock.lock();
outputRequestCount -= canSend;
lock.unlock();
} else {
mux.sendTransmitCmd(StreamChannel.this, buffer, 0, currentPos);
lock.lock();
outputRequestCount -= currentPos;
lock.unlock();
currentPos = 0;
}
}
@Override
public void close() throws IOException {
flush();
channel.closeInput();
disconnect();
}
void request(int len) {
lock.lock();
outputRequestCount += len;
cond.signalAll();
lock.unlock();
}
void disconnect() {
lock.lock();
try {
connected = false;
cond.signalAll();
} finally {
lock.unlock();
}
}
boolean isConnected() {
lock.lock();
try {
return connected;
} finally {
lock.unlock();
}
}
}
private final StreamChannelManager mux;
private final int channelId;
private final ChannelInputStream min = new ChannelInputStream(this);
private final ChannelOutputStream mout = new ChannelOutputStream(this);
private boolean open;
public StreamChannel(StreamChannelManager mux, int id) {
this.mux = mux;
channelId = id;
open = true;
}
public int getId() {
return channelId;
}
public InputStream getInputStream() {
return min;
}
public OutputStream getOutputStream() {
return mout;
}
public boolean isOpen() {
return open;
}
public void close() throws IOException {
mux.sendCloseCmd(this);
}
void receive(byte[] buf, int len) throws IOException {
min.receive(buf, len);
}
void request(int len) {
mout.request(len);
}
void disconnect() {
min.disconnect();
mout.disconnect();
}
void setClosed() {
open = false;
}
void disconnectInput() {
min.disconnect();
}
void disconnectOutput() {
mout.disconnect();
}
void closeInput() throws IOException {
mux.sendCloseInputCmd(this);
}
void closeOutput() throws IOException {
mux.sendCloseOutputCmd(this);
}
boolean isInputConnected() {
return min.isConnected();
}
boolean isOutputConnected() {
return mout.isConnected();
}
}

View file

@ -0,0 +1,562 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*
*******************************************************************************/
package org.eclipse.remote.proxy.protocol.core;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class StreamChannelManager implements Runnable {
public interface IChannelListener {
public void newChannel(StreamChannel chan);
public void closeChannel(StreamChannel chan);
}
private class Sender implements Runnable {
private OutputStream out;
private BlockingQueue<ByteArrayOutputStream> queue = new LinkedBlockingQueue<ByteArrayOutputStream>();
private boolean running = true;
public Sender(OutputStream out) {
this.out = out;
}
public void sendOpenCmd(int id) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
data.writeByte(CMD_OPEN);
data.writeByte(id);
try {
queue.put(bytes);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendTransmitCmd(int id, byte buf[], int off, int len) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
data.writeByte(CMD_TRANSMIT);
data.writeByte(id);
data.writeInt(len);
data.write(buf, off, len);
try {
queue.put(bytes);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendCloseCmd(int id) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
data.writeByte(CMD_CLOSE);
data.writeByte(id);
try {
queue.put(bytes);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendCloseAckCmd(int id) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
data.writeByte(CMD_CLOSEACK);
data.writeByte(id);
try {
queue.put(bytes);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendRequestCmd(int id, int len) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
data.writeByte(CMD_REQUEST);
data.writeByte(id);
data.writeInt(len);
try {
queue.put(bytes);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendCloseInputCmd(int id) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
data.writeByte(CMD_CLOSE_INPUT);
data.writeByte(id);
try {
queue.put(bytes);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void sendCloseOutputCmd(int id) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
data.writeByte(CMD_CLOSE_OUTPUT);
data.writeByte(id);
try {
queue.put(bytes);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void shutdown() {
running = false;
try {
queue.put(new ByteArrayOutputStream());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
try {
while (running) {
ByteArrayOutputStream bytes = queue.take();
if (bytes != null) {
bytes.writeTo(out);
out.flush();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private boolean isMyChannel(int id) {
return !(isServer ^ ((id & SERVER_ID_MASK) == SERVER_ID_MASK));
}
private class Receiver implements Runnable {
private DataInputStream dataIn;
public Receiver(InputStream in) {
this.dataIn = new DataInputStream(in);
}
@Override
public void run() {
StreamChannel chan;
running = true;
try {
while (true) {
debugPrint("start read");
int cmd = dataIn.readByte() & 0xff;
int id = dataIn.readByte() & 0xff;
switch (cmd) {
case CMD_OPEN:
debugPrint("received cmd=OPEN id="+id);
chan = channels.get(id);
if (chan != null) {
throw new IOException("Channel already exists");
}
if (!isServer && (id & SERVER_ID_MASK) != SERVER_ID_MASK) {
throw new IOException("Client received invalid server channel id: " + id);
}
if (isServer && (id & SERVER_ID_MASK) == SERVER_ID_MASK) {
throw new IOException("Server received invalid client channel id: " + id);
}
chan = new StreamChannel(StreamChannelManager.this, id);
channels.put(id, chan);
newChannelCallback(chan);
break;
case CMD_CLOSE:
/*
* Received a command to close the channel.
* Clean up channel and free channel ID if we allocated it.
*/
debugPrint("received cmd=CLOSE id="+id);
chan = channels.get(id);
if (chan == null) {
throw new IOException("CLOSE: Invalid channel id: " + id);
}
chan.disconnect();
if (chan.isOpen()) {
sendCloseAckCmd(chan);
}
closeChannelCallback(chan);
channels.remove(id);
if (isMyChannel(id)) {
freeId(id);
}
break;
case CMD_CLOSEACK:
/*
* Received acknowledgement for our close command.
* Clean up channel and free channel ID if we allocated it.
*/
debugPrint("received cmd=CLOSEACK id="+id);
chan = channels.get(id);
if (chan == null) {
throw new IOException("CLOSEACK: Invalid channel id");
}
if (chan.isOpen()) {
throw new IOException("Channel is still open");
}
chan.disconnect();
channels.remove(id);
if (isMyChannel(id)) {
freeId(id);
}
break;
case CMD_TRANSMIT:
debugPrint("received cmd=TRANSMIT id="+id);
chan = channels.get(id);
if (chan == null) {
throw new IOException("TRANSMIT: Invalid channel id: " + id);
}
int len = dataIn.readInt();
byte[] buf = new byte[len];
dataIn.readFully(buf, 0, len);
chan.receive(buf, len);
break;
case CMD_REQUEST:
chan = channels.get(id);
if (chan == null) {
throw new IOException("REQUEST: Invalid channel id: " + id);
}
int req = dataIn.readInt();
debugPrint("received cmd=REQUEST id="+id+ " len="+req);
chan.request(req);
break;
case CMD_CLOSE_INPUT:
/*
* Received a command to close the input side of the channel.
*/
debugPrint("received cmd=CLOSE_INPUT id="+id);
chan = channels.get(id);
if (chan == null) {
throw new IOException("CLOSE: Invalid channel id: " + id);
}
chan.disconnectInput();
break;
case CMD_CLOSE_OUTPUT:
/*
* Received a command to close the output side of the channel.
*/
debugPrint("received cmd=CLOSE_OUTPUT id="+id);
chan = channels.get(id);
if (chan == null) {
throw new IOException("CLOSE: Invalid channel id: " + id);
}
chan.disconnectOutput();
break;
default:
synchronized (System.err) {
System.err.print("invalid command: "+ dump_byte((byte)cmd) + dump_byte((byte)id));
}
try {
while (true) {
byte b = dataIn.readByte();
System.err.print(dump_byte(b));
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
throw new IOException("Invalid command: " + cmd);
}
}
} catch (EOFException e) {
// Finish
} catch (Exception e) {
e.printStackTrace();
debugPrint("run got exception:" + e.getMessage());
} finally {
debugPrint("shutting down manager");
StreamChannelManager.this.shutdown();
}
}
public void shutdown() {
try {
dataIn.close();
} catch (IOException e) {
// Ignore
}
}
}
private final static int CMD_OPEN = 0xA1; // Open a new channel
private final static int CMD_CLOSE = 0xA2; // Close a channel; acknowledgement required
private final static int CMD_CLOSEACK = 0xA3; // Channel close acknowledgement
private final static int CMD_REQUEST = 0xA4; // Request buffer space
private final static int CMD_TRANSMIT = 0xA5; // Transmit a buffer
private final static int CMD_CLOSE_INPUT = 0xA6; // Close input side of the channel; no acknowledgement required
private final static int CMD_CLOSE_OUTPUT = 0xA7; // Close output side of the channel; no acknowledgement required
private final static int SERVER_ID_MASK = 1 << 15;
private final static int MAX_CHANNELS = SERVER_ID_MASK >> 1;
private final Map<Integer, StreamChannel> channels = (Map<Integer, StreamChannel>) Collections.synchronizedMap(new HashMap<Integer,StreamChannel>());
private final List<IChannelListener> listeners = (List<IChannelListener>)Collections.synchronizedList(new ArrayList<IChannelListener>());
private Set<Short> usedIds = new HashSet<>();
private int nextUnusedChannelId;
private boolean isServer;
private volatile boolean running = true;
private Sender sender;
private Receiver receiver;
private boolean debug = false;
public StreamChannelManager(InputStream in, OutputStream out) {
sender = new Sender(new BufferedOutputStream(out));
receiver = new Receiver(new BufferedInputStream(in));
}
/**
* Clients allocate IDs with leading bit 0
* Servers allocate IDs with leading bit 1
*
* Reuse an ID if it is not longer being used.
*
* @return new ID
*/
synchronized int newId() throws IOException {
if (!usedIds.isEmpty()) {
Short id = usedIds.iterator().next();
usedIds.remove(id);
debugPrint("recover id="+id);
return id;
}
int nextId = nextUnusedChannelId;
if (nextUnusedChannelId++ > (MAX_CHANNELS - 1)) {
throw new IOException("Maximum number of channels exceeded");
}
return nextId | (isServer ? SERVER_ID_MASK : 0);
}
synchronized void freeId(int id) {
debugPrint("free id="+id);
usedIds.add((short)id);
}
void dump_buf(String pref, byte[] b, int off, int len) {
System.err.print(pref + ": ");
for (int i = off; i < len+off; i++) {
if (b[i] <= 32 || b[i] > 126) {
System.err.print(String.format(" 0x%02x ", b[i]));
} else {
System.err.print((char)b[i]);
}
}
System.err.println();
}
public boolean isServer() {
return isServer;
}
public void setServer(boolean server) {
isServer = server;
}
public void addListener(IChannelListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
public void removeListener(IChannelListener listener) {
if (listeners.contains(listener)) {
listeners.remove(listener);
}
}
protected void newChannelCallback(StreamChannel chan) {
for (IChannelListener listener : listeners.toArray(new IChannelListener[listeners.size()])) {
listener.newChannel(chan);
}
}
protected void closeChannelCallback(StreamChannel chan) {
for (IChannelListener listener : listeners.toArray(new IChannelListener[listeners.size()])) {
listener.closeChannel(chan);
}
}
public String dump_byte(byte b) {
if (b <= 32 || b > 126) {
return String.format(" 0x%02x ", b);
}
return String.valueOf((char)b);
}
public StreamChannel openChannel() throws IOException {
if (!running) {
throw new IOException("Multiplexer is not running");
}
StreamChannel chan = new StreamChannel(this, newId());
channels.put(chan.getId(), chan);
debugPrint("send cmd=OPEN id="+chan.getId());
sender.sendOpenCmd(chan.getId());
return chan;
}
synchronized void sendTransmitCmd(StreamChannel chan, byte buf[], int off, int len) throws IOException {
if (running && chan.isOpen()) {
debugPrint("send cmd=TRANSMIT id="+chan.getId()+" len="+len + " off=" + off + " buflen="+buf.length);
sender.sendTransmitCmd(chan.getId(), buf, off, len);
}
}
synchronized void sendCloseCmd(StreamChannel chan) throws IOException {
if (running && chan.isOpen()) {
debugPrint("send cmd=CLOSE id="+chan.getId());
chan.disconnect();
sender.sendCloseCmd(chan.getId());
chan.setClosed();
}
}
synchronized void sendCloseAckCmd(StreamChannel chan) throws IOException {
if (running && chan.isOpen()) {
debugPrint("send cmd=CLOSEACK id="+chan.getId());
sender.sendCloseAckCmd(chan.getId());
chan.setClosed();
}
}
synchronized void sendRequestCmd(StreamChannel chan, int len) throws IOException {
if (running && chan.isOpen()) {
debugPrint("send cmd=REQUEST id="+chan.getId()+" len="+len);
sender.sendRequestCmd(chan.getId(), len);
}
}
synchronized void sendCloseInputCmd(StreamChannel chan) throws IOException {
if (running && chan.isOpen()) {
if (!chan.isOutputConnected()) {
sendCloseCmd(chan);
} else {
debugPrint("send cmd=CLOSE_INPUT id="+chan.getId());
sender.sendCloseInputCmd(chan.getId());
}
}
}
synchronized void sendCloseOutputCmd(StreamChannel chan) throws IOException {
if (running && chan.isOpen()) {
if (!chan.isInputConnected()) {
sendCloseCmd(chan);
} else {
debugPrint("send cmd=CLOSE_OUTPUT id="+chan.getId());
sender.sendCloseOutputCmd(chan.getId());
}
}
}
public void debugPrint(String x) {
if (debug) {
synchronized (System.err) {
System.err.println(x);
}
}
}
public void shutdown() {
if (!running) {
return;
}
running = false;
synchronized (channels) {
for (StreamChannel c : channels.values()) {
c.disconnect();
}
}
channels.clear();
sender.shutdown();
receiver.shutdown();
debugPrint("chan mpx stopped");
// Should in and out be closed also?
}
private String asString(int v) {
switch (v) {
case CMD_OPEN:
return "OPEN";
case CMD_CLOSE:
return "CLOSE";
case CMD_CLOSEACK:
return "CLOSEACK";
case CMD_TRANSMIT:
return "TRANSMIT";
case CMD_REQUEST:
return "REQUEST";
}
return "<UNKNOWN>";
}
@Override
public void run() {
debugPrint("mux starting");
new Thread(sender, "mux sender").start();
receiver.run();
}
}

View file

@ -0,0 +1,17 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.proxy.protocol.core.exceptions;
public class ProxyException extends Exception {
private static final long serialVersionUID = 1L;
public ProxyException(String message) {
super(message);
}
}

View file

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

View file

@ -0,0 +1 @@
/bin/

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.remote.proxy.server.core</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,12 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,59 @@
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
sp_cleanup.add_missing_annotations=true
sp_cleanup.add_missing_deprecated_annotations=true
sp_cleanup.add_missing_methods=false
sp_cleanup.add_missing_nls_tags=false
sp_cleanup.add_missing_override_annotations=true
sp_cleanup.add_missing_override_annotations_interface_methods=true
sp_cleanup.add_serial_version_id=false
sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=false
sp_cleanup.format_source_code_changes_only=false
sp_cleanup.insert_inferred_type_arguments=false
sp_cleanup.make_local_variable_final=true
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
sp_cleanup.make_type_abstract_if_missing_method=false
sp_cleanup.make_variable_declarations_final=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
sp_cleanup.on_save_use_additional_actions=false
sp_cleanup.organize_imports=true
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_redundant_type_arguments=false
sp_cleanup.remove_trailing_whitespaces=false
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=true
sp_cleanup.remove_unnecessary_nls_tags=false
sp_cleanup.remove_unused_imports=false
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
sp_cleanup.use_lambda=true
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true

View file

@ -0,0 +1,4 @@
eclipse.preferences.version=1
pluginProject.equinox=false
pluginProject.extensions=true
resolve.requirebundle=false

View file

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.remote.proxy.server.core;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.eclipse.core.filesystem,
org.eclipse.core.runtime,
org.eclipse.core.runtime.adaptor,
org.eclipse.equinox.app,
org.eclipse.remote.core,
org.eclipse.remote.proxy.protocol.core,
org.eclipse.remote.proxy.protocol.core.exceptions,
org.osgi.framework,
org.osgi.framework.launch
Bundle-Vendor: %pluginProvider
Bundle-Localization: plugin
Require-Bundle: org.eclipse.cdt.core.native

View file

@ -0,0 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<title>About</title>
<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
</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">http://www.eclipse.org.</p>
</body>
</html>

View file

@ -0,0 +1,7 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.xml,\
plugin.properties,\
about.html

View file

@ -0,0 +1,11 @@
###############################################################################
# Copyright (c) 2016 Oak Ridge National Laboratory 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
#
###############################################################################
pluginName=Remote Proxy Server Support
pluginProvider=Eclipse PTP

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
id="application"
point="org.eclipse.core.runtime.applications">
<application
cardinality="singleton-global"
thread="main"
visible="true">
<run
class="org.eclipse.remote.internal.proxy.server.core.Application">
</run>
</application>
</extension>
</plugin>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.remote</groupId>
<artifactId>remote-parent</artifactId>
<version>3.0.0-SNAPSHOT</version>
<relativePath>../../releng/org.eclipse.remote.build/pom.xml</relativePath>
</parent>
<artifactId>org.eclipse.remote.proxy.server.core</artifactId>
<packaging>eclipse-plugin</packaging>
<version>1.0.0-SNAPSHOT</version>
</project>

View file

@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core;
import java.nio.ByteBuffer;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.remote.proxy.protocol.core.Protocol;
/**
* This class controls all aspects of the application's execution
*/
public class Application implements IApplication {
private Server server = new Server();
/* (non-Javadoc)
* @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
*/
public Object start(IApplicationContext context) throws Exception {
String[] args = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
for (String arg : args) {
if (arg.equals("-magic")) { //$NON-NLS-1$
ByteBuffer b = ByteBuffer.allocate(4);
b.putInt(Protocol.MAGIC);
System.out.write(b.array());
};
}
server.start();
server.waitFor();
return IApplication.EXIT_OK;
}
/* (non-Javadoc)
* @see org.eclipse.equinox.app.IApplication#stop()
*/
public void stop() {
// Nothing
}
}

View file

@ -0,0 +1,291 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.remote.internal.proxy.server.core.commands.AbstractServerCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerChildInfosCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerDeleteCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerExecCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerFetchInfoCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetCwdCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetEnvCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetInputStreamCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetOutputStreamCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetPropertiesCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerMkdirCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerPutInfoCommand;
import org.eclipse.remote.internal.proxy.server.core.commands.ServerShellCommand;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class CommandServer implements Runnable {
private Server server;
private DataInputStream cmdIn;
private DataOutputStream cmdOut;
private boolean running = true;
private StreamChannel chan;
public CommandServer(StreamChannel chan, Server server) {
this.chan = chan;
this.server = server;
this.cmdIn = new DataInputStream(chan.getInputStream());
this.cmdOut = new DataOutputStream(chan.getOutputStream());
}
public void run() {
new Thread("cmd reader") { //$NON-NLS-1$
@Override
public void run() {
try {
while (running) {
byte proto = cmdIn.readByte();
switch (proto) {
case Protocol.PROTO_COMMAND:
try {
dispatchCommand(cmdIn);
sendOKResult();
} catch (ProxyException e) {
sendErrorResult(e.getMessage());
}
break;
case Protocol.PROTO_SHUTDOWN:
running = false;
break;
default:
System.err.println("Invalid protocol ID: " + proto);
break;
}
}
} catch (EOFException e) {
// Exit server
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
running = false;
}
}
}.start();
}
private void sendOKResult() throws IOException {
cmdOut.writeByte(Protocol.PROTO_OK);
cmdOut.flush();
}
private void sendErrorResult(String error) throws IOException {
cmdOut.writeByte(Protocol.PROTO_ERROR);
cmdOut.writeUTF(error);
cmdOut.flush();
}
/**
* TODO replace with dynamic dispatcher
*/
private void dispatchCommand(DataInputStream in) throws ProxyException, IOException {
AbstractServerCommand serverCmd;
short cmd = in.readShort();
switch (cmd) {
case Protocol.CMD_CHILDINFOS:
serverCmd = cmdChildInfos(in);
break;
case Protocol.CMD_DELETE:
serverCmd = cmdDelete(in);
break;
case Protocol.CMD_EXEC:
serverCmd = cmdExec(in);
break;
case Protocol.CMD_SHELL:
serverCmd = cmdShell(in);
break;
case Protocol.CMD_FETCHINFO:
serverCmd = cmdFetchInfo(in);
break;
case Protocol.CMD_GETCWD:
serverCmd = cmdGetCwd(in);
break;
case Protocol.CMD_GETENV:
serverCmd = cmdGetEnv(in);
break;
case Protocol.CMD_GETINPUTSTREAM:
serverCmd = cmdGetInputStream(in);
break;
case Protocol.CMD_GETOUTPUTSTREAM:
serverCmd = cmdGetOutputStream(in);
break;
case Protocol.CMD_GETPROPERTIES:
serverCmd = cmdGetProperties(in);
break;
case Protocol.CMD_MKDIR:
serverCmd = cmdMkdir(in);
break;
case Protocol.CMD_PUTINFO:
serverCmd = cmdPutInfo(in);
break;
default:
System.err.println("Invalid command ID: " + cmd);
throw new ProxyException("Invalid command ID: " + cmd); //$NON-NLS-1$
}
serverCmd.exec();
}
private AbstractServerCommand cmdExec(DataInputStream in) throws ProxyException, IOException {
int cmdChanId = in.readByte();
int ioChanId = in.readByte();
int errChanId = in.readByte();
int length = in.readInt();
List<String> command = new ArrayList<String>(length);
for (int i = 0; i < length; i++) {
command.add(in.readUTF());
}
length = in.readInt();
Map<String, String> env = new HashMap<String, String>(length);
for (int i = 0; i < length; i++) {
String key = in.readUTF();
String val = in.readUTF();
env.put(key, val);
}
String dir = in.readUTF();
boolean redirect = in.readBoolean();
boolean appendEnv = in.readBoolean();
StreamChannel cmdChan = server.getChannel(cmdChanId);
StreamChannel ioChan = server.getChannel(ioChanId);
StreamChannel errChan= server.getChannel(errChanId);
if (cmdChan == null || ioChan == null || errChan == null) {
throw new ProxyException("Unable to locate channels for command"); //$NON-NLS-1$
}
return new ServerExecCommand(command, env, dir, redirect, appendEnv, cmdChan, ioChan, errChan);
}
private AbstractServerCommand cmdShell(DataInputStream in) throws ProxyException, IOException {
int cmdChanId = in.readByte();
int ioChanId = in.readByte();
StreamChannel cmdChan = server.getChannel(cmdChanId);
StreamChannel ioChan = server.getChannel(ioChanId);
if (cmdChan == null || ioChan == null) {
throw new ProxyException("Unable to locate channels for command"); //$NON-NLS-1$
}
return new ServerShellCommand(cmdChan, ioChan);
}
private AbstractServerCommand cmdGetCwd(DataInputStream in) throws ProxyException, IOException {
int chanId = in.readByte();
StreamChannel chan = server.getChannel(chanId);
if (chan == null) {
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
}
return new ServerGetCwdCommand(chan);
}
private AbstractServerCommand cmdGetEnv(DataInputStream in) throws ProxyException, IOException {
int chanId = in.readByte();
StreamChannel chan = server.getChannel(chanId);
if (chan == null) {
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
}
return new ServerGetEnvCommand(chan);
}
private AbstractServerCommand cmdGetProperties(DataInputStream in) throws ProxyException, IOException {
int chanId = in.readByte();
StreamChannel chan = server.getChannel(chanId);
if (chan == null) {
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
}
return new ServerGetPropertiesCommand(chan);
}
private AbstractServerCommand cmdChildInfos(DataInputStream in) throws ProxyException, IOException {
int chanId = in.readByte();
StreamChannel chan = server.getChannel(chanId);
if (chan == null) {
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
}
String path = in.readUTF();
return new ServerChildInfosCommand(chan, path);
}
private AbstractServerCommand cmdFetchInfo(DataInputStream in) throws ProxyException, IOException {
int chanId = in.readByte();
StreamChannel chan = server.getChannel(chanId);
if (chan == null) {
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
}
String path = in.readUTF();
return new ServerFetchInfoCommand(chan, path);
}
private AbstractServerCommand cmdGetInputStream(DataInputStream in) throws ProxyException, IOException {
int chanId = in.readByte();
StreamChannel chan = server.getChannel(chanId);
if (chan == null) {
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
}
int options = in.readInt();
String path = in.readUTF();
return new ServerGetInputStreamCommand(chan, options, path);
}
private AbstractServerCommand cmdGetOutputStream(DataInputStream in) throws ProxyException, IOException {
int chanId = in.readByte();
StreamChannel chan = server.getChannel(chanId);
if (chan == null) {
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
}
int options = in.readInt();
String path = in.readUTF();
return new ServerGetOutputStreamCommand(chan, options, path);
}
private AbstractServerCommand cmdDelete(DataInputStream in) throws ProxyException, IOException {
int options = in.readInt();
String path = in.readUTF();
return new ServerDeleteCommand(options, path);
}
private AbstractServerCommand cmdMkdir(DataInputStream in) throws ProxyException, IOException {
int options = in.readInt();
String path = in.readUTF();
return new ServerMkdirCommand(options, path);
}
private AbstractServerCommand cmdPutInfo(DataInputStream in) throws ProxyException, IOException {
int options = in.readInt();
String path = in.readUTF();
SerializableFileInfo info = new SerializableFileInfo();
info.readObject(in);
return new ServerPutInfoCommand(info.getIFileInfo(), options, path);
}
}

View file

@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.remote.proxy.protocol.core.StreamChannelManager;
import org.eclipse.remote.proxy.protocol.core.StreamChannelManager.IChannelListener;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
public class Server {
private volatile boolean running;
private Thread serverThread;
private StreamChannel cmdChannel;
private Map<Integer, StreamChannel> auxChannel = Collections.synchronizedMap(new HashMap<Integer, StreamChannel>());
public void start() {
final StreamChannelManager mux = new StreamChannelManager(System.in, System.out);
mux.setServer(true);
mux.addListener(new IChannelListener() {
@Override
public void newChannel(StreamChannel chan) {
Runnable runnable;
System.err.println("newChannel: " + chan.getId());
// First channel opened becomes command channel
if (cmdChannel == null) {
cmdChannel = chan;
runnable = new CommandServer(chan, Server.this);
new Thread(runnable).start();
} else {
auxChannel.put(chan.getId(), chan);
}
}
@Override
public void closeChannel(StreamChannel chan) {
System.err.println("closeChannel: " + chan.getId());
auxChannel.remove(chan.getId());
}
});
serverThread = new Thread(mux) {
@Override
public void run() {
running = true;
mux.run();
running = false;
}
};
serverThread.start();
}
public StreamChannel getChannel(int id) {
System.err.println("getChannel: "+id);
return auxChannel.get(id);
}
public void waitFor() {
if (running && serverThread != null) {
try {
serverThread.join();
} catch (InterruptedException e) {
// Ignore
}
}
}
}

View file

@ -0,0 +1,14 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public abstract class AbstractServerCommand {
public abstract void exec() throws ProxyException;
}

View file

@ -0,0 +1,232 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.remote.proxy.protocol.core.Protocol;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public abstract class AbstractServerExecCommand extends AbstractServerCommand {
private class CommandRunner implements Runnable {
@Override
public void run() {
try {
int exit = 0;
try {
proc = doRun();
Forwarder stdoutFwd = startForwarder("stdout", proc.getInputStream(), stdoutChan); //$NON-NLS-1$
Forwarder stderrFwd = null;
if (!redirect) {
stderrFwd = startForwarder("stderr", proc.getErrorStream(), stderrChan); //$NON-NLS-1$
}
startForwarder("stdin", stdinChan, proc.getOutputStream()); //$NON-NLS-1$
new Thread(new ProcMonitor(), "process monitor").start(); //$NON-NLS-1$
exit = proc.waitFor();
/*
* After the process has finished, wait for the stdout and stderr forwarders to finish to
* ensure that all output is flushed.
*/
stdoutFwd.waitFor();
if (stderrFwd != null) {
stderrFwd.waitFor();
}
} catch (IOException e) {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stderrChan));
try {
writer.write(e.getMessage());
writer.flush();
} catch (IOException e1) {
// Things look pretty hopeless
}
exit = -1;
}
try {
resultStream.writeInt(exit);
resultStream.flush();
} catch (IOException e) {
// We're finished anyway
}
} catch (InterruptedException e) {
// Ignore?
}
}
}
private class ProcMonitor implements Runnable {
@Override
public void run() {
try {
switch (cmdStream.readByte()) {
case Protocol.CONTROL_KILL:
doKill(proc);
break;
case Protocol.CONTROL_SETTERMINALSIZE:
int cols = cmdStream.readInt();
int rows = cmdStream.readInt();
cmdStream.readInt(); // pixel dimensions not supported
cmdStream.readInt(); // pixel dimensions not supported
doSetTerminalSize(proc, cols, rows);
break;
}
} catch (IOException e) {
// Finish
}
}
}
private class Forwarder implements Runnable {
private final InputStream in;
private final OutputStream out;
private final String name;
private boolean running = true;
private final Lock lock = new ReentrantLock();
private final Condition cond = lock.newCondition();
public Forwarder(String name, InputStream in, OutputStream out) {
this.name = name;
this.in = new BufferedInputStream(in);
this.out = new BufferedOutputStream(out);
}
@Override
public void run() {
byte[] buf = new byte[8192];
int n;
try {
while (running) {
n = in.read(buf);
if (n > 0) {
out.write(buf, 0, n);
out.flush();
}
if (n < 0) break;
}
} catch (IOException e) {
// Finish
}
lock.lock();
try {
running = false;
try {
out.close();
} catch (IOException e) {
// Best effort
}
cond.signalAll();
} finally {
lock.unlock();
}
}
public String getName() {
return name;
}
public synchronized void waitFor() {
lock.lock();
try {
while (running) {
try {
cond.await();
} catch (InterruptedException e) {
// Check terminated flag
}
}
} finally {
lock.unlock();
}
}
}
private final List<String> command;
private final Map<String, String> env;
private final boolean redirect;
private final boolean appendEnv;
private final String directory;
private final InputStream stdinChan;
private final OutputStream stdoutChan;
private final OutputStream stderrChan;
private final DataInputStream cmdStream;
private final DataOutputStream resultStream;
private Process proc;
public AbstractServerExecCommand(List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv, StreamChannel cmdChan, StreamChannel ioChan, StreamChannel errChan) {
this.command = command;
this.env = env;
this.directory = directory;
this.redirect = redirect;
this.appendEnv = appendEnv;
this.stdinChan = ioChan.getInputStream();
this.stdoutChan = ioChan.getOutputStream();
this.stderrChan = errChan != null ? errChan.getOutputStream() : this.stdoutChan;
this.resultStream = new DataOutputStream(cmdChan.getOutputStream());
this.cmdStream = new DataInputStream(cmdChan.getInputStream());
}
protected abstract Process doRun() throws IOException;
protected abstract void doKill(Process proc);
protected abstract void doSetTerminalSize(Process proc, int col, int rows);
protected List<String> getCommand() {
return command;
}
protected Map<String,String> getEnv() {
return env;
}
protected boolean isRedirect() {
return redirect;
}
protected boolean isAppendEnv() {
return appendEnv;
}
protected String getDirectory() {
return directory;
}
public void exec() throws ProxyException {
new Thread(new CommandRunner()).start();
}
private Forwarder startForwarder(String name, InputStream in, OutputStream out) {
Forwarder forwarder = new Forwarder(name, in, out);
Thread thread = new Thread(forwarder, forwarder.getName());
thread.start();
return forwarder;
}
}

View file

@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ServerChildInfosCommand extends AbstractServerCommand {
private IFileInfo[] infos;
private final URI uri;
private final OutputStream out;
private class CommandRunner implements Runnable {
@Override
public void run() {
try {
DataOutputStream result = new DataOutputStream(out);
result.writeInt(infos.length);
for (int i = 0; i < infos.length; i++) {
SerializableFileInfo sInfo = new SerializableFileInfo(infos[i]);
sInfo.writeObject(result);
}
result.flush();
} catch (IOException e) {
// Failed
e.printStackTrace();
}
}
}
public ServerChildInfosCommand(StreamChannel chan, String path) {
this.out = chan.getOutputStream();
this.uri = URI.create("file:" + path); //$NON-NLS-1$
}
public void exec() throws ProxyException {
try {
infos = EFS.getStore(uri).childInfos(EFS.NONE, null);
} catch (CoreException e) {
throw new ProxyException(e.getMessage());
}
new Thread(new CommandRunner()).start();
}
}

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ServerDeleteCommand extends AbstractServerCommand {
private final int options;
private final URI uri;
public ServerDeleteCommand(int options, String path) {
this.options = options;
this.uri = URI.create("file:" + path); //$NON-NLS-1$
}
public void exec() throws ProxyException {
try {
EFS.getStore(uri).delete(options, new NullProgressMonitor());
} catch (CoreException e) {
throw new ProxyException(e.getMessage());
}
}
}

View file

@ -0,0 +1,65 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
/**
* TODO: Fix hang if command fails...
*
*/
public class ServerExecCommand extends AbstractServerExecCommand {
public Process doRun() throws IOException {
System.err.print("exec: ");
for (String arg:getCommand()) {
System.err.print(arg + " ");
}
System.err.println();
ProcessBuilder builder = new ProcessBuilder(getCommand());
try {
if (!isAppendEnv()) {
builder.environment().clear();
builder.environment().putAll(getEnv());
} else {
for (Map.Entry<String, String> entry : getEnv().entrySet()) {
String val = builder.environment().get(entry.getKey());
if (val == null || !val.equals(entry.getValue())) {
builder.environment().put(entry.getKey(), entry.getValue());
}
}
}
} catch (UnsupportedOperationException | IllegalArgumentException e) {
// Leave environment untouched
}
File dir = new File(getDirectory());
if (dir.exists() && dir.isAbsolute()) {
builder.directory(dir);
}
builder.redirectErrorStream(isRedirect());
return builder.start();
}
protected void doKill(Process proc) {
if (proc.isAlive()) {
proc.destroyForcibly();
}
}
protected void doSetTerminalSize(Process proc, int cols, int rows) {
// Not supported
}
public ServerExecCommand(List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv, StreamChannel cmdChan, StreamChannel ioChan, StreamChannel errChan) {
super(command, env, directory, redirect, appendEnv, cmdChan, ioChan, errChan);
}
}

View file

@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ServerFetchInfoCommand extends AbstractServerCommand {
private IFileInfo info;
private final URI uri;
private final OutputStream out;
private class CommandRunner implements Runnable {
@Override
public void run() {
try {
DataOutputStream result = new DataOutputStream(out);
SerializableFileInfo sInfo = new SerializableFileInfo(info);
sInfo.writeObject(result);
result.flush();
} catch (IOException e) {
// Failed
e.printStackTrace();
}
}
}
public ServerFetchInfoCommand(StreamChannel chan, String path) {
this.out = chan.getOutputStream();
this.uri = URI.create("file:" + path); //$NON-NLS-1$
}
public void exec() throws ProxyException {
try {
info = EFS.getStore(uri).fetchInfo();
} catch (CoreException e) {
throw new ProxyException(e.getMessage());
}
new Thread(new CommandRunner()).start();
}
}

View file

@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.DataOutputStream;
import java.io.IOException;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ServerGetCwdCommand extends AbstractServerCommand {
private String cwd;
private final DataOutputStream result;
private class CommandRunner implements Runnable {
@Override
public void run() {
try {
result.writeUTF(cwd);
result.flush();
} catch (IOException e) {
// Failed
}
}
}
public ServerGetCwdCommand(StreamChannel chan) {
this.result = new DataOutputStream(chan.getOutputStream());
}
public void exec() throws ProxyException {
cwd = System.getProperty("user.dir"); //$NON-NLS-1$
new Thread(new CommandRunner()).start();
}
}

View file

@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Map;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ServerGetEnvCommand extends AbstractServerCommand {
private final DataOutputStream result;
private class CommandRunner implements Runnable {
@Override
public void run() {
try {
Map<String,String> env = System.getenv();
result.writeInt(env.size());
for (Map.Entry<String, String> entry : env.entrySet()) {
result.writeUTF(entry.getKey());
result.writeUTF(entry.getValue());
}
result.flush();
} catch (IOException e) {
// Failed
}
}
}
public ServerGetEnvCommand(StreamChannel chan) {
this.result = new DataOutputStream(chan.getOutputStream());
}
public void exec() throws ProxyException {
new Thread(new CommandRunner()).start();
}
}

View file

@ -0,0 +1,86 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
/**
* TODO: Fix hang if command fails...
*
*/
public class ServerGetInputStreamCommand extends AbstractServerCommand {
private final OutputStream out;
private final URI uri;
private final int options;
private class Forwarder implements Runnable {
private final InputStream in;
private final OutputStream out;
public Forwarder(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
byte[] buf = new byte[8192];
int n;
try {
while ((n = in.read(buf)) >= 0) {
if (n > 0) {
out.write(buf, 0, n); // should block if no-one is reading
out.flush();
}
}
} catch (IOException e) {
// Finish
}
try {
out.close();
} catch (IOException e) {
// Ignore
}
try {
in.close();
} catch (IOException e) {
// Ignore
}
}
}
public ServerGetInputStreamCommand(StreamChannel chan, int options, String path) {
this.out = chan.getOutputStream();
this.options = options;
this.uri = URI.create("file:" + path); //$NON-NLS-1$
}
public void exec() throws ProxyException {
try {
InputStream in = new BufferedInputStream(EFS.getStore(uri).openInputStream(options, new NullProgressMonitor()));
startForwarder(in, out);
} catch (Exception e) {
throw new ProxyException(e.getMessage());
}
}
private void startForwarder(InputStream in, OutputStream out) {
Forwarder forwarder = new Forwarder(in, out);
new Thread(forwarder).start();
}
}

View file

@ -0,0 +1,87 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
/**
* TODO: Fix hang if command fails...
*
*/
public class ServerGetOutputStreamCommand extends AbstractServerCommand {
private final InputStream in;
private final URI uri;
private final int options;
private class Forwarder implements Runnable {
private final InputStream in;
private final OutputStream out;
public Forwarder(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
byte[] buf = new byte[8192];
int n;
try {
while ((n = in.read(buf)) >= 0) {
if (n > 0) {
out.write(buf, 0, n); // should block if no-one is reading
}
}
out.flush();
} catch (IOException e) {
// Finish
}
try {
out.close();
} catch (IOException e) {
// Ignore
}
try {
in.close();
} catch (IOException e) {
// Ignore
}
}
}
public ServerGetOutputStreamCommand(StreamChannel chan, int options, String path) {
this.in = chan.getInputStream();
this.options = options;
this.uri = URI.create("file:" + path); //$NON-NLS-1$
}
public void exec() throws ProxyException {
try {
OutputStream out = new BufferedOutputStream(EFS.getStore(uri).openOutputStream(options, new NullProgressMonitor()));
startForwarder(in, out);
} catch (CoreException e) {
throw new ProxyException(e.getMessage());
}
}
private void startForwarder(InputStream in, OutputStream out) {
Forwarder forwarder = new Forwarder(in, out);
new Thread(forwarder).start();
}
}

View file

@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ServerGetPropertiesCommand extends AbstractServerCommand {
private final DataOutputStream result;
private class CommandRunner implements Runnable {
@Override
public void run() {
try {
Map<String,String> props = new HashMap<String, String>();
props.put(IRemoteConnection.FILE_SEPARATOR_PROPERTY, System.getProperty(IRemoteConnection.FILE_SEPARATOR_PROPERTY));
props.put(IRemoteConnection.PATH_SEPARATOR_PROPERTY, System.getProperty(IRemoteConnection.PATH_SEPARATOR_PROPERTY));
props.put(IRemoteConnection.LINE_SEPARATOR_PROPERTY, System.getProperty(IRemoteConnection.LINE_SEPARATOR_PROPERTY));
props.put(IRemoteConnection.USER_HOME_PROPERTY, System.getProperty(IRemoteConnection.USER_HOME_PROPERTY));
props.put(IRemoteConnection.OS_NAME_PROPERTY, System.getProperty(IRemoteConnection.OS_NAME_PROPERTY));
props.put(IRemoteConnection.OS_VERSION_PROPERTY, System.getProperty(IRemoteConnection.OS_VERSION_PROPERTY));
props.put(IRemoteConnection.OS_ARCH_PROPERTY, System.getProperty(IRemoteConnection.OS_ARCH_PROPERTY));
props.put(IRemoteConnection.LOCALE_CHARMAP_PROPERTY, System.getProperty("file.encoding")); //$NON-NLS-1$
result.writeInt(props.size());
for (Map.Entry<String, String> entry : props.entrySet()) {
result.writeUTF(entry.getKey());
result.writeUTF(entry.getValue());
}
result.flush();
} catch (IOException e) {
// Failed
}
}
}
public ServerGetPropertiesCommand(StreamChannel chan) {
this.result = new DataOutputStream(chan.getOutputStream());
}
public void exec() throws ProxyException {
new Thread(new CommandRunner()).start();
}
}

View file

@ -0,0 +1,33 @@
/*******************************************************************************
* Copyright (c) 2016 Oak Ridge National Laboratory 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
*******************************************************************************/
package org.eclipse.remote.internal.proxy.server.core.commands;
import java.net.URI;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
public class ServerMkdirCommand extends AbstractServerCommand {
private final int options;
private final URI uri;
public ServerMkdirCommand(int options, String path) {
this.options = options;
this.uri = URI.create("file:" + path); //$NON-NLS-1$
}
public void exec() throws ProxyException {
try {
EFS.getStore(uri).mkdir(options, new NullProgressMonitor());
} catch (CoreException e) {
throw new ProxyException(e.getMessage());
}
}
}

Some files were not shown because too many files have changed in this diff Show more