blob: ed00228382b1af29fba4607e09da0f4225dd4a91 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2009 Boeing.
* 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:
* Boeing - initial API and implementation
*******************************************************************************/
package org.eclipse.osee.ote.core.test.shells;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.logging.Level;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TelnetNotificationHandler;
import org.apache.commons.net.telnet.TelnetOption;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
import org.eclipse.osee.framework.jdk.core.util.io.InputBufferThread;
import org.eclipse.osee.framework.logging.OseeLog;
import org.eclipse.osee.ote.core.environment.TestEnvironment;
/**
* Created on Aug 15, 2005
*/
public class TelnetShell implements TelnetNotificationHandler {
private static final int MAX_RESPONSE_TIME = 10000;
public final static class Piper extends Thread {
private final InputStream inStream;
private final OutputStream outStream;
public final ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
public Piper(InputStream in, OutputStream out) {
super("Stream Piper");
this.inStream = in;
this.outStream = out;
}
@Override
public void run() {
final ReadableByteChannel in = Channels.newChannel(inStream);
final WritableByteChannel out = Channels.newChannel(outStream);
try {
buffer.clear();
while (true) {
in.read(buffer);
buffer.flip();
out.write(buffer);
buffer.compact();
}
} catch (IOException e) {
e.printStackTrace(System.err);
}
}
}
private final TelnetClient telnet;
private final InputStream in;
private final OutputStream out;
private InputBufferThread inputBuffer;
private String prompt = "$ ";
private int currentOutput = 0;
/**
* Connects telnet to the specified ipAddress and port
*/
public TelnetShell(String ipAddress, int port) throws SocketException, IOException {
this(ipAddress, port, true);
}
public TelnetShell(String ipAddress, int port, boolean start) throws SocketException, IOException {
telnet = new TelnetClient();
telnet.registerNotifHandler(this);
SuppressGAOptionHandler sgaOpt = new SuppressGAOptionHandler(true, true, true, true);
TerminalTypeOptionHandler ttOpt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
EchoOptionHandler eOPt = new EchoOptionHandler(true, false, true, false);
try {
telnet.addOptionHandler(ttOpt);
telnet.addOptionHandler(sgaOpt);
telnet.addOptionHandler(eOPt);
} catch (InvalidTelnetOptionException e) {
throw new IllegalStateException("invalid telnet options", e);
}
telnet.connect(ipAddress, port);
try {
Thread.sleep(1500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
/*
* try { if (!telnet.sendAYT(5000)) { throw new SocketException("server appears to be in use"); } } catch
* (IllegalArgumentException ex) { ex.printStackTrace(); } catch (InterruptedException ex) { ex.printStackTrace();
* }
*/
//printOptionStates();
in = telnet.getInputStream();
out = telnet.getOutputStream();
if (start) {
inputBuffer = new InputBufferThread(in);
inputBuffer.start();
}
}
/**
* writes the command given to the output stream ( telnet )
*
* @param string The command to give
*/
public void write(String string) {
// currentOutput = inputBuffer.getLength() + string.length() + 1;
try {
for (byte b : string.getBytes("us-ascii")) {
out.write(b);
out.flush();
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
out.write(getNewline());
out.flush();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String writeAndGetPrompt(String string, int timeout) throws Exception {
inputBuffer.clear();
// currentOutput = inputBuffer.getLength() + string.length() + 1;
for (byte b : string.getBytes("us-ascii")) {
out.write(b);
out.flush();
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
out.write(getNewline());
out.flush();
Thread.sleep(timeout);
return inputBuffer.getBuffer();
}
/**
* Sits on the line, reading in characters, and waits for the expected output from telnet
*
* @param string The String this function will stop on and return
*/
public synchronized void waitFor(String string) throws InterruptedException {
if (inputBuffer.waitFor(string, true, MAX_RESPONSE_TIME) < 0) {
throw new InterruptedException(
"Waiting for '" + string + "' took longer then " + MAX_RESPONSE_TIME + " miliseconds.");
}
}
public synchronized MatchResult waitForPattern(Pattern pattern, int millis) throws InterruptedException {
MatchResult index = inputBuffer.waitFor(pattern, false, millis);
if (index == null) {
throw new InterruptedException(
"Waiting for '" + pattern.pattern() + "' took longer then " + millis + " miliseconds.");
}
return index;
}
public synchronized void waitForTransmission(int millis) throws InterruptedException {
if (!inputBuffer.waitFor(millis)) {
throw new InterruptedException("Waiting for transmission took longer then " + millis + " miliseconds.");
}
}
public synchronized String getBuffer(int start, int end) {
return inputBuffer.subString(start, end);
}
public synchronized String captureTo(String string) throws InterruptedException {
int index = inputBuffer.waitFor(string, false, MAX_RESPONSE_TIME);
if (index < 0) {
throw new InterruptedException(
"Waiting for '" + string + "' took longer then " + MAX_RESPONSE_TIME + " miliseconds.");
}
return inputBuffer.subString(0, index);
}
/**
* Writes the command to telnet and waits for the normal command prompt
*
* @param string The command to issue
*/
public void sendCommand(String string) throws InterruptedException {
currentOutput = inputBuffer.getLength() + string.length() + 1;
write(string);
waitFor(prompt);
}
/**
* disconnects from telnet
*/
public void disconnect() {
try {
try {
inputBuffer.stopNow();
} finally {
telnet.disconnect();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter host name or ip address (#.#.#.#))");
String host = reader.readLine();
System.out.println("Enter port");
String string = reader.readLine();
if (string == null) {
return;
}
int port = Integer.parseInt(string);
TelnetShell shell = new TelnetShell(host, port, false);
Piper piper = new Piper(shell.in, System.out);
piper.start();
try {
boolean done = false;
while (!done) {
String in = reader.readLine();
if (in.equals("quit")) {
done = true;
} else {
shell.write(in);
}
}
shell.disconnect();
} finally {
piper.interrupt();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
public String getBuffer() {
return inputBuffer.getBuffer();
}
public String getCurrentBuffer() {
try {
inputBuffer.waitFor(MAX_RESPONSE_TIME);
} catch (InterruptedException e) {
OseeLog.log(TestEnvironment.class, Level.SEVERE, e.getMessage(), e);
}
return inputBuffer.subString(currentOutput);
}
public InputStream getInputStream() {
return in;
}
public TelnetClient getTelnet() {
return telnet;
}
public void clearBuffer() {
inputBuffer.clear();
}
@Override
public void receivedNegotiation(int negotiationCode, int option) {
final String negotiationCodeStr;
switch (negotiationCode) {
case TelnetNotificationHandler.RECEIVED_DO:
negotiationCodeStr = "DO";
break;
case TelnetNotificationHandler.RECEIVED_DONT:
negotiationCodeStr = "DONT";
break;
case TelnetNotificationHandler.RECEIVED_WILL:
negotiationCodeStr = "WILL";
break;
case TelnetNotificationHandler.RECEIVED_WONT:
negotiationCodeStr = "WONT";
break;
default:
throw new Error("unhandled negotiation code of " + negotiationCode);
}
System.out.printf("Negotiation recieved: %s for option %s\n", negotiationCodeStr, TelnetOption.getOption(option));
}
public void printOptionStates() {
for (int i = 0; i < TelnetOption.MAX_OPTION_VALUE; i++) {
String str = TelnetOption.getOption(i);
if (!str.equals("UNASSIGNED")) {
boolean local = telnet.getLocalOptionState(i);
boolean remote = telnet.getRemoteOptionState(i);
if (local || remote) {
System.out.printf("%s (%02d): local %b, remote %b\n", TelnetOption.getOption(i), i, local, remote);
}
}
}
}
private byte[] getNewline() throws UnsupportedEncodingException {
return "\n".getBytes("US-ASCII");
}
}