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 examples.telnet; 019 020import java.io.IOException; 021import java.io.InputStream; 022import java.io.OutputStream; 023import java.io.FileOutputStream; 024import java.util.StringTokenizer; 025 026import org.apache.commons.net.telnet.TelnetClient; 027import org.apache.commons.net.telnet.TelnetNotificationHandler; 028import org.apache.commons.net.telnet.SimpleOptionHandler; 029import org.apache.commons.net.telnet.EchoOptionHandler; 030import org.apache.commons.net.telnet.TerminalTypeOptionHandler; 031import org.apache.commons.net.telnet.SuppressGAOptionHandler; 032import org.apache.commons.net.telnet.InvalidTelnetOptionException; 033 034 035/*** 036 * This is a simple example of use of TelnetClient. 037 * An external option handler (SimpleTelnetOptionHandler) is used. 038 * Initial configuration requested by TelnetClient will be: 039 * WILL ECHO, WILL SUPPRESS-GA, DO SUPPRESS-GA. 040 * VT100 terminal type will be subnegotiated. 041 * <p> 042 * Also, use of the sendAYT(), getLocalOptionState(), getRemoteOptionState() 043 * is demonstrated. 044 * When connected, type AYT to send an AYT command to the server and see 045 * the result. 046 * Type OPT to see a report of the state of the first 25 options. 047 ***/ 048public class TelnetClientExample implements Runnable, TelnetNotificationHandler 049{ 050 static TelnetClient tc = null; 051 052 /*** 053 * Main for the TelnetClientExample. 054 * @param args input params 055 * @throws Exception on error 056 ***/ 057 public static void main(String[] args) throws Exception 058 { 059 FileOutputStream fout = null; 060 061 if(args.length < 1) 062 { 063 System.err.println("Usage: TelnetClientExample <remote-ip> [<remote-port>]"); 064 System.exit(1); 065 } 066 067 String remoteip = args[0]; 068 069 int remoteport; 070 071 if (args.length > 1) 072 { 073 remoteport = (new Integer(args[1])).intValue(); 074 } 075 else 076 { 077 remoteport = 23; 078 } 079 080 try 081 { 082 fout = new FileOutputStream ("spy.log", true); 083 } 084 catch (IOException e) 085 { 086 System.err.println( 087 "Exception while opening the spy file: " 088 + e.getMessage()); 089 } 090 091 tc = new TelnetClient(); 092 093 TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false); 094 EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false); 095 SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true); 096 097 try 098 { 099 tc.addOptionHandler(ttopt); 100 tc.addOptionHandler(echoopt); 101 tc.addOptionHandler(gaopt); 102 } 103 catch (InvalidTelnetOptionException e) 104 { 105 System.err.println("Error registering option handlers: " + e.getMessage()); 106 } 107 108 while (true) 109 { 110 boolean end_loop = false; 111 try 112 { 113 tc.connect(remoteip, remoteport); 114 115 116 Thread reader = new Thread (new TelnetClientExample()); 117 tc.registerNotifHandler(new TelnetClientExample()); 118 System.out.println("TelnetClientExample"); 119 System.out.println("Type AYT to send an AYT telnet command"); 120 System.out.println("Type OPT to print a report of status of options (0-24)"); 121 System.out.println("Type REGISTER to register a new SimpleOptionHandler"); 122 System.out.println("Type UNREGISTER to unregister an OptionHandler"); 123 System.out.println("Type SPY to register the spy (connect to port 3333 to spy)"); 124 System.out.println("Type UNSPY to stop spying the connection"); 125 System.out.println("Type ^[A-Z] to send the control character; use ^^ to send ^"); 126 127 reader.start(); 128 OutputStream outstr = tc.getOutputStream(); 129 130 byte[] buff = new byte[1024]; 131 int ret_read = 0; 132 133 do 134 { 135 try 136 { 137 ret_read = System.in.read(buff); 138 if(ret_read > 0) 139 { 140 final String line = new String(buff, 0, ret_read); // deliberate use of default charset 141 if(line.startsWith("AYT")) 142 { 143 try 144 { 145 System.out.println("Sending AYT"); 146 147 System.out.println("AYT response:" + tc.sendAYT(5000)); 148 } 149 catch (IOException e) 150 { 151 System.err.println("Exception waiting AYT response: " + e.getMessage()); 152 } 153 } 154 else if(line.startsWith("OPT")) 155 { 156 System.out.println("Status of options:"); 157 for(int ii=0; ii<25; ii++) { 158 System.out.println("Local Option " + ii + ":" + tc.getLocalOptionState(ii) + 159 " Remote Option " + ii + ":" + tc.getRemoteOptionState(ii)); 160 } 161 } 162 else if(line.startsWith("REGISTER")) 163 { 164 StringTokenizer st = new StringTokenizer(new String(buff)); 165 try 166 { 167 st.nextToken(); 168 int opcode = Integer.parseInt(st.nextToken()); 169 boolean initlocal = Boolean.parseBoolean(st.nextToken()); 170 boolean initremote = Boolean.parseBoolean(st.nextToken()); 171 boolean acceptlocal = Boolean.parseBoolean(st.nextToken()); 172 boolean acceptremote = Boolean.parseBoolean(st.nextToken()); 173 SimpleOptionHandler opthand = new SimpleOptionHandler(opcode, initlocal, initremote, 174 acceptlocal, acceptremote); 175 tc.addOptionHandler(opthand); 176 } 177 catch (Exception e) 178 { 179 if(e instanceof InvalidTelnetOptionException) 180 { 181 System.err.println("Error registering option: " + e.getMessage()); 182 } 183 else 184 { 185 System.err.println("Invalid REGISTER command."); 186 System.err.println("Use REGISTER optcode initlocal initremote acceptlocal acceptremote"); 187 System.err.println("(optcode is an integer.)"); 188 System.err.println("(initlocal, initremote, acceptlocal, acceptremote are boolean)"); 189 } 190 } 191 } 192 else if(line.startsWith("UNREGISTER")) 193 { 194 StringTokenizer st = new StringTokenizer(new String(buff)); 195 try 196 { 197 st.nextToken(); 198 int opcode = (new Integer(st.nextToken())).intValue(); 199 tc.deleteOptionHandler(opcode); 200 } 201 catch (Exception e) 202 { 203 if(e instanceof InvalidTelnetOptionException) 204 { 205 System.err.println("Error unregistering option: " + e.getMessage()); 206 } 207 else 208 { 209 System.err.println("Invalid UNREGISTER command."); 210 System.err.println("Use UNREGISTER optcode"); 211 System.err.println("(optcode is an integer)"); 212 } 213 } 214 } 215 else if(line.startsWith("SPY")) 216 { 217 tc.registerSpyStream(fout); 218 } 219 else if(line.startsWith("UNSPY")) 220 { 221 tc.stopSpyStream(); 222 } 223 else if(line.matches("^\\^[A-Z^]\\r?\\n?$")) 224 { 225 byte toSend = buff[1]; 226 if (toSend == '^') { 227 outstr.write(toSend); 228 } else { 229 outstr.write(toSend - 'A' + 1); 230 } 231 outstr.flush(); 232 } 233 else 234 { 235 try 236 { 237 outstr.write(buff, 0 , ret_read); 238 outstr.flush(); 239 } 240 catch (IOException e) 241 { 242 end_loop = true; 243 } 244 } 245 } 246 } 247 catch (IOException e) 248 { 249 System.err.println("Exception while reading keyboard:" + e.getMessage()); 250 end_loop = true; 251 } 252 } 253 while((ret_read > 0) && (end_loop == false)); 254 255 try 256 { 257 tc.disconnect(); 258 } 259 catch (IOException e) 260 { 261 System.err.println("Exception while connecting:" + e.getMessage()); 262 } 263 } 264 catch (IOException e) 265 { 266 System.err.println("Exception while connecting:" + e.getMessage()); 267 System.exit(1); 268 } 269 } 270 } 271 272 273 /*** 274 * Callback method called when TelnetClient receives an option 275 * negotiation command. 276 * 277 * @param negotiation_code - type of negotiation command received 278 * (RECEIVED_DO, RECEIVED_DONT, RECEIVED_WILL, RECEIVED_WONT, RECEIVED_COMMAND) 279 * @param option_code - code of the option negotiated 280 ***/ 281 @Override 282 public void receivedNegotiation(int negotiation_code, int option_code) 283 { 284 String command = null; 285 switch (negotiation_code) { 286 case TelnetNotificationHandler.RECEIVED_DO: 287 command = "DO"; 288 break; 289 case TelnetNotificationHandler.RECEIVED_DONT: 290 command = "DONT"; 291 break; 292 case TelnetNotificationHandler.RECEIVED_WILL: 293 command = "WILL"; 294 break; 295 case TelnetNotificationHandler.RECEIVED_WONT: 296 command = "WONT"; 297 break; 298 case TelnetNotificationHandler.RECEIVED_COMMAND: 299 command = "COMMAND"; 300 break; 301 default: 302 command = Integer.toString(negotiation_code); // Should not happen 303 break; 304 } 305 System.out.println("Received " + command + " for option code " + option_code); 306 } 307 308 /*** 309 * Reader thread. 310 * Reads lines from the TelnetClient and echoes them 311 * on the screen. 312 ***/ 313 @Override 314 public void run() 315 { 316 InputStream instr = tc.getInputStream(); 317 318 try 319 { 320 byte[] buff = new byte[1024]; 321 int ret_read = 0; 322 323 do 324 { 325 ret_read = instr.read(buff); 326 if(ret_read > 0) 327 { 328 System.out.print(new String(buff, 0, ret_read)); 329 } 330 } 331 while (ret_read >= 0); 332 } 333 catch (IOException e) 334 { 335 System.err.println("Exception while reading socket:" + e.getMessage()); 336 } 337 338 try 339 { 340 tc.disconnect(); 341 } 342 catch (IOException e) 343 { 344 System.err.println("Exception while closing telnet:" + e.getMessage()); 345 } 346 } 347} 348