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