View Javadoc
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  
18  package org.apache.commons.net.telnet;
19  
20  /**
21   * Implements the telnet window size option RFC 1073.
22   *
23   * @since 2.0
24   */
25  public class WindowSizeOptionHandler extends TelnetOptionHandler {
26      /**
27       * Window size option
28       */
29      protected static final int WINDOW_SIZE = 31;
30  
31      /**
32       * Horizontal Size
33       */
34      private int width = 80;
35  
36      /**
37       * Vertical Size
38       */
39      private int height = 24;
40  
41      /**
42       * Constructor for the WindowSizeOptionHandler. Initial and accept behavior flags are set to false
43       *
44       * @param nWidth  - Window width.
45       * @param nHeight - Window Height
46       */
47      public WindowSizeOptionHandler(final int nWidth, final int nHeight) {
48          super(TelnetOption.WINDOW_SIZE, false, false, false, false);
49  
50          width = nWidth;
51          height = nHeight;
52      }
53  
54      /**
55       * Constructor for the WindowSizeOptionHandler. Allows defining desired initial setting for local/remote activation of this option and behavior in case a
56       * local/remote activation request for this option is received.
57       * <p>
58       *
59       * @param nWidth       - Window width.
60       * @param nHeight      - Window Height
61       * @param initlocal    - if set to true, a {@code WILL} is sent upon connection.
62       * @param initremote   - if set to true, a {@code DO} is sent upon connection.
63       * @param acceptlocal  - if set to true, any {@code DO} request is accepted.
64       * @param acceptremote - if set to true, any {@code WILL} request is accepted.
65       */
66      public WindowSizeOptionHandler(final int nWidth, final int nHeight, final boolean initlocal, final boolean initremote, final boolean acceptlocal,
67              final boolean acceptremote) {
68          super(TelnetOption.WINDOW_SIZE, initlocal, initremote, acceptlocal, acceptremote);
69  
70          width = nWidth;
71          height = nHeight;
72      }
73  
74      /**
75       * Implements the abstract method of TelnetOptionHandler. This will send the client Height and Width to the server.
76       *
77       * @return array to send to remote system
78       */
79      @Override
80      public int[] startSubnegotiationLocal() {
81          final int nCompoundWindowSize = width * 0x10000 + height;
82          int nResponseSize = 5;
83          int nIndex;
84          int nShift;
85          int nTurnedOnBits;
86  
87          if (width % 0x100 == 0xFF) {
88              nResponseSize += 1;
89          }
90  
91          if (width / 0x100 == 0xFF) {
92              nResponseSize += 1;
93          }
94  
95          if (height % 0x100 == 0xFF) {
96              nResponseSize += 1;
97          }
98  
99          if (height / 0x100 == 0xFF) {
100             nResponseSize += 1;
101         }
102 
103         //
104         // allocate response array
105         //
106         final int[] response = new int[nResponseSize];
107 
108         //
109         // Build response array.
110         // ---------------------
111         // 1. put option name.
112         // 2. loop through Window size and fill the values,
113         // 3. duplicate 'ff' if needed.
114         //
115 
116         response[0] = WINDOW_SIZE; // 1 //
117 
118         for ( // 2 //
119                 nIndex = 1, nShift = 24; nIndex < nResponseSize; nIndex++, nShift -= 8) {
120             nTurnedOnBits = 0xFF;
121             nTurnedOnBits <<= nShift;
122             response[nIndex] = (nCompoundWindowSize & nTurnedOnBits) >>> nShift;
123 
124             if (response[nIndex] == 0xff) { // 3 //
125                 nIndex++;
126                 response[nIndex] = 0xff;
127             }
128         }
129 
130         return response;
131     }
132 
133 }