mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 01:36:01 +02:00
Bug 465212 - SSH should support command shell service
Added JSchCommandShellService which creates a ChannelShell through JSch in order to open a remote terminal. Change-Id: Ib7ddeb3f9c964ab32130baf99a8d70d36605c3d8 Signed-off-by: Matthew Bastien <mbastien@qnx.com>
This commit is contained in:
parent
6ee3aff83b
commit
efeb6fc7bb
6 changed files with 104 additions and 12 deletions
|
@ -164,7 +164,7 @@ public class RemoteServicesManager implements IRemoteServicesManager {
|
|||
List<IRemoteConnectionType> connTypes = new ArrayList<IRemoteConnectionType>();
|
||||
for (IRemoteConnectionType connType : getAllConnectionTypes()) {
|
||||
for (Class<? extends IRemoteConnection.Service> service : services) {
|
||||
if (!connType.hasConnectionService(service)) {
|
||||
if (connType.hasConnectionService(service)) {
|
||||
connTypes.add(connType);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
factory="org.eclipse.remote.internal.jsch.core.JSchConnection$Factory"
|
||||
service="org.eclipse.remote.internal.jsch.core.JSchConnection">
|
||||
</connectionService>
|
||||
<connectionService
|
||||
connectionTypeId="org.eclipse.remote.JSch"
|
||||
factory="org.eclipse.remote.internal.jsch.core.JSchCommandShellService$Factory"
|
||||
service="org.eclipse.remote.core.IRemoteCommandShellService">
|
||||
</connectionService>
|
||||
<processService
|
||||
connectionTypeId="org.eclipse.remote.JSch"
|
||||
factory="org.eclipse.remote.internal.jsch.core.JSchProcess$Factory"
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*******************************************************************************
|
||||
* 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.jsch.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 JSchCommandShellService implements IRemoteCommandShellService {
|
||||
private IRemoteConnection fRemoteConnection;
|
||||
|
||||
public JSchCommandShellService(IRemoteConnection remoteConnection) {
|
||||
fRemoteConnection = remoteConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRemoteConnection getRemoteConnection() {
|
||||
return fRemoteConnection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IRemoteProcess getCommandShell(int flags) throws IOException {
|
||||
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 JSchCommandShellService(connection);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,6 +42,7 @@ import org.eclipse.remote.internal.jsch.core.messages.Messages;
|
|||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.ChannelSftp;
|
||||
import com.jcraft.jsch.ChannelShell;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
import com.jcraft.jsch.Session;
|
||||
import com.jcraft.jsch.UIKeyboardInteractive;
|
||||
|
@ -541,6 +542,22 @@ public class JSchConnection implements IRemoteConnectionControlService, IRemoteC
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a shell channel to the remote host.
|
||||
*
|
||||
* @return shell channel or null if the progress monitor was cancelled
|
||||
*
|
||||
* @throws RemoteConnectionException
|
||||
* if a channel could not be opened
|
||||
*/
|
||||
public ChannelShell getShellChannel() throws RemoteConnectionException {
|
||||
try {
|
||||
return (ChannelShell) fSessions.get(0).openChannel("shell"); //$NON-NLS-1$
|
||||
} catch (JSchException e) {
|
||||
throw new RemoteConnectionException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public String getPassphrase() {
|
||||
return fRemoteConnection.getSecureAttribute(PASSPHRASE_ATTR);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,9 @@ import org.eclipse.remote.core.IRemoteProcessSignalService;
|
|||
import org.eclipse.remote.core.IRemoteProcessTerminalService;
|
||||
import org.eclipse.remote.core.exception.RemoteConnectionException;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.ChannelShell;
|
||||
|
||||
public class JSchProcess implements IRemoteProcessControlService, IRemoteProcessSignalService, IRemoteProcessTerminalService {
|
||||
@SuppressWarnings("nls")
|
||||
|
@ -32,7 +34,7 @@ public class JSchProcess implements IRemoteProcessControlService, IRemoteProcess
|
|||
private static int WAIT_TIMEOUT = 1000;
|
||||
private static int refCount = 0;
|
||||
|
||||
private final ChannelExec fChannel;
|
||||
private final Channel fChannel;
|
||||
private final IRemoteProcess fProcess;
|
||||
|
||||
private InputStream fProcStdout;
|
||||
|
@ -127,14 +129,14 @@ public class JSchProcess implements IRemoteProcessControlService, IRemoteProcess
|
|||
fProcStdout = new PipedInputStream(pipedOutput);
|
||||
fProcStderr = new NullInputStream();
|
||||
|
||||
fStderrReader = new Thread(new ProcReader(fChannel.getErrStream(), pipedOutput));
|
||||
fStderrReader = new Thread(new ProcReader(fChannel.getExtInputStream(), pipedOutput));
|
||||
fStdoutReader = new Thread(new ProcReader(fChannel.getInputStream(), pipedOutput));
|
||||
|
||||
fStderrReader.start();
|
||||
fStdoutReader.start();
|
||||
} else {
|
||||
fProcStdout = fChannel.getInputStream();
|
||||
fProcStderr = fChannel.getErrStream();
|
||||
fProcStderr = fChannel.getExtInputStream();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Activator.log(e);
|
||||
|
@ -237,7 +239,11 @@ public class JSchProcess implements IRemoteProcessControlService, IRemoteProcess
|
|||
*/
|
||||
@Override
|
||||
public void setTerminalSize(int cols, int rows, int width, int height) {
|
||||
fChannel.setPtySize(cols, rows, width, height);
|
||||
if (fChannel instanceof ChannelExec) {
|
||||
((ChannelExec) fChannel).setPtySize(cols, rows, width, height);
|
||||
} else if (fChannel instanceof ChannelShell) {
|
||||
((ChannelShell) fChannel).setPtySize(cols, rows, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -32,7 +32,9 @@ import org.eclipse.remote.internal.core.RemoteDebugOptions;
|
|||
import org.eclipse.remote.internal.core.RemoteProcess;
|
||||
import org.eclipse.remote.internal.jsch.core.messages.Messages;
|
||||
|
||||
import com.jcraft.jsch.Channel;
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.ChannelShell;
|
||||
import com.jcraft.jsch.JSchException;
|
||||
|
||||
public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
|
||||
|
@ -41,7 +43,7 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
|
|||
private final Map<String, String> fRemoteEnv = new HashMap<String, String>();
|
||||
private final Set<Character> charSet = new HashSet<Character>();
|
||||
|
||||
private ChannelExec fChannel;
|
||||
private Channel fChannel;
|
||||
private Map<String, String> fNewRemoteEnv;
|
||||
private boolean fPreamble = true;
|
||||
|
||||
|
@ -64,6 +66,10 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
|
|||
this(connection, Arrays.asList(command));
|
||||
}
|
||||
|
||||
public JSchProcessBuilder(IRemoteConnection connection) {
|
||||
this(connection, "shell"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFileStore directory() {
|
||||
IFileStore dir = super.directory();
|
||||
|
@ -155,13 +161,19 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
|
|||
}
|
||||
|
||||
try {
|
||||
fChannel = fConnection.getExecChannel();
|
||||
String command = buildCommand(remoteCmd, env, clearEnv);
|
||||
fChannel.setCommand(command);
|
||||
fChannel.setPty((flags & ALLOCATE_PTY) == ALLOCATE_PTY);
|
||||
if (cmdArgs.size() == 1 && cmdArgs.get(0).equals("shell")) { //$NON-NLS-1$
|
||||
fChannel = fConnection.getShellChannel();
|
||||
((ChannelShell) fChannel).setPty((flags & ALLOCATE_PTY) == ALLOCATE_PTY);
|
||||
RemoteDebugOptions.trace(RemoteDebugOptions.DEBUG_REMOTE_COMMANDS, "executing command: shell"); //$NON-NLS-1$
|
||||
} else {
|
||||
fChannel = fConnection.getExecChannel();
|
||||
String command = buildCommand(remoteCmd, env, clearEnv);
|
||||
((ChannelExec) fChannel).setCommand(command);
|
||||
((ChannelExec) fChannel).setPty((flags & ALLOCATE_PTY) == ALLOCATE_PTY);
|
||||
RemoteDebugOptions.trace(RemoteDebugOptions.DEBUG_REMOTE_COMMANDS, "executing command: " + command); //$NON-NLS-1$
|
||||
}
|
||||
fChannel.setXForwarding((flags & FORWARD_X11) == FORWARD_X11);
|
||||
fChannel.connect();
|
||||
RemoteDebugOptions.trace(RemoteDebugOptions.DEBUG_REMOTE_COMMANDS, "executing command: " + command); //$NON-NLS-1$
|
||||
return new RemoteProcess(getRemoteConnection(), this);
|
||||
} catch (RemoteConnectionException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
|
@ -170,7 +182,7 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
public ChannelExec getChannel() {
|
||||
public Channel getChannel() {
|
||||
return fChannel;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue