1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-04 07:35:24 +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.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.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.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
@ -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.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.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.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

View file

@ -14,12 +14,17 @@
* Sheldon D'souza (Celunite) - [186536] login and password should be configurable
* Sheldon D'souza (Celunite) - [186570] handle invalid user id and password more gracefully
* 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;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
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.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_CONNECT_TIMEOUT = 60; //seconds - TODO: Make configurable
private TelnetClient fTelnetClient = new TelnetClient();
private List fTelnetClients = new ArrayList();
private SessionLostHandler fSessionLostHandler;
private InputStream in;
private PrintStream out;
@ -109,6 +114,27 @@ public class TelnetConnectorService extends StandardConnectorService implements
}
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 user = getUserId();
String password = ""; //$NON-NLS-1$
@ -116,14 +142,14 @@ public class TelnetConnectorService extends StandardConnectorService implements
Exception nestedException = null;
try {
Activator.trace("Telnet Service: Connecting....."); //$NON-NLS-1$
fTelnetClient.connect(host, TELNET_DEFAULT_PORT);
client.connect(host, TELNET_DEFAULT_PORT);
SystemSignonInformation ssi = getSignonInformation();
if (ssi != null) {
password = ssi.getPassword();
}
in = fTelnetClient.getInputStream();
out = new PrintStream(fTelnetClient.getOutputStream());
in = client.getInputStream();
out = new PrintStream(client.getOutputStream());
long millisToEnd = System.currentTimeMillis() + TELNET_CONNECT_TIMEOUT*1000;
LoginThread checkLogin = new LoginThread(user, password);
@ -156,10 +182,13 @@ public class TelnetConnectorService extends StandardConnectorService implements
} finally {
if (status == CONNECT_CANCELED) {
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) {
fSessionLostHandler = new SessionLostHandler(this);
notifyConnection();
Activator.trace("Telnet Service: Connected"); //$NON-NLS-1$
} else {
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.makeSubstitution(getHost().getAliasName());
}
internalDisconnect(null);
throw new SystemMessageException(msg);
}
}
return client;
}
/**
@ -185,18 +214,20 @@ public class TelnetConnectorService extends StandardConnectorService implements
*/
private synchronized void sessionDisconnect() {
Activator.trace("TelnetConnectorService.sessionDisconnect"); //$NON-NLS-1$
try {
if (fTelnetClient != null) {
synchronized (fTelnetClient) {
if (fTelnetClient.isConnected())
fTelnetClient.disconnect();
Iterator it = fTelnetClients.iterator();
while (it.hasNext()) {
TelnetClient client = (TelnetClient)it.next();
if (client.isConnected()) {
try {
client.disconnect();
} catch(IOException e) {
// Avoid NPE on disconnect shown in UI
// This is a non-critical exception so print only in debug mode
if (Activator.isTracingOn())
e.printStackTrace();
}
}
} catch (Exception e) {
// Avoid NPE on disconnect shown in UI
// This is a non-critical exception so print only in debug mode
if (Activator.isTracingOn())
e.printStackTrace();
it.remove();
}
}
@ -267,10 +298,6 @@ public class TelnetConnectorService extends StandardConnectorService implements
notifyDisconnection();
}
public TelnetClient getTelnetClient() {
return fTelnetClient;
}
/**
* Handle session-lost events. This is generic for any sort of connector
* 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() {
Display display = Display.getCurrent();
if (display == null) {
@ -535,17 +550,23 @@ public class TelnetConnectorService extends StandardConnectorService implements
}
public boolean isConnected() {
boolean connected = false;
if (fTelnetClient != null) {
synchronized (fTelnetClient) {
connected = fTelnetClient.isConnected();
boolean anyConnected = false;
synchronized(this) {
Iterator it = fTelnetClients.iterator();
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$
fSessionLostHandler.sessionLost();
}
return connected;
return anyConnected;
}
/**

View file

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