You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by br...@apache.org on 2002/04/03 06:42:22 UTC
cvs commit: jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp TFTP.java TFTPAckPacket.java TFTPClient.java TFTPDataPacket.java TFTPErrorPacket.java TFTPPacket.java TFTPPacketException.java TFTPReadRequestPacket.java TFTPRequestPacket.java TFTPWriteRequestPacket.java
brekke 02/04/02 20:42:22
Added: net/src/java/org/apache/commons/net/tftp TFTP.java
TFTPAckPacket.java TFTPClient.java
TFTPDataPacket.java TFTPErrorPacket.java
TFTPPacket.java TFTPPacketException.java
TFTPReadRequestPacket.java TFTPRequestPacket.java
TFTPWriteRequestPacket.java
Log:
Moved com.oroinc.net.tftp to org.apache.commons.net.tftp
Revision Changes Path
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTP.java
Index: TFTP.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.*;
import java.net.*;
/***
* The TFTP class exposes a set of methods to allow you to deal with the TFTP
* protocol directly, in case you want to write your own TFTP client or
* server. However, almost every user should only be concerend with
* the <a href="org.apache.commons.net.DatagramSocketClient.html#open"> open() </a>,
* and <a href="org.apache.commons.net.DatagramSocketClient.html#close"> close() </a>,
* methods. Additionally,the a
* <a href="org.apache.commons.net.DatagramSocketClient.html#setDefaultTimeout">
* setDefaultTimeout() </a> method may be of importance for performance tuning.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals.
* <p>
* <p>
* @author Daniel F. Savarese
* @see org.apache.commons.net.DatagramSocketClient
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTPClient
***/
public class TFTP extends org.apache.commons.net.DatagramSocketClient {
/***
* The ascii transfer mode. Its value is 0 and equivalent to NETASCII_MODE
***/
public static final int ASCII_MODE = 0;
/***
* The netascii transfer mode. Its value is 0.
***/
public static final int NETASCII_MODE = 0;
/***
* The binary transfer mode. Its value is 1 and equivalent to OCTET_MODE.
***/
public static final int BINARY_MODE = 1;
/***
* The image transfer mode. Its value is 1 and equivalent to OCTET_MODE.
***/
public static final int IMAGE_MODE = 1;
/***
* The octet transfer mode. Its value is 1.
***/
public static final int OCTET_MODE = 1;
/***
* The default number of milliseconds to wait to receive a datagram
* before timing out. The default is 5000 milliseconds (5 seconds).
***/
public static final int DEFAULT_TIMEOUT = 5000;
/***
* The default TFTP port according to RFC 783 is 69.
***/
public static final int DEFAULT_PORT = 69;
/***
* The size to use for TFTP packet buffers. Its 4 plus the
* TFTPPacket.SEGMENT_SIZE, i.e. 516.
***/
static final int PACKET_SIZE = TFTPPacket.SEGMENT_SIZE + 4;
/*** A buffer used to accelerate receives in bufferedReceive() ***/
private byte[] __receiveBuffer;
/*** A datagram used to minimize memory allocation in bufferedReceive() ***/
private DatagramPacket __receiveDatagram;
/*** A datagram used to minimize memory allocation in bufferedSend() ***/
private DatagramPacket __sendDatagram;
/***
* A buffer used to accelerate sends in bufferedSend().
* It is left package visible so that TFTPClient may be slightly more
* efficient during file sends. It saves the creation of an
* additional buffer and prevents a buffer copy in _newDataPcket().
***/
byte[] _sendBuffer;
/***
* Returns the TFTP string representation of a TFTP transfer mode.
* Will throw an ArrayIndexOutOfBoundsException if an invalid transfer
* mode is specified.
* <p>
* @param mode The TFTP transfer mode. One of the MODE constants.
* @return The TFTP string representation of the TFTP transfer mode.
***/
public static final String getModeName(int mode) {
return TFTPRequestPacket._modeStrings[mode];
}
/***
* Creates a TFTP instance with a default timeout of DEFAULT_TIMEOUT,
* a null socket, and buffered operations disabled.
***/
public TFTP() {
setDefaultTimeout(DEFAULT_TIMEOUT);
__receiveBuffer = null;
__receiveDatagram = null;
}
/***
* This method synchronizes a connection by discarding all packets that
* may be in the local socket buffer. This method need only be called
* when you implement your own TFTP client or server.
* <p>
* @exception IOException if an I/O error occurs.
***/
public final void discardPackets() throws IOException {
int to;
DatagramPacket datagram;
datagram = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
to = getSoTimeout();
setSoTimeout(1);
try {
while(true)
_socket_.receive(datagram);
} catch(SocketException e) {
// Do nothing. We timed out so we hope we're caught up.
} catch(InterruptedIOException e) {
// Do nothing. We timed out so we hope we're caught up.
}
setSoTimeout(to);
}
/***
* This is a special method to perform a more efficient packet receive.
* It should only be used after calling
* <a href="#beginBufferedOps"> beginBufferedOps() </a>. beginBufferedOps()
* initializes a set of buffers used internally that prevent the new
* allocation of a DatagramPacket and byte array for each send and receive.
* To use these buffers you must call the bufferedReceive() and
* bufferedSend() methods instead of send() and receive(). You must
* also be certain that you don't manipulate the resulting packet in
* such a way that it interferes with future buffered operations.
* For example, a TFTPDataPacket received with bufferedReceive() will
* have a reference to the internal byte buffer. You must finish using
* this data before calling bufferedReceive() again, or else the data
* will be overwritten by the the call.
* <p>
* @return The TFTPPacket received.
* @exception InterruptedIOException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception SocketException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception IOException If some other I/O error occurs.
* @exception TFTPPacketException If an invalid TFTP packet is received.
***/
public final TFTPPacket bufferedReceive() throws IOException,
InterruptedIOException, SocketException, TFTPPacketException
{
__receiveDatagram.setData(__receiveBuffer);
__receiveDatagram.setLength(__receiveBuffer.length);
_socket_.receive(__receiveDatagram);
return TFTPPacket.newTFTPPacket(__receiveDatagram);
}
/***
* This is a special method to perform a more efficient packet send.
* It should only be used after calling
* <a href="#beginBufferedOps"> beginBufferedOps() </a>. beginBufferedOps()
* initializes a set of buffers used internally that prevent the new
* allocation of a DatagramPacket and byte array for each send and receive.
* To use these buffers you must call the bufferedReceive() and
* bufferedSend() methods instead of send() and receive(). You must
* also be certain that you don't manipulate the resulting packet in
* such a way that it interferes with future buffered operations.
* For example, a TFTPDataPacket received with bufferedReceive() will
* have a reference to the internal byte buffer. You must finish using
* this data before calling bufferedReceive() again, or else the data
* will be overwritten by the the call.
* <p>
* @param TFTPPacket The TFTP packet to send.
* @exception IOException If some I/O error occurs.
***/
public final void bufferedSend(TFTPPacket packet) throws IOException {
_socket_.send(packet._newDatagram(__sendDatagram, _sendBuffer));
}
/***
* Initializes the internal buffers used by
* <a href="#bufferedSend"> bufferedSend() </a> and
* <a href="#bufferedReceive"> bufferedReceive() </a>. This
* method must be called before calling either one of those two
* methods. When you finish using buffered operations, you must
* call <a href="#endBufferedOps"> endBufferedOps() </a>.
***/
public final void beginBufferedOps() {
__receiveBuffer = new byte[PACKET_SIZE];
__receiveDatagram =
new DatagramPacket(__receiveBuffer, __receiveBuffer.length);
_sendBuffer = new byte[PACKET_SIZE];
__sendDatagram =
new DatagramPacket(_sendBuffer, _sendBuffer.length);
}
/***
* Releases the resources used to perform buffered sends and receives.
***/
public final void endBufferedOps() {
__receiveBuffer = null;
__receiveDatagram = null;
_sendBuffer = null;
__sendDatagram = null;
}
/***
* Sends a TFTP packet to its destination.
* <p>
* @param TFTPPacket The TFTP packet to send.
* @exception IOException If some I/O error occurs.
***/
public final void send(TFTPPacket packet) throws IOException {
_socket_.send(packet.newDatagram());
}
/***
* Receives a TFTPPacket.
* <p>
* @return The TFTPPacket received.
* @exception InterruptedIOException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception SocketException If a socket timeout occurs. The
* Java documentation claims an InterruptedIOException is thrown
* on a DatagramSocket timeout, but in practice we find a
* SocketException is thrown. You should catch both to be safe.
* @exception IOException If some other I/O error occurs.
* @exception TFTPPacketException If an invalid TFTP packet is received.
***/
public final TFTPPacket receive() throws IOException, InterruptedIOException,
SocketException, TFTPPacketException
{
DatagramPacket packet;
packet = new DatagramPacket(new byte[PACKET_SIZE], PACKET_SIZE);
_socket_.receive(packet);
return TFTPPacket.newTFTPPacket(packet);
}
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPAckPacket.java
Index: TFTPAckPacket.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.net.*;
/***
* A final class derived from TFTPPacket definiing the TFTP Acknowledgement
* packet type.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPAckPacket extends TFTPPacket {
/*** The block number being acknowledged by the packet. ***/
int _blockNumber;
/***
* Creates an acknowledgment packet to be sent to a host at a given port
* acknowledging receipt of a block.
* <p>
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param blockNumber The block number being acknowledged.
***/
public TFTPAckPacket(InetAddress destination, int port, int blockNumber) {
super(TFTPPacket.ACKNOWLEDGEMENT, destination, port);
_blockNumber = blockNumber;
}
/***
* Creates an acknowledgement packet based from a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
* <p>
* @param datagram The datagram containing the received acknowledgement.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* acknowledgement packet.
***/
TFTPAckPacket(DatagramPacket datagram) throws TFTPPacketException {
super(TFTPPacket.ACKNOWLEDGEMENT, datagram.getAddress(),
datagram.getPort());
byte[] data;
data = datagram.getData();
if(getType() != data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
_blockNumber = (((data[2] & 0xff) << 8) | (data[3] & 0xff));
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
* <p>
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data) {
data[0] = 0; data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(4);
return datagram;
}
/***
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
* class.
* Under normal circumstances, you should not have a need to call this
* method. It creates a UDP datagram containing all the TFTP
* acknowledgement packet data in the proper format.
* <p>
* @return A UDP datagram containing the TFTP acknowledgement packet.
***/
public DatagramPacket newDatagram() {
byte[] data;
data = new byte[4];
data[0] = 0; data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
return new DatagramPacket(data, data.length, _address, _port);
}
/***
* Returns the block number of the acknowledgement.
* <p>
* @return The block number of the acknowledgement.
***/
public int getBlockNumber() { return _blockNumber; }
/*** Sets the block number of the acknowledgement. ***/
public void setBlockNumber(int blockNumber) { _blockNumber = blockNumber; }
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPClient.java
Index: TFTPClient.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.io.*;
import java.net.*;
import org.apache.commons.io.*;
/***
* The TFTPClient class encapsulates all the aspects of the TFTP protocol
* necessary to receive and send files through TFTP. It is derived from
* the <a href="org.apache.commons.net.tftp.TFTP.html"> TFTP class </a> because
* it is more convenient than using aggregation, and as a result exposes
* the same set of methods to allow you to deal with the TFTP protocol
* directly. However, almost every user should only be concerend with the
* the <a href="org.apache.commons.net.DatagramSocketClient.html#open"> open() </a>,
* <a href="org.apache.commons.net.DatagramSocketClient.html#close"> close() </a>,
* <a href="#sendFile"> sendFile() </a>, and
* <a href="#receiveFile"> receiveFile() </a> methods. Additionally, the
* <a href="#setMaxTimeouts"> setMaxTimeouts() </a> and
* <a href="org.apache.commons.net.DatagramSocketClient.html#setDefaultTimeout">
* setDefaultTimeout() </a> methods may be of importance for performance
* tuning.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTP
* @see TFTPPacket
* @see TFTPPacketException
***/
public class TFTPClient extends TFTP {
/***
* The default number of times a receive attempt is allowed to timeout
* before ending attempts to retry the receive and failing. The default
* is 5 timeouts.
***/
public static final int DEFAULT_MAX_TIMEOUTS = 5;
/*** The maximum number of timeouts allowed before failing. ***/
private int __maxTimeouts;
/***
* Creates a TFTPClient instance with a default timeout of DEFAULT_TIMEOUT,
* maximum timeouts value of DEFAULT_MAX_TIMEOUTS, a null socket,
* and buffered operations disabled.
***/
public TFTPClient() {
__maxTimeouts = DEFAULT_MAX_TIMEOUTS;
}
/***
* Sets the maximum number of times a receive attempt is allowed to
* timeout during a receiveFile() or sendFile() operation before ending
* attempts to retry the receive and failing.
* The default is DEFAULT_MAX_TIMEOUTS.
* <p>
* @param numTimeouts The maximum number of timeouts to allow. Values
* less than 1 should not be used, but if they are, they are
* treated as 1.
***/
public void setMaxTimeouts(int numTimeouts) {
if(__maxTimeouts < 1)
__maxTimeouts = 1;
else
__maxTimeouts = numTimeouts;
}
/***
* Returns the maximum number of times a receive attempt is allowed to
* timeout before ending attempts to retry the receive and failing.
* <p>
* @return The maximum number of timeouts allowed.
***/
public int getMaxTimeouts() { return __maxTimeouts; }
/***
* Requests a named file from a remote host, writes the
* file to an OutputStream, closes the connection, and returns the number
* of bytes read. A local UDP socket must first be created by
* <a href="org.apache.commons.net.DatagramSocketClient.html#open">open()</a> before
* invoking this method. This method will not close the OutputStream
* containing the file; you must close it after the method invocation.
* <p>
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param host The remote host serving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
***/
public int receiveFile(String filename, int mode, OutputStream output,
InetAddress host, int port) throws IOException
{
int bytesRead, timeouts, lastBlock, block, hostPort, dataLength;
TFTPPacket sent, received = null;
TFTPErrorPacket error;
TFTPDataPacket data;
TFTPAckPacket ack = new TFTPAckPacket(host, port, 0);
beginBufferedOps();
dataLength = lastBlock = hostPort = bytesRead = 0;
block = 1;
if(mode == TFTP.ASCII_MODE)
output = new FromNetASCIIOutputStream(output);
sent =
new TFTPReadRequestPacket(host, port, filename, mode);
_sendPacket:
do {
bufferedSend(sent);
_receivePacket:
while(true) {
timeouts = 0;
while(timeouts < __maxTimeouts) {
try {
//System.err.println("Receiving.");
received = bufferedReceive();
break;
} catch(SocketException e) {
if(++timeouts >= __maxTimeouts) {
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
} catch(InterruptedIOException e) {
if(++timeouts >= __maxTimeouts) {
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
} catch(TFTPPacketException e) {
endBufferedOps();
throw new IOException("Bad packet: " + e.getMessage());
}
}
//System.err.println("Got an answer.");
// The first time we receive we get the port number.
if(lastBlock == 0) {
hostPort = received.getPort();
ack.setPort(hostPort);
}
// Comply with RFC 783 indication that an error acknowledgement
// should be sent to originator if unexpected TID or host.
if(host.equals(received.getAddress()) &&
received.getPort() == hostPort) {
//System.err.println("Got this far.");
switch(received.getType()) {
case TFTPPacket.ERROR:
error = (TFTPErrorPacket)received;
endBufferedOps();
throw new IOException("Error code " + error.getError() +
" received: " + error.getMessage());
case TFTPPacket.DATA:
data = (TFTPDataPacket)received;
dataLength = data.getDataLength();
lastBlock = data.getBlockNumber();
//System.err.println("Data: Got Block: " + lastBlock +" Expected: " + block);
if(lastBlock == block) {
try {
output.write(data.getData(), data.getDataOffset(),
dataLength);
} catch(IOException e){
error = new TFTPErrorPacket(host, hostPort,
TFTPErrorPacket.OUT_OF_SPACE,
"File write failed.");
bufferedSend(error);
endBufferedOps();
throw e;
}
++block;
break _receivePacket;
} else {
discardPackets();
if(lastBlock == (block - 1))
continue _sendPacket; // Resend last acknowledgement.
continue _receivePacket; // Start fetching packets again.
}
//break;
default:
endBufferedOps();
throw new IOException("Received unexpected packet type.");
}
} else {
error = new TFTPErrorPacket(received.getAddress(),
received.getPort(),
TFTPErrorPacket.UNKNOWN_TID,
"Unexpected host or port.");
bufferedSend(error);
continue _sendPacket;
}
// We should never get here, but this is a safety to avoid
// infinite loop. If only Java had the goto statement.
//break;
}
//System.err.println("Setting acknowledgement: " + lastBlock);
ack.setBlockNumber(lastBlock);
sent = ack;
bytesRead+=dataLength;
//System.err.println("bytesRead: " + bytesRead);
}// First data packet less than 512 bytes signals end of stream.
while(dataLength == TFTPPacket.SEGMENT_SIZE);
bufferedSend(sent);
endBufferedOps();
return bytesRead;
}
/***
* Requests a named file from a remote host, writes the
* file to an OutputStream, closes the connection, and returns the number
* of bytes read. A local UDP socket must first be created by
* <a href="org.apache.commons.net.DatagramSocketClient.html#open">open()</a> before
* invoking this method. This method will not close the OutputStream
* containing the file; you must close it after the method invocation.
* <p>
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param hostname The name of the remote host serving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public int receiveFile(String filename, int mode, OutputStream output,
String hostname, int port)
throws UnknownHostException, IOException
{
return receiveFile(filename, mode, output, InetAddress.getByName(hostname),
port);
}
/***
* Same as calling
* <code> receiveFile(filename, mode, output, host, TFTP.DEFAULT_PORT)
* </code> <p>
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param host The remote host serving the file.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
***/
public int receiveFile(String filename, int mode, OutputStream output,
InetAddress host)
throws IOException
{
return receiveFile(filename, mode, output, host, DEFAULT_PORT);
}
/***
* Same as calling
* <code> receiveFile(filename, mode, output, hostname, TFTP.DEFAULT_PORT)
* </code> <p>
* @param filename The name of the file to receive.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The OutputStream to which the file should be written.
* @param hostname The name of the remote host serving the file.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public int receiveFile(String filename, int mode, OutputStream output,
String hostname)
throws UnknownHostException, IOException
{
return receiveFile(filename, mode, output, InetAddress.getByName(hostname),
DEFAULT_PORT);
}
/***
* Requests to send a file to a remote host, reads the file from an
* InputStream, sends the file to the remote host, and closes the
* connection. A local UDP socket must first be created by
* <a href="org.apache.commons.net.DatagramSocketClient.html#open">open()</a> before
* invoking this method. This method will not close the InputStream
* containing the file; you must close it after the method invocation.
* <p>
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The InputStream containing the file.
* @param host The remote host receiving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
***/
public void sendFile(String filename, int mode, InputStream input,
InetAddress host, int port) throws IOException {
int bytesRead, timeouts, lastBlock, block, hostPort, dataLength, offset;
TFTPPacket sent, received = null;
TFTPErrorPacket error;
TFTPDataPacket data =
new TFTPDataPacket(host, port, 0, _sendBuffer, 4, 0);;
TFTPAckPacket ack;
beginBufferedOps();
dataLength = lastBlock = hostPort = bytesRead = 0;
block = 0;
if(mode == TFTP.ASCII_MODE)
input = new ToNetASCIIInputStream(input);
sent =
new TFTPWriteRequestPacket(host, port, filename, mode);
_sendPacket:
do {
bufferedSend(sent);
_receivePacket:
while(true) {
timeouts = 0;
while(timeouts < __maxTimeouts) {
try {
//System.err.println("Receiving.");
received = bufferedReceive();
break;
} catch(SocketException e) {
if(++timeouts >= __maxTimeouts) {
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
} catch(InterruptedIOException e) {
if(++timeouts >= __maxTimeouts) {
endBufferedOps();
throw new IOException("Connection timed out.");
}
continue;
} catch(TFTPPacketException e) {
endBufferedOps();
throw new IOException("Bad packet: " + e.getMessage());
}
}
//System.err.println("Got an answer.");
// The first time we receive we get the port number.
if(lastBlock == 0) {
hostPort = received.getPort();
data.setPort(hostPort);
}
// Comply with RFC 783 indication that an error acknowledgement
// should be sent to originator if unexpected TID or host.
if(host.equals(received.getAddress()) &&
received.getPort() == hostPort) {
//System.err.println("Got this far.");
switch(received.getType()) {
case TFTPPacket.ERROR:
error = (TFTPErrorPacket)received;
endBufferedOps();
throw new IOException("Error code " + error.getError() +
" received: " + error.getMessage());
case TFTPPacket.ACKNOWLEDGEMENT:
ack = (TFTPAckPacket)received;
lastBlock = ack.getBlockNumber();
//System.err.println("Ack: Got Block: " + lastBlock +" Expected: " + block);
if(lastBlock == block) {
++block;
break _receivePacket;
} else {
discardPackets();
if(lastBlock == (block - 1))
continue _sendPacket; // Resend last acknowledgement.
continue _receivePacket; // Start fetching packets again.
}
//break;
default:
endBufferedOps();
throw new IOException("Received unexpected packet type.");
}
} else {
error = new TFTPErrorPacket(received.getAddress(),
received.getPort(),
TFTPErrorPacket.UNKNOWN_TID,
"Unexpected host or port.");
bufferedSend(error);
continue _sendPacket;
}
// We should never get here, but this is a safety to avoid
// infinite loop. If only Java had the goto statement.
//break;
}
dataLength = TFTPPacket.SEGMENT_SIZE;
offset = 4;
while(dataLength > 0 &&
(bytesRead = input.read(_sendBuffer, offset, dataLength)) > 0) {
offset+=bytesRead;
dataLength-=bytesRead;
}
data.setBlockNumber(block);
data.setData(_sendBuffer, 4, offset - 4);
sent = data;
} while(dataLength == 0);
bufferedSend(sent);
endBufferedOps();
}
/***
* Requests to send a file to a remote host, reads the file from an
* InputStream, sends the file to the remote host, and closes the
* connection. A local UDP socket must first be created by
* <a href="org.apache.commons.net.DatagramSocketClient.html#open">open()</a> before
* invoking this method. This method will not close the InputStream
* containing the file; you must close it after the method invocation.
* <p>
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The InputStream containing the file.
* @param hostname The name of the remote host receiving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public void sendFile(String filename, int mode, InputStream input,
String hostname, int port)
throws UnknownHostException, IOException
{
sendFile(filename, mode, input, InetAddress.getByName(hostname), port);
}
/***
* Same as calling
* <code> sendFile(filename, mode, input, host, TFTP.DEFAULT_PORT); </code>
* <p>
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The InputStream containing the file.
* @param hostname The name of the remote host receiving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public void sendFile(String filename, int mode, InputStream input,
InetAddress host)
throws IOException
{
sendFile(filename, mode, input, host, DEFAULT_PORT);
}
/***
* Same as calling
* <code> sendFile(filename, mode, input, hostname, TFTP.DEFAULT_PORT);
* </code> <p>
* @param filename The name the remote server should use when creating
* the file on its file system.
* @param mode The TFTP mode of the transfer (one of the MODE constants).
* @param output The InputStream containing the file.
* @param hostname The name of the remote host receiving the file.
* @param port The port number of the remote TFTP server.
* @exception IOException If an I/O error occurs. The nature of the
* error will be reported in the message.
* @exception UnknownHostException If the hostname cannot be resolved.
***/
public void sendFile(String filename, int mode, InputStream input,
String hostname)
throws UnknownHostException, IOException
{
sendFile(filename, mode, input, InetAddress.getByName(hostname),
DEFAULT_PORT);
}
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPDataPacket.java
Index: TFTPDataPacket.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.net.*;
/***
* A final class derived from TFTPPacket definiing the TFTP Data
* packet type.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPDataPacket extends TFTPPacket {
/*** The maximum number of bytes in a TFTP data packet (512) ***/
public static final int MAX_DATA_LENGTH = 512;
/*** The minimum number of bytes in a TFTP data packet (0) ***/
public static final int MIN_DATA_LENGTH = 0;
/*** The block number of the packet. ***/
int _blockNumber;
/*** The length of the data. ***/
int _length;
/*** The offset into the _data array at which the data begins. ***/
int _offset;
/*** The data stored in the packet. ***/
byte[] _data;
/***
* Creates a data packet to be sent to a host at a given port
* with a given block number. The actual data to be sent is passed as
* an array, an offset, and a length. The offset is the offset into
* the byte array where the data starts. The length is the length of
* the data. If the length is greater than MAX_DATA_LENGTH, it is
* truncated.
* <p>
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param blockNumber The block number of the data.
* @param data The byte array containing the data.
* @param offset The offset into the array where the data starts.
* @param length The length of the data.
***/
public TFTPDataPacket(InetAddress destination, int port, int blockNumber,
byte[] data, int offset, int length){
super(TFTPPacket.DATA, destination, port);
_blockNumber = blockNumber;
_data = data;
_offset = offset;
if(length > MAX_DATA_LENGTH)
_length = MAX_DATA_LENGTH;
else
_length = length;
}
public TFTPDataPacket(InetAddress destination, int port, int blockNumber,
byte[] data) {
this(destination, port, blockNumber, data, 0, data.length);
}
/***
* Creates a data packet based from a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
* <p>
* @param datagram The datagram containing the received data.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* data packet.
***/
TFTPDataPacket(DatagramPacket datagram) throws TFTPPacketException {
super(TFTPPacket.DATA, datagram.getAddress(), datagram.getPort());
_data = datagram.getData();
_offset = 4;
if(getType() != _data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
_blockNumber = (((_data[2] & 0xff) << 8) | (_data[3] & 0xff));
_length = datagram.getLength() - 4;
if(_length > MAX_DATA_LENGTH)
_length = MAX_DATA_LENGTH;
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
* <p>
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data) {
data[0] = 0; data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
// Doublecheck we're not the same
if(data != _data)
System.arraycopy(_data, _offset, data, 4, _length);
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(_length + 4);
return datagram;
}
/***
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
* class.
* Under normal circumstances, you should not have a need to call this
* method. It creates a UDP datagram containing all the TFTP
* data packet data in the proper format.
* <p>
* @return A UDP datagram containing the TFTP data packet.
***/
public DatagramPacket newDatagram() {
byte[] data;
DatagramPacket datagram;
data = new byte[_length + 4];
data[0] = 0; data[1] = (byte)_type;
data[2] = (byte)((_blockNumber & 0xffff) >> 8);
data[3] = (byte)(_blockNumber & 0xff);
System.arraycopy(_data, _offset, data, 4, _length);
return new DatagramPacket(data, _length + 4, _address, _port);
}
/***
* Returns the block number of the data packet.
* <p>
* @return The block number of the data packet.
***/
public int getBlockNumber() { return _blockNumber; }
/*** Sets the block number of the data packet. ***/
public void setBlockNumber(int blockNumber) { _blockNumber = blockNumber; }
/***
* Sets the data for the data packet.
* <p>
* @param data The byte array containing the data.
* @param offset The offset into the array where the data starts.
* @param length The length of the data.
***/
public void setData(byte[] data, int offset, int length) {
_data = data;
_offset = offset;
_length = length;
if(length > MAX_DATA_LENGTH)
_length = MAX_DATA_LENGTH;
else
_length = length;
}
/***
* Returns the length of the data part of the data packet.
* <p>
* @return The length of the data part of the data packet.
***/
public int getDataLength() { return _length; }
/***
* Returns the offset into the byte array where the packet data actually
* starts.
* <p>
* @return The offset into the byte array where the packet data actually
* starts.
***/
public int getDataOffset() { return _offset; }
/***
* Returns the byte array containing the packet data.
* <p>
* @return The byte array containing the packet data.
***/
public byte[] getData() { return _data; }
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPErrorPacket.java
Index: TFTPErrorPacket.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.net.*;
/***
* A final class derived from TFTPPacket definiing the TFTP Error
* packet type.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPErrorPacket extends TFTPPacket {
/*** The undefined error code according to RFC 783, value 0. ***/
public static final int UNDEFINED = 0;
/*** The file not found error code according to RFC 783, value 1. ***/
public static final int FILE_NOT_FOUND = 1;
/*** The access violation error code according to RFC 783, value 2. ***/
public static final int ACCESS_VIOLATION = 2;
/*** The disk full error code according to RFC 783, value 3. ***/
public static final int OUT_OF_SPACE = 3;
/***
* The illegal TFTP operation error code according to RFC 783, value 4.
***/
public static final int ILLEGAL_OPERATION = 4;
/*** The unknown transfer id error code according to RFC 783, value 5. ***/
public static final int UNKNOWN_TID = 5;
/*** The file already exists error code according to RFC 783, value 6. ***/
public static final int FILE_EXISTS = 6;
/*** The no such user error code according to RFC 783, value 7. ***/
public static final int NO_SUCH_USER = 7;
/*** The error code of this packet. ***/
int _error;
/*** The error message of this packet. ***/
String _message;
/***
* Creates an error packet to be sent to a host at a given port
* with an error code and error message.
* <p>
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param error The error code of the packet.
* @param message The error message of the packet.
***/
public TFTPErrorPacket(InetAddress destination, int port,
int error, String message) {
super(TFTPPacket.ERROR, destination, port);
_error = error;
_message = message;
}
/***
* Creates an error packet based from a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
* <p>
* @param datagram The datagram containing the received error.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* error packet.
***/
TFTPErrorPacket(DatagramPacket datagram) throws TFTPPacketException {
super(TFTPPacket.ERROR, datagram.getAddress(), datagram.getPort());
int index, length;
byte[] data;
StringBuffer buffer;
data = datagram.getData();
length = datagram.getLength();
if(getType() != data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
_error = (((data[2] & 0xff) << 8) | (data[3] & 0xff));
if(length < 5)
throw new TFTPPacketException("Bad error packet. No message.");
index = 4;
buffer = new StringBuffer();
while(index < length && data[index] != 0) {
buffer.append((char)data[index]);
++index;
}
_message = buffer.toString();
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
* <p>
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data) {
int length;
length = _message.length();
data[0] = 0; data[1] = (byte)_type;
data[2] = (byte)((_error & 0xffff) >> 8);
data[3] = (byte)(_error & 0xff);
System.arraycopy(_message.getBytes(), 0, data, 4, length);
data[length + 4] = 0;
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(length + 4);
return datagram;
}
/***
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
* class.
* Under normal circumstances, you should not have a need to call this
* method. It creates a UDP datagram containing all the TFTP
* error packet data in the proper format.
* <p>
* @return A UDP datagram containing the TFTP error packet.
***/
public DatagramPacket newDatagram() {
byte[] data;
int length;
length = _message.length();
data = new byte[length + 5];
data[0] = 0; data[1] = (byte)_type;
data[2] = (byte)((_error & 0xffff) >> 8);
data[3] = (byte)(_error & 0xff);
System.arraycopy(_message.getBytes(), 0, data, 4, length);
data[length + 4] = 0;
return new DatagramPacket(data, data.length, _address, _port);
}
/***
* Returns the error code of the packet.
* <p>
* @return The error code of the packet.
***/
public int getError() { return _error; }
/***
* Returns the error message of the packet.
* <p>
* @return The error message of the packet.
***/
public String getMessage() { return _message; }
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPPacket.java
Index: TFTPPacket.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.net.*;
/***
* TFTPPacket is an abstract class encapsulating the functionality common
* to the 5 types of TFTP packets. It also provides a static factory
* method that will create the correct TFTP packet instance from a
* datagram. This relieves the programmer from having to figure out what
* kind of TFTP packet is contained in a datagram and create it himself.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacketException
* @see TFTP
***/
public abstract class TFTPPacket {
/***
* The minimum size of a packet. This is 4 bytes. It is enough
* to store the opcode and blocknumber or other required data
* depending on the packet type.
***/
static final int MIN_PACKET_SIZE = 4;
/***
* Identifier returned by <a href="#getType">getType()</a>
* indicating a read request packet. This is the actual TFTP spec
* identifier and is equal to 1.
***/
public static final int READ_REQUEST = 1;
/***
* Identifier returned by <a href="#getType">getType()</a>
* indicating a write request packet. This is the actual TFTP spec
* identifier and is equal to 2.
***/
public static final int WRITE_REQUEST = 2;
/***
* Identifier returned by <a href="#getType">getType()</a>
* indicating a data packet. This is the actual TFTP spec
* identifier and is equal to 3.
***/
public static final int DATA = 3;
/***
* Identifier returned by <a href="#getType">getType()</a>
* indicating an acknowledgement packet. This is the actual TFTP spec
* identifier and is equal to 4.
***/
public static final int ACKNOWLEDGEMENT = 4;
/***
* Identifier returned by <a href="#getType">getType()</a>
* indicating an error packet. This is the actual TFTP spec
* identifier and is equal to 5.
***/
public static final int ERROR = 5;
/***
* The TFTP data packet maximum segment size in bytes. This is 512
* and is useful for those familiar with the TFTP protocol who want
* to use the <a href="org.apache.commons.net.tftp.TFTP.html#_top_">TFTP</a>
* class methods to implement their own TFTP servers or clients.
***/
public static final int SEGMENT_SIZE = 512;
/*** The type of packet. ***/
int _type;
/*** The port the packet came from or is going to. ***/
int _port;
/*** The host the packet is going to be sent or where it came from. ***/
InetAddress _address;
/***
* When you receive a datagram that you expect to be a TFTP packet, you use
* this factory method to create the proper TFTPPacket object
* encapsulating the data contained in that datagram. This method is the
* only way you can instantiate a TFTPPacket derived class from a
* datagram.
* <p>
* @param datagram The datagram containing a TFTP packet.
* @return The TFTPPacket object corresponding to the datagram.
* @exception TFTPPacketException If the datagram does not contain a valid
* TFTP packet.
***/
public final static TFTPPacket newTFTPPacket(DatagramPacket datagram)
throws TFTPPacketException
{
byte[] data;
TFTPPacket packet = null;
if(datagram.getLength() < MIN_PACKET_SIZE)
throw new TFTPPacketException(
"Bad packet. Datagram data length is too short.");
data = datagram.getData();
switch(data[1]) {
case READ_REQUEST:
packet = new TFTPReadRequestPacket(datagram);
break;
case WRITE_REQUEST:
packet = new TFTPWriteRequestPacket(datagram);
break;
case DATA:
packet = new TFTPDataPacket(datagram);
break;
case ACKNOWLEDGEMENT:
packet = new TFTPAckPacket(datagram);
break;
case ERROR:
packet = new TFTPErrorPacket(datagram);
break;
default:
throw new TFTPPacketException(
"Bad packet. Invalid TFTP operator code.");
}
return packet;
}
/***
* This constructor is not visible outside of the package. It is used
* by subclasses within the package to initialize base data.
* <p>
* @param type The type of the packet.
* @param address The host the packet came from or is going to be sent.
* @param port The port the packet came from or is going to be sent.
**/
TFTPPacket(int type, InetAddress address, int port) {
_type = type;
_address = address;
_port = port;
}
/***
* This is an abstract method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* should be set as the datagram's data and the datagram returned.
* <p>
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
abstract DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data);
/***
* This is an abstract method, exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
* class.
* Under normal circumstances, you should not have a need to call this
* method. It creates a UDP datagram containing all the TFTP packet
* data in the proper format.
* <p>
* @return A UDP datagram containing the TFTP packet.
***/
public abstract DatagramPacket newDatagram();
/***
* Returns the type of the packet.
* <p>
* @return The type of the packet.
***/
public final int getType() { return _type; }
/***
* Returns the address of the host where the packet is going to be sent
* or where it came from.
* <p>
* @return The type of the packet.
***/
public final InetAddress getAddress() { return _address; }
/***
* Returns the port where the packet is going to be sent
* or where it came from.
* <p>
* @return The port where the packet came from or where it is going.
***/
public final int getPort() { return _port; }
/*** Sets the port where the packet is going to be sent. ***/
public final void setPort(int port) { _port = port; }
/*** Sets the host address where the packet is going to be sent. ***/
public final void setAddress(InetAddress address) { _address = address; }
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPPacketException.java
Index: TFTPPacketException.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
/***
* A class used to signify the occurrence of an error in the creation of
* a TFTP packet. It is not declared final so that it may be subclassed
* to identify more specific errors. You would only want to do this if
* you were building your own TFTP client or server on top of the
* <a href="org.apache.commons.net.tftp.TFTP.html#_top_">TFTP</a>
* class if you
* wanted more functionality than the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods provide.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTP
***/
public class TFTPPacketException extends Exception {
/***
* Simply calls the corresponding constructor of its superclass.
***/
public TFTPPacketException() {
super();
}
/***
* Simply calls the corresponding constructor of its superclass.
***/
public TFTPPacketException(String message) {
super(message);
}
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPReadRequestPacket.java
Index: TFTPReadRequestPacket.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.net.*;
/***
* A class derived from TFTPRequestPacket definiing a TFTP read request
* packet type.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPRequestPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPReadRequestPacket extends TFTPRequestPacket {
/***
* Creates a read request packet to be sent to a host at a
* given port with a filename and transfer mode request.
* <p>
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param filename The requested filename.
* @param mode The requested transfer mode. This should be on of the TFTP
* class MODE constants (e.g., TFTP.NETASCII_MODE).
***/
public TFTPReadRequestPacket(InetAddress destination, int port,
String filename, int mode) {
super(destination, port, TFTPPacket.READ_REQUEST, filename, mode);
}
/***
* Creates a read request packet of based on a received
* datagram and assumes the datagram has already been identified as a
* read request. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
* <p>
* @param datagram The datagram containing the received request.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* request packet.
***/
TFTPReadRequestPacket(DatagramPacket datagram) throws TFTPPacketException {
super(TFTPPacket.READ_REQUEST, datagram);
}
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPRequestPacket.java
Index: TFTPRequestPacket.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.net.*;
/***
* An abstract class derived from TFTPPacket definiing a TFTP Request
* packet type. It is subclassed by the
* <a href="org.apache.commons.net.tftp.TFTPReadRequestPacket.html#_top_">
* TFTPReadRequestPacket</a> and
* <a href="org.apache.commons.net.tftp.TFTPWriteRequestPacket.html#_top_">
* TFTPWriteRequestPacket</a> classes.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPReadRequestPacket
* @see TFTPWriteRequestPacket
* @see TFTPPacketException
* @see TFTP
***/
public abstract class TFTPRequestPacket extends TFTPPacket {
/***
* An array containing the string names of the transfer modes and indexed
* by the transfer mode constants.
***/
static final String[] _modeStrings = { "netascii", "octet" };
/***
* A null terminated byte array representation of the ascii names of the
* transfer mode constants. This is convenient for creating the TFTP
* request packets.
***/
static final byte[] _modeBytes[] = {
{ (byte)'n', (byte)'e', (byte)'t', (byte)'a', (byte)'s', (byte)'c',
(byte)'i', (byte)'i', 0 },
{ (byte)'o', (byte)'c', (byte)'t', (byte)'e', (byte)'t', 0 }
};
/*** The transfer mode of the request. ***/
int _mode;
/*** The filename of the request. ***/
String _filename;
/***
* Creates a request packet of a given type to be sent to a host at a
* given port with a filename and transfer mode request.
* <p>
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param type The type of the request (either TFTPPacket.READ_REQUEST or
* TFTPPacket.WRITE_REQUEST).
* @param filename The requested filename.
* @param mode The requested transfer mode. This should be on of the TFTP
* class MODE constants (e.g., TFTP.NETASCII_MODE).
***/
TFTPRequestPacket(InetAddress destination, int port,
int type, String filename, int mode) {
super(type, destination, port);
_filename = filename;
_mode = mode;
}
/***
* Creates a request packet of a given type based on a received
* datagram. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
* <p>
* @param type The type of the request (either TFTPPacket.READ_REQUEST or
* TFTPPacket.WRITE_REQUEST).
* @param datagram The datagram containing the received request.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* request packet of the appropriate type.
***/
TFTPRequestPacket(int type, DatagramPacket datagram)
throws TFTPPacketException
{
super(type, datagram.getAddress(), datagram.getPort());
byte[] data;
int index, length;
String mode;
StringBuffer buffer;
data = datagram.getData();
if(getType() != data[1])
throw new TFTPPacketException("TFTP operator code does not match type.");
buffer = new StringBuffer();
index = 2;
length = datagram.getLength();
while(index < length && data[index] != 0) {
buffer.append((char)data[index]);
++index;
}
_filename = buffer.toString();
if(index >= length)
throw new TFTPPacketException("Bad filename and mode format.");
buffer.setLength(0);
++index; // need to advance beyond the end of string marker
while(index < length && data[index] != 0) {
buffer.append((char)data[index]);
++index;
}
mode = buffer.toString().toLowerCase();
length = _modeStrings.length;
for(index = 0; index < length; index++) {
if(mode.equals(_modeStrings[index])) {
_mode = index;
break;
}
}
if(index >= length) {
throw new TFTPPacketException("Unrecognized TFTP transfer mode: " + mode);
// May just want to default to binary mode instead of throwing
// exception.
//_mode = TFTP.OCTET_MODE;
}
}
/***
* This is a method only available within the package for
* implementing efficient datagram transport by elminating buffering.
* It takes a datagram as an argument, and a byte buffer in which
* to store the raw datagram data. Inside the method, the data
* is set as the datagram's data and the datagram returned.
* <p>
* @param datagram The datagram to create.
* @param data The buffer to store the packet and to use in the datagram.
* @return The datagram argument.
***/
final DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data) {
int fileLength, modeLength;
fileLength = _filename.length();
modeLength = _modeBytes[_mode].length;
data[0] = 0; data[1] = (byte)_type;
System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
data[fileLength + 2] = 0;
System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
modeLength);
datagram.setAddress(_address);
datagram.setPort(_port);
datagram.setData(data);
datagram.setLength(fileLength + modeLength + 4);
return datagram;
}
/***
* This is a method exposed to the programmer in case he
* wants to implement his own TFTP client instead of using
* the <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a>
* class. Under normal circumstances, you should not have a need to call
* this method. It creates a UDP datagram containing all the TFTP
* request packet data in the proper format.
* <p>
* @return A UDP datagram containing the TFTP request packet.
***/
public final DatagramPacket newDatagram() {
int fileLength, modeLength;
byte[] data;
fileLength = _filename.length();
modeLength = _modeBytes[_mode].length;
data = new byte[fileLength + modeLength + 4];
data[0] = 0; data[1] = (byte)_type;
System.arraycopy(_filename.getBytes(), 0, data, 2, fileLength);
data[fileLength + 2] = 0;
System.arraycopy(_modeBytes[_mode], 0, data, fileLength + 3,
modeLength);
return new DatagramPacket(data, data.length, _address, _port);
}
/***
* Returns the transfer mode of the request.
* <p>
* @return The transfer mode of the request.
***/
public final int getMode() { return _mode; }
/***
* Returns the requested filename.
* <p>
* @return The requested filename.
***/
public final String getFilename() { return _filename; }
}
1.1 jakarta-commons-sandbox/net/src/java/org/apache/commons/net/tftp/TFTPWriteRequestPacket.java
Index: TFTPWriteRequestPacket.java
===================================================================
package org.apache.commons.net.tftp;
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache Commons" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache Turbine", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
import java.net.*;
/***
* A class derived from TFTPRequestPacket definiing a TFTP write request
* packet type.
* <p>
* Details regarding the TFTP protocol and the format of TFTP packets can
* be found in RFC 783. But the point of these classes is to keep you
* from having to worry about the internals. Additionally, only very
* few people should have to care about any of the TFTPPacket classes
* or derived classes. Almost all users should only be concerned with the
* <a href="org.apache.commons.net.tftp.TFTPClient.html#_top_">TFTPClient</a> class
* <a href="org.apache.commons.net.tftp.TFTPClient.html#receiveFile">receiveFile()</a>
* and
* <a href="org.apache.commons.net.tftp.TFTPClient.html#sendFile">sendFile()</a>
* methods.
* <p>
* <p>
* @author Daniel F. Savarese
* @see TFTPPacket
* @see TFTPRequestPacket
* @see TFTPPacketException
* @see TFTP
***/
public final class TFTPWriteRequestPacket extends TFTPRequestPacket {
/***
* Creates a write request packet to be sent to a host at a
* given port with a filename and transfer mode request.
* <p>
* @param destination The host to which the packet is going to be sent.
* @param port The port to which the packet is going to be sent.
* @param filename The requested filename.
* @param mode The requested transfer mode. This should be on of the TFTP
* class MODE constants (e.g., TFTP.NETASCII_MODE).
***/
public TFTPWriteRequestPacket(InetAddress destination, int port,
String filename, int mode) {
super(destination, port, TFTPPacket.WRITE_REQUEST, filename, mode);
}
/***
* Creates a write request packet of based on a received
* datagram and assumes the datagram has already been identified as a
* write request. Assumes the datagram is at least length 4, else an
* ArrayIndexOutOfBoundsException may be thrown.
* <p>
* @param datagram The datagram containing the received request.
* @throws TFTPPacketException If the datagram isn't a valid TFTP
* request packet.
***/
TFTPWriteRequestPacket(DatagramPacket datagram) throws TFTPPacketException {
super(TFTPPacket.WRITE_REQUEST, datagram);
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>