mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-22 00:15:25 +02:00
Bug 530750 - Enable launch support using proxy. Also adds support for
command shell and fixes a number of bugs. Change-Id: I6b9a0bf40647d6f5682c425c754371f8af6cb918 Signed-off-by: Greg Watson <g.watson@computer.org>
This commit is contained in:
parent
a0fe3f1cf2
commit
ea50b5d22c
45 changed files with 703 additions and 344 deletions
|
@ -40,7 +40,7 @@
|
||||||
</connectionService>
|
</connectionService>
|
||||||
<connectionService
|
<connectionService
|
||||||
connectionTypeId="org.eclipse.remote.Proxy"
|
connectionTypeId="org.eclipse.remote.Proxy"
|
||||||
factory="org.eclipse.remote.internal.proxy.core.ProxyCommandShellService$Factory"
|
factory="org.eclipse.remote.internal.proxy.core.ProxyConnection$Factory"
|
||||||
service="org.eclipse.remote.core.IRemoteCommandShellService">
|
service="org.eclipse.remote.core.IRemoteCommandShellService">
|
||||||
</connectionService>
|
</connectionService>
|
||||||
<processService
|
<processService
|
||||||
|
@ -58,6 +58,11 @@
|
||||||
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
|
factory="org.eclipse.remote.internal.proxy.core.ProxyProcess$Factory"
|
||||||
service="org.eclipse.remote.core.IRemoteProcessTerminalService">
|
service="org.eclipse.remote.core.IRemoteProcessTerminalService">
|
||||||
</processService>
|
</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>
|
||||||
<extension
|
<extension
|
||||||
id="org.eclipse.remote.proxy.filesystem"
|
id="org.eclipse.remote.proxy.filesystem"
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
/*******************************************************************************
|
|
||||||
* Copyright (c) 2015 QNX Software Systems and others.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*
|
|
||||||
* Contributors:
|
|
||||||
* QNX Software Systems - Initial API and implementation
|
|
||||||
*******************************************************************************/
|
|
||||||
package org.eclipse.remote.internal.proxy.core;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.eclipse.remote.core.IRemoteCommandShellService;
|
|
||||||
import org.eclipse.remote.core.IRemoteConnection;
|
|
||||||
import org.eclipse.remote.core.IRemoteProcess;
|
|
||||||
|
|
||||||
public class ProxyCommandShellService implements IRemoteCommandShellService {
|
|
||||||
private IRemoteConnection fRemoteConnection;
|
|
||||||
|
|
||||||
public ProxyCommandShellService(IRemoteConnection remoteConnection) {
|
|
||||||
fRemoteConnection = remoteConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IRemoteConnection getRemoteConnection() {
|
|
||||||
return fRemoteConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IRemoteProcess getCommandShell(int flags) throws IOException {
|
|
||||||
return null;
|
|
||||||
// return new JSchProcessBuilder(getRemoteConnection()).start(flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
if (IRemoteCommandShellService.class.equals(service)) {
|
|
||||||
return (T) new ProxyCommandShellService(connection);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -37,8 +37,8 @@ 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.GetEnvCommand;
|
||||||
import org.eclipse.remote.internal.proxy.core.commands.GetPropertiesCommand;
|
import org.eclipse.remote.internal.proxy.core.commands.GetPropertiesCommand;
|
||||||
import org.eclipse.remote.internal.proxy.core.messages.Messages;
|
import org.eclipse.remote.internal.proxy.core.messages.Messages;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannelManager;
|
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
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 org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
||||||
import com.jcraft.jsch.ChannelShell;
|
import com.jcraft.jsch.ChannelShell;
|
||||||
|
@ -48,7 +48,8 @@ import com.jcraft.jsch.ChannelShell;
|
||||||
*/
|
*/
|
||||||
public class ProxyConnection implements IRemoteConnectionControlService,
|
public class ProxyConnection implements IRemoteConnectionControlService,
|
||||||
IRemoteConnectionChangeListener, IRemoteProcessService,
|
IRemoteConnectionChangeListener, IRemoteProcessService,
|
||||||
IRemoteCommandShellService, IRemoteConnectionHostService {
|
IRemoteCommandShellService, IRemoteConnectionHostService,
|
||||||
|
IRemoteConnectionPropertyService {
|
||||||
// Connection Type ID
|
// Connection Type ID
|
||||||
public static final String JSCH_ID = "org.eclipse.remote.Proxy"; //$NON-NLS-1$
|
public static final String JSCH_ID = "org.eclipse.remote.Proxy"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
@ -72,7 +73,6 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
||||||
private StreamChannelManager channelMux;
|
private StreamChannelManager channelMux;
|
||||||
private StreamChannel commandChannel;
|
private StreamChannel commandChannel;
|
||||||
private boolean isOpen;
|
private boolean isOpen;
|
||||||
private boolean proxyRunning;
|
|
||||||
|
|
||||||
private final IRemoteConnection fRemoteConnection;
|
private final IRemoteConnection fRemoteConnection;
|
||||||
|
|
||||||
|
@ -133,7 +133,8 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
||||||
|| IRemoteConnectionPropertyService.class.equals(service)
|
|| IRemoteConnectionPropertyService.class.equals(service)
|
||||||
|| IRemoteConnectionHostService.class.equals(service)
|
|| IRemoteConnectionHostService.class.equals(service)
|
||||||
|| IRemoteProcessService.class.equals(service)
|
|| IRemoteProcessService.class.equals(service)
|
||||||
|| IRemoteCommandShellService.class.equals(service)) {
|
|| IRemoteCommandShellService.class.equals(service)
|
||||||
|
|| IRemoteConnectionPropertyService.class.equals(service)) {
|
||||||
return (T) connection.getService(ProxyConnection.class);
|
return (T) connection.getService(ProxyConnection.class);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -348,7 +349,7 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IRemoteProcess getCommandShell(int flags) throws IOException {
|
public IRemoteProcess getCommandShell(int flags) throws IOException {
|
||||||
throw new IOException("Not implemented yet");
|
return new ProxyProcessBuilder(this).start(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -454,4 +455,9 @@ public class ProxyConnection implements IRemoteConnectionControlService,
|
||||||
wc.setAttribute(USERNAME_ATTR, username);
|
wc.setAttribute(USERNAME_ATTR, username);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProperty(String key) {
|
||||||
|
return fProperties.get(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ public class ProxyConnectionBootstrap {
|
||||||
int n;
|
int n;
|
||||||
while ((n = in.read(buf)) >= 0) {
|
while ((n = in.read(buf)) >= 0) {
|
||||||
if (n < 510) {
|
if (n < 510) {
|
||||||
writer.write(encoder.encodeToString(Arrays.copyOf(buf, n)) + "\n");
|
writer.write(encoder.encodeToString(Arrays.copyOf(buf, n)) + "\n"); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
writer.write(encoder.encodeToString(buf));
|
writer.write(encoder.encodeToString(buf));
|
||||||
}
|
}
|
||||||
|
@ -311,7 +311,7 @@ public class ProxyConnectionBootstrap {
|
||||||
throw new RemoteConnectionException(Messages.ProxyConnectionBootstrap_8);
|
throw new RemoteConnectionException(Messages.ProxyConnectionBootstrap_8);
|
||||||
}
|
}
|
||||||
exec = (ChannelExec) session.openChannel("exec"); //$NON-NLS-1$
|
exec = (ChannelExec) session.openChannel("exec"); //$NON-NLS-1$
|
||||||
exec.setCommand("/bin/sh -l"); //$NON-NLS-1$
|
exec.setCommand("/bin/bash -l"); //$NON-NLS-1$
|
||||||
exec.connect();
|
exec.connect();
|
||||||
return exec;
|
return exec;
|
||||||
} catch (JSchException e) {
|
} catch (JSchException e) {
|
||||||
|
|
|
@ -12,18 +12,18 @@ import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.remote.core.IRemoteConnection;
|
|
||||||
import org.eclipse.remote.core.IRemoteProcess;
|
import org.eclipse.remote.core.IRemoteProcess;
|
||||||
import org.eclipse.remote.core.IRemoteProcessBuilder;
|
|
||||||
import org.eclipse.remote.core.IRemoteProcessControlService;
|
import org.eclipse.remote.core.IRemoteProcessControlService;
|
||||||
import org.eclipse.remote.core.IRemoteProcessSignalService;
|
import org.eclipse.remote.core.IRemoteProcessSignalService;
|
||||||
import org.eclipse.remote.core.IRemoteProcessTerminalService;
|
import org.eclipse.remote.core.IRemoteProcessTerminalService;
|
||||||
import org.eclipse.remote.internal.core.RemoteProcess;
|
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||||
|
|
||||||
public class ProxyProcess extends RemoteProcess implements IRemoteProcessControlService, IRemoteProcessTerminalService {
|
public class ProxyProcess implements IRemoteProcessControlService, IRemoteProcessTerminalService {
|
||||||
private IRemoteProcess remoteProcess;
|
private IRemoteProcess remoteProcess;
|
||||||
|
|
||||||
private final StreamChannel stdIOChan;
|
private final StreamChannel stdIOChan;
|
||||||
private final StreamChannel stdErrChan;
|
private final StreamChannel stdErrChan;
|
||||||
private final StreamChannel controlChan;
|
private final StreamChannel controlChan;
|
||||||
|
@ -44,8 +44,8 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public <T extends IRemoteProcess.Service> T getService(IRemoteProcess remoteProcess, Class<T> service) {
|
public <T extends IRemoteProcess.Service> T getService(IRemoteProcess remoteProcess, Class<T> service) {
|
||||||
if (ProxyProcess.class.equals(service) && remoteProcess instanceof ProxyProcess) {
|
if (ProxyProcess.class.equals(service)) {
|
||||||
return (T) remoteProcess;
|
return (T) new ProxyProcess(remoteProcess);
|
||||||
}
|
}
|
||||||
if (IRemoteProcessControlService.class.equals(service) || IRemoteProcessSignalService.class.equals(service)
|
if (IRemoteProcessControlService.class.equals(service) || IRemoteProcessSignalService.class.equals(service)
|
||||||
|| IRemoteProcessTerminalService.class.equals(service)) {
|
|| IRemoteProcessTerminalService.class.equals(service)) {
|
||||||
|
@ -55,17 +55,19 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProxyProcess(IRemoteConnection connection, IRemoteProcessBuilder builder, StreamChannel stdIO, StreamChannel stdErr, StreamChannel control) {
|
protected ProxyProcess(IRemoteProcess process) {
|
||||||
super(connection, builder);
|
remoteProcess = process;
|
||||||
stdIOChan = stdIO;
|
ProxyProcessBuilder builder = (ProxyProcessBuilder)process.getProcessBuilder();
|
||||||
stdErrChan = stdErr;
|
List<StreamChannel> streams = builder.getStreams();
|
||||||
controlChan = control;
|
controlChan = streams.get(0);
|
||||||
cmdStream = new DataOutputStream(control.getOutputStream());
|
stdIOChan = streams.get(1);
|
||||||
resultStream = new DataInputStream(control.getInputStream());
|
stdErrChan = streams.size() > 2 ? streams.get(2) : null;
|
||||||
|
cmdStream = new DataOutputStream(controlChan.getOutputStream());
|
||||||
|
resultStream = new DataInputStream(controlChan.getInputStream());
|
||||||
isCompleted = false;
|
isCompleted = false;
|
||||||
exitValue = 0;
|
exitValue = 0;
|
||||||
|
|
||||||
cmdThread = new Thread("process " + builder.command().get(0) + " result reader") { //$NON-NLS-1$ //$NON-NLS-2$
|
cmdThread = new Thread("process result reader") { //$NON-NLS-1$
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
@ -77,36 +79,15 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
||||||
try {
|
try {
|
||||||
stdIOChan.close();
|
stdIOChan.close();
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
// TODO Auto-generated catch block
|
// Ignore
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
stdErrChan.close();
|
if (stdErrChan != null) {
|
||||||
|
stdErrChan.close();
|
||||||
|
}
|
||||||
} catch (IOException e1) {
|
} catch (IOException e1) {
|
||||||
// TODO Auto-generated catch block
|
// Ignore
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
}
|
||||||
// if (stdout == null) {
|
|
||||||
// try {
|
|
||||||
// stdIOChan.getInputStream().close();
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// // Ignore
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (stdin == null) {
|
|
||||||
// try {
|
|
||||||
// stdIOChan.getOutputStream().close();
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// // Ignore
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (stderr == null) {
|
|
||||||
// try {
|
|
||||||
// stdErrChan.close();
|
|
||||||
// } catch (IOException e) {
|
|
||||||
// // Ignore
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
try {
|
try {
|
||||||
controlChan.close();
|
controlChan.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -125,7 +106,7 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
||||||
@Override
|
@Override
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
try {
|
try {
|
||||||
cmdStream.writeByte(0);
|
cmdStream.writeByte(Protocol.CONTROL_KILL);
|
||||||
cmdStream.flush();
|
cmdStream.flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
isCompleted = true;
|
isCompleted = true;
|
||||||
|
@ -152,6 +133,19 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public InputStream getErrorStream() {
|
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();
|
return stdErrChan.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +197,15 @@ public class ProxyProcess extends RemoteProcess implements IRemoteProcessControl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTerminalSize(int cols, int rows, int pwidth, int pheight) {
|
public void setTerminalSize(int cols, int rows, int pwidth, int pheight) {
|
||||||
// Nothing?
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
package org.eclipse.remote.internal.proxy.core;
|
package org.eclipse.remote.internal.proxy.core;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -22,6 +23,7 @@ import org.eclipse.remote.core.IRemoteFileService;
|
||||||
import org.eclipse.remote.core.IRemoteProcess;
|
import org.eclipse.remote.core.IRemoteProcess;
|
||||||
import org.eclipse.remote.core.IRemoteProcessBuilder;
|
import org.eclipse.remote.core.IRemoteProcessBuilder;
|
||||||
import org.eclipse.remote.internal.proxy.core.commands.ExecCommand;
|
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.internal.proxy.core.messages.Messages;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
@ -29,6 +31,7 @@ import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
||||||
private final ProxyConnection proxyConnection;
|
private final ProxyConnection proxyConnection;
|
||||||
private Map<String, String> remoteEnv;
|
private Map<String, String> remoteEnv;
|
||||||
|
private List<StreamChannel> streams = new ArrayList<>();
|
||||||
|
|
||||||
public ProxyProcessBuilder(ProxyConnection connection, List<String> command) {
|
public ProxyProcessBuilder(ProxyConnection connection, List<String> command) {
|
||||||
super(connection.getRemoteConnection(), command);
|
super(connection.getRemoteConnection(), command);
|
||||||
|
@ -43,6 +46,17 @@ public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
||||||
this(connection, Arrays.asList(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)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -76,41 +90,66 @@ public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public IRemoteProcess start(int flags) throws IOException {
|
public IRemoteProcess start(int flags) throws IOException {
|
||||||
final List<String> cmdArgs = command();
|
|
||||||
if (cmdArgs.size() < 1) {
|
|
||||||
throw new IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
final ProxyConnection conn = getRemoteConnection().getService(ProxyConnection.class);
|
final ProxyConnection conn = getRemoteConnection().getService(ProxyConnection.class);
|
||||||
if (conn == null) {
|
if (conn == null) {
|
||||||
throw new IOException(Messages.ProxyProcessBuilder_0);
|
throw new IOException(Messages.ProxyProcessBuilder_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
final StreamChannel chanStdIO = conn.openChannel();
|
Job job;
|
||||||
final StreamChannel chanStdErr = conn.openChannel();
|
|
||||||
final StreamChannel chanControl = conn.openChannel();
|
|
||||||
|
|
||||||
Job job = new Job("process executor") { //$NON-NLS-1$
|
final List<String> cmdArgs = command();
|
||||||
@Override
|
if (cmdArgs != null) {
|
||||||
protected IStatus run(IProgressMonitor monitor) {
|
if (cmdArgs.size() < 1) {
|
||||||
ExecCommand cmd = new ExecCommand(conn, cmdArgs, env, directory().toURI().getPath(), redirectErrorStream(), append,
|
throw new IOException(Messages.ProxyProcessBuilder_1);
|
||||||
chanStdIO.getId(), chanStdErr.getId(), chanControl.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;
|
|
||||||
}
|
}
|
||||||
};
|
/*
|
||||||
|
* 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();
|
job.schedule();
|
||||||
try {
|
try {
|
||||||
job.join();
|
job.join();
|
||||||
|
@ -121,7 +160,10 @@ public class ProxyProcessBuilder extends AbstractRemoteProcessBuilder {
|
||||||
throw new IOException(job.getResult().getMessage());
|
throw new IOException(job.getResult().getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
ProxyProcess proc = new ProxyProcess(getRemoteConnection(), this, chanStdIO, chanStdErr, chanControl);
|
return newRemoteProcess();
|
||||||
return proc;
|
}
|
||||||
|
|
||||||
|
public List<StreamChannel> getStreams() {
|
||||||
|
return streams;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.util.concurrent.TimeoutException;
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.SubMonitor;
|
import org.eclipse.core.runtime.SubMonitor;
|
||||||
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
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.StreamChannel;
|
||||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
||||||
|
@ -29,14 +30,10 @@ public abstract class AbstractCommand<T> implements Callable<T> {
|
||||||
|
|
||||||
private final ProxyConnection connection;
|
private final ProxyConnection connection;
|
||||||
|
|
||||||
|
|
||||||
private Future<T> asyncCmdInThread() throws ProxyException {
|
private Future<T> asyncCmdInThread() throws ProxyException {
|
||||||
return executors.submit(this);
|
return executors.submit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void finalizeCmdInThread() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public StreamChannel openChannel() throws IOException {
|
public StreamChannel openChannel() throws IOException {
|
||||||
return connection.openChannel();
|
return connection.openChannel();
|
||||||
}
|
}
|
||||||
|
@ -52,12 +49,8 @@ public abstract class AbstractCommand<T> implements Callable<T> {
|
||||||
public T getResult(IProgressMonitor monitor) throws ProxyException {
|
public T getResult(IProgressMonitor monitor) throws ProxyException {
|
||||||
Future<T> future = null;
|
Future<T> future = null;
|
||||||
progressMonitor = SubMonitor.convert(monitor, 10);
|
progressMonitor = SubMonitor.convert(monitor, 10);
|
||||||
try {
|
future = asyncCmdInThread();
|
||||||
future = asyncCmdInThread();
|
return waitCmdInThread(future);
|
||||||
return waitCmdInThread(future);
|
|
||||||
} finally {
|
|
||||||
finalizeCmdInThread();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private T waitCmdInThread(Future<T> future) throws ProxyException {
|
private T waitCmdInThread(Future<T> future) throws ProxyException {
|
||||||
|
@ -78,7 +71,7 @@ public abstract class AbstractCommand<T> implements Callable<T> {
|
||||||
Thread.currentThread().interrupt(); // set current thread flag
|
Thread.currentThread().interrupt(); // set current thread flag
|
||||||
}
|
}
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
throw new ProxyException("Operation cancelled by user");
|
throw new ProxyException(Messages.AbstractCommand_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -44,7 +44,6 @@ public class ChildInfosCommand extends AbstractCommand<IFileInfo[]> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("childinfos command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ public class DeleteCommand extends AbstractCommand<Void> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("delete command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -26,12 +26,12 @@ public class ExecCommand extends AbstractCommand<Void> {
|
||||||
private final String directory;
|
private final String directory;
|
||||||
private final boolean appendEnv;
|
private final boolean appendEnv;
|
||||||
private final boolean redirect;
|
private final boolean redirect;
|
||||||
private final int chanA;
|
private final int cmdChan;
|
||||||
private final int chanB;
|
private final int ioChan;
|
||||||
private final int chanC;
|
private final int errChan;
|
||||||
|
|
||||||
public ExecCommand(ProxyConnection conn, List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv,
|
public ExecCommand(ProxyConnection conn, List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv,
|
||||||
int chanA, int chanB, int chanC) {
|
int cmdChan, int ioChan, int errChan) {
|
||||||
super(conn);
|
super(conn);
|
||||||
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
|
this.out = new DataOutputStream(conn.getCommandChannel().getOutputStream());
|
||||||
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
|
this.in = new DataInputStream(conn.getCommandChannel().getInputStream());
|
||||||
|
@ -40,18 +40,18 @@ public class ExecCommand extends AbstractCommand<Void> {
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.redirect = redirect;
|
this.redirect = redirect;
|
||||||
this.appendEnv = appendEnv;
|
this.appendEnv = appendEnv;
|
||||||
this.chanA = chanA;
|
this.cmdChan = cmdChan;
|
||||||
this.chanB = chanB;
|
this.ioChan = ioChan;
|
||||||
this.chanC = chanC;
|
this.errChan = errChan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Void call() throws ProxyException {
|
public Void call() throws ProxyException {
|
||||||
try {
|
try {
|
||||||
out.writeByte(Protocol.PROTO_COMMAND);
|
out.writeByte(Protocol.PROTO_COMMAND);
|
||||||
out.writeShort(Protocol.CMD_EXEC);
|
out.writeShort(Protocol.CMD_EXEC);
|
||||||
out.writeByte(chanA);
|
out.writeByte(cmdChan);
|
||||||
out.writeByte(chanB);
|
out.writeByte(ioChan);
|
||||||
out.writeByte(chanC);
|
out.writeByte(errChan);
|
||||||
out.writeInt(command.size());
|
out.writeInt(command.size());
|
||||||
for (String arg : command) {
|
for (String arg : command) {
|
||||||
out.writeUTF(arg);
|
out.writeUTF(arg);
|
||||||
|
@ -69,7 +69,6 @@ public class ExecCommand extends AbstractCommand<Void> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("exec command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -44,7 +44,6 @@ public class FetchInfoCommand extends AbstractCommand<IFileInfo> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("fetchinfo command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ public class GetCwdCommand extends AbstractCommand<String> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("getcwd command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ public class GetEnvCommand extends AbstractCommand<Map<String, String>> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("getenv command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
|
||||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
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;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
||||||
public class GetInputStreamCommand extends AbstractCommand<InputStream> {
|
public class GetInputStreamCommand extends AbstractCommand<InputStream> {
|
||||||
|
@ -47,7 +47,6 @@ public class GetInputStreamCommand extends AbstractCommand<InputStream> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("getinputstream command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
import org.eclipse.remote.internal.proxy.core.ProxyConnection;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
|
||||||
import org.eclipse.remote.proxy.protocol.core.Protocol;
|
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;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
||||||
public class GetOutputStreamCommand extends AbstractCommand<OutputStream> {
|
public class GetOutputStreamCommand extends AbstractCommand<OutputStream> {
|
||||||
|
@ -47,7 +47,6 @@ public class GetOutputStreamCommand extends AbstractCommand<OutputStream> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("getoutputstream command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ public class GetPropertiesCommand extends AbstractCommand<Map<String, String>> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("getproperties command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,6 @@ public class MkdirCommand extends AbstractCommand<Void> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("mkdir command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -47,7 +47,6 @@ public class PutInfoCommand extends AbstractCommand<Void> {
|
||||||
byte res = in.readByte();
|
byte res = in.readByte();
|
||||||
if (res != Protocol.PROTO_OK) {
|
if (res != Protocol.PROTO_OK) {
|
||||||
String errMsg = in.readUTF();
|
String errMsg = in.readUTF();
|
||||||
System.err.println("fetchinfo command failed:" + errMsg);
|
|
||||||
throw new ProxyException(errMsg);
|
throw new ProxyException(errMsg);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,8 @@ import org.eclipse.osgi.util.NLS;
|
||||||
public class Messages extends NLS {
|
public class Messages extends NLS {
|
||||||
private static final String BUNDLE_ID = "org.eclipse.remote.internal.proxy.core.messages.messages"; //$NON-NLS-1$
|
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_format1;
|
||||||
public static String AbstractRemoteCommand_format2;
|
public static String AbstractRemoteCommand_format2;
|
||||||
public static String AbstractRemoteCommand_Get_symlink_target;
|
public static String AbstractRemoteCommand_Get_symlink_target;
|
||||||
|
@ -56,6 +58,8 @@ public class Messages extends NLS {
|
||||||
public static String JschFileStore_A_file_of_name_already_exists;
|
public static String JschFileStore_A_file_of_name_already_exists;
|
||||||
public static String JschFileStore_The_parent_of_directory_does_not_exist;
|
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_0;
|
||||||
|
|
||||||
public static String ProxyConnection_2;
|
public static String ProxyConnection_2;
|
||||||
|
@ -98,6 +102,8 @@ public class Messages extends NLS {
|
||||||
|
|
||||||
public static String ProxyProcessBuilder_0;
|
public static String ProxyProcessBuilder_0;
|
||||||
|
|
||||||
|
public static String ProxyProcessBuilder_1;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// load message values from bundle file
|
// load message values from bundle file
|
||||||
NLS.initializeMessages(BUNDLE_ID, Messages.class);
|
NLS.initializeMessages(BUNDLE_ID, Messages.class);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
# Contributors:
|
# Contributors:
|
||||||
# IBM Corporation - initial implementation
|
# IBM Corporation - initial implementation
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
AbstractCommand_0=Operation cancelled by user
|
||||||
AbstractRemoteCommand_format1={0,number,integer} {1} completed
|
AbstractRemoteCommand_format1={0,number,integer} {1} completed
|
||||||
AbstractRemoteCommand_format2={0,number,integer} {1} of {2,number,integer} {3} complete ({4,number,percent})
|
AbstractRemoteCommand_format2={0,number,integer} {1} of {2,number,integer} {3} complete ({4,number,percent})
|
||||||
AbstractRemoteCommand_Get_symlink_target=Get symlink target
|
AbstractRemoteCommand_Get_symlink_target=Get symlink target
|
||||||
|
@ -43,6 +44,7 @@ JschFileStore_No_remote_services_found_for_URI=No remote services found for URI:
|
||||||
JschFileStore_The_directory_could_not_be_created=The directory {0} could not be created
|
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_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
|
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_0=Opening connection...
|
||||||
ProxyConnection_2=User canceled opening connection
|
ProxyConnection_2=User canceled opening connection
|
||||||
ProxyConnectionBootstrap_0=Initializing
|
ProxyConnectionBootstrap_0=Initializing
|
||||||
|
@ -64,3 +66,4 @@ ProxyFileStore_5=A file of name {0} already exists
|
||||||
ProxyFileStore_6=File {0} does not exist
|
ProxyFileStore_6=File {0} does not exist
|
||||||
ProxyFileStore_7={0} is a directory
|
ProxyFileStore_7={0} is a directory
|
||||||
ProxyProcessBuilder_0=Unable to located connection for this process
|
ProxyProcessBuilder_0=Unable to located connection for this process
|
||||||
|
ProxyProcessBuilder_1=No command to run\!
|
||||||
|
|
|
@ -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.proxy.protocol.core;singleton:=true
|
Bundle-SymbolicName: org.eclipse.remote.proxy.protocol.core;singleton:=true
|
||||||
Bundle-Version: 1.0.0.qualifier
|
Bundle-Version: 2.0.0.qualifier
|
||||||
Bundle-Activator: org.eclipse.remote.internal.proxy.protocol.core.Activator
|
Bundle-Activator: org.eclipse.remote.internal.proxy.protocol.core.Activator
|
||||||
Bundle-Vendor: %pluginProvider
|
Bundle-Vendor: %pluginProvider
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
|
|
|
@ -12,5 +12,5 @@
|
||||||
|
|
||||||
<artifactId>org.eclipse.remote.proxy.protocol.core</artifactId>
|
<artifactId>org.eclipse.remote.proxy.protocol.core</artifactId>
|
||||||
<packaging>eclipse-plugin</packaging>
|
<packaging>eclipse-plugin</packaging>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>2.0.0-SNAPSHOT</version>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -17,16 +17,25 @@ public class Protocol {
|
||||||
|
|
||||||
public final static short CmdBase = 100;
|
public final static short CmdBase = 100;
|
||||||
|
|
||||||
public final static short CMD_EXEC = CmdBase + 1;
|
public final static short CMD_EXEC = CmdBase + 1;
|
||||||
public final static short CMD_SHELL = CmdBase + 2;
|
public final static short CMD_SHELL = CmdBase + 2;
|
||||||
public final static short CMD_GETCWD = CmdBase + 3;
|
public final static short CMD_GETCWD = CmdBase + 3;
|
||||||
public final static short CMD_GETENV = CmdBase + 4;
|
public final static short CMD_GETENV = CmdBase + 4;
|
||||||
public final static short CMD_CHILDINFOS = CmdBase + 5;
|
public final static short CMD_CHILDINFOS = CmdBase + 5;
|
||||||
public final static short CMD_DELETE = CmdBase + 6;
|
public final static short CMD_DELETE = CmdBase + 6;
|
||||||
public final static short CMD_FETCHINFO = CmdBase + 7;
|
public final static short CMD_FETCHINFO = CmdBase + 7;
|
||||||
public final static short CMD_GETINPUTSTREAM = CmdBase + 8;
|
public final static short CMD_GETINPUTSTREAM = CmdBase + 8;
|
||||||
public final static short CMD_GETOUTPUTSTREAM = CmdBase + 9;
|
public final static short CMD_GETOUTPUTSTREAM = CmdBase + 9;
|
||||||
public final static short CMD_MKDIR = CmdBase + 10;
|
public final static short CMD_MKDIR = CmdBase + 10;
|
||||||
public final static short CMD_PUTINFO = CmdBase + 11;
|
public final static short CMD_PUTINFO = CmdBase + 11;
|
||||||
public final static short CMD_GETPROPERTIES = CmdBase + 12;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
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.methodParameters=do not generate
|
||||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
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.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.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.8
|
||||||
|
|
|
@ -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
|
|
@ -15,3 +15,4 @@ Import-Package: org.eclipse.core.filesystem,
|
||||||
org.osgi.framework.launch
|
org.osgi.framework.launch
|
||||||
Bundle-Vendor: %pluginProvider
|
Bundle-Vendor: %pluginProvider
|
||||||
Bundle-Localization: plugin
|
Bundle-Localization: plugin
|
||||||
|
Require-Bundle: org.eclipse.cdt.core.native
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class Application implements IApplication {
|
||||||
public Object start(IApplicationContext context) throws Exception {
|
public Object start(IApplicationContext context) throws Exception {
|
||||||
String[] args = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
|
String[] args = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
|
||||||
for (String arg : args) {
|
for (String arg : args) {
|
||||||
if (arg.equals("-magic")) {
|
if (arg.equals("-magic")) { //$NON-NLS-1$
|
||||||
ByteBuffer b = ByteBuffer.allocate(4);
|
ByteBuffer b = ByteBuffer.allocate(4);
|
||||||
b.putInt(Protocol.MAGIC);
|
b.putInt(Protocol.MAGIC);
|
||||||
System.out.write(b.array());
|
System.out.write(b.array());
|
||||||
|
@ -40,5 +40,6 @@ public class Application implements IApplication {
|
||||||
* @see org.eclipse.equinox.app.IApplication#stop()
|
* @see org.eclipse.equinox.app.IApplication#stop()
|
||||||
*/
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
// Nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,18 +16,19 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.AbstractServerCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.AbstractServerCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerChildInfosCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerChildInfosCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerDeleteCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerDeleteCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerExecCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerExecCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerFetchInfoCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerFetchInfoCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetCwdCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetCwdCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetEnvCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetEnvCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetInputStreamCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetInputStreamCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetOutputStreamCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetOutputStreamCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerGetPropertiesCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerGetPropertiesCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerMkdirCommand;
|
import org.eclipse.remote.internal.proxy.server.core.commands.ServerMkdirCommand;
|
||||||
import org.eclipse.remote.internal.proxy.server.commands.ServerPutInfoCommand;
|
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.Protocol;
|
||||||
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
|
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||||
|
@ -48,7 +49,7 @@ public class CommandServer implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
new Thread("cmd reader") {
|
new Thread("cmd reader") { //$NON-NLS-1$
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
@ -117,6 +118,10 @@ public class CommandServer implements Runnable {
|
||||||
serverCmd = cmdExec(in);
|
serverCmd = cmdExec(in);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Protocol.CMD_SHELL:
|
||||||
|
serverCmd = cmdShell(in);
|
||||||
|
break;
|
||||||
|
|
||||||
case Protocol.CMD_FETCHINFO:
|
case Protocol.CMD_FETCHINFO:
|
||||||
serverCmd = cmdFetchInfo(in);
|
serverCmd = cmdFetchInfo(in);
|
||||||
break;
|
break;
|
||||||
|
@ -151,16 +156,16 @@ public class CommandServer implements Runnable {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.err.println("Invalid command ID: " + cmd);
|
System.err.println("Invalid command ID: " + cmd);
|
||||||
throw new ProxyException("Invalid command ID: " + cmd);
|
throw new ProxyException("Invalid command ID: " + cmd); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
serverCmd.exec();
|
serverCmd.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
private AbstractServerCommand cmdExec(DataInputStream in) throws ProxyException, IOException {
|
private AbstractServerCommand cmdExec(DataInputStream in) throws ProxyException, IOException {
|
||||||
int chanAId = in.readByte();
|
int cmdChanId = in.readByte();
|
||||||
int chanBId = in.readByte();
|
int ioChanId = in.readByte();
|
||||||
int chanCId = in.readByte();
|
int errChanId = in.readByte();
|
||||||
int length = in.readInt();
|
int length = in.readInt();
|
||||||
List<String> command = new ArrayList<String>(length);
|
List<String> command = new ArrayList<String>(length);
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
|
@ -176,25 +181,30 @@ public class CommandServer implements Runnable {
|
||||||
String dir = in.readUTF();
|
String dir = in.readUTF();
|
||||||
boolean redirect = in.readBoolean();
|
boolean redirect = in.readBoolean();
|
||||||
boolean appendEnv = in.readBoolean();
|
boolean appendEnv = in.readBoolean();
|
||||||
System.err.print("dispatch: ");
|
StreamChannel cmdChan = server.getChannel(cmdChanId);
|
||||||
for (String s:command) {
|
StreamChannel ioChan = server.getChannel(ioChanId);
|
||||||
System.err.print(" " + s);
|
StreamChannel errChan= server.getChannel(errChanId);
|
||||||
|
if (cmdChan == null || ioChan == null || errChan == null) {
|
||||||
|
throw new ProxyException("Unable to locate channels for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
System.err.println(" [" + chanAId + "," + chanBId+ ","+ chanCId + "]");
|
return new ServerExecCommand(command, env, dir, redirect, appendEnv, cmdChan, ioChan, errChan);
|
||||||
StreamChannel chanA = server.getChannel(chanAId);
|
|
||||||
StreamChannel chanB = server.getChannel(chanBId);
|
|
||||||
StreamChannel chanC= server.getChannel(chanCId);
|
|
||||||
if (chanA == null || chanB == null || chanC == null) {
|
|
||||||
throw new ProxyException("Unable to locate channels for command");
|
|
||||||
}
|
|
||||||
return new ServerExecCommand(command, env, dir, redirect, appendEnv, chanA, chanB, chanC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
private AbstractServerCommand cmdGetCwd(DataInputStream in) throws ProxyException, IOException {
|
||||||
int chanId = in.readByte();
|
int chanId = in.readByte();
|
||||||
StreamChannel chan = server.getChannel(chanId);
|
StreamChannel chan = server.getChannel(chanId);
|
||||||
if (chan == null) {
|
if (chan == null) {
|
||||||
throw new ProxyException("Unable to locate channel for command");
|
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
return new ServerGetCwdCommand(chan);
|
return new ServerGetCwdCommand(chan);
|
||||||
}
|
}
|
||||||
|
@ -203,7 +213,7 @@ public class CommandServer implements Runnable {
|
||||||
int chanId = in.readByte();
|
int chanId = in.readByte();
|
||||||
StreamChannel chan = server.getChannel(chanId);
|
StreamChannel chan = server.getChannel(chanId);
|
||||||
if (chan == null) {
|
if (chan == null) {
|
||||||
throw new ProxyException("Unable to locate channel for command");
|
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
return new ServerGetEnvCommand(chan);
|
return new ServerGetEnvCommand(chan);
|
||||||
}
|
}
|
||||||
|
@ -212,7 +222,7 @@ public class CommandServer implements Runnable {
|
||||||
int chanId = in.readByte();
|
int chanId = in.readByte();
|
||||||
StreamChannel chan = server.getChannel(chanId);
|
StreamChannel chan = server.getChannel(chanId);
|
||||||
if (chan == null) {
|
if (chan == null) {
|
||||||
throw new ProxyException("Unable to locate channel for command");
|
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
return new ServerGetPropertiesCommand(chan);
|
return new ServerGetPropertiesCommand(chan);
|
||||||
}
|
}
|
||||||
|
@ -221,7 +231,7 @@ public class CommandServer implements Runnable {
|
||||||
int chanId = in.readByte();
|
int chanId = in.readByte();
|
||||||
StreamChannel chan = server.getChannel(chanId);
|
StreamChannel chan = server.getChannel(chanId);
|
||||||
if (chan == null) {
|
if (chan == null) {
|
||||||
throw new ProxyException("Unable to locate channel for command");
|
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
String path = in.readUTF();
|
String path = in.readUTF();
|
||||||
return new ServerChildInfosCommand(chan, path);
|
return new ServerChildInfosCommand(chan, path);
|
||||||
|
@ -231,7 +241,7 @@ public class CommandServer implements Runnable {
|
||||||
int chanId = in.readByte();
|
int chanId = in.readByte();
|
||||||
StreamChannel chan = server.getChannel(chanId);
|
StreamChannel chan = server.getChannel(chanId);
|
||||||
if (chan == null) {
|
if (chan == null) {
|
||||||
throw new ProxyException("Unable to locate channel for command");
|
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
String path = in.readUTF();
|
String path = in.readUTF();
|
||||||
return new ServerFetchInfoCommand(chan, path);
|
return new ServerFetchInfoCommand(chan, path);
|
||||||
|
@ -241,7 +251,7 @@ public class CommandServer implements Runnable {
|
||||||
int chanId = in.readByte();
|
int chanId = in.readByte();
|
||||||
StreamChannel chan = server.getChannel(chanId);
|
StreamChannel chan = server.getChannel(chanId);
|
||||||
if (chan == null) {
|
if (chan == null) {
|
||||||
throw new ProxyException("Unable to locate channel for command");
|
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
int options = in.readInt();
|
int options = in.readInt();
|
||||||
String path = in.readUTF();
|
String path = in.readUTF();
|
||||||
|
@ -252,7 +262,7 @@ public class CommandServer implements Runnable {
|
||||||
int chanId = in.readByte();
|
int chanId = in.readByte();
|
||||||
StreamChannel chan = server.getChannel(chanId);
|
StreamChannel chan = server.getChannel(chanId);
|
||||||
if (chan == null) {
|
if (chan == null) {
|
||||||
throw new ProxyException("Unable to locate channel for command");
|
throw new ProxyException("Unable to locate channel for command"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
int options = in.readInt();
|
int options = in.readInt();
|
||||||
String path = in.readUTF();
|
String path = in.readUTF();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
|
@ -5,14 +5,13 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -23,83 +22,37 @@ import java.util.concurrent.locks.Condition;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
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.StreamChannel;
|
||||||
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
||||||
/**
|
public abstract class AbstractServerExecCommand extends AbstractServerCommand {
|
||||||
* TODO: Fix hang if command fails...
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ServerExecCommand extends AbstractServerCommand {
|
|
||||||
|
|
||||||
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 stdin;
|
|
||||||
private final OutputStream stdout;
|
|
||||||
private final OutputStream stderr;
|
|
||||||
private final DataOutputStream result;
|
|
||||||
private final DataInputStream cmd;
|
|
||||||
|
|
||||||
private Process proc;
|
|
||||||
|
|
||||||
private class CommandRunner implements Runnable {
|
private class CommandRunner implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ProcessBuilder builder = new ProcessBuilder(command);
|
|
||||||
try {
|
|
||||||
if (!appendEnv) {
|
|
||||||
builder.environment().clear();
|
|
||||||
builder.environment().putAll(env);
|
|
||||||
} else {
|
|
||||||
for (Map.Entry<String, String> entry : env.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(directory);
|
|
||||||
if (dir.exists() && dir.isAbsolute()) {
|
|
||||||
builder.directory(dir);
|
|
||||||
}
|
|
||||||
builder.redirectErrorStream(redirect);
|
|
||||||
try {
|
try {
|
||||||
int exit = 0;
|
int exit = 0;
|
||||||
try {
|
try {
|
||||||
proc = builder.start();
|
proc = doRun();
|
||||||
Forwarder stdoutFwd = startForwarder("stdout", proc.getInputStream(), stdout); //$NON-NLS-1$
|
Forwarder stdoutFwd = startForwarder("stdout", proc.getInputStream(), stdoutChan); //$NON-NLS-1$
|
||||||
Forwarder stderrFwd = null;
|
Forwarder stderrFwd = null;
|
||||||
if (!redirect) {
|
if (!redirect) {
|
||||||
stderrFwd = startForwarder("stderr", proc.getErrorStream(), stderr); //$NON-NLS-1$
|
stderrFwd = startForwarder("stderr", proc.getErrorStream(), stderrChan); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
startForwarder("stdin", stdin, proc.getOutputStream()); //$NON-NLS-1$
|
startForwarder("stdin", stdinChan, proc.getOutputStream()); //$NON-NLS-1$
|
||||||
new Thread(new ProcMonitor(), "process monitor").start(); //$NON-NLS-1$
|
new Thread(new ProcMonitor(), "process monitor").start(); //$NON-NLS-1$
|
||||||
System.err.println("wait for process");
|
|
||||||
exit = proc.waitFor();
|
exit = proc.waitFor();
|
||||||
System.err.println("wait for process close in");
|
|
||||||
// stdoutFwd.terminate();
|
|
||||||
// if (!redirect) {
|
|
||||||
// stderrFwd.terminate();
|
|
||||||
// }
|
|
||||||
System.err.println("wait for readers");
|
|
||||||
/*
|
/*
|
||||||
* After the process has finished, wait for the stdout and stderr forwarders to finish to
|
* After the process has finished, wait for the stdout and stderr forwarders to finish to
|
||||||
* ensure that all output is flushed.
|
* ensure that all output is flushed.
|
||||||
*/
|
*/
|
||||||
// stdoutFwd.waitFor();
|
stdoutFwd.waitFor();
|
||||||
// System.err.println("wait for process finished out");
|
if (stderrFwd != null) {
|
||||||
// if (stderrFwd != null) {
|
stderrFwd.waitFor();
|
||||||
// stderrFwd.waitFor();
|
}
|
||||||
// }
|
|
||||||
System.err.println("wait for readers done");
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stderr));
|
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stderrChan));
|
||||||
try {
|
try {
|
||||||
writer.write(e.getMessage());
|
writer.write(e.getMessage());
|
||||||
writer.flush();
|
writer.flush();
|
||||||
|
@ -109,8 +62,8 @@ public class ServerExecCommand extends AbstractServerCommand {
|
||||||
exit = -1;
|
exit = -1;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
result.writeInt(exit);
|
resultStream.writeInt(exit);
|
||||||
result.flush();
|
resultStream.flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// We're finished anyway
|
// We're finished anyway
|
||||||
}
|
}
|
||||||
|
@ -124,9 +77,17 @@ public class ServerExecCommand extends AbstractServerCommand {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
cmd.readByte();
|
switch (cmdStream.readByte()) {
|
||||||
if (proc.isAlive()) {
|
case Protocol.CONTROL_KILL:
|
||||||
proc.destroyForcibly();
|
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) {
|
} catch (IOException e) {
|
||||||
// Finish
|
// Finish
|
||||||
|
@ -139,8 +100,7 @@ public class ServerExecCommand extends AbstractServerCommand {
|
||||||
private final OutputStream out;
|
private final OutputStream out;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private volatile boolean running = true;
|
private boolean running = true;
|
||||||
private boolean terminated = false;
|
|
||||||
|
|
||||||
private final Lock lock = new ReentrantLock();
|
private final Lock lock = new ReentrantLock();
|
||||||
private final Condition cond = lock.newCondition();
|
private final Condition cond = lock.newCondition();
|
||||||
|
@ -156,58 +116,44 @@ public class ServerExecCommand extends AbstractServerCommand {
|
||||||
byte[] buf = new byte[8192];
|
byte[] buf = new byte[8192];
|
||||||
int n;
|
int n;
|
||||||
try {
|
try {
|
||||||
while (true) {
|
while (running) {
|
||||||
// if (in.available() == 0) {
|
|
||||||
// System.err.println("avail=0");
|
|
||||||
// /* Avoid spinning if no data */
|
|
||||||
// lock.lock();
|
|
||||||
// try {
|
|
||||||
// cond.await(100, TimeUnit.MILLISECONDS);
|
|
||||||
// } catch (InterruptedException e) {
|
|
||||||
// } finally {
|
|
||||||
// lock.unlock();
|
|
||||||
// }
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
n = in.read(buf);
|
n = in.read(buf);
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
out.write(buf, 0, n);
|
out.write(buf, 0, n);
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
if (n==0) System.err.println("forwarder n=0");
|
|
||||||
if (n < 0) break;
|
if (n < 0) break;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Finish
|
// Finish
|
||||||
System.err.println("forwarder "+e.getMessage());
|
|
||||||
}
|
}
|
||||||
System.err.println("forwarder closing name="+name);
|
|
||||||
|
|
||||||
try {
|
|
||||||
out.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// Best effort
|
|
||||||
}
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
terminated = true;
|
|
||||||
try {
|
try {
|
||||||
|
running = false;
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Best effort
|
||||||
|
}
|
||||||
cond.signalAll();
|
cond.signalAll();
|
||||||
} finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void terminate() {
|
public String getName() {
|
||||||
running = false;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void waitFor() {
|
public synchronized void waitFor() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
if (!terminated) {
|
while (running) {
|
||||||
try {
|
try {
|
||||||
cond.await();
|
cond.await();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
// Check terminated flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -216,27 +162,70 @@ public class ServerExecCommand extends AbstractServerCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerExecCommand(List<String> command, Map<String, String> env, String directory, boolean redirect, boolean appendEnv, StreamChannel chanA, StreamChannel chanB, StreamChannel chanC) {
|
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.command = command;
|
||||||
this.env = env;
|
this.env = env;
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.redirect = redirect;
|
this.redirect = redirect;
|
||||||
this.appendEnv = appendEnv;
|
this.appendEnv = appendEnv;
|
||||||
this.stdin = chanA.getInputStream();
|
|
||||||
this.stdout = chanA.getOutputStream();
|
|
||||||
this.stderr = chanB.getOutputStream();
|
|
||||||
|
|
||||||
this.result = new DataOutputStream(chanC.getOutputStream());
|
this.stdinChan = ioChan.getInputStream();
|
||||||
this.cmd = new DataInputStream(chanC.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 {
|
public void exec() throws ProxyException {
|
||||||
new Thread(new CommandRunner(), command.get(0)).start();
|
new Thread(new CommandRunner()).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Forwarder startForwarder(String name, InputStream in, OutputStream out) {
|
private Forwarder startForwarder(String name, InputStream in, OutputStream out) {
|
||||||
Forwarder forwarder = new Forwarder(name, in, out);
|
Forwarder forwarder = new Forwarder(name, in, out);
|
||||||
Thread thread = new Thread(forwarder, command.get(0) + " " + name); //$NON-NLS-1$
|
Thread thread = new Thread(forwarder, forwarder.getName());
|
||||||
thread.start();
|
thread.start();
|
||||||
return forwarder;
|
return forwarder;
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -15,8 +15,8 @@ import java.net.URI;
|
||||||
import org.eclipse.core.filesystem.EFS;
|
import org.eclipse.core.filesystem.EFS;
|
||||||
import org.eclipse.core.filesystem.IFileInfo;
|
import org.eclipse.core.filesystem.IFileInfo;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
|
||||||
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
|
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;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
||||||
public class ServerChildInfosCommand extends AbstractServerCommand {
|
public class ServerChildInfosCommand extends AbstractServerCommand {
|
||||||
|
@ -45,7 +45,7 @@ public class ServerChildInfosCommand extends AbstractServerCommand {
|
||||||
|
|
||||||
public ServerChildInfosCommand(StreamChannel chan, String path) {
|
public ServerChildInfosCommand(StreamChannel chan, String path) {
|
||||||
this.out = chan.getOutputStream();
|
this.out = chan.getOutputStream();
|
||||||
this.uri = URI.create("file:" + path);
|
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exec() throws ProxyException {
|
public void exec() throws ProxyException {
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ public class ServerDeleteCommand extends AbstractServerCommand {
|
||||||
|
|
||||||
public ServerDeleteCommand(int options, String path) {
|
public ServerDeleteCommand(int options, String path) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.uri = URI.create("file:" + path);
|
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exec() throws ProxyException {
|
public void exec() throws ProxyException {
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -15,8 +15,8 @@ import java.net.URI;
|
||||||
import org.eclipse.core.filesystem.EFS;
|
import org.eclipse.core.filesystem.EFS;
|
||||||
import org.eclipse.core.filesystem.IFileInfo;
|
import org.eclipse.core.filesystem.IFileInfo;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
|
||||||
import org.eclipse.remote.proxy.protocol.core.SerializableFileInfo;
|
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;
|
import org.eclipse.remote.proxy.protocol.core.exceptions.ProxyException;
|
||||||
|
|
||||||
public class ServerFetchInfoCommand extends AbstractServerCommand {
|
public class ServerFetchInfoCommand extends AbstractServerCommand {
|
||||||
|
@ -42,7 +42,7 @@ public class ServerFetchInfoCommand extends AbstractServerCommand {
|
||||||
|
|
||||||
public ServerFetchInfoCommand(StreamChannel chan, String path) {
|
public ServerFetchInfoCommand(StreamChannel chan, String path) {
|
||||||
this.out = chan.getOutputStream();
|
this.out = chan.getOutputStream();
|
||||||
this.uri = URI.create("file:" + path);
|
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exec() throws ProxyException {
|
public void exec() throws ProxyException {
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -35,7 +35,7 @@ public class ServerGetCwdCommand extends AbstractServerCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exec() throws ProxyException {
|
public void exec() throws ProxyException {
|
||||||
cwd = System.getProperty("user.dir");
|
cwd = System.getProperty("user.dir"); //$NON-NLS-1$
|
||||||
new Thread(new CommandRunner()).start();
|
new Thread(new CommandRunner()).start();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -32,7 +32,7 @@ public class ServerGetPropertiesCommand extends AbstractServerCommand {
|
||||||
props.put(IRemoteConnection.OS_NAME_PROPERTY, System.getProperty(IRemoteConnection.OS_NAME_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_VERSION_PROPERTY, System.getProperty(IRemoteConnection.OS_VERSION_PROPERTY));
|
||||||
props.put(IRemoteConnection.OS_ARCH_PROPERTY, System.getProperty(IRemoteConnection.OS_ARCH_PROPERTY));
|
props.put(IRemoteConnection.OS_ARCH_PROPERTY, System.getProperty(IRemoteConnection.OS_ARCH_PROPERTY));
|
||||||
props.put(IRemoteConnection.LOCALE_CHARMAP_PROPERTY, System.getProperty("file.encoding"));
|
props.put(IRemoteConnection.LOCALE_CHARMAP_PROPERTY, System.getProperty("file.encoding")); //$NON-NLS-1$
|
||||||
|
|
||||||
result.writeInt(props.size());
|
result.writeInt(props.size());
|
||||||
for (Map.Entry<String, String> entry : props.entrySet()) {
|
for (Map.Entry<String, String> entry : props.entrySet()) {
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ public class ServerMkdirCommand extends AbstractServerCommand {
|
||||||
|
|
||||||
public ServerMkdirCommand(int options, String path) {
|
public ServerMkdirCommand(int options, String path) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.uri = URI.create("file:" + path);
|
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exec() throws ProxyException {
|
public void exec() throws ProxyException {
|
|
@ -5,7 +5,7 @@
|
||||||
* 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
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.remote.internal.proxy.server.commands;
|
package org.eclipse.remote.internal.proxy.server.core.commands;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ public class ServerPutInfoCommand extends AbstractServerCommand {
|
||||||
public ServerPutInfoCommand(IFileInfo info, int options, String path) {
|
public ServerPutInfoCommand(IFileInfo info, int options, String path) {
|
||||||
this.info = info;
|
this.info = info;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.uri = URI.create("file:" + path);
|
this.uri = URI.create("file:" + path); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exec() throws ProxyException {
|
public void exec() throws ProxyException {
|
|
@ -0,0 +1,178 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* 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.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.utils.pty.PTY;
|
||||||
|
import org.eclipse.cdt.utils.pty.PTY.Mode;
|
||||||
|
import org.eclipse.cdt.utils.spawner.ProcessFactory;
|
||||||
|
import org.eclipse.remote.proxy.protocol.core.StreamChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Fix hang if command fails...
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ServerShellCommand extends AbstractServerExecCommand {
|
||||||
|
private class ShellProcess extends Process {
|
||||||
|
private final Process proc;
|
||||||
|
private final PTY pty;
|
||||||
|
|
||||||
|
public ShellProcess(Process proc, PTY pty) {
|
||||||
|
this.proc = proc;
|
||||||
|
this.pty = pty;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OutputStream getOutputStream() {
|
||||||
|
if (pty != null) {
|
||||||
|
return pty.getOutputStream();
|
||||||
|
}
|
||||||
|
return proc.getOutputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getInputStream() {
|
||||||
|
if (pty != null) {
|
||||||
|
return pty.getInputStream();
|
||||||
|
}
|
||||||
|
return proc.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getErrorStream() {
|
||||||
|
if (pty != null) {
|
||||||
|
return pty.getInputStream();
|
||||||
|
}
|
||||||
|
return proc.getErrorStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int waitFor() throws InterruptedException {
|
||||||
|
return proc.waitFor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int exitValue() {
|
||||||
|
return proc.exitValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy() {
|
||||||
|
proc.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTerminalSize(int cols, int rows) {
|
||||||
|
if (pty != null) {
|
||||||
|
pty.setTerminalSize(cols, rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerShellCommand(StreamChannel cmdChan, StreamChannel ioChan) {
|
||||||
|
super(null, null, null, true, false, cmdChan, ioChan, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Process doRun() throws IOException {
|
||||||
|
String shell = findLoginShell();
|
||||||
|
|
||||||
|
if (PTY.isSupported(Mode.TERMINAL)) {
|
||||||
|
PTY pty = new PTY(Mode.TERMINAL);
|
||||||
|
Process p = ProcessFactory.getFactory().exec(new String[] {shell, "-l"}, null, null, pty); //$NON-NLS-1$
|
||||||
|
return new ShellProcess(p, pty);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessFactory.getFactory().exec(new String[] {shell, "-l"}, null, null); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doKill(Process proc) {
|
||||||
|
if (proc.isAlive()) {
|
||||||
|
proc.destroyForcibly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doSetTerminalSize(Process proc, int cols, int rows) {
|
||||||
|
if (proc.isAlive() && proc instanceof ShellProcess) {
|
||||||
|
ShellProcess shell = (ShellProcess)proc;
|
||||||
|
shell.setTerminalSize(cols, rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the login shell.
|
||||||
|
*
|
||||||
|
* On Linux, use `getent passwd $USER`
|
||||||
|
* On Mac OSX, use `dscl . -read /Users/$USER UserShell`
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String findLoginShell() throws IOException {
|
||||||
|
String res;
|
||||||
|
|
||||||
|
String osName = System.getProperty("os.name"); //$NON-NLS-1$
|
||||||
|
String userName = System.getProperty("user.name"); //$NON-NLS-1$
|
||||||
|
if (osName == null || userName == null) {
|
||||||
|
throw new IOException("Unable to obtain information needed to find login shell"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
switch (osName) {
|
||||||
|
case "Mac OS X": //$NON-NLS-1$
|
||||||
|
res = executeCommand("dscl . -read /Users/" + userName + " UserShell"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
if (res != null) {
|
||||||
|
String[] vals = res.split(" "); //$NON-NLS-1$
|
||||||
|
if (vals.length == 2) {
|
||||||
|
return vals[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "Linux": //$NON-NLS-1$
|
||||||
|
res = executeCommand("getent passwd " + userName); //$NON-NLS-1$
|
||||||
|
if (res != null) {
|
||||||
|
String[] vals = res.split(":"); //$NON-NLS-1$
|
||||||
|
if (vals.length == 7) {
|
||||||
|
return vals[6];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
throw new IOException("Unable to find login shell for os=" + osName + " user=" + userName); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
|
||||||
|
private String executeCommand(String command) throws IOException {
|
||||||
|
String line;
|
||||||
|
StringBuffer output = new StringBuffer();
|
||||||
|
|
||||||
|
Process p;
|
||||||
|
try {
|
||||||
|
p = Runtime.getRuntime().exec(command);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
p.waitFor();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new IOException(e.getMessage());
|
||||||
|
}
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||||
|
line = reader.readLine();
|
||||||
|
while (line != null) {
|
||||||
|
output.append(line);
|
||||||
|
line = reader.readLine();
|
||||||
|
if (line != null) {
|
||||||
|
output.append("\n"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,6 @@
|
||||||
<windowImages/>
|
<windowImages/>
|
||||||
|
|
||||||
<launcher name="proxy">
|
<launcher name="proxy">
|
||||||
<solaris/>
|
|
||||||
<win useIco="false">
|
<win useIco="false">
|
||||||
<bmp/>
|
<bmp/>
|
||||||
</win>
|
</win>
|
||||||
|
@ -28,6 +27,8 @@
|
||||||
|
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin id="com.ibm.icu"/>
|
<plugin id="com.ibm.icu"/>
|
||||||
|
<plugin id="org.eclipse.cdt.core.macosx" fragment="true"/>
|
||||||
|
<plugin id="org.eclipse.cdt.core.linux.x86_64" fragment="true"/>
|
||||||
<plugin id="org.eclipse.cdt.core.native"/>
|
<plugin id="org.eclipse.cdt.core.native"/>
|
||||||
<plugin id="org.eclipse.core.contenttype"/>
|
<plugin id="org.eclipse.core.contenttype"/>
|
||||||
<plugin id="org.eclipse.core.expressions"/>
|
<plugin id="org.eclipse.core.expressions"/>
|
||||||
|
@ -53,10 +54,6 @@
|
||||||
<plugin id="org.eclipse.remote.proxy.server.core"/>
|
<plugin id="org.eclipse.remote.proxy.server.core"/>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|
||||||
<features>
|
|
||||||
<feature id="org.eclipse.remote.proxy"/>
|
|
||||||
</features>
|
|
||||||
|
|
||||||
<configurations>
|
<configurations>
|
||||||
<plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" />
|
<plugin id="org.eclipse.core.runtime" autoStart="true" startLevel="0" />
|
||||||
<plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
|
<plugin id="org.eclipse.equinox.common" autoStart="true" startLevel="2" />
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<?pde version="3.8"?>
|
<?pde version="3.8"?><target name="remote-oxygen" sequenceNumber="0">
|
||||||
<target name="remote-oxygen" sequenceNumber="0">
|
|
||||||
<locations>
|
<locations>
|
||||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||||
<unit id="org.eclipse.sdk.ide" version="0.0.0"/>
|
|
||||||
<unit id="org.eclipse.equinox.executable.feature.group" version="0.0.0"/>
|
<unit id="org.eclipse.equinox.executable.feature.group" version="0.0.0"/>
|
||||||
|
<unit id="org.eclipse.sdk.ide" version="0.0.0"/>
|
||||||
<repository location="http://download.eclipse.org/eclipse/updates/4.7/"/>
|
<repository location="http://download.eclipse.org/eclipse/updates/4.7/"/>
|
||||||
</location>
|
</location>
|
||||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||||
<unit id="org.mockito" version="0.0.0"/>
|
|
||||||
<unit id="org.hamcrest" version="0.0.0"/>
|
<unit id="org.hamcrest" version="0.0.0"/>
|
||||||
|
<unit id="org.mockito" version="0.0.0"/>
|
||||||
<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20170919201930/repository/"/>
|
<repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20170919201930/repository/"/>
|
||||||
</location>
|
</location>
|
||||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||||
<unit id="org.eclipse.cdt.native.serial" version="0.0.0"/>
|
|
||||||
<unit id="org.eclipse.cdt.core" version="0.0.0"/>
|
<unit id="org.eclipse.cdt.core" version="0.0.0"/>
|
||||||
|
<unit id="org.eclipse.cdt.native.feature.group" version="0.0.0"/>
|
||||||
|
<unit id="org.eclipse.cdt.native.serial" version="0.0.0"/>
|
||||||
<repository location="http://download.eclipse.org/tools/cdt/builds/master/nightly/"/>
|
<repository location="http://download.eclipse.org/tools/cdt/builds/master/nightly/"/>
|
||||||
</location>
|
</location>
|
||||||
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
|
||||||
|
|
Loading…
Add table
Reference in a new issue