/*****************************************************************************/
/* File name: RegistrationServer.java                                        */
/* Purpose: an abstract class to provide portmapper registration             */
/*          for classes that inherit from rpc.ParserResponder                */
/* Last modified: 01.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 rpc;


import java.net.*;
import java.io.*;


public
class

RegistrationServer
                     extends rpc.ParserResponder
{

  private final static String RCSID = "$Header: /d/NFS/rpc/RCS/RegistrationServer.java,v 1.5 1999/08/02 16:49:11 vklimov Exp $";


  public boolean registerWithPortMapper = true;
  protected Thread  portmapperThread = null;


  public

  RegistrationServer( int port,
                      java.lang.String propertiesFilePath )

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

      super( port, propertiesFilePath );

    }
/*end of RegistrationServer*/



  public
  void

  sendRegistrationRPCMessageToPortMapper(
    long transactionId,
    long programNumber,
    long versionNumber,
    long protocolNumber,
    long portNumber                       )
/*****************************************************************************/
/* Function name: sendRegistrationRPCMessageToPortMapper                     */
/* File name: RegistrationServer.java                                        */
/* Purpose: to create a port registration RPC message and send it            */
/*          to portmapping server                                            */
/* Parameters: transactionId                                                 */
/*             programNumber                                                 */
/*             versionNumber                                                 */
/*             protocolNumber                                                */
/*             portNumber                                                    */
/* 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;

                                /* sendRegistrationRPCMessageToPortMapper */
/*---------------------------------------------------------------------------*/

      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( (long) pm.Constants.PMAP_PROG );
      rpcMessage.
        putUnsignedInteger( pm.Constants.PMAP_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAPPROC_SET );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();
                                                    /* registration 4-tuple */

      rpcMessage.
        putUnsignedInteger( programNumber );
      rpcMessage.
        putUnsignedInteger( versionNumber );
      rpcMessage.
        putUnsignedInteger( protocolNumber );
      rpcMessage.
        putUnsignedInteger( portNumber );

      portToSendTo = pm.Constants.PORT_MAPPER_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,
                          "sendRegistrationRPCMessageToPortMapper" );
        }
      catch( IOException e )
        {
          System.out.println(
            "sendRegistrationRPCMessageToPortMapper: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendRegistrationRPCMessageToPortMapper*/


  public
  void

  sendUnregisterRPCMessageToPortMapper(
    long transactionId,
    long programNumber,
    long versionNumber,
    long protocolNumber,
    long portNumber                     )
/*****************************************************************************/
/* Function name: sendUnregisterRPCMessageToPortMapper                       */
/* File name: RegistrationServer.java                                        */
/* Purpose: to create an unregister RPC message and send it                  */
/*          to portmapping server                                            */
/* Parameters: transactionId                                                 */
/*             programNumber                                                 */
/*             versionNumber                                                 */
/*             protocolNumber                                                */
/*             portNumber                                                    */
/* 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;

                                /* sendUnregisterRPCMessageToPortMapper */
/*---------------------------------------------------------------------------*/

      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( (long) pm.Constants.PMAP_PROG );
      rpcMessage.
        putUnsignedInteger( pm.Constants.PMAP_VERS_HIGH );
      rpcMessage.
        putUnsignedInteger( (long) pm.Constants.PMAPPROC_UNSET );
      rpcMessage.
        putEmptyOpaqueAuthentication();
      rpcMessage.
        putEmptyOpaqueAuthentication();
                                                    /* registration 4-tuple */

      rpcMessage.
        putUnsignedInteger( programNumber );
      rpcMessage.
        putUnsignedInteger( versionNumber );
      rpcMessage.
        putUnsignedInteger( protocolNumber );
      rpcMessage.
        putUnsignedInteger( portNumber );

      portToSendTo = pm.Constants.PORT_MAPPER_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,
                          "sendUnregisterRPCMessageToPortMapper" );
        }
      catch( IOException e )
        {
          System.out.println(
            "sendUnregisterRPCMessageToPortMapper: " +
            "IOException in sending datagram\n" +
            e.getMessage()                              );
        }
    /*end of try-catch*/

    }
/*end of sendUnregisterRPCMessageToPortMapper*/


  public
  boolean

  analyzeRPCReplyMessageFromRegistration(
    ParserResponderReturnArguments
      parserResponderReturnArguments     )
/*****************************************************************************/
/* Function name: analyzeRPCReplyMessageFromRegistration                     */
/* File name: RegistrationServer.java                                        */
/* Purpose: to analyze the reply of the portmapper on registration request   */
/* Parameters: parserResponderReturnArguments                                */
/* Returns: true - if registered OK, false - otherwise                       */
/* Last modified: 01.08.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      String stringToPrintOut = "";
      long registeredOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;

                               /* analyzeRPCReplyMessageFromRegistration */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      registeredOK =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      if (registeredOK == xdr.Constants.TRUE)
        {
          if ( (logTransactions) &&
               (log != null)
             )
            {
              stringToPrintOut +=
                "RegistrationServer, analyzeRPCReplyMessageFromRegistration\n";
              stringToPrintOut +=
                "registered OK\n";
              log.write( stringToPrintOut );
            }
          else
            ;
        /*end of if*/

          return true;
        }
      else
        {
          if ( (logTransactions) &&
               (log != null)
             )
            {
              stringToPrintOut +=
                "RegistrationServer, analyzeRPCReplyMessageFromRegistration\n";
              stringToPrintOut +=
                "NOT registered!\n";
              log.write( stringToPrintOut );
            }
          else
            ;
        /*end of if*/

          return false;

        }
    /*end of if*/

    }
/*end of analyzeRPCReplyMessageFromRegistration*/


  public
  boolean

  analyzeRPCReplyMessageUnregister(
    ParserResponderReturnArguments
      parserResponderReturnArguments  )
/*****************************************************************************/
/* Function name: analyzeRPCReplyMessageUnregister                           */
/* File name: RegistrationServer.java                                        */
/* Purpose: to analyze the reply of the portmapper on unregister request     */
/* Parameters: parserResponderReturnArguments                                */
/* Returns: true - if unregistered OK, false - otherwise                     */
/* Last modified: 31.07.99                                                   */
/* Author: Victor Klimov, 1999                                               */
/*****************************************************************************/
    {
      long unregisteredOK;
      Message rpcMessageWithParametersToRemoteProcedure = null;
      String stringToPrintOut = "";

                               /* analyzeRPCReplyMessageUnregister */
/*---------------------------------------------------------------------------*/

      rpcMessageWithParametersToRemoteProcedure = new
        Message(
          parserResponderReturnArguments.
            byteArrayContainingParametersToRemoteProcedure );

      unregisteredOK =
        rpcMessageWithParametersToRemoteProcedure.
          getUnsignedInteger();

      if (unregisteredOK == xdr.Constants.TRUE)
        {
          if ( (logTransactions) &&
               (log != null)
             )
            {
              stringToPrintOut +=
                "RegistrationServer, analyzeRPCReplyMessageUnregister\n";
              stringToPrintOut +=
                "unregistered OK\n";
              log.write( stringToPrintOut );
            }
          else
            ;
        /*end of if*/

          return true;
        }
      else
        {

          stringToPrintOut +=
            "RegistrationServer, analyzeRPCReplyMessageUnregister\n";
          stringToPrintOut +=
            "NOT unregistered!\n";
          log.write( stringToPrintOut );

          return false;
        }
    /*end of if*/

    }
/*end of analyzeRPCReplyMessageUnregister*/


  public
  boolean

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

                 /* receiveRegistrationConfirmationRPCMessageFromPortMapper */
/*---------------------------------------------------------------------------*/

      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 )
        {
          registeredOK =
            analyzeRPCReplyMessageFromRegistration(
              parserResponderReturnArguments        );

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

      return false;

    }
/*end of receiveRegistrationConfirmationRPCMessageFromPortMapper*/


  public
  boolean

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

                 /* receiveUnregisterConfirmationRPCMessageFromPortMapper */
/*---------------------------------------------------------------------------*/

      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 )
        {
          unregisteredOK =
            analyzeRPCReplyMessageUnregister(
              parserResponderReturnArguments  );

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

      return false;

    }
/*end of receiveUnregisterConfirmationRPCMessageFromPortMapper*/


} /* end of RegistrationServer class */

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