From 388854b81cdf58a11b509ba41954fbb2a75f1090 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Fri, 2 Nov 2018 01:06:02 +0800 Subject: [PATCH 1/2] refactor TelnetConsole to support pure java telnet client. #272 --- client/pom.xml | 7 +- .../java/com/taobao/arthas/client/IOUtil.java | 72 +++ .../com/taobao/arthas/client/OSUtils.java | 13 + .../taobao/arthas/client/TelnetConsole.java | 514 +++++++++++------- 4 files changed, 408 insertions(+), 198 deletions(-) create mode 100644 client/src/main/java/com/taobao/arthas/client/IOUtil.java create mode 100644 client/src/main/java/com/taobao/arthas/client/OSUtils.java diff --git a/client/pom.xml b/client/pom.xml index d5bbbff44..efc7e16e8 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -56,6 +56,11 @@ com.alibaba.middleware cli + + jline + jline + 2.14.6 + - \ No newline at end of file + diff --git a/client/src/main/java/com/taobao/arthas/client/IOUtil.java b/client/src/main/java/com/taobao/arthas/client/IOUtil.java new file mode 100644 index 000000000..13cb46899 --- /dev/null +++ b/client/src/main/java/com/taobao/arthas/client/IOUtil.java @@ -0,0 +1,72 @@ +package com.taobao.arthas.client; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; + +/*** + * This is a utility class providing a reader/writer capability required by the + * weatherTelnet, rexec, rshell, and rlogin example programs. The only point of + * the class is to hold the static method readWrite which spawns a reader thread + * and a writer thread. The reader thread reads from a local input source + * (presumably stdin) and writes the data to a remote output destination. The + * writer thread reads from a remote input source and writes to a local output + * destination. The threads terminate when the remote input source closes. + ***/ + +public final class IOUtil { + + public static final void readWrite(final InputStream remoteInput, final OutputStream remoteOutput, + final InputStream localInput, final Writer localOutput) { + Thread reader, writer; + + reader = new Thread() { + @Override + public void run() { + int ch; + + try { + while (!interrupted() && (ch = localInput.read()) != -1) { + remoteOutput.write(ch); + remoteOutput.flush(); + } + } catch (IOException e) { + // e.printStackTrace(); + } + } + }; + + writer = new Thread() { + @Override + public void run() { + try { + while (true) { + int singleByte = remoteInput.read(); + if (singleByte < 0) { + break; + } + localOutput.write(singleByte); + localOutput.flush(); + } + } catch (IOException e) { + e.printStackTrace(); + System.exit(1); + } + } + }; + + writer.setPriority(Thread.currentThread().getPriority() + 1); + + writer.start(); + reader.setDaemon(true); + reader.start(); + + try { + writer.join(); + reader.interrupt(); + } catch (InterruptedException e) { + // Ignored + } + } + +} \ No newline at end of file diff --git a/client/src/main/java/com/taobao/arthas/client/OSUtils.java b/client/src/main/java/com/taobao/arthas/client/OSUtils.java new file mode 100644 index 000000000..3c6dbb384 --- /dev/null +++ b/client/src/main/java/com/taobao/arthas/client/OSUtils.java @@ -0,0 +1,13 @@ +package com.taobao.arthas.client; + +public class OSUtils { + + public static boolean isWindowsOS() { + boolean isWindowsOS = false; + String osName = System.getProperty("os.name"); + if (osName.toLowerCase().indexOf("windows") > -1) { + isWindowsOS = true; + } + return isWindowsOS; + } +} diff --git a/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java b/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java index e331f0dcc..6afe5746b 100644 --- a/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java +++ b/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java @@ -1,213 +1,333 @@ package com.taobao.arthas.client; -import com.taobao.middleware.cli.Argument; -import com.taobao.middleware.cli.CLI; -import com.taobao.middleware.cli.CLIs; -import com.taobao.middleware.cli.CommandLine; -import com.taobao.middleware.cli.Option; -import com.taobao.middleware.cli.TypedOption; -import org.apache.commons.net.telnet.TelnetClient; -import org.apache.commons.net.telnet.WindowSizeOptionHandler; - +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; -import java.io.PrintStream; +import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.apache.commons.net.telnet.InvalidTelnetOptionException; +import org.apache.commons.net.telnet.TelnetClient; +import org.apache.commons.net.telnet.TelnetOptionHandler; +import org.apache.commons.net.telnet.WindowSizeOptionHandler; + +import com.taobao.middleware.cli.CLI; +import com.taobao.middleware.cli.CLIException; +import com.taobao.middleware.cli.CommandLine; +import com.taobao.middleware.cli.UsageMessageFormatter; +import com.taobao.middleware.cli.annotations.Argument; +import com.taobao.middleware.cli.annotations.CLIConfigurator; +import com.taobao.middleware.cli.annotations.Description; +import com.taobao.middleware.cli.annotations.Name; +import com.taobao.middleware.cli.annotations.Option; +import com.taobao.middleware.cli.annotations.Summary; + +import jline.Terminal; +import jline.TerminalSupport; +import jline.UnixTerminal; +import jline.console.ConsoleReader; +import jline.console.KeyMap; + /** * @author ralf0131 2016-12-29 11:55. + * @author hengyunabc 2018-11-01 */ -public class TelnetConsole{ - - private static final String PROMPT = "$"; - private static final String DEFAULT_TELNET_PORT = "3658"; - private static final int DEFAULT_CONNECTION_TIMEOUT = 5000; // 5000 ms - private static final String DEFAULT_WINDOW_WIDTH = "120"; - private static final String DEFAULT_WINDOW_HEIGHT = "40"; - private static final int DEFAULT_BUFFER_SIZE = 1024; - - private TelnetClient telnet; - private String address; - private int port; - private InputStream in; - private PrintStream out; - - public TelnetConsole(String address, int port, int width, int height) { - this.telnet = new TelnetClient(); - this.address = address; - this.port = port; - try { - telnet.addOptionHandler(new WindowSizeOptionHandler(width, height, true, false, true, false)); - } catch (Exception e) { - e.printStackTrace(); - } - telnet.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT); - } - - public void connect() { - try { - // Connect to the specified server - telnet.connect(address, port); - // Get input and output stream references - in = telnet.getInputStream(); - out = new PrintStream(telnet.getOutputStream()); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public String readUntil(String prompt) { - try { - StringBuilder sBuffer = new StringBuilder(); - byte[] b = new byte[DEFAULT_BUFFER_SIZE]; - while(true) { - int size = in.read(b); - if(-1 != size) { - sBuffer.append(new String(b,0,size)); - String data = sBuffer.toString(); - if(data.trim().endsWith(prompt)) { - break; - } - } - } - return sBuffer.toString(); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - - public String readUntilPrompt() { - return readUntil(PROMPT); - } - - public void write(String value) { - try { - out.println(value); - out.flush(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void sendCommand(String command) { - try { - write(command); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void disconnect() { - try { - telnet.disconnect(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * 批处理模式 - */ - public void batchModeRun(File batchFile) { - if (batchFile == null || !batchFile.exists()) { - return; - } - batchModeRun(readLines(batchFile)); - } - - private void batchModeRun(List commands) { - for (String command: commands) { - // send command to server - sendCommand(command + " | plaintext"); - // read result from server and output - String response = readUntilPrompt(); - System.out.print(response); - } - } - - private List readLines(File batchFile) { - List list = new ArrayList(); - BufferedReader br = null; - try { - br = new BufferedReader(new FileReader(batchFile)); - String line = br.readLine(); - while (line != null) { - list.add(line); - line = br.readLine(); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (br != null) { - try { - br.close(); - } catch (IOException e) { - // ignore - } - } - } - return list; - } - - public static void main(String[] args) { - try { - if (args.length < 1) { - System.err.println("Usage: TelnetConsole [-p PORT] [-c COMMAND] [-f BATCH_FILE] [-w WIDTH] [-h HEIGHT]"); - System.exit(1); - } - - CommandLine commandLine = parseArguments(args); - - TelnetConsole console = new TelnetConsole( - (String)commandLine.getArgumentValue("target-ip"), - (Integer)commandLine.getOptionValue("p"), - (Integer)commandLine.getOptionValue("w"), - (Integer)commandLine.getOptionValue("h")); - - console.connect(); - String logo = console.readUntilPrompt(); - System.out.print(logo); - - String cmd = commandLine.getOptionValue("c"); - if (cmd != null) { - List cmds = new ArrayList(); - for (String c: cmd.split(";")) { - cmds.add(c.trim()); - } - console.batchModeRun(cmds); - } - - String filePath = commandLine.getOptionValue("f"); - if (filePath != null) { - File batchFile = new File(filePath); - console.batchModeRun(batchFile); - } - - console.disconnect(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static CommandLine parseArguments(String[] args) { - Argument addr = new Argument().setArgName("target-ip").setIndex(0).setRequired(true); - Option port = new TypedOption().setType(Integer.class).setShortName("p") - .setDefaultValue(DEFAULT_TELNET_PORT); - Option command = new TypedOption().setType(String.class).setShortName("c"); - Option batchFileOption = new TypedOption().setType(String.class).setShortName("f"); - Option width = new TypedOption().setType(Integer.class).setShortName("w") - .setDefaultValue(DEFAULT_WINDOW_WIDTH); - Option height = new TypedOption().setType(Integer.class).setShortName("h") - .setDefaultValue(DEFAULT_WINDOW_HEIGHT); - CLI cli = CLIs.create("TelnetConsole").addArgument(addr).addOption(port) - .addOption(command).addOption(batchFileOption).addOption(width).addOption(height); - return cli.parse(Arrays.asList(args)); - } +@Name("arthas-client") +@Summary("Arthas Telnet Client") +public class TelnetConsole { + private static final String PROMPT = "$"; + private static final int DEFAULT_CONNECTION_TIMEOUT = 5000; // 5000 ms + private static final int DEFAULT_BUFFER_SIZE = 1024; + + private static final byte CTRL_C = 0x03; + + private boolean help = false; + + private String targetIp = "127.0.0.1"; + private int port = 3658; + + private String command; + private String batchFile; + + private Integer width = null; + private Integer height = null; + + @Argument(argName = "targetIp", index = 0, required = false) + @Description("target-ip") + public void setTargetIp(String targetIp) { + this.targetIp = targetIp; + } + + @Option(longName = "help", flag = true) + @Description("Print usage") + public void setHelp(boolean help) { + this.help = help; + } + + @Option(shortName = "p", longName = "port") + @Description("The remote server port") + public void setPort(int port) { + this.port = port; + } + + @Option(shortName = "c", longName = "command") + @Description("The command to execute, multiple commands separated by ;") + public void setCommand(String command) { + this.command = command; + } + + @Option(shortName = "f", longName = "batchFile") + @Description("The batch file to execute") + public void setBatchFile(String batchFile) { + this.batchFile = batchFile; + } + + @Option(shortName = "w", longName = "width") + @Description("The terminal width") + public void setWidth(int width) { + this.width = width; + } + + @Option(shortName = "h", longName = "height") + @Description("The terminal height") + public void setheight(int height) { + this.height = height; + } + + public TelnetConsole() { + } + + private static String readUntil(InputStream in, String prompt) { + try { + StringBuilder sBuffer = new StringBuilder(); + byte[] b = new byte[DEFAULT_BUFFER_SIZE]; + while (true) { + int size = in.read(b); + if (-1 != size) { + sBuffer.append(new String(b, 0, size)); + String data = sBuffer.toString(); + if (data.trim().endsWith(prompt)) { + break; + } + } + } + return sBuffer.toString(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private static List readLines(File batchFile) { + List list = new ArrayList(); + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(batchFile)); + String line = br.readLine(); + while (line != null) { + list.add(line); + line = br.readLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + // ignore + } + } + } + return list; + } + + public static void main(String[] args) throws IOException { + TelnetConsole telnetConsole = new TelnetConsole(); + + CLI cli = CLIConfigurator.define(TelnetConsole.class); + CommandLine commandLine = cli.parse(Arrays.asList(args)); + + try { + CLIConfigurator.inject(commandLine, telnetConsole); + } catch (CLIException e) { + e.printStackTrace(); + System.out.println(usage(cli)); + System.exit(1); + } + + if (telnetConsole.isHelp()) { + System.out.println(usage(cli)); + System.exit(0); + } + + // Try to read cmds + List cmds = new ArrayList(); + if (telnetConsole.getCommand() != null) { + for (String c : telnetConsole.getCommand().split(";")) { + cmds.add(c.trim()); + } + } else if (telnetConsole.getBatchFile() != null) { + File file = new File(telnetConsole.getBatchFile()); + if (!file.exists()) { + throw new IllegalArgumentException("batch file do not exist: " + telnetConsole.getBatchFile()); + } else { + cmds.addAll(readLines(file)); + } + } + + final ConsoleReader consoleReader = new ConsoleReader(System.in, System.out); + consoleReader.setHandleUserInterrupt(true); + Terminal terminal = consoleReader.getTerminal(); + + if (terminal instanceof TerminalSupport) { + ((TerminalSupport) terminal).disableInterruptCharacter(); + } + + // support catch ctrl+c event + terminal.disableInterruptCharacter(); + if (terminal instanceof UnixTerminal) { + ((UnixTerminal) terminal).disableLitteralNextCharacter(); + } + + int width = TerminalSupport.DEFAULT_WIDTH; + int height = TerminalSupport.DEFAULT_HEIGHT; + + // 如果cmds 非空,则说明是batch mode + // 如果是 batch mode,如果没有设置 window size,则用默认的。 + if (!cmds.isEmpty()) { + if (telnetConsole.getWidth() != null) { + width = telnetConsole.getWidth(); + } + if (telnetConsole.getheight() != null) { + height = telnetConsole.getheight(); + } + } else { + if (telnetConsole.getWidth() != null) { + width = telnetConsole.getWidth(); + } else { + width = terminal.getWidth(); + // hack for windows dos + if (OSUtils.isWindowsOS()) { + width--; + } + } + if (telnetConsole.getheight() != null) { + height = telnetConsole.getheight(); + } else { + height = terminal.getHeight(); + } + } + + final TelnetClient telnet = new TelnetClient(); + telnet.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT); + + // send init terminal size + TelnetOptionHandler sizeOpt = new WindowSizeOptionHandler(width, height, true, true, false, false); + try { + telnet.addOptionHandler(sizeOpt); + } catch (InvalidTelnetOptionException e) { + // ignore + } + + // ctrl + c event callback + consoleReader.getKeys().bind(new Character((char) CTRL_C).toString(), new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + consoleReader.getCursorBuffer().clear(); // clear current line + telnet.getOutputStream().write(CTRL_C); + telnet.getOutputStream().flush(); + } catch (Exception e1) { + e1.printStackTrace(); + } + } + + }); + + // ctrl + d event call back + consoleReader.getKeys().bind(new Character(KeyMap.CTRL_D).toString(), new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + }); + + try { + telnet.connect(telnetConsole.getTargetIp(), telnetConsole.getPort()); + } catch (IOException e) { + System.out.println( + "Connect to telnet server error: " + telnetConsole.getTargetIp() + " " + telnetConsole.getPort()); + e.printStackTrace(); + System.exit(1); + } + + if (cmds.isEmpty()) { + IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(), consoleReader.getInput(), + consoleReader.getOutput()); + } else { + batchModeRun(telnet, cmds); + telnet.disconnect(); + } + } + + private static void batchModeRun(TelnetClient telnet, List commands) throws IOException { + InputStream inputStream = telnet.getInputStream(); + OutputStream outputStream = telnet.getOutputStream(); + + for (String command : commands) { + if (command.trim().isEmpty()) { + continue; + } + // send command to server + outputStream.write((command + " | plaintext\n").getBytes()); + outputStream.flush(); + // read result from server and output + String response = readUntil(inputStream, PROMPT); + System.out.print(response); + } + } + + private static String usage(CLI cli) { + StringBuilder usageStringBuilder = new StringBuilder(); + UsageMessageFormatter usageMessageFormatter = new UsageMessageFormatter(); + usageMessageFormatter.setOptionComparator(null); + cli.usage(usageStringBuilder, usageMessageFormatter); + return usageStringBuilder.toString(); + } + + public String getTargetIp() { + return targetIp; + } + + public int getPort() { + return port; + } + + public String getCommand() { + return command; + } + + public String getBatchFile() { + return batchFile; + } + + public Integer getWidth() { + return width; + } + + public Integer getheight() { + return height; + } + + public boolean isHelp() { + return help; + } } From fca047db11c6059b9c6373aad60d455f4318e694 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Fri, 2 Nov 2018 11:41:17 +0800 Subject: [PATCH 2/2] update TelnetConsole usage. #272 --- .../taobao/arthas/client/TelnetConsole.java | 215 +++++++++--------- 1 file changed, 109 insertions(+), 106 deletions(-) diff --git a/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java b/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java index 6afe5746b..90e3b1989 100644 --- a/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java +++ b/client/src/main/java/com/taobao/arthas/client/TelnetConsole.java @@ -18,7 +18,6 @@ import org.apache.commons.net.telnet.TelnetOptionHandler; import org.apache.commons.net.telnet.WindowSizeOptionHandler; import com.taobao.middleware.cli.CLI; -import com.taobao.middleware.cli.CLIException; import com.taobao.middleware.cli.CommandLine; import com.taobao.middleware.cli.UsageMessageFormatter; import com.taobao.middleware.cli.annotations.Argument; @@ -40,6 +39,9 @@ import jline.console.KeyMap; */ @Name("arthas-client") @Summary("Arthas Telnet Client") +@Description("EXAMPLES:\n" + " java -jar arthas-client.jar 127.0.0.1 3658\n" + + " java -jar arthas-client.jar -c 'dashboard -n 1' \n" + + " java -jar arthas-client.jar -f batch.as 127.0.0.1\n") public class TelnetConsole { private static final String PROMPT = "$"; private static final int DEFAULT_CONNECTION_TIMEOUT = 5000; // 5000 ms @@ -59,25 +61,25 @@ public class TelnetConsole { private Integer height = null; @Argument(argName = "targetIp", index = 0, required = false) - @Description("target-ip") + @Description("Target ip") public void setTargetIp(String targetIp) { this.targetIp = targetIp; } + @Argument(argName = "port", index = 1, required = false) + @Description("The remote server port") + public void setPort(int port) { + this.port = port; + } + @Option(longName = "help", flag = true) @Description("Print usage") public void setHelp(boolean help) { this.help = help; } - @Option(shortName = "p", longName = "port") - @Description("The remote server port") - public void setPort(int port) { - this.port = port; - } - @Option(shortName = "c", longName = "command") - @Description("The command to execute, multiple commands separated by ;") + @Description("Command to execute, multiple commands separated by ;") public void setCommand(String command) { this.command = command; } @@ -152,129 +154,130 @@ public class TelnetConsole { TelnetConsole telnetConsole = new TelnetConsole(); CLI cli = CLIConfigurator.define(TelnetConsole.class); - CommandLine commandLine = cli.parse(Arrays.asList(args)); try { - CLIConfigurator.inject(commandLine, telnetConsole); - } catch (CLIException e) { - e.printStackTrace(); - System.out.println(usage(cli)); - System.exit(1); - } + CommandLine commandLine = cli.parse(Arrays.asList(args)); - if (telnetConsole.isHelp()) { - System.out.println(usage(cli)); - System.exit(0); - } + CLIConfigurator.inject(commandLine, telnetConsole); - // Try to read cmds - List cmds = new ArrayList(); - if (telnetConsole.getCommand() != null) { - for (String c : telnetConsole.getCommand().split(";")) { - cmds.add(c.trim()); + if (telnetConsole.isHelp()) { + System.out.println(usage(cli)); + System.exit(0); } - } else if (telnetConsole.getBatchFile() != null) { - File file = new File(telnetConsole.getBatchFile()); - if (!file.exists()) { - throw new IllegalArgumentException("batch file do not exist: " + telnetConsole.getBatchFile()); - } else { - cmds.addAll(readLines(file)); + + // Try to read cmds + List cmds = new ArrayList(); + if (telnetConsole.getCommand() != null) { + for (String c : telnetConsole.getCommand().split(";")) { + cmds.add(c.trim()); + } + } else if (telnetConsole.getBatchFile() != null) { + File file = new File(telnetConsole.getBatchFile()); + if (!file.exists()) { + throw new IllegalArgumentException("batch file do not exist: " + telnetConsole.getBatchFile()); + } else { + cmds.addAll(readLines(file)); + } } - } - final ConsoleReader consoleReader = new ConsoleReader(System.in, System.out); - consoleReader.setHandleUserInterrupt(true); - Terminal terminal = consoleReader.getTerminal(); + final ConsoleReader consoleReader = new ConsoleReader(System.in, System.out); + consoleReader.setHandleUserInterrupt(true); + Terminal terminal = consoleReader.getTerminal(); - if (terminal instanceof TerminalSupport) { - ((TerminalSupport) terminal).disableInterruptCharacter(); - } + if (terminal instanceof TerminalSupport) { + ((TerminalSupport) terminal).disableInterruptCharacter(); + } - // support catch ctrl+c event - terminal.disableInterruptCharacter(); - if (terminal instanceof UnixTerminal) { - ((UnixTerminal) terminal).disableLitteralNextCharacter(); - } + // support catch ctrl+c event + terminal.disableInterruptCharacter(); + if (terminal instanceof UnixTerminal) { + ((UnixTerminal) terminal).disableLitteralNextCharacter(); + } - int width = TerminalSupport.DEFAULT_WIDTH; - int height = TerminalSupport.DEFAULT_HEIGHT; + int width = TerminalSupport.DEFAULT_WIDTH; + int height = TerminalSupport.DEFAULT_HEIGHT; - // 如果cmds 非空,则说明是batch mode - // 如果是 batch mode,如果没有设置 window size,则用默认的。 - if (!cmds.isEmpty()) { - if (telnetConsole.getWidth() != null) { - width = telnetConsole.getWidth(); - } - if (telnetConsole.getheight() != null) { - height = telnetConsole.getheight(); - } - } else { - if (telnetConsole.getWidth() != null) { - width = telnetConsole.getWidth(); - } else { - width = terminal.getWidth(); - // hack for windows dos - if (OSUtils.isWindowsOS()) { - width--; + if (!cmds.isEmpty()) { + // batch mode + if (telnetConsole.getWidth() != null) { + width = telnetConsole.getWidth(); + } + if (telnetConsole.getheight() != null) { + height = telnetConsole.getheight(); } - } - if (telnetConsole.getheight() != null) { - height = telnetConsole.getheight(); } else { - height = terminal.getHeight(); + // normal telnet client, get current terminal size + if (telnetConsole.getWidth() != null) { + width = telnetConsole.getWidth(); + } else { + width = terminal.getWidth(); + // hack for windows dos + if (OSUtils.isWindowsOS()) { + width--; + } + } + if (telnetConsole.getheight() != null) { + height = telnetConsole.getheight(); + } else { + height = terminal.getHeight(); + } } - } - final TelnetClient telnet = new TelnetClient(); - telnet.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT); + final TelnetClient telnet = new TelnetClient(); + telnet.setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT); - // send init terminal size - TelnetOptionHandler sizeOpt = new WindowSizeOptionHandler(width, height, true, true, false, false); - try { - telnet.addOptionHandler(sizeOpt); - } catch (InvalidTelnetOptionException e) { - // ignore - } + // send init terminal size + TelnetOptionHandler sizeOpt = new WindowSizeOptionHandler(width, height, true, true, false, false); + try { + telnet.addOptionHandler(sizeOpt); + } catch (InvalidTelnetOptionException e) { + // ignore + } - // ctrl + c event callback - consoleReader.getKeys().bind(new Character((char) CTRL_C).toString(), new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - try { - consoleReader.getCursorBuffer().clear(); // clear current line - telnet.getOutputStream().write(CTRL_C); - telnet.getOutputStream().flush(); - } catch (Exception e1) { - e1.printStackTrace(); + // ctrl + c event callback + consoleReader.getKeys().bind(new Character((char) CTRL_C).toString(), new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + consoleReader.getCursorBuffer().clear(); // clear current line + telnet.getOutputStream().write(CTRL_C); + telnet.getOutputStream().flush(); + } catch (Exception e1) { + e1.printStackTrace(); + } } - } - }); + }); - // ctrl + d event call back - consoleReader.getKeys().bind(new Character(KeyMap.CTRL_D).toString(), new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - System.exit(0); + // ctrl + d event call back + consoleReader.getKeys().bind(new Character(KeyMap.CTRL_D).toString(), new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + }); + + try { + telnet.connect(telnetConsole.getTargetIp(), telnetConsole.getPort()); + } catch (IOException e) { + System.out.println("Connect to telnet server error: " + telnetConsole.getTargetIp() + " " + + telnetConsole.getPort()); + throw e; } - }); - try { - telnet.connect(telnetConsole.getTargetIp(), telnetConsole.getPort()); - } catch (IOException e) { - System.out.println( - "Connect to telnet server error: " + telnetConsole.getTargetIp() + " " + telnetConsole.getPort()); + if (cmds.isEmpty()) { + IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(), consoleReader.getInput(), + consoleReader.getOutput()); + } else { + batchModeRun(telnet, cmds); + telnet.disconnect(); + } + } catch (Throwable e) { e.printStackTrace(); + System.out.println(usage(cli)); System.exit(1); } - if (cmds.isEmpty()) { - IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(), consoleReader.getInput(), - consoleReader.getOutput()); - } else { - batchModeRun(telnet, cmds); - telnet.disconnect(); - } } private static void batchModeRun(TelnetClient telnet, List commands) throws IOException {