1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 09:46:02 +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:
Matthew Bastien 2015-04-22 13:54:18 -04:00
parent 6ee3aff83b
commit efeb6fc7bb
6 changed files with 104 additions and 12 deletions

View file

@ -164,7 +164,7 @@ public class RemoteServicesManager implements IRemoteServicesManager {
List<IRemoteConnectionType> connTypes = new ArrayList<IRemoteConnectionType>(); List<IRemoteConnectionType> connTypes = new ArrayList<IRemoteConnectionType>();
for (IRemoteConnectionType connType : getAllConnectionTypes()) { for (IRemoteConnectionType connType : getAllConnectionTypes()) {
for (Class<? extends IRemoteConnection.Service> service : services) { for (Class<? extends IRemoteConnection.Service> service : services) {
if (!connType.hasConnectionService(service)) { if (connType.hasConnectionService(service)) {
connTypes.add(connType); connTypes.add(connType);
break; break;
} }

View file

@ -44,6 +44,11 @@
factory="org.eclipse.remote.internal.jsch.core.JSchConnection$Factory" factory="org.eclipse.remote.internal.jsch.core.JSchConnection$Factory"
service="org.eclipse.remote.internal.jsch.core.JSchConnection"> service="org.eclipse.remote.internal.jsch.core.JSchConnection">
</connectionService> </connectionService>
<connectionService
connectionTypeId="org.eclipse.remote.JSch"
factory="org.eclipse.remote.internal.jsch.core.JSchCommandShellService$Factory"
service="org.eclipse.remote.core.IRemoteCommandShellService">
</connectionService>
<processService <processService
connectionTypeId="org.eclipse.remote.JSch" connectionTypeId="org.eclipse.remote.JSch"
factory="org.eclipse.remote.internal.jsch.core.JSchProcess$Factory" factory="org.eclipse.remote.internal.jsch.core.JSchProcess$Factory"

View file

@ -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;
}
}
}

View file

@ -42,6 +42,7 @@ import org.eclipse.remote.internal.jsch.core.messages.Messages;
import com.jcraft.jsch.Channel; import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelSftp; import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSchException; import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session; import com.jcraft.jsch.Session;
import com.jcraft.jsch.UIKeyboardInteractive; 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() { public String getPassphrase() {
return fRemoteConnection.getSecureAttribute(PASSPHRASE_ATTR); return fRemoteConnection.getSecureAttribute(PASSPHRASE_ATTR);
} }

View file

@ -22,7 +22,9 @@ import org.eclipse.remote.core.IRemoteProcessSignalService;
import org.eclipse.remote.core.IRemoteProcessTerminalService; import org.eclipse.remote.core.IRemoteProcessTerminalService;
import org.eclipse.remote.core.exception.RemoteConnectionException; import org.eclipse.remote.core.exception.RemoteConnectionException;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelShell;
public class JSchProcess implements IRemoteProcessControlService, IRemoteProcessSignalService, IRemoteProcessTerminalService { public class JSchProcess implements IRemoteProcessControlService, IRemoteProcessSignalService, IRemoteProcessTerminalService {
@SuppressWarnings("nls") @SuppressWarnings("nls")
@ -32,7 +34,7 @@ public class JSchProcess implements IRemoteProcessControlService, IRemoteProcess
private static int WAIT_TIMEOUT = 1000; private static int WAIT_TIMEOUT = 1000;
private static int refCount = 0; private static int refCount = 0;
private final ChannelExec fChannel; private final Channel fChannel;
private final IRemoteProcess fProcess; private final IRemoteProcess fProcess;
private InputStream fProcStdout; private InputStream fProcStdout;
@ -127,14 +129,14 @@ public class JSchProcess implements IRemoteProcessControlService, IRemoteProcess
fProcStdout = new PipedInputStream(pipedOutput); fProcStdout = new PipedInputStream(pipedOutput);
fProcStderr = new NullInputStream(); 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)); fStdoutReader = new Thread(new ProcReader(fChannel.getInputStream(), pipedOutput));
fStderrReader.start(); fStderrReader.start();
fStdoutReader.start(); fStdoutReader.start();
} else { } else {
fProcStdout = fChannel.getInputStream(); fProcStdout = fChannel.getInputStream();
fProcStderr = fChannel.getErrStream(); fProcStderr = fChannel.getExtInputStream();
} }
} catch (IOException e) { } catch (IOException e) {
Activator.log(e); Activator.log(e);
@ -237,7 +239,11 @@ public class JSchProcess implements IRemoteProcessControlService, IRemoteProcess
*/ */
@Override @Override
public void setTerminalSize(int cols, int rows, int width, int height) { 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);
}
} }
/* /*

View file

@ -32,7 +32,9 @@ import org.eclipse.remote.internal.core.RemoteDebugOptions;
import org.eclipse.remote.internal.core.RemoteProcess; import org.eclipse.remote.internal.core.RemoteProcess;
import org.eclipse.remote.internal.jsch.core.messages.Messages; import org.eclipse.remote.internal.jsch.core.messages.Messages;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.ChannelShell;
import com.jcraft.jsch.JSchException; import com.jcraft.jsch.JSchException;
public class JSchProcessBuilder extends AbstractRemoteProcessBuilder { 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 Map<String, String> fRemoteEnv = new HashMap<String, String>();
private final Set<Character> charSet = new HashSet<Character>(); private final Set<Character> charSet = new HashSet<Character>();
private ChannelExec fChannel; private Channel fChannel;
private Map<String, String> fNewRemoteEnv; private Map<String, String> fNewRemoteEnv;
private boolean fPreamble = true; private boolean fPreamble = true;
@ -64,6 +66,10 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
this(connection, Arrays.asList(command)); this(connection, Arrays.asList(command));
} }
public JSchProcessBuilder(IRemoteConnection connection) {
this(connection, "shell"); //$NON-NLS-1$
}
@Override @Override
public IFileStore directory() { public IFileStore directory() {
IFileStore dir = super.directory(); IFileStore dir = super.directory();
@ -155,13 +161,19 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
} }
try { try {
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(); fChannel = fConnection.getExecChannel();
String command = buildCommand(remoteCmd, env, clearEnv); String command = buildCommand(remoteCmd, env, clearEnv);
fChannel.setCommand(command); ((ChannelExec) fChannel).setCommand(command);
fChannel.setPty((flags & ALLOCATE_PTY) == ALLOCATE_PTY); ((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.setXForwarding((flags & FORWARD_X11) == FORWARD_X11);
fChannel.connect(); fChannel.connect();
RemoteDebugOptions.trace(RemoteDebugOptions.DEBUG_REMOTE_COMMANDS, "executing command: " + command); //$NON-NLS-1$
return new RemoteProcess(getRemoteConnection(), this); return new RemoteProcess(getRemoteConnection(), this);
} catch (RemoteConnectionException e) { } catch (RemoteConnectionException e) {
throw new IOException(e.getMessage()); throw new IOException(e.getMessage());
@ -170,7 +182,7 @@ public class JSchProcessBuilder extends AbstractRemoteProcessBuilder {
} }
} }
public ChannelExec getChannel() { public Channel getChannel() {
return fChannel; return fChannel;
} }