Coverage Report - org.apache.xbean.terminal.telnet.TelnetInputStream
 
Classes in this File Line Coverage Branch Coverage Complexity
TelnetInputStream
0%
0/93
0%
0/46
3.167
 
 1  
 /**
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  *
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.xbean.terminal.telnet;
 18  
 
 19  
 import java.io.FilterInputStream;
 20  
 import java.io.IOException;
 21  
 import java.io.InputStream;
 22  
 import java.io.OutputStream;
 23  
 
 24  
 public class TelnetInputStream extends FilterInputStream implements TelnetCodes {
 25  
     // state table for what options have been negotiated
 26  0
     private TelnetOption[] options = new TelnetOption[256];
 27  0
     private OutputStream out = null;
 28  
 
 29  
     /**
 30  
      * We haven yet implemented any Telnet options, so we just explicitly
 31  
      * disable some common options for safety sake.
 32  
      * <p/>
 33  
      * Certain Telnet clients (MS Windows Telnet) are enabling options without
 34  
      * asking first. Shame, shame, shame.
 35  
      *
 36  
      * @throws IOException
 37  
      */
 38  
     public TelnetInputStream(InputStream in, OutputStream out) throws IOException {
 39  0
         super(in);
 40  0
         this.out = out;
 41  0
         negotiateOption(DONT, 1);
 42  0
         negotiateOption(DONT, 6);
 43  0
         negotiateOption(DONT, 24);
 44  0
         negotiateOption(DONT, 33);
 45  0
         negotiateOption(DONT, 34);
 46  0
     }
 47  
 
 48  
     public int read() throws IOException {
 49  0
         int b = super.read();
 50  0
         if (b == IAC) {
 51  
             // The cosole has a reference
 52  
             // to this input stream
 53  0
             processCommand();
 54  
             // Call read recursively as
 55  
             // the next character could
 56  
             // also be a command
 57  0
             b = this.read();
 58  
         }
 59  
         //System.out.println("B="+b);
 60  0
         return b;
 61  
     }
 62  
 
 63  
     /**
 64  
      * This is only called by TelnetInputStream
 65  
      * it is assumed that the IAC byte has already been read from the stream.
 66  
      *
 67  
      * @throws IOException
 68  
      */
 69  
     private void processCommand() throws IOException {
 70  
         // Debug statement
 71  0
         print("C: IAC ");
 72  0
         int command = super.read();
 73  0
         switch (command) {
 74  
             case WILL:
 75  0
                 senderWillEnableOption(super.read());
 76  0
                 break;
 77  
             case DO:
 78  0
                 pleaseDoEnableOption(super.read());
 79  0
                 break;
 80  
             case WONT:
 81  0
                 senderWontEnableOption(super.read());
 82  0
                 break;
 83  
             case DONT:
 84  0
                 pleaseDontEnableOption(super.read());
 85  0
                 break;
 86  
             default:
 87  0
                 unimplementedCommand(command);
 88  
                 break;
 89  
         }
 90  0
     }
 91  
 
 92  
     private void unimplementedCommand(int command) {
 93  0
         println(command + ": command not found");
 94  0
     }
 95  
 
 96  
     /**
 97  
      * Client says: I will enable OptionX
 98  
      * <p/>
 99  
      * If the sender initiated the negotiation of the
 100  
      * option, we must send a reply. Replies can be DO or DON'T.
 101  
      *
 102  
      * @param optionID
 103  
      * @throws IOException
 104  
      */
 105  
     private void senderWillEnableOption(int optionID) throws IOException {
 106  
         // Debug statement
 107  0
         println("WILL " + optionID);
 108  0
         TelnetOption option = getOption(optionID);
 109  0
         if (option.hasBeenNegotiated()) return;
 110  0
         if (option.isInNegotiation()) {
 111  0
             option.enable();
 112  0
         } else if (!option.isInNegotiation() && option.isSupported()) {
 113  0
             negotiateOption(DO, optionID);
 114  0
             option.enable();
 115  0
         } else if (!option.isInNegotiation() && !option.isSupported()) {
 116  0
             negotiateOption(DONT, optionID);
 117  0
             option.disable();
 118  
         }
 119  0
     }
 120  
 
 121  
     /**
 122  
      * Client says: Please, do enable OptionX
 123  
      * <p/>
 124  
      * If the sender initiated the negotiation of the
 125  
      * option, we must send a reply.
 126  
      * <p/>
 127  
      * Replies can be WILL or WON'T.
 128  
      *
 129  
      * @param optionID
 130  
      * @throws IOException
 131  
      */
 132  
     private void pleaseDoEnableOption(int optionID) throws IOException {
 133  
         // Debug statement
 134  0
         println("DO " + optionID);
 135  0
         TelnetOption option = getOption(optionID);
 136  0
         if (option.hasBeenNegotiated()) return;
 137  0
         if (option.isInNegotiation()) {
 138  0
             option.enable();
 139  0
         } else if (!option.isInNegotiation() && option.isSupported()) {
 140  0
             negotiateOption(WILL, optionID);
 141  0
             option.enable();
 142  0
         } else if (!option.isInNegotiation() && !option.isSupported()) {
 143  0
             negotiateOption(WONT, optionID);
 144  0
             option.disable();
 145  
         }
 146  0
     }
 147  
 
 148  
     /**
 149  
      * Client says: I won't enable OptionX
 150  
      * <p/>
 151  
      * <p/>
 152  
      * If the sender initiated the negotiation of the
 153  
      * option, we must send a reply.
 154  
      * <p/>
 155  
      * Replies can only be DON'T.
 156  
      *
 157  
      * @param optionID
 158  
      * @throws IOException
 159  
      */
 160  
     private void senderWontEnableOption(int optionID) throws IOException {
 161  0
         println("WONT " + optionID);
 162  0
         TelnetOption option = getOption(optionID);
 163  0
         if (option.hasBeenNegotiated()) return;
 164  0
         if (!option.isInNegotiation()) {
 165  0
             negotiateOption(DONT, optionID);
 166  
         }
 167  0
         option.disable();
 168  0
     }
 169  
 
 170  
     /**
 171  
      * Client says: Please, don't enable OptionX
 172  
      * <p/>
 173  
      * If the sender initiated the negotiation of the
 174  
      * option, we must send a reply.
 175  
      * <p/>
 176  
      * Replies can only be WON'T.
 177  
      *
 178  
      * @param optionID
 179  
      * @throws IOException
 180  
      */
 181  
     private void pleaseDontEnableOption(int optionID) throws IOException {
 182  
         // Debug statement
 183  0
         println("DONT " + optionID);
 184  0
         TelnetOption option = getOption(optionID);
 185  0
         if (option.hasBeenNegotiated()) return;
 186  0
         if (!option.isInNegotiation()) {
 187  0
             negotiateOption(WONT, optionID);
 188  
         }
 189  0
         option.disable();
 190  0
     }
 191  
 
 192  
     // TODO:0: Replace with actual logging
 193  
     private void println(String s) {
 194  
         // System.out.println(s);
 195  0
     }
 196  
 
 197  
     // TODO:0: Replace with actual logging
 198  
     private void print(String s) {
 199  
         // System.out.print(s);
 200  0
     }
 201  
 
 202  
     /**
 203  
      * Send an option negitiation command to the client
 204  
      *
 205  
      * @param negotiate
 206  
      * @param optionID
 207  
      * @throws IOException
 208  
      */
 209  
     private void negotiateOption(int negotiate, int optionID)
 210  
             throws IOException {
 211  0
         TelnetOption option = getOption(optionID);
 212  0
         option.isInNegotiation(true);
 213  0
         String n = null;
 214  0
         switch (negotiate) {
 215  
             case WILL:
 216  0
                 n = "WILL ";
 217  0
                 break;
 218  
             case DO:
 219  0
                 n = "DO ";
 220  0
                 break;
 221  
             case WONT:
 222  0
                 n = "WONT ";
 223  0
                 break;
 224  
             case DONT:
 225  0
                 n = "DONT ";
 226  
                 break;
 227  
         }
 228  
         // Debug statement
 229  0
         println("S: IAC " + n + optionID);
 230  0
         synchronized (out) {
 231  0
             out.write(IAC);
 232  0
             out.write(negotiate);
 233  0
             out.write(optionID);
 234  0
         }
 235  0
     }
 236  
 
 237  
     private TelnetOption getOption(int optionID) {
 238  0
         TelnetOption opt = options[optionID];
 239  0
         if (opt == null) {
 240  0
             opt = new TelnetOption(optionID);
 241  0
             options[optionID] = opt;
 242  
         }
 243  0
         return opt;
 244  
     }
 245  
 }