Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: af46bd2851db7c924811cd4dde8398d0a11646b5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*******************************************************************************
 * Copyright (c) 2010, 2017 SAP AG 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:
 *     Lazar Kirchev, SAP AG - initial API and implementation  
 *     IBM Corporation - ongoing development
 *******************************************************************************/
package org.eclipse.equinox.console.telnet;

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.CommandSession;
import java.io.Closeable;

import org.eclipse.equinox.console.common.ConsoleInputHandler;
import org.eclipse.equinox.console.common.ConsoleInputScanner;
import org.eclipse.equinox.console.common.ConsoleInputStream;
import org.osgi.framework.BundleContext;

/**
 * This class manages a telnet connection. It is responsible for wrapping the original io streams
 * from the socket, and starting a CommandSession to execute commands from the telnet.
 *
 */
public class TelnetConnection extends Thread implements Closeable {
	
	private Socket socket;
	private CommandProcessor processor;
	private BundleContext context;
	protected boolean isTelnetNegotiationFinished = false;
    private Callback callback;
    private static final long TIMEOUT = 1000;
    private static final long NEGOTIATION_TIMEOUT = 60000;
    private static final String PROMPT = "prompt";
    private static final String OSGI_PROMPT = "osgi> ";
    private static final String SCOPE = "SCOPE";
    private static final String EQUINOX_SCOPE = "equinox:*";
    private static final String CLOSEABLE = "CLOSEABLE";
	
	public TelnetConnection (Socket socket, CommandProcessor processor, BundleContext context) {
		this.socket = socket;
		this.processor = processor;
		this.context = context;
		callback = new NegotiationFinishedCallback(this);
	}
	
	@Override
	public void run() {
		try {
			ConsoleInputStream in = new ConsoleInputStream();
			TelnetOutputStream out = new TelnetOutputStream(socket.getOutputStream());
			out.autoSend();
			TelnetInputHandler telnetInputHandler = new TelnetInputHandler(socket.getInputStream(), in, out, callback);
			telnetInputHandler.start();
			
			long start = System.currentTimeMillis();
			
			synchronized (this) {
				while (isTelnetNegotiationFinished == false && System.currentTimeMillis() - start < NEGOTIATION_TIMEOUT) {
					try {
						wait(TIMEOUT);
					} catch (InterruptedException e) {
						// do nothing
					}
				}
			}
			final CommandSession session;
			PrintStream output = new PrintStream(out);
			
			ConsoleInputStream inp = new ConsoleInputStream();
			
	        ConsoleInputHandler consoleInputHandler = new ConsoleInputHandler(in, inp, out);
	        consoleInputHandler.getScanner().setBackspace(telnetInputHandler.getScanner().getBackspace());
	        consoleInputHandler.getScanner().setDel(telnetInputHandler.getScanner().getDel());
	        consoleInputHandler.getScanner().setCurrentEscapesToKey(telnetInputHandler.getScanner().getCurrentEscapesToKey());
	        consoleInputHandler.getScanner().setEscapes(telnetInputHandler.getScanner().getEscapes());
	        ((ConsoleInputScanner)consoleInputHandler.getScanner()).setContext(context);
	        
	        consoleInputHandler.start();
	        
	        session = processor.createSession(inp, output, output);
	        session.put(SCOPE, EQUINOX_SCOPE);
	        session.put(PROMPT, OSGI_PROMPT);
	        // Store this closeable object in the session, so that the disconnect command can close it
	        session.put(CLOSEABLE, this);
	        ((ConsoleInputScanner)consoleInputHandler.getScanner()).setSession(session);
	        
			try {
	            session.execute("gosh --login --noshutdown");
	        } catch (Exception e) {
	            e.printStackTrace();
	        } finally {
	            session.close();
	            try {
	                socket.close();
	            }
	            catch (IOException e) {
	            	// do nothing
	            }
	        }
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void close() {
		try {
			this.interrupt();
			socket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public synchronized void telnetNegotiationFinished() {
		isTelnetNegotiationFinished = true;
		notify();
	}
}

Back to the top