1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-15 04:55:22 +02:00

[187301] support multiple telnet shells

This commit is contained in:
Martin Oberhuber 2007-06-27 08:24:08 +00:00
parent 55f2d9b0d0
commit d2d6658cb8
4 changed files with 89 additions and 57 deletions

View file

@ -16,7 +16,7 @@ plugin@org.eclipse.rse=v20070605,:pserver:anonymous:none@dev.eclipse.org:/cvsroo
plugin@org.eclipse.rse.connectorservice.dstore=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.dstore plugin@org.eclipse.rse.connectorservice.dstore=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.dstore
plugin@org.eclipse.rse.connectorservice.local=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.local plugin@org.eclipse.rse.connectorservice.local=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.local
plugin@org.eclipse.rse.connectorservice.ssh=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.ssh plugin@org.eclipse.rse.connectorservice.ssh=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.ssh
plugin@org.eclipse.rse.connectorservice.telnet=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.telnet plugin@org.eclipse.rse.connectorservice.telnet=v20070627,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.connectorservice.telnet
plugin@org.eclipse.rse.core=v20070620,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.core plugin@org.eclipse.rse.core=v20070620,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.core
plugin@org.eclipse.rse.doc.isv=v20070620,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/doc/org.eclipse.rse.doc.isv plugin@org.eclipse.rse.doc.isv=v20070620,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/doc/org.eclipse.rse.doc.isv
plugin@org.eclipse.rse.doc.user=v20070620a,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/doc/org.eclipse.rse.doc.user plugin@org.eclipse.rse.doc.user=v20070620a,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/doc/org.eclipse.rse.doc.user
@ -34,7 +34,7 @@ plugin@org.eclipse.rse.services.dstore=v20070614,:pserver:anonymous:none@dev.ecl
plugin@org.eclipse.rse.services.files.ftp=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.files.ftp plugin@org.eclipse.rse.services.files.ftp=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.files.ftp
plugin@org.eclipse.rse.services.local=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.local plugin@org.eclipse.rse.services.local=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.local
plugin@org.eclipse.rse.services.ssh=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.ssh plugin@org.eclipse.rse.services.ssh=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.ssh
plugin@org.eclipse.rse.services.telnet=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.telnet plugin@org.eclipse.rse.services.telnet=v20070627,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.telnet
plugin@org.eclipse.rse.services=v20070605,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services plugin@org.eclipse.rse.services=v20070605,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services
plugin@org.eclipse.rse.shells.ui=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.shells.ui plugin@org.eclipse.rse.shells.ui=v20070606,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.shells.ui
plugin@org.eclipse.rse.subsystems.files.core=v20070609,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.subsystems.files.core plugin@org.eclipse.rse.subsystems.files.core=v20070609,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.subsystems.files.core

View file

@ -14,12 +14,17 @@
* Sheldon D'souza (Celunite) - [186536] login and password should be configurable * Sheldon D'souza (Celunite) - [186536] login and password should be configurable
* Sheldon D'souza (Celunite) - [186570] handle invalid user id and password more gracefully * Sheldon D'souza (Celunite) - [186570] handle invalid user id and password more gracefully
* Martin Oberhuber (Wind River) - [187218] Fix error reporting for connect() * Martin Oberhuber (Wind River) - [187218] Fix error reporting for connect()
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
*******************************************************************************/ *******************************************************************************/
package org.eclipse.rse.internal.connectorservice.telnet; package org.eclipse.rse.internal.connectorservice.telnet;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.net.telnet.TelnetClient; import org.apache.commons.net.telnet.TelnetClient;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
@ -60,7 +65,7 @@ public class TelnetConnectorService extends StandardConnectorService implements
private static final int TELNET_DEFAULT_PORT = 23; // TODO Make configurable private static final int TELNET_DEFAULT_PORT = 23; // TODO Make configurable
private static final int TELNET_CONNECT_TIMEOUT = 60; //seconds - TODO: Make configurable private static final int TELNET_CONNECT_TIMEOUT = 60; //seconds - TODO: Make configurable
private TelnetClient fTelnetClient = new TelnetClient(); private List fTelnetClients = new ArrayList();
private SessionLostHandler fSessionLostHandler; private SessionLostHandler fSessionLostHandler;
private InputStream in; private InputStream in;
private PrintStream out; private PrintStream out;
@ -109,6 +114,27 @@ public class TelnetConnectorService extends StandardConnectorService implements
} }
protected void internalConnect(IProgressMonitor monitor) throws Exception { protected void internalConnect(IProgressMonitor monitor) throws Exception {
try {
TelnetClient client = makeNewTelnetClient(monitor);
if( client != null ) {
synchronized(this) {
fTelnetClients.add(client);
if (fSessionLostHandler==null) {
fSessionLostHandler = new SessionLostHandler(this);
}
}
notifyConnection();
}
}catch( Exception e) {
if( e instanceof SystemMessageException ) {
internalDisconnect( null );
throw e;
}
}
}
public TelnetClient makeNewTelnetClient( IProgressMonitor monitor ) throws Exception {
TelnetClient client = new TelnetClient();
String host = getHostName(); String host = getHostName();
String user = getUserId(); String user = getUserId();
String password = ""; //$NON-NLS-1$ String password = ""; //$NON-NLS-1$
@ -116,14 +142,14 @@ public class TelnetConnectorService extends StandardConnectorService implements
Exception nestedException = null; Exception nestedException = null;
try { try {
Activator.trace("Telnet Service: Connecting....."); //$NON-NLS-1$ Activator.trace("Telnet Service: Connecting....."); //$NON-NLS-1$
fTelnetClient.connect(host, TELNET_DEFAULT_PORT); client.connect(host, TELNET_DEFAULT_PORT);
SystemSignonInformation ssi = getSignonInformation(); SystemSignonInformation ssi = getSignonInformation();
if (ssi != null) { if (ssi != null) {
password = ssi.getPassword(); password = ssi.getPassword();
} }
in = fTelnetClient.getInputStream(); in = client.getInputStream();
out = new PrintStream(fTelnetClient.getOutputStream()); out = new PrintStream(client.getOutputStream());
long millisToEnd = System.currentTimeMillis() + TELNET_CONNECT_TIMEOUT*1000; long millisToEnd = System.currentTimeMillis() + TELNET_CONNECT_TIMEOUT*1000;
LoginThread checkLogin = new LoginThread(user, password); LoginThread checkLogin = new LoginThread(user, password);
@ -156,10 +182,13 @@ public class TelnetConnectorService extends StandardConnectorService implements
} finally { } finally {
if (status == CONNECT_CANCELED) { if (status == CONNECT_CANCELED) {
Activator.trace("Telnet Service: Canceled"); //$NON-NLS-1$ Activator.trace("Telnet Service: Canceled"); //$NON-NLS-1$
sessionDisconnect(); //will eventually destroy the LoginThread try {
client.disconnect(); //will eventually destroy the LoginThread
} catch(Exception e) {
/*ignore on forced disconnect*/
}
client = null;
} else if (status == SUCCESS_CODE) { } else if (status == SUCCESS_CODE) {
fSessionLostHandler = new SessionLostHandler(this);
notifyConnection();
Activator.trace("Telnet Service: Connected"); //$NON-NLS-1$ Activator.trace("Telnet Service: Connected"); //$NON-NLS-1$
} else { } else {
Activator.trace("Telnet Service: Connect failed"); //$NON-NLS-1$ Activator.trace("Telnet Service: Connect failed"); //$NON-NLS-1$
@ -173,10 +202,10 @@ public class TelnetConnectorService extends StandardConnectorService implements
msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_COMM_AUTH_FAILED); msg = RSEUIPlugin.getPluginMessage(ISystemMessages.MSG_COMM_AUTH_FAILED);
msg.makeSubstitution(getHost().getAliasName()); msg.makeSubstitution(getHost().getAliasName());
} }
internalDisconnect(null);
throw new SystemMessageException(msg); throw new SystemMessageException(msg);
} }
} }
return client;
} }
/** /**
@ -185,20 +214,22 @@ public class TelnetConnectorService extends StandardConnectorService implements
*/ */
private synchronized void sessionDisconnect() { private synchronized void sessionDisconnect() {
Activator.trace("TelnetConnectorService.sessionDisconnect"); //$NON-NLS-1$ Activator.trace("TelnetConnectorService.sessionDisconnect"); //$NON-NLS-1$
Iterator it = fTelnetClients.iterator();
while (it.hasNext()) {
TelnetClient client = (TelnetClient)it.next();
if (client.isConnected()) {
try { try {
if (fTelnetClient != null) { client.disconnect();
synchronized (fTelnetClient) { } catch(IOException e) {
if (fTelnetClient.isConnected())
fTelnetClient.disconnect();
}
}
} catch (Exception e) {
// Avoid NPE on disconnect shown in UI // Avoid NPE on disconnect shown in UI
// This is a non-critical exception so print only in debug mode // This is a non-critical exception so print only in debug mode
if (Activator.isTracingOn()) if (Activator.isTracingOn())
e.printStackTrace(); e.printStackTrace();
} }
} }
it.remove();
}
}
public int readUntil(String pattern) { public int readUntil(String pattern) {
try { try {
@ -267,10 +298,6 @@ public class TelnetConnectorService extends StandardConnectorService implements
notifyDisconnection(); notifyDisconnection();
} }
public TelnetClient getTelnetClient() {
return fTelnetClient;
}
/** /**
* Handle session-lost events. This is generic for any sort of connector * Handle session-lost events. This is generic for any sort of connector
* service. Most of this is extracted from dstore's * service. Most of this is extracted from dstore's
@ -514,18 +541,6 @@ public class TelnetConnectorService extends StandardConnectorService implements
} }
} }
/*
* Notification from sub-services that our session was lost. Notify all
* subsystems properly.
* TODO allow user to try and reconnect?
*/
public void handleSessionLost() {
Activator.trace("TelnetConnectorService: handleSessionLost"); //$NON-NLS-1$
if (fSessionLostHandler != null) {
fSessionLostHandler.sessionLost();
}
}
protected static Display getStandardDisplay() { protected static Display getStandardDisplay() {
Display display = Display.getCurrent(); Display display = Display.getCurrent();
if (display == null) { if (display == null) {
@ -535,17 +550,23 @@ public class TelnetConnectorService extends StandardConnectorService implements
} }
public boolean isConnected() { public boolean isConnected() {
boolean connected = false; boolean anyConnected = false;
if (fTelnetClient != null) { synchronized(this) {
synchronized (fTelnetClient) { Iterator it = fTelnetClients.iterator();
connected = fTelnetClient.isConnected(); while (it.hasNext()) {
TelnetClient client = (TelnetClient)it.next();
if (client.isConnected()) {
anyConnected = true;
} else {
it.remove();
} }
} }
if (!connected && fSessionLostHandler != null) { }
if (!anyConnected && fSessionLostHandler != null) {
Activator.trace("TelnetConnectorService.isConnected: false -> sessionLost"); //$NON-NLS-1$ Activator.trace("TelnetConnectorService.isConnected: false -> sessionLost"); //$NON-NLS-1$
fSessionLostHandler.sessionLost(); fSessionLostHandler.sessionLost();
} }
return connected; return anyConnected;
} }
/** /**

View file

@ -13,15 +13,21 @@
* *
* Contributors: * Contributors:
* Sheldon D'souza (Celunite) - adapted from ISshSessionProvider * Sheldon D'souza (Celunite) - adapted from ISshSessionProvider
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
*******************************************************************************/ *******************************************************************************/
package org.eclipse.rse.internal.services.telnet; package org.eclipse.rse.internal.services.telnet;
import org.apache.commons.net.telnet.TelnetClient; import org.apache.commons.net.telnet.TelnetClient;
import org.eclipse.core.runtime.IProgressMonitor;
public interface ITelnetSessionProvider { public interface ITelnetSessionProvider {
public TelnetClient getTelnetClient(); /**
* Create a new Commons.Net TelnetClient.
* @param monitor progress monitor
* @return a new Commons.Net TelnetClient for the given connection, already authenticated
* @throws Exception in case of any error
*/
public TelnetClient makeNewTelnetClient(IProgressMonitor monitor) throws Exception ;
/* Inform the connectorService that a session has been lost. */
public void handleSessionLost();
} }

View file

@ -14,6 +14,7 @@
* Contributors: * Contributors:
* Martin Oberhuber (Wind River) - Adapted from LocalHostShell. * Martin Oberhuber (Wind River) - Adapted from LocalHostShell.
* Sheldon D'souza (Celunite) - Adapted from SshHostShell * Sheldon D'souza (Celunite) - Adapted from SshHostShell
* Sheldon D'souza (Celunite) - [187301] support multiple telnet shells
*******************************************************************************/ *******************************************************************************/
package org.eclipse.rse.internal.services.telnet.shell; package org.eclipse.rse.internal.services.telnet.shell;
@ -25,6 +26,7 @@ import java.io.PrintWriter;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.net.telnet.TelnetClient; import org.apache.commons.net.telnet.TelnetClient;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider; import org.eclipse.rse.internal.services.telnet.ITelnetSessionProvider;
import org.eclipse.rse.services.clientserver.PathUtility; import org.eclipse.rse.services.clientserver.PathUtility;
import org.eclipse.rse.services.shells.AbstractHostShell; import org.eclipse.rse.services.shells.AbstractHostShell;
@ -39,15 +41,17 @@ public class TelnetHostShell extends AbstractHostShell implements IHostShell {
private TelnetShellOutputReader fStdoutHandler; private TelnetShellOutputReader fStdoutHandler;
private TelnetShellOutputReader fStderrHandler; private TelnetShellOutputReader fStderrHandler;
private TelnetShellWriterThread fShellWriter; private TelnetShellWriterThread fShellWriter;
private TelnetClient fTelnetClient;
public TelnetHostShell(ITelnetSessionProvider sessionProvider, String initialWorkingDirectory, String commandToRun, String encoding, String[] environment) { public TelnetHostShell(ITelnetSessionProvider sessionProvider, String initialWorkingDirectory, String commandToRun, String encoding, String[] environment) {
try { try {
fSessionProvider = sessionProvider; fSessionProvider = sessionProvider;
fTelnetClient = fSessionProvider.makeNewTelnetClient(new NullProgressMonitor());
fStdoutHandler = new TelnetShellOutputReader(this, new BufferedReader(new InputStreamReader(sessionProvider.getTelnetClient().getInputStream())), false); fStdoutHandler = new TelnetShellOutputReader(this, new BufferedReader(new InputStreamReader(fTelnetClient.getInputStream())), false);
fStderrHandler = new TelnetShellOutputReader(this, null,true); fStderrHandler = new TelnetShellOutputReader(this, null,true);
OutputStream outputStream = sessionProvider.getTelnetClient().getOutputStream(); OutputStream outputStream = fTelnetClient.getOutputStream();
//TODO check if encoding or command to execute needs to be considered //TODO check if encoding or command to execute needs to be considered
//If a command is given, it might be possible to do without a Thread //If a command is given, it might be possible to do without a Thread
//Charset cs = Charset.forName(encoding); //Charset cs = Charset.forName(encoding);
@ -85,11 +89,10 @@ public class TelnetHostShell extends AbstractHostShell implements IHostShell {
try { try {
//TODO disconnect should better be done via the ConnectorService!! //TODO disconnect should better be done via the ConnectorService!!
//Because like we do it here, the connector service is not notified! //Because like we do it here, the connector service is not notified!
TelnetClient client = fSessionProvider.getTelnetClient(); if (fTelnetClient!=null) {
if (client!=null) { synchronized(fTelnetClient) {
synchronized(client) { if (fTelnetClient.isConnected())
if (client.isConnected()) fTelnetClient.disconnect();
client.disconnect();
} }
} }
} catch (IOException e) { } catch (IOException e) {
@ -106,16 +109,18 @@ public class TelnetHostShell extends AbstractHostShell implements IHostShell {
} }
public boolean isActive() { public boolean isActive() {
TelnetClient client = fSessionProvider.getTelnetClient(); if (fTelnetClient!=null && fTelnetClient.isConnected()) {
if (client!=null ) {
return true; return true;
} }
// shell is not active: check for session lost // shell is not active: check for session lost
exit(); exit();
if (client!=null && !client.isConnected()) { ////MOB: Telnet sessions are really independent of each other.
fSessionProvider.handleSessionLost(); ////So if one telnet session disconnects, it must not disconnect
} ////the other sessions.
//if (fTelnetClient!=null && !fTelnetClient.isConnected()) {
// fSessionProvider.handleSessionLost();
//}
return false; return false;
} }