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>