001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.net.examples.telnet; 019 020import java.io.FileOutputStream; 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.OutputStream; 024import java.util.StringTokenizer; 025 026import org.apache.commons.net.telnet.EchoOptionHandler; 027import org.apache.commons.net.telnet.InvalidTelnetOptionException; 028import org.apache.commons.net.telnet.SimpleOptionHandler; 029import org.apache.commons.net.telnet.SuppressGAOptionHandler; 030import org.apache.commons.net.telnet.TelnetClient; 031import org.apache.commons.net.telnet.TelnetNotificationHandler; 032import org.apache.commons.net.telnet.TerminalTypeOptionHandler; 033 034/** 035 * This is a simple example of use of TelnetClient. An external option handler (SimpleTelnetOptionHandler) is used. Initial configuration requested by 036 * TelnetClient will be: WILL ECHO, WILL SUPPRESS-GA, DO SUPPRESS-GA. VT100 terminal type will be subnegotiated. 037 * <p> 038 * Also, use of the sendAYT(), getLocalOptionState(), getRemoteOptionState() is demonstrated. When connected, type AYT to send an AYT command to the server and 039 * see the result. Type OPT to see a report of the state of the first 25 options. 040 */ 041public class TelnetClientExample implements Runnable, TelnetNotificationHandler { 042 private static TelnetClient tc; 043 044 /** 045 * Main for the TelnetClientExample. 046 * 047 * @param args input params 048 * @throws Exception on error 049 */ 050 public static void main(final String[] args) throws Exception { 051 FileOutputStream fout = null; 052 053 if (args.length < 1) { 054 System.err.println("Usage: TelnetClientExample <remote-ip> [<remote-port>]"); 055 System.exit(1); 056 } 057 058 final String remoteip = args[0]; 059 060 final int remoteport; 061 062 if (args.length > 1) { 063 remoteport = Integer.parseInt(args[1]); 064 } else { 065 remoteport = 23; 066 } 067 068 try { 069 fout = new FileOutputStream("spy.log", true); 070 } catch (final IOException e) { 071 System.err.println("Exception while opening the spy file: " + e.getMessage()); 072 } 073 074 tc = new TelnetClient(); 075 076 final TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false); 077 final EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false); 078 final SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true); 079 080 try { 081 tc.addOptionHandler(ttopt); 082 tc.addOptionHandler(echoopt); 083 tc.addOptionHandler(gaopt); 084 } catch (final InvalidTelnetOptionException e) { 085 System.err.println("Error registering option handlers: " + e.getMessage()); 086 } 087 088 while (true) { 089 boolean end_loop = false; 090 try { 091 tc.connect(remoteip, remoteport); 092 093 final Thread reader = new Thread(new TelnetClientExample()); 094 tc.registerNotifHandler(new TelnetClientExample()); 095 System.out.println("TelnetClientExample"); 096 System.out.println("Type AYT to send an AYT telnet command"); 097 System.out.println("Type OPT to print a report of status of options (0-24)"); 098 System.out.println("Type REGISTER to register a new SimpleOptionHandler"); 099 System.out.println("Type UNREGISTER to unregister an OptionHandler"); 100 System.out.println("Type SPY to register the spy (connect to port 3333 to spy)"); 101 System.out.println("Type UNSPY to stop spying the connection"); 102 System.out.println("Type ^[A-Z] to send the control character; use ^^ to send ^"); 103 104 reader.start(); 105 final OutputStream outstr = tc.getOutputStream(); 106 107 final byte[] buff = new byte[1024]; 108 int ret_read = 0; 109 110 do { 111 try { 112 ret_read = System.in.read(buff); 113 if (ret_read > 0) { 114 final String line = new String(buff, 0, ret_read); // deliberate use of default charset 115 if (line.startsWith("AYT")) { 116 try { 117 System.out.println("Sending AYT"); 118 119 System.out.println("AYT response:" + tc.sendAYT(5000)); 120 } catch (final IOException e) { 121 System.err.println("Exception waiting AYT response: " + e.getMessage()); 122 } 123 } else if (line.startsWith("OPT")) { 124 System.out.println("Status of options:"); 125 for (int ii = 0; ii < 25; ii++) { 126 System.out.println("Local Option " + ii + ":" + tc.getLocalOptionState(ii) + " Remote Option " + ii + ":" 127 + tc.getRemoteOptionState(ii)); 128 } 129 } else if (line.startsWith("REGISTER")) { 130 final StringTokenizer st = new StringTokenizer(new String(buff)); 131 try { 132 st.nextToken(); 133 final int opcode = Integer.parseInt(st.nextToken()); 134 final boolean initlocal = Boolean.parseBoolean(st.nextToken()); 135 final boolean initremote = Boolean.parseBoolean(st.nextToken()); 136 final boolean acceptlocal = Boolean.parseBoolean(st.nextToken()); 137 final boolean acceptremote = Boolean.parseBoolean(st.nextToken()); 138 final SimpleOptionHandler opthand = new SimpleOptionHandler(opcode, initlocal, initremote, acceptlocal, acceptremote); 139 tc.addOptionHandler(opthand); 140 } catch (final Exception e) { 141 if (e instanceof InvalidTelnetOptionException) { 142 System.err.println("Error registering option: " + e.getMessage()); 143 } else { 144 System.err.println("Invalid REGISTER command."); 145 System.err.println("Use REGISTER optcode initlocal initremote acceptlocal acceptremote"); 146 System.err.println("(optcode is an integer.)"); 147 System.err.println("(initlocal, initremote, acceptlocal, acceptremote are boolean)"); 148 } 149 } 150 } else if (line.startsWith("UNREGISTER")) { 151 final StringTokenizer st = new StringTokenizer(new String(buff)); 152 try { 153 st.nextToken(); 154 final int opcode = Integer.parseInt(st.nextToken()); 155 tc.deleteOptionHandler(opcode); 156 } catch (final Exception e) { 157 if (e instanceof InvalidTelnetOptionException) { 158 System.err.println("Error unregistering option: " + e.getMessage()); 159 } else { 160 System.err.println("Invalid UNREGISTER command."); 161 System.err.println("Use UNREGISTER optcode"); 162 System.err.println("(optcode is an integer)"); 163 } 164 } 165 } else if (line.startsWith("SPY")) { 166 tc.registerSpyStream(fout); 167 } else if (line.startsWith("UNSPY")) { 168 tc.stopSpyStream(); 169 } else if (line.matches("^\\^[A-Z^]\\r?\\n?$")) { 170 final byte toSend = buff[1]; 171 if (toSend == '^') { 172 outstr.write(toSend); 173 } else { 174 outstr.write(toSend - 'A' + 1); 175 } 176 outstr.flush(); 177 } else { 178 try { 179 outstr.write(buff, 0, ret_read); 180 outstr.flush(); 181 } catch (final IOException e) { 182 end_loop = true; 183 } 184 } 185 } 186 } catch (final IOException e) { 187 System.err.println("Exception while reading keyboard:" + e.getMessage()); 188 end_loop = true; 189 } 190 } while (ret_read > 0 && !end_loop); 191 192 try { 193 tc.disconnect(); 194 } catch (final IOException e) { 195 System.err.println("Exception while connecting:" + e.getMessage()); 196 } 197 } catch (final IOException e) { 198 System.err.println("Exception while connecting:" + e.getMessage()); 199 System.exit(1); 200 } 201 } 202 } 203 204 /** 205 * Callback method called when TelnetClient receives an option negotiation command. 206 * 207 * @param negotiation_code - type of negotiation command received (RECEIVED_DO, RECEIVED_DONT, RECEIVED_WILL, RECEIVED_WONT, RECEIVED_COMMAND) 208 * @param option_code - code of the option negotiated 209 */ 210 @Override 211 public void receivedNegotiation(final int negotiation_code, final int option_code) { 212 String command = null; 213 switch (negotiation_code) { 214 case TelnetNotificationHandler.RECEIVED_DO: 215 command = "DO"; 216 break; 217 case TelnetNotificationHandler.RECEIVED_DONT: 218 command = "DONT"; 219 break; 220 case TelnetNotificationHandler.RECEIVED_WILL: 221 command = "WILL"; 222 break; 223 case TelnetNotificationHandler.RECEIVED_WONT: 224 command = "WONT"; 225 break; 226 case TelnetNotificationHandler.RECEIVED_COMMAND: 227 command = "COMMAND"; 228 break; 229 default: 230 command = Integer.toString(negotiation_code); // Should not happen 231 break; 232 } 233 System.out.println("Received " + command + " for option code " + option_code); 234 } 235 236 /** 237 * Reader thread. Reads lines from the TelnetClient and echoes them on the screen. 238 */ 239 @Override 240 public void run() { 241 final InputStream instr = tc.getInputStream(); 242 243 try { 244 final byte[] buff = new byte[1024]; 245 int ret_read = 0; 246 247 do { 248 ret_read = instr.read(buff); 249 if (ret_read > 0) { 250 System.out.print(new String(buff, 0, ret_read)); 251 } 252 } while (ret_read >= 0); 253 } catch (final IOException e) { 254 System.err.println("Exception while reading socket:" + e.getMessage()); 255 } 256 257 try { 258 tc.disconnect(); 259 } catch (final IOException e) { 260 System.err.println("Exception while closing telnet:" + e.getMessage()); 261 } 262 } 263}