%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.net.tftp.TFTPRequestPacket |
|
|
1 | /* |
|
2 | * Copyright 2001-2005 The Apache Software Foundation |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
15 | */ |
|
16 | package org.apache.commons.net.tftp; |
|
17 | ||
18 | import java.net.DatagramPacket; |
|
19 | import java.net.InetAddress; |
|
20 | ||
21 | /*** |
|
22 | * An abstract class derived from TFTPPacket definiing a TFTP Request |
|
23 | * packet type. It is subclassed by the |
|
24 | * {@link org.apache.commons.net.tftp.TFTPReadRequestPacket} |
|
25 | * and |
|
26 | * {@link org.apache.commons.net.tftp.TFTPWriteRequestPacket} |
|
27 | * classes. |
|
28 | * <p> |
|
29 | * Details regarding the TFTP protocol and the format of TFTP packets can |
|
30 | * be found in RFC 783. But the point of these classes is to keep you |
|
31 | * from having to worry about the internals. Additionally, only very |
|
32 | * few people should have to care about any of the TFTPPacket classes |
|
33 | * or derived classes. Almost all users should only be concerned with the |
|
34 | * {@link org.apache.commons.net.tftp.TFTPClient} class |
|
35 | * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()} |
|
36 | * and |
|
37 | * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()} |
|
38 | * methods. |
|
39 | * <p> |
|
40 | * <p> |
|
41 | * @author Daniel F. Savarese |
|
42 | * @see TFTPPacket |
|
43 | * @see TFTPReadRequestPacket |
|
44 | * @see TFTPWriteRequestPacket |
|
45 | * @see TFTPPacketException |
|
46 | * @see TFTP |
|
47 | ***/ |
|
48 | ||
49 | public abstract class TFTPRequestPacket extends TFTPPacket |
|
50 | { |
|
51 | /*** |
|
52 | * An array containing the string names of the transfer modes and indexed |
|
53 | * by the transfer mode constants. |
|
54 | ***/ |
|
55 | 0 | static final String[] _modeStrings = { "netascii", "octet" }; |
56 | ||
57 | /*** |
|
58 | * A null terminated byte array representation of the ascii names of the |
|
59 | * transfer mode constants. This is convenient for creating the TFTP |
|
60 | * request packets. |
|
61 | ***/ |
|
62 | 0 | static final byte[] _modeBytes[] = { |
63 | { (byte)'n', (byte)'e', (byte)'t', (byte)'a', (byte)'s', (byte)'c', |
|
64 | (byte)'i', (byte)'i', 0 }, |
|
65 | { (byte)'o', (byte)'c', (byte)'t', (byte)'e', (byte)'t', 0 } |
|
66 | }; |
|
67 | ||
68 | /*** The transfer mode of the request. ***/ |
|
69 | int _mode; |
|
70 | ||
71 | /*** The filename of the request. ***/ |
|
72 | String _filename; |
|
73 | ||
74 | /*** |
|
75 | * Creates a request packet of a given type to be sent to a host at a |
|
76 | * given port with a filename and transfer mode request. |
|
77 | * <p> |
|
78 | * @param destination The host to which the packet is going to be sent. |
|
79 | * @param port The port to which the packet is going to be sent. |
|
80 | * @param type The type of the request (either TFTPPacket.READ_REQUEST or |
|
81 | * TFTPPacket.WRITE_REQUEST). |
|
82 | * @param filename The requested filename. |
|
83 | * @param mode The requested transfer mode. This should be on of the TFTP |
|
84 | * class MODE constants (e.g., TFTP.NETASCII_MODE). |
|
85 | ***/ |
|
86 | TFTPRequestPacket(InetAddress destination, int port, |
|
87 | int type, String filename, class="keyword">int mode) |
|
88 | { |
|
89 | 0 | super(type, destination, port); |
90 | ||
91 | 0 | _filename = filename; |
92 | 0 | _mode = mode; |
93 | 0 | } |
94 | ||
95 | /*** |
|
96 | * Creates a request packet of a given type based on a received |
|
97 | * datagram. Assumes the datagram is at least length 4, else an |
|
98 | * ArrayIndexOutOfBoundsException may be thrown. |
|
99 | * <p> |
|
100 | * @param type The type of the request (either TFTPPacket.READ_REQUEST or |
|
101 | * TFTPPacket.WRITE_REQUEST). |
|
102 | * @param datagram The datagram containing the received request. |
|
103 | * @throws TFTPPacketException If the datagram isn't a valid TFTP |
|
104 | * request packet of the appropriate type. |
|
105 | ***/ |
|
106 | TFTPRequestPacket(int type, DatagramPacket datagram) |
|
107 | throws TFTPPacketException |
|
108 | { |
|
109 | 0 | super(type, datagram.getAddress(), datagram.getPort()); |
110 | ||
111 | byte[] data; |
|
112 | int index, length; |
|
113 | String mode; |
|
114 | StringBuffer buffer; |
|
115 | ||
116 | 0 | data = datagram.getData(); |
117 | ||
118 | 0 | if (getType() != data[1]) |
119 | 0 | throw new TFTPPacketException("TFTP operator code does not match type."); |
120 | ||
121 | 0 | buffer = new StringBuffer(); |
122 | ||
123 | 0 | index = 2; |
124 | 0 | length = datagram.getLength(); |
125 | ||
126 | 0 | while (index < length && data[index] != 0) |
127 | { |
|
128 | 0 | buffer.append((char)data[index]); |
129 | 0 | ++index; |
130 | } |
|
131 | ||
132 | 0 | _filename = buffer.toString(); |
133 | ||
134 | 0 | if (index >= length) |
135 | 0 | throw new TFTPPacketException("Bad filename and mode format."); |
136 | ||
137 | 0 | buffer.setLength(0); |
138 | 0 | ++index; // need to advance beyond the end of string marker |
139 | 0 | while (index < length && data[index] != 0) |
140 | { |
|
141 | 0 | buffer.append((char)data[index]); |
142 | 0 | ++index; |
143 | } |
|
144 | ||
145 | 0 | mode = buffer.toString().toLowerCase(); |
146 | 0 | length = _modeStrings.length; |
147 | ||
148 | 0 | for (index = 0; index < length; index++) |
149 | { |
|
150 | 0 | if (mode.equals(_modeStrings[index])) |
151 | { |
|
152 | 0 | _mode = index; |
153 | 0 | break; |
154 | } |
|
155 | } |
|
156 | ||
157 | 0 | if (index >= length) |
158 | { |
|
159 | 0 | throw new TFTPPacketException("Unrecognized TFTP transfer mode: " + mode); |
160 | // May just want to default to binary mode instead of throwing |
|
161 | // exception. |
|
162 | //_mode = TFTP.OCTET_MODE; |
|
163 | } |
|
164 | 0 | } |
165 | ||
166 | ||
167 | /*** |
|
168 | * This is a method only available within the package for |
|
169 | * implementing efficient datagram transport by elminating buffering. |
|
170 | * It takes a datagram as an argument, and a byte buffer in which |
|
171 | * to store the raw datagram data. Inside the method, the data |
|
172 | * is set as the datagram's data and the datagram returned. |
|
173 | * <p> |
|
174 | * @param datagram The datagram to create. |
|
175 | * @param data The buffer to store the packet and to use in the datagram. |
|
176 | * @return The datagram argument. |
|
177 | ***/ |
|
178 | final DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data) |
|
179 | { |
|
180 | int fileLength, modeLength; |
|
181 | ||
182 | 0 | fileLength = _filename.length(); |
183 | 0 | modeLength = _modeBytes[_mode].length; |
184 | ||
185 | 0 | data[0] = 0; |
186 | 0 | data[1] = (byte)_type; |
187 | 0 | System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength); |
188 | 0 | data[fileLength + 2] = 0; |
189 | 0 | System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3, |
190 | modeLength); |
|
191 | ||
192 | 0 | datagram.setAddress(_address); |
193 | 0 | datagram.setPort(_port); |
194 | 0 | datagram.setData(data); |
195 | 0 | datagram.setLength(fileLength + modeLength + 3); |
196 | ||
197 | 0 | return datagram; |
198 | } |
|
199 | ||
200 | /*** |
|
201 | * Creates a UDP datagram containing all the TFTP |
|
202 | * request packet data in the proper format. |
|
203 | * This is a method exposed to the programmer in case he |
|
204 | * wants to implement his own TFTP client instead of using |
|
205 | * the {@link org.apache.commons.net.tftp.TFTPClient} |
|
206 | * class. Under normal circumstances, you should not have a need to call |
|
207 | * this method. |
|
208 | * <p> |
|
209 | * @return A UDP datagram containing the TFTP request packet. |
|
210 | ***/ |
|
211 | public final DatagramPacket newDatagram() |
|
212 | { |
|
213 | int fileLength, modeLength; |
|
214 | byte[] data; |
|
215 | ||
216 | 0 | fileLength = _filename.length(); |
217 | 0 | modeLength = _modeBytes[_mode].length; |
218 | ||
219 | 0 | data = new byte[fileLength + modeLength + 4]; |
220 | 0 | data[0] = 0; |
221 | 0 | data[1] = (byte)_type; |
222 | 0 | System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength); |
223 | 0 | data[fileLength + 2] = 0; |
224 | 0 | System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3, |
225 | modeLength); |
|
226 | ||
227 | 0 | return new DatagramPacket(data, data.length, _address, _port); |
228 | } |
|
229 | ||
230 | /*** |
|
231 | * Returns the transfer mode of the request. |
|
232 | * <p> |
|
233 | * @return The transfer mode of the request. |
|
234 | ***/ |
|
235 | public final int getMode() |
|
236 | { |
|
237 | 0 | return _mode; |
238 | } |
|
239 | ||
240 | /*** |
|
241 | * Returns the requested filename. |
|
242 | * <p> |
|
243 | * @return The requested filename. |
|
244 | ***/ |
|
245 | public final String getFilename() |
|
246 | { |
|
247 | 0 | return _filename; |
248 | } |
|
249 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |