| /******************************************************************************* |
| * Copyright (c) 2010, 2017 SAP AG and others |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * 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(); |
| } |
| } |