/*****************************************************************************/
/* File name: TestClient.java                                                */
/* Purpose: to test NFS server                                               */
/*                                                                           */
/* Last modified: 18.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*                                                                           */
/* This program is distributed in the hope that it will be useful, but       */
/* WITHOUT ANY WARRANTY; without even the implied warranty of                */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General */
/* Public License for more details.                                          */
/*                                                                           */
/* This software is distributed under the terms                              */
/* of the GNU General Public License as published                            */
/* by the Free Software Foundation; either version 2, or (at your option)    */
/* any later version.                                                        */
/* See file COPYING for your rights (GNU GPL)                                */
/*****************************************************************************/

package nfs;


import java.net.*;
import java.io.*;
import java.util.*;
import rpc.*;
import mount.*;


public
class

TestClient
        extends rpc.ParserResponder
                                    implements Runnable
{

  private final static String RCSID = "$Header: /d/NFS/nfs/RCS/TestClient.java,v 1.16 1999/08/19 19:49:40 vklimov Exp $";



  public

  TestClient( java.lang.String propertiesFilePath )

                                               throws  SocketException
/*****************************************************************************/
/* Function name: TestClient                                                 */
/* File name: TestClient.java                                                */
/* Purpose: constructor for the TestClient class                             */
/* Throws: SocketException                                                   */
/* Parameters: propertiesFilePath                                            */
/* Returns:                                                                  */
/* Last modified: 11.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
                                                       /* TestClient */
/*---------------------------------------------------------------------------*/

      super( (int) Constants.NFS_TEST_PORT,
             propertiesFilePath             );
    }
/*end of TestClient*/


  public
  void

  sendAttributesGetRequest( long transactionId,
                            Fhandle fhandle     )
/*****************************************************************************/
/* Function name: sendAttributesGetRequest                                   */
/* File name: TestClient.java                                                */
/* Purpose: to send an attribute get request                                 */
/* Parameters: transactionId                                                 */
/*             fhandle                                                       */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                       /* sendAttributesGetRequest */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.NFSPROC_GETATTR_UDP_PACKET_DATA_LENGTH
                 ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFSPROC_GETATTR );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      fhandle.putItselfIntoRPCMessage( rpcMessage );

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendAttributesGetRequest" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendAttributesGetRequest: " +
            "IOException in sending datagram\n" +
            e.getMessage()                        );
        }
    /*end of try-catch*/

    }
/*end of sendAttributesGetRequest*/


  public
  void

  sendLookupRequest( long transactionId,
                     Fhandle fhandle,
                     String fileName      )
/*****************************************************************************/
/* Function name: sendLookupRequest                                          */
/* File name: TestClient.java                                                */
/* Purpose: to send an attribute get request                                 */
/* Parameters: transactionId                                                 */
/*             fhandle                                                       */
/*             fileName                                                      */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;
      DirectoryOperationArguments dirOpArgs = null;

                                               /* sendLookupRequest */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.NFSPROC_LOOKUP_UDP_PACKET_DATA_LENGTH
                 ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFSPROC_LOOKUP );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      dirOpArgs = new DirectoryOperationArguments();
      dirOpArgs.directoryFHandle = fhandle;
      dirOpArgs.fileName = fileName;

      dirOpArgs.
        putItselfIntoRPCMessage(
          rpcMessage             );

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendLookupRequest" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendLookupRequest: " +
            "IOException in sending datagram\n" +
            e.getMessage()                        );
        }
    /*end of try-catch*/

    }
/*end of sendLookupRequest*/


  public
  FileReadReply

  analyzeFileReadReply(
    ParserResponderReturnArguments
      parserResponderReturnArguments,
    String fileName,
    int lengthOfDataInUDPPacketReceived )
/*****************************************************************************/
/* Function name: analyzeFileReadReply                                       */
/* File name: TestMount.java                                                 */
/* Purpose: to analyze the reply of the NFS server on file read request      */
/* Parameters: parserResponderReturnArguments                                */
/*             fileName                                                      */
/*             lengthOfDataInUDPPacketReceived                               */
/* Returns: the result object                                                */
/* Last modified: 18.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] unparsedData;
      int lengthOfFileDataToAppendToLocalFile;
      int indexOfTheFirstByteOfData;
      long currentLocalFileLength;
      boolean gotFileAttributesOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;
      FileReadReply fileReadReply = null;
      byte[] byteArrayToAppendToLocalFile = null;
      RandomAccessFile localRandomAccessFile = null;

                                              /* analyzeFileReadReply */
/*---------------------------------------------------------------------------*/

      fileReadReply = new FileReadReply();

      try
        {
          localRandomAccessFile = new
            RandomAccessFile( fileName, "rw" );
        }
      catch( IOException e )
        {
          System.out.println( "IOException!: " +
                              "can\'t append to file " +
                              fileName + "\n" +
                              e.getMessage()            );
          fileReadReply.status =
            general.Constants.JAVA_ERROR_CODE;
        }
    /*end of try-catch*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      fileReadReply.status =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      System.out.println( "analyzeFileReadReply: " +
                          "fileReadReply.status=" +
                          fileReadReply.status              );

      if (fileReadReply.status == Constants.NFS_OK)
        {
          gotFileAttributesOK =
            fileReadReply.
              fileAttributes.
                getItselfFromRPCMessage(
                  rpcMessageWithParametersToRemoteProcedure );

          System.out.println( "gotFileAttributesOK=" +
                              gotFileAttributesOK );

          lengthOfFileDataToAppendToLocalFile = (int)
            rpcMessageWithParametersToRemoteProcedure.
              getUnsignedInteger();

          indexOfTheFirstByteOfData = ( 1 +
            nfs.Constants.N_XDR_UINTS_IN_FATTR ) *
            rpc.Constants.XDR_UNSIGNED_INT_LENGTH;

          try
            {
              currentLocalFileLength =
                localRandomAccessFile.length();
              localRandomAccessFile.seek(
                currentLocalFileLength    );

              byteArrayToAppendToLocalFile = new
                byte[ lengthOfFileDataToAppendToLocalFile ] ;
              unparsedData =
                rpcMessageWithParametersToRemoteProcedure.
                  getUnparsedData();

              localRandomAccessFile.write(
                unparsedData, 0,
                lengthOfFileDataToAppendToLocalFile );

            }
          catch( IOException e )
            {
              fileReadReply.status =
                general.Constants.JAVA_ERROR_CODE;
              return fileReadReply;                        /* return ! */
            }
        /*end of try-catch*/

          fileReadReply.nBytesRead = (long)
            lengthOfFileDataToAppendToLocalFile;
        }
      else
        {
          fileReadReply.status =
            general.Constants.JAVA_ERROR_CODE;
          return fileReadReply;                        /* return ! */
        }
    /*end of if*/

      try
        {
          if (localRandomAccessFile != null)
            localRandomAccessFile.close();
          else
            ;
        /*end of if*/
        }
      catch( IOException e )
        {
        }
    /*end of try-catch*/

      return fileReadReply;

    }
/*end of analyzeFileReadReply*/


  public
  FileReadReply

  receiveFileReadReplyAndAppendToTheFile(
    String fileName                      )
/*****************************************************************************/
/* Function name: receiveFileReadReplyAndAppendToTheFile                     */
/* File name: TestClient.java                                                */
/* Purpose: to get reply on a file read request and append it                */
/*          to the local file                                                */
/* Parameters: fileName                                                      */
/* Returns: FileReadReply                                                    */
/* Last modified: 18.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int lengthOfDataReceived;
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      FileReadReply fileReadReply = null;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                                 /* receiveFileReadReplyAndAppendToTheFile */
/*---------------------------------------------------------------------------*/

      System.out.println(
        "receiveFileReadReplyAndAppendToTheFile: " +
        "entering"                                 );

      byteBuffer = new byte[
        nfs.Constants.
          NFSPROC_FILE_READ_REPLY_PREFIX_LENGTH +
        nfs.Constants.MAXDATA +
        rpc.Constants.XDR_UNSIGNED_INT_LENGTH     ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      lengthOfDataReceived = udpPacket.getLength();

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          fileReadReply =
            analyzeFileReadReply(
              parserResponderReturnArguments,
              fileName,
              lengthOfDataReceived            );
        }
      else
        {
          fileReadReply = new FileReadReply();
          fileReadReply.status =
            general.Constants.JAVA_ERROR_CODE;

          System.out.println(
            "receiveFileReadReplyAndAppendToTheFile: " +
            "error in receiving reply"         );
        }
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return fileReadReply;

    }
/*end of receiveFileReadReplyAndAppendToTheFile*/


  public
  void

  pumpAFileOverIntoTheCurrentDirectory(
    long transactionId,
    Fhandle fhandle,
    String fileName                    )
/*****************************************************************************/
/* Function name: pumpAFileOverIntoTheCurrentDirectory                       */
/* File name: TestClient.java                                                */
/* Purpose: to transfer a file into the current directory                    */
/* Parameters: transactionId                                                 */
/*             fhandle                                                       */
/*             fileName                                                      */
/* Returns:                                                                  */
/* Last modified: 27.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
      long totalBytesRead = 0;
      long nBytesToReadThisTime = 0;
      long status;
      boolean continueToLoopOnRead = true;
      FAttributes fileAttributes = null;
      FhStatus fhStatus = new FhStatus();
      Fhandle fileHandle = null;
      FileReadReply fileReadReply = null;

                                 /* pumpAFileOverIntoTheCurrentDirectory */
/*---------------------------------------------------------------------------*/

      System.out.println(
        "pumpAFileOverIntoTheCurrentDirectory: " +
        "entering"                                 );

      sendLookupRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fhandle,
        fileName                               );

      fileAttributes =
        receiveLookupReply(
          fhStatus          );

      System.out.println( "after receiveLookupReply:" +
                          "fhStatus=\n" +
                          fhStatus +
                          ( (fileAttributes==null) ?
                            ("fileAttributes is null") :
                            ( "\nfileAttributes=\n" +
                              fileAttributes.toString() ) ) );

      fileHandle = fhStatus.fhandle;

      i = 0;
      while( (fileAttributes.size >
              totalBytesRead         ) &&
             continueToLoopOnRead
           )
        {

          System.out.println(
            "pumpAFileOverIntoTheCurrentDirectory: " +
            "i="  + i                                  );


          if (fileAttributes.size > 
              Constants.MAXDATA    )
            nBytesToReadThisTime = Constants.MAXDATA;
          else
            nBytesToReadThisTime = fileAttributes.size;
        /*end of if*/
          
          sendFileReadRequest(
            nfs.Constants.INITIAL_TRANSACTION_ID,
            fileHandle,
            totalBytesRead,                             /* offset */
            nBytesToReadThisTime                 );

          fileReadReply =
            receiveFileReadReplyAndAppendToTheFile(
              fileName                              );

          fileAttributes = fileReadReply.fileAttributes;

          totalBytesRead += fileReadReply.nBytesRead;

          status = fileReadReply.status;

          System.out.println( "i=" + i +
                              " totalBytesRead=" +
                              totalBytesRead  +
                              "\n\t\tfileReadReply=" +
                              fileReadReply            );

          if (status != Constants.NFS_OK)
            continueToLoopOnRead = false;
          else
            ;
        /*end of if*/

          i++;
        }
    /*end of while-loop*/

    }
/*end of pumpAFileOverIntoTheCurrentDirectory*/


  public
  void

  sendFileReadRequest( long transactionId,
                       Fhandle fhandle,
                       long offset,
                       long nBytesReadyToReceive )
/*****************************************************************************/
/* Function name: sendFileReadRequest                                        */
/* File name: TestClient.java                                                */
/* Purpose: to send a file read request                                      */
/* Parameters: transactionId                                                 */
/*             fhandle                                                       */
/*             offset                                                        */
/*             nBytesReadyToReceive                                          */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                                /* sendFileReadRequest */
/*---------------------------------------------------------------------------*/

      System.out.println(
        "sendFileReadRequest: " +
        "entering"                );

      ibuf = new byte[
              nfs.Constants.NFSPROC_READ_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFSPROC_READ );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      fhandle.putItselfIntoRPCMessage( rpcMessage );
      rpcMessage.
        putUnsignedInteger( offset );
      rpcMessage.
        putUnsignedInteger( nBytesReadyToReceive );
      rpcMessage.
        putUnsignedInteger( (long) 0 );                /* not used */

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendFileReadRequest" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendFileReadRequest: " +
            "IOException in sending datagram\n" +
            e.getMessage()                        );
        }
    /*end of try-catch*/

    }
/*end of sendFileReadRequest*/


  public
  void

  sendDirectoryReadRequest( long transactionId,
                            Fhandle fhandle,
                            long cookie,
                            int  nBytesReadyToReceive )
/*****************************************************************************/
/* Function name: sendDirectoryReadRequest                                   */
/* File name: TestClient.java                                                */
/* Purpose: to send a directory read request                                 */
/* Parameters: transactionId                                                 */
/*             fhandle                                                       */
/*             cookie                                                        */
/*             nBytesReadyToReceive                                          */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                       /* sendDirectoryReadRequest */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.NFSPROC_READDIR_UDP_PACKET_DATA_LENGTH
                 ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFSPROC_READDIR );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      fhandle.putItselfIntoRPCMessage( rpcMessage );
      rpcMessage.
        putUnsignedInteger( cookie );
      rpcMessage.
        putUnsignedInteger( (long) nBytesReadyToReceive );

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendDirectoryReadRequest" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendDirectoryReadRequest: " +
            "IOException in sending datagram\n" +
            e.getMessage()                        );
        }
    /*end of try-catch*/

    }
/*end of sendDirectoryReadRequest*/


  public
  void

  sendRPCRequestWithoutParameters( long transactionId,
                                   long procedureNumber )
/*****************************************************************************/
/* Function name: sendRPCRequestWithoutParameters                            */
/* File name: TestClient.java                                                */
/* Purpose: to send all the needed RPC stuff including only a procedure      */
/*          number without any parameters                                    */
/* Parameters: transactionId                                                 */
/*             procedureNumber                                               */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendRPCRequestWithoutParameters */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.
        putUnsignedInteger( procedureNumber );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendRPCRequestWithoutParameters" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendRPCRequestWithoutParameters: " +
            "IOException in sending datagram\n" +
            e.getMessage()                        );
        }
    /*end of try-catch*/

    }
/*end of sendRPCRequestWithoutParameters*/


  public
  void

  sendWrongRPCProtocolVersionMessage( long transactionId )
/*****************************************************************************/
/* Function name: sendWrongRPCProtocolVersionMessage                         */
/* File name: TestClient.java                                                */
/* Purpose: to test response on wrong protocol version                       */
/* Parameters: transactionId                                                 */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendWrongRPCProtocolVersionMessage */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.   /* rpc protocol version number is intentionally wrong ! */
        putUnsignedInteger( (long) 99 );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.
        putUnsignedInteger( Constants.NFSPROC_NULL );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendWrongRPCProtocolVersionMessage" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendWrongRPCProtocolVersionMessage: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendWrongRPCProtocolVersionMessage*/


  public
  void

  sendWrongProgramNumberMessage( long transactionId )
/*****************************************************************************/
/* Function name: sendWrongProgramNumberMessage                              */
/* File name: TestClient.java                                                */
/* Purpose: to test response on wrong program number                         */
/* Parameters: transactionId                                                 */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendWrongProgramNumberMessage */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.                   /* prog number is intentionally wrong ! */
        putUnsignedInteger( (long) 99 );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.
        putUnsignedInteger( Constants.NFSPROC_NULL );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendWrongProgramNumberMessage" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendWrongProgramNumberMessage: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendWrongProgramNumberMessage*/


  public
  void

  sendWrongNFSProtocolVersionMessage( long transactionId )
/*****************************************************************************/
/* Function name: sendWrongNFSProtocolVersionMessage                         */
/* File name: TestClient.java                                                */
/* Purpose: to test response on wrong NFS protocol version number            */
/* Parameters: transactionId                                                 */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendWrongNFSProtocolVersionMessage */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.   /* NFS protocol version number is intentionally wrong ! */
        putUnsignedInteger( (long) 99 );

      rpcMessage.
        putUnsignedInteger( Constants.NFSPROC_NULL );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendWrongNFSProtocolVersionMessage" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendWrongNFSProtocolVersionMessage: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendWrongNFSProtocolVersionMessage*/


  public
  void

  sendWrongNFSProcedureNumberMessage( long transactionId )
/*****************************************************************************/
/* Function name: sendWrongNFSProcedureNumberMessage                         */
/* File name: TestClient.java                                                */
/* Purpose: to test response on wrong NFS procedure number                   */
/* Parameters: transactionId                                                 */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendWrongNFSProcedureNumberMessage */
/*---------------------------------------------------------------------------*/

      ibuf = new byte[
              nfs.Constants.
                PORTMAPPER_REGISTRATION_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );

      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_PROGRAM );

      rpcMessage.
        putUnsignedInteger( nfs.Constants.NFS_VERSION );

      rpcMessage.          /* NFS procedure number is intentionally wrong ! */
        putUnsignedInteger( (long) 99 );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();

      portToSendTo = (int) nfs.Constants.NFS_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendWrongNFSProcedureNumberMessage" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS TestClient, " +
            "sendWrongNFSProcedureNumberMessage: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendWrongNFSProcedureNumberMessage*/


  public
  void

  receiveNullProcedureReply()
/*****************************************************************************/
/* Function name: receiveNullProcedureReply                                  */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer from the NFS server                             */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 11.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean registeredOK;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;
                                           /* receiveNullProcedureReply */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[ pm.Constants.UDP_PACKET_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {

          System.out.println( "receiveNullProcedureReply: " +
                            "got reply on null procedure"    );

        }
      else
        System.out.println( "receiveNullProcedureReply: " +
                            "error in receiving reply"       );
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

    }
/*end of receiveNullProcedureReply*/


  public
  long

  analyzeDirectoryReadReply(
    ParserResponderReturnArguments
      parserResponderReturnArguments,
    Vector fileHandlesVector              )
/*****************************************************************************/
/* Function name: analyzeDirectoryReadReply                                  */
/* File name: TestMount.java                                                 */
/* Purpose: to analyze the reply of the NFS server on directory read request */
/* Parameters: parserResponderReturnArguments                                */
/*             fileHandlesVector                                             */
/* Returns: the cookie                                                       */
/* Last modified: 03.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      int i;
      boolean continueToGetEntries = true;
      long fileId;
      long nextEntry;
      long status;
      long cookie = 0;
      long eof;
      Fhandle fileHandle = null;
      String name;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                                       /* analyzeDirectoryReadReply */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      status =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      System.out.println( "analyzeDirectoryReadReply: " +
                          "status=" + status              );

      if (status == Constants.NFS_OK)
        {
          i = 0;
          while( continueToGetEntries )
            {
              nextEntry =
                rpcMessageWithParametersToRemoteProcedure.
                  getUnsignedInteger();
              if (nextEntry == xdr.Constants.FALSE)
                continueToGetEntries = false;
              else
                {
                  fileId =
                    rpcMessageWithParametersToRemoteProcedure.
                      getUnsignedInteger();
                  System.out.println( "i=" + i +
                                      " fileId=" + fileId );
                  name =
                    rpcMessageWithParametersToRemoteProcedure.
                      getString();
                  cookie =
                    rpcMessageWithParametersToRemoteProcedure.
                      getUnsignedInteger();

                  fileHandle = new Fhandle( fileId,
                                            null,
                                            name,
                                            null );
                  fileHandlesVector.addElement( fileHandle );

                  System.out.println( "i=" + i +
                                      " fileId=" + fileId +
                                      " cookie=" + cookie +
                                      "\n\t\t\tname=" + name );
                  i++;
                }
            /*end of if on FALSE*/
            }
        /*end of while-loop*/

          eof =
            rpcMessageWithParametersToRemoteProcedure.
              getUnsignedInteger();

          System.out.println( "\neof=" + eof );

        }
      else
        {
          return general.Constants.JAVA_ERROR_CODE;    /* error ! */
        }
    /*end of if*/

      return cookie;

    }
/*end of analyzeDirectoryReadReply*/


  public
  FAttributes

  analyzeAttributesGetReply(
    ParserResponderReturnArguments
      parserResponderReturnArguments )
/*****************************************************************************/
/* Function name: analyzeAttributesGetReply                                  */
/* File name: TestMount.java                                                 */
/* Purpose: to analyze the reply of the NFS server on attributes get request */
/* Parameters: parserResponderReturnArguments                                */
/* Returns: FAttributes received or                                          */
/*          null in case of an error                                         */
/* Last modified: 27.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long status;
      FAttributes fileAttributes = null;
      boolean gotOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                                            /* analyzeAttributesGetReply */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      status =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      System.out.println( "analyzeAttributesGetReply: " +
                          "status=" + status              );

      if (status == Constants.NFS_OK)
        {
          fileAttributes = new FAttributes();

          gotOK =
            fileAttributes.
              getItselfFromRPCMessage(
                rpcMessageWithParametersToRemoteProcedure );

          System.out.println( "gotOK=" + gotOK );

        }
      else
        {
        }
    /*end of if*/

      return fileAttributes;

    }
/*end of analyzeAttributesGetReply*/


  public
  FAttributes

  analyzeLookupReply(
    ParserResponderReturnArguments
      parserResponderReturnArguments,
    mount.FhStatus fhStatus          )
/*****************************************************************************/
/* Function name: analyzeLookupReply                                         */
/* File name: TestMount.java                                                 */
/* Purpose: to analyze the reply of the NFS server on lookup request         */
/* Parameters: parserResponderReturnArguments                                */
/*             fhStatus                                                      */
/* Returns: FAttributes received or                                          */
/*          null in case of an error                                         */
/* Last modified: 27.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long status;
      DirectoryOperationResults dirOpRes = null;
      Fhandle fhandle = null;
      FAttributes fileAttributes = null;
      boolean gotOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                                            /* analyzeLookupReply */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      fhStatus.status =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      System.out.println( "analyzeLookupReply: " +
                          "fhStatus.status=" +
                          fhStatus.status           );

      if (fhStatus.status == Constants.NFS_OK)
        {
          dirOpRes = new DirectoryOperationResults();

          gotOK =
            dirOpRes.
              getItselfFromRPCMessage(
                rpcMessageWithParametersToRemoteProcedure );

          System.out.println( "gotOK=" + gotOK +
                              " dirOpRes=\n" +
                              dirOpRes.toString() );
          fhStatus.fhandle =
            dirOpRes.fileHandle;

          fileAttributes =
            dirOpRes.fileAttributes;
        }
      else
        {
        }
    /*end of if*/

      return fileAttributes;

    }
/*end of analyzeLookupReply*/


  public
  FAttributes

  receiveLookupReply(
    mount.FhStatus fhStatus )
/*****************************************************************************/
/* Function name: receiveLookupReply                                         */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer on lookup request from the NFS server           */
/* Parameters: fhStatus                                                      */
/* Returns: FAttributes received or                                          */
/*          null in case of an error                                         */
/* Last modified: 27.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;
      FAttributes fileAttributes = null;
                                                  /* receiveLookupReply */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[
        nfs.Constants.NFSPROC_LOOKUP_REPLY_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          fileAttributes =
            analyzeLookupReply(
              parserResponderReturnArguments,
              fhStatus                         );
        }
      else
        System.out.println( "receiveLookupReply: " +
                            "error in receiving reply"       );
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return fileAttributes;

    }
/*end of receiveLookupReply*/


  public
  FAttributes

  receiveAttributesGetReply()
/*****************************************************************************/
/* Function name: receiveAttributesGetReply                                  */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer on attributes get request from the NFS server   */
/* Parameters:                                                               */
/* Returns: FAttributes received or                                          */
/*          null in case of an error                                         */
/* Last modified: 27.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;
      FAttributes fileAttributes = null;
                                           /* receiveAttributesGetReply */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[
        nfs.Constants.NFSPROC_GETATTR_REPLY_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          fileAttributes =
            analyzeAttributesGetReply(
              parserResponderReturnArguments );
        }
      else
        System.out.println( "receiveAttributesGetReply: " +
                            "error in receiving reply"       );
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return fileAttributes;

    }
/*end of receiveAttributesGetReply*/


  public
  long

  receiveDirectoryReadReply(
    int nBytesReadyToReceiveDirectoryEntries,
    Vector fileHandlesVector                      )
/*****************************************************************************/
/* Function name: receiveDirectoryReadReply                                  */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer on directory read request from the NFS server   */
/* Parameters: nBytesReadyToReceiveDirectoryEntries                          */
/*             fileHandlesVector                                             */
/* Returns:                                                                  */
/* Last modified: 23.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long cookie = 0;
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;
                                           /* receiveDirectoryReadReply */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[
        nBytesReadyToReceiveDirectoryEntries + 
        nfs.Constants.NFSPROC_READDIR_REPLY_PREFIX_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          cookie =
            analyzeDirectoryReadReply(
              parserResponderReturnArguments,
              fileHandlesVector                );
        }
      else
        System.out.println( "receiveDirectoryReadReply: " +
                            "error in receiving reply"       );
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return cookie;

    }
/*end of receiveDirectoryReadReply*/


  public
  void

  receiveRepliesWithGeneralErrors()
/*****************************************************************************/
/* Function name: receiveRepliesWithGeneralErrors                            */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer from the portmapper                             */
/* Parameters:                                                               */
/* Returns: true - if registered OK, false - otherwise                       */
/* Last modified: 08.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean registeredOK;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                                /* receiveRepliesWithGeneralErrors */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[ pm.Constants.UDP_PACKET_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          System.out.println( "receiveRepliesWithGeneralErrors: " +
                              "hmm, strange, no errors, everything " +
                              "seems to be all right..."               );
        }
      else
        {
          switch( (int) parserResponderReturnArguments.
                          replyStat                       )
            {
            case (int) rpc.Constants.MSG_ACCEPTED:

              System.out.println( "message was accepted:" +
                                  "\nacceptStat=" +
                                  parserResponderReturnArguments.
                                    acceptStat                     );

              switch( (int) parserResponderReturnArguments.
                              acceptStat                    )
                {
                case (int) rpc.Constants.SUCCESS:
                  System.out.println( "receiveRepliesWithGeneralErrors: " +
                                      "hmm, strange, no errors, everything " +
                                      "seems to be all right..."             );

                  break;
                case (int) rpc.Constants.PROG_MISMATCH:
                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "program version mismatch." +
                    "\nsupported are versions from " +
                    parserResponderReturnArguments.
                      lowestProgramVersionSupportedByServer +
                    " thorough " +
                    parserResponderReturnArguments.
                      highestProgramVersionSupportedByServer  );
                  break;
                case (int) rpc.Constants.PROG_UNAVAIL:
                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "the server hasn\'t exported program"   );
                  break;
                case (int) rpc.Constants.PROC_UNAVAIL:
                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "the server doesn\'t support procedure"   );
                  break;
                case (int) rpc.Constants.GARBAGE_ARGS:
                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "the procedure can\'t decode parameters"   );
                  break;
                default: /* no additional data */
                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "the RPC message was accepted, but " +
                    "\nan error was detected nonetheless"   );

                  break;
                }
            /*end of switch on acceptStat*/

              break;

            case (int) rpc.Constants.MSG_DENIED:

              System.out.println(
                "receiveRepliesWithGeneralErrors: " +
                "the RPC message rejected !"            );

              switch( (int) parserResponderReturnArguments.
                              rejectStat                    )
                {
                case (int) rpc.Constants.RPC_MISMATCH:
                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "RPC_MISMATCH,\n" +
                    "the lowest RPC protocol version" +
                    " supported is " +
                    parserResponderReturnArguments.
                      lowestProtocolVersionSupportedByServer +
                    "\nthe highest is " +
                    parserResponderReturnArguments.
                      highestProtocolVersionSupportedByServer  );

                  break;
                case (int) rpc.Constants.AUTH_ERROR:

                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "AUTH_ERROR !"                          );

                  break;
                }
            /*end of switch on rejectStat*/

              break;

            default:

                  System.out.println(
                    "receiveRepliesWithGeneralErrors: " +
                    "unknown ERROR !"                       );
            }
        /*end of switch on replyStat*/
          
        }
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

    }
/*end of receiveRepliesWithGeneralErrors*/


  public
  void

  sendMountRPCMessageToNFSMountServer( long transactionId,
                                       String dirPath      )
/*****************************************************************************/
/* Function name: sendMountRPCMessageToNFSMountServer                        */
/* File name: TestClient.java                                                */
/* Purpose: to create a mount request RPC message and send it                */
/*          to mount server                                                  */
/* Parameters: transactionId                                                 */
/*             dirPath                                                       */
/* Returns:                                                                  */
/* Last modified: 30.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendMountRPCMessageToNFSMountServer */
/*---------------------------------------------------------------------------*/

      if (dirPath.length() >
          mount.Constants.MNTPATHLEN)
        {
          System.out.println( "dirPath is too long!" );
          return;                                        /* return ! */
        }
      else
        ;
    /*end of if*/

      ibuf = new byte[
              mount.Constants.
                MOUNT_REQUEST_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );
      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );
      rpcMessage.
        putUnsignedInteger( (long) mount.Constants.MOUNTPROG );
      rpcMessage.
        putUnsignedInteger( mount.Constants.MOUNT_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) mount.Constants.MOUNTPROC_MNT );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();


      try
        {
          rpcMessage.
            putString( dirPath,
                       mount.Constants.MNTPATHLEN );
        }
      catch( ArrayIndexOutOfBoundsException e )
        {
          System.out.println( "dirPath is too long!" );
          return;                                      /* return ! */
        }
      catch( ArrayStoreException e )
        {
          System.out.println( dirPath +
                              "\n" + e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try-catch*/

      portToSendTo = mount.Constants.MOUNT_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendMountRPCMessageToNFSMountServer" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS mount TestMount, " +
            "sendMountRPCMessageToNFSMountServer: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendMountRPCMessageToNFSMountServer*/


  public
  boolean

  analyzeRPCReplyMessageOnMountRequest(
    ParserResponderReturnArguments
      parserResponderReturnArguments,
    mount.FhStatus fhStatus              )
/*****************************************************************************/
/* Function name: analyzeRPCReplyMessageOnMountRequest                       */
/* File name: TestMount.java                                                 */
/* Purpose: to analyze the reply of the NFS mount server on mount request    */
/* Parameters: parserResponderReturnArguments                                */
/*             fhStatus                                                      */
/* Returns: true - if mounted OK, false - otherwise                          */
/* Last modified: 16.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      Fhandle fhandle;
      boolean gotFhandleOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                               /* analyzeRPCReplyMessageOnMountRequest */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      fhStatus.status =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      if (fhStatus.status == mount.Constants.FHSTATUS_OK)
        {
          fhandle = new Fhandle();
          gotFhandleOK =
            fhandle.getItselfFromRPCMessage(
              rpcMessageWithParametersToRemoteProcedure );
          fhStatus.fhandle = fhandle;
          return gotFhandleOK;
        }
      else
        {
          return false;
        }
    /*end of if*/

    }
/*end of analyzeRPCReplyMessageOnMountRequest*/


  public
  boolean

  receiveFhstatusRPCMessageFromNFSMountServer( FhStatus fhStatus )
/*****************************************************************************/
/* Function name: receiveFhstatusRPCMessageFromNFSMountServer                */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer from the mount                                  */
/* Parameters:                                                               */
/* Returns: true - if mounted OK, false - otherwise                          */
/* Last modified: 16.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean mountedOK;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                          /* receiveFhstatusRPCMessageFromNFSMountServer */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[ mount.Constants.UDP_PACKET_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        {
          mountedOK =
            analyzeRPCReplyMessageOnMountRequest(
              parserResponderReturnArguments,
              fhStatus                            );

          return mountedOK;                                /* return ! */
        }
      else
        ;
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

      return false;

    }
/*end of receiveFhstatusRPCMessageFromNFSMountServer*/


  public
  boolean

  receiveUnmountReply()
/*****************************************************************************/
/* Function name: receiveUnmountReply                                        */
/* File name: TestClient.java                                                */
/* Purpose: to get an answer from the mount                                  */
/* Parameters:                                                               */
/* Returns: true - if received a good RPC reply message, false - otherwise   */
/* Last modified: 17.06.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      ParserResponderReturnArguments
        parserResponderReturnArguments;
      boolean unmountedOK;
      boolean nowMayProcessTheParametersToRemoteProcedure;
      byte[] byteBuffer = null;
      DatagramPacket udpPacket = null;

                                                /* receiveUnmountReply */
/*---------------------------------------------------------------------------*/

      byteBuffer = new byte[ mount.Constants.UDP_PACKET_LENGTH ];

      udpPacket = new
        DatagramPacket( byteBuffer,
                        byteBuffer.length );

      try
        {
          udpSocket.receive( udpPacket );
        }
      catch( IOException e )
        {
          System.out.println(
            "udpSocket.receive: " +
            e.getMessage()          );
        }
    /*end of try-catch*/

      parserResponderReturnArguments = new
        ParserResponderReturnArguments();

      nowMayProcessTheParametersToRemoteProcedure =
        processUDPPacket(
          udpPacket,
          parserResponderReturnArguments      );

      if ( nowMayProcessTheParametersToRemoteProcedure )
        return true;
      else
        return false;
    /*end of if on nowMayProcessTheParametersToRemoteProcedure*/

    }
/*end of receiveUnmountReply*/


  public
  void

  sendUnmountRPCMessageToMountServer( long transactionId,
                                      String dirPath      )
/*****************************************************************************/
/* Function name: sendUnmountRPCMessageToMountServer                         */
/* File name: TestClient.java                                                */
/* Purpose: to create an unmount RPC message and send it to mount server     */
/* Parameters: transactionId                                                 */
/*             dirPath                                                       */
/* Returns:                                                                  */
/* Last modified: 15.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      byte[] ibuf = null;
      int ilength = 0;
      InetAddress ipAddressWhereToSend = null;
      int portToSendTo = 0;
      DatagramPacket udpPacket = null;
      Message rpcMessage = null;

                                /* sendUnmountRPCMessageToMountServer */
/*---------------------------------------------------------------------------*/

      if (dirPath.length() >
          mount.Constants.MNTPATHLEN)
        {
          System.out.println( "dirPath is too long!" );
          return;                                        /* return ! */
        }
      else
        ;
    /*end of if*/

      ibuf = new byte[
              mount.Constants.
                MOUNT_REQUEST_UDP_PACKET_DATA_LENGTH ];

      rpcMessage =
        new Message( ibuf );

      rpcMessage.
        putUnsignedInteger( transactionId );
      rpcMessage.
        putUnsignedInteger( rpc.Constants.RPC_CALL );
      rpcMessage.
        putUnsignedInteger(
          rpc.Constants.HIGHEST_RPC_PROTOCOL_VERSION_SUPPORTED );
      rpcMessage.
        putUnsignedInteger( (long) mount.Constants.MOUNTPROG );
      rpcMessage.
        putUnsignedInteger( mount.Constants.MOUNT_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) mount.Constants.MOUNTPROC_UMNT );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();


      try
        {
          rpcMessage.
            putString( dirPath,
                       mount.Constants.MNTPATHLEN );
        }
      catch( ArrayIndexOutOfBoundsException e )
        {
          System.out.println( "dirPath is too long!" );
          return;                                      /* return ! */
        }
      catch( ArrayStoreException e )
        {
          System.out.println( dirPath +
                              "\n" + e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try-catch*/

      portToSendTo = mount.Constants.MOUNT_PORT;

      try
        {
          ipAddressWhereToSend =
            InetAddress.getByName(
              rpc.Constants.LOCAL_LOOP_IP_ADDRESS );
        }
      catch( UnknownHostException e )
        {
          System.out.println( e.getMessage() );
          return;                                      /* return ! */
        }
    /*end of try*/

      udpPacket = new
        DatagramPacket( ibuf, ibuf.length,
                        ipAddressWhereToSend,
                        portToSendTo          );

      try
        {
          udpSocket.send( udpPacket,
                          transactionId,
                          "sendUnmountRPCMessageToMountServer" );
        }
      catch( IOException e )
        {
          System.out.println(
            "NFS mount TestClient, " +
            "sendUnmountRPCMessageToMountServer: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendUnmountRPCMessageToMountServer*/


  public
  void

  run()
/*****************************************************************************/
/* Function name: run                                                        */
/* File name: TestClient.java                                                */
/* Purpose: to test the NFS server                                           */
/* Parameters:                                                               */
/* Returns:                                                                  */
/* Last modified: 06.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long cookie;
      Vector fileHandlesVector = new Vector();
      boolean mountedOK;
      boolean unmountedOK;
      FhStatus fhStatus = new FhStatus();
      Fhandle fileHandle = null;
      Fhandle NFSFileHandle = null;
      int nBytesReadyToReceiveDirectoryEntries;
      FAttributes fileAttributes = null;
                                                                 /* run */
/*---------------------------------------------------------------------------*/

      System.out.println( "testing wrong RPC protocol handling" );

      sendWrongRPCProtocolVersionMessage(
        nfs.Constants.INITIAL_TRANSACTION_ID );

      receiveRepliesWithGeneralErrors();

      System.out.println( "testing wrong program number handling" );

      sendWrongProgramNumberMessage(
        nfs.Constants.INITIAL_TRANSACTION_ID );

      receiveRepliesWithGeneralErrors();

      System.out.println( "testing wrong NFS protocol handling" );

      sendWrongNFSProtocolVersionMessage(
        nfs.Constants.INITIAL_TRANSACTION_ID );

      receiveRepliesWithGeneralErrors();

      System.out.println( "testing wrong procedure handling" );

      sendWrongNFSProcedureNumberMessage(
        nfs.Constants.INITIAL_TRANSACTION_ID );

      receiveRepliesWithGeneralErrors();

      System.out.println( "testing null procedure handling" );

      sendRPCRequestWithoutParameters(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        Constants.NFSPROC_NULL                 );

      receiveNullProcedureReply();

      System.out.println( "testing ROOT procedure handling" );

      sendRPCRequestWithoutParameters(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        Constants.NFSPROC_ROOT                 );

      receiveRepliesWithGeneralErrors();

      System.out.println( "\n\ntesting NFSPROC_WRITECACHE " +
                          "procedure handling"                );

      sendRPCRequestWithoutParameters(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        Constants.NFSPROC_WRITECACHE          );

      receiveRepliesWithGeneralErrors();

      System.out.println( "\n\ntesting mounting" );

      sendMountRPCMessageToNFSMountServer( 
        nfs.Constants.INITIAL_TRANSACTION_ID,
        "/hdmsdos/tmp/nfs.tgz"                );
      mountedOK =
        receiveFhstatusRPCMessageFromNFSMountServer(
          fhStatus                                   );
      System.out.println( "\n\nrun: mountedOK=" + mountedOK );

      fileHandle = fhStatus.fhandle;

      System.out.println( "\n\ntesting directory read" );

      nBytesReadyToReceiveDirectoryEntries = 200;

      sendDirectoryReadRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle,
        (long) 0,                                      /* from the beginning */
        nBytesReadyToReceiveDirectoryEntries );

      cookie =
        receiveDirectoryReadReply(
          nBytesReadyToReceiveDirectoryEntries,
          fileHandlesVector                      );

      System.out.println( "\ncookie=" + cookie );

      System.out.println( "\n\ntesting directory read #2" );

      nBytesReadyToReceiveDirectoryEntries = 100;

      sendDirectoryReadRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle,
        cookie,
        nBytesReadyToReceiveDirectoryEntries );

      cookie =
        receiveDirectoryReadReply(
          nBytesReadyToReceiveDirectoryEntries,
          fileHandlesVector                     );

      System.out.println( "\ncookie=" + cookie );

      System.out.println( "\n\ntesting directory read #3" );

      nBytesReadyToReceiveDirectoryEntries = 500;

      sendDirectoryReadRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle,
        cookie,
        nBytesReadyToReceiveDirectoryEntries );

      cookie =
        receiveDirectoryReadReply(
          nBytesReadyToReceiveDirectoryEntries,
          fileHandlesVector                     );

      System.out.println( "\ncookie=" + cookie );

      System.out.println( "\n\ntesting directory read #4:" +
                          "\n\nreading a subdirectory"       );

      nBytesReadyToReceiveDirectoryEntries = 500;

      fileHandle = (Fhandle)
        fileHandlesVector.lastElement();

      System.out.println( "asking for listing of fileHandle=" +
                          fileHandle.toString()                 );

      sendDirectoryReadRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle,
        (long) 0,                                      /* from the beginning */
        nBytesReadyToReceiveDirectoryEntries );

      cookie =
        receiveDirectoryReadReply(
          nBytesReadyToReceiveDirectoryEntries,
          fileHandlesVector                     );

      System.out.println( "\ncookie=" + cookie );

      System.out.println( "\n\ntesting attibutes get" );

      System.out.println( "asking for attributes of fileHandle=" +
                          fileHandle.toString()                 );

      NFSFileHandle = fileHandle;

      sendAttributesGetRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle                            );

      fileAttributes =
        receiveAttributesGetReply();

      System.out.println( " fileAttributes=\n" +
                          ( (fileAttributes==null) ?
                            "null" :
                            fileAttributes.toString() ) );

      System.out.println( "\n\ntesting existing file lookup, #1" );

      System.out.println( "asking to look up " +
                          "in directory fileHandle=" +
                          fileHandle.toString()         );

      sendLookupRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle,
        "NFS"                                 );

      fileAttributes =
        receiveLookupReply(
          fhStatus          );


      System.out.println( "\n\ntesting file lookup, #2" );

      fileHandle = NFSFileHandle;


      System.out.println( "asking to look up " +
                          "in directory fileHandle=" +
                          fileHandle.toString()         );

      sendLookupRequest(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle,
        "exports"                                  );

      fileAttributes =
        receiveLookupReply(
          fhStatus          );

/*=========================================================================*/

                                                 /* testing file read */

/*=========================================================================*/

      fileHandle = NFSFileHandle;

      System.out.println( "\n\ntesting file read" );

      
      pumpAFileOverIntoTheCurrentDirectory(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        fileHandle,
        "COPYING"                                  );

      sendUnmountRPCMessageToMountServer(
        nfs.Constants.INITIAL_TRANSACTION_ID,
        "/hdmsdos/tmp/nfs.tgz"                );

      unmountedOK =
        receiveUnmountReply();

      if (unmountedOK)
        {
          System.out.println( "received an unmount reply" );
        }
      else
        {
          System.out.println( "NO unmount reply!" );
        }
    /*end of if on unmountedOK*/

      udpSocket.close();

  }
/*end of run*/


  public
  static
  void

  main( String[] args )
/*****************************************************************************/
/* Function name: main                                                       */
/* File name: TestClient.java                                                */
/* Purpose: main method for the TestClient class                             */
/* Parameters: agrument strings array                                        */
/* Returns:                                                                  */
/* Last modified: 11.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      TestClient test = null;
                                                          /* main */
/*---------------------------------------------------------------------------*/

      try
        {
          test = new TestClient( Constants.PROPERTIES_FILE_PATH );
        }
      catch( SocketException e )
        {
          System.out.println(
            "can\'t create io.UdpSocket: " +
            e.getMessage()                      );
          System.exit( 1 );
        }
    /*end of try-catch*/

      test.run();
      System.exit( 0 );

    }
/*end of main*/


} /* end of TestClient class */

/*****************************************************************************/
/* End of file: TestClient.java                                              */
/*****************************************************************************/
