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    *      https://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      /**
28       * Window size option
29       */
30      protected static final int WINDOW_SIZE = 31;
31  
32      /**
33       * Horizontal Size
34       */
35      private int width = 80;
36  
37      /**
38       * Vertical Size
39       */
40      private int height = 24;
41  
42      /**
43       * Constructor for the WindowSizeOptionHandler. Initial and accept behavior flags are set to false
44       *
45       * @param nWidth    Window width.
46       * @param nHeight   Window Height
47       */
48      public WindowSizeOptionHandler(final int nWidth, final int nHeight) {
49          super(TelnetOption.WINDOW_SIZE, false, false, false, false);
50  
51          width = nWidth;
52          height = nHeight;
53      }
54  
55      /**
56       * Constructor for the WindowSizeOptionHandler. Allows defining desired initial setting for local/remote activation of this option and behavior in case a
57       * local/remote activation request for this option is received.
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         // 2 //
119         for (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 }