# Package org.acplt.oncrpc

Sun's ONC/RPC Remote Procedure Call mechanism.

This package implements Sun's ONC/RPC Remote Procedure Call specification (see RFC 1831, RFC 1832, RFC 1833).

Functionality currently supported:

- RPC calls over TCP/IP as well as UDP/IP.
- RPC client functionality.
- RPC server functionality (see package org.acplt.oncrpc.server).
- Querying the ONC/RPC portmapper.
- jrpcgen-utility for converting x-files into Java classes.
- Support for authentication types `AUTH_NONE`, `AUTH_UNIX` and `AUTH_SHORT` on both the client and the server side.

To manually convert x-files into serializable Java classes, first map the primitive rpcgen data types (and thus the data types described in RFC 1832 to some extend) onto Java's primitive data types. The following table should help you doing this.

rpcgen / RFC 1832 | Java
`char` (used as character) | 8 bits / platform dependent | `byte` | 8 bits | `xdr.xdrEncodeByte(byte)` `byte = xdr.xdrDecodeByte()`
`unsigned char` (used as character) | 8 bits / platform dependent | `byte` | 8 bits | `xdr.xdrEncodeByte(byte)` `byte = xdr.xdrDecodeByte()`
`char` (used as 8 bit quantitiy) | 8 bits / platform dependent | `byte` | 8 bits | `xdr.xdrEncodeByte(byte)` `byte = xdr.xdrDecodeByte()`
`unsigned char` (used as 8 bit quantitiy) | 8 bits / platform dependent | `byte` | 8 bits | `xdr.xdrEncodeByte(byte)` `byte = xdr.xdrDecodeByte()`
`short` | platform dependent | `short` | 16 bits | `xdr.xdrEncodeShort(short)` `short = xdr.xdrDecodeShort()`
`unsigned short` | platform dependent | `short` | 16 bits | `xdr.xdrEncodeShort(short)` `short = xdr.xdrDecodeShort()`
`int` | 32 bits | `int` | 32 bits | `xdr.xdrEncodeInt(int)` `int = xdr.xdrDecodeInt()`
`unsigned int` | 32 bits | `int` | 32 bits | `xdr.xdrEncodeInt(int)` `int = xdr.xdrDecodeInt()`
`hyper` | 64 bits | `long` | 64 bits | `xdr.xdrEncodeLong(long)` `long = xdr.xdrDecodeLong()`
`unsigned hyper` | 64 bits | `long` | 64 bits | `xdr.xdrEncodeLong(long)` `long = xdr.xdrDecodeLong()`
`enum` | 32 bits | `int` | 32 bits | `xdr.xdrEncodeInt(int)` `int = xdr.xdrDecodeInt()`
`bool` |  | `boolean` |  | `xdr.xdrEncodeBoolean(boolean)` `boolean = xdr.xdrDecodeBoolean()`
`float` | 32 bits | `float` | 32 bits | `xdr.xdrEncodeFloat(float)` `float = xdr.xdrDecodeFloat()`
`double` | 64 bits | `double` | 64 bits | `xdr.xdrEncodeDouble(double)` `double = xdr.xdrDecodeDouble()`
`quadruple` | 128 bits | `n/a` |  |
`opaque[n]` | exactly n octets | `byte[]` | n bytes | `xdr.xdrEncodeOpaque(byte[])` `byte[] = xdr.xdrDecodeOpaque(n)`
`opaque<n>` | 4 bytes size followed by at most n octets | `byte[]` | ?? bytes | `xdr.xdrEncodeDynamicOpaque(byte[])` `byte[] = xdr.xdrDecodeDynamicOpaque()`
`opaque<>` | 4 bytes size followed by ?? octets | `byte[]` | ?? bytes | `xdr.xdrEncodeDynamicOpaque(byte[])` `byte[] = xdr.xdrDecodeDynamicOpaque()`
`string<n>` | 4 bytes size followed by at most n octets | `String` | ?? bytes | `xdr.xdrEncodeString(String)` `String = xdr.xdrDecodeString()`
`string<>` | 4 bytes size followed by ?? octets | `String` | ?? bytes | `xdr.xdrEncodeString(String)` `String = xdr.xdrDecodeString()`
`void` | 0 bits | `XdrVoid` |  | `xdrvoid.xdrEncode(xdr)` `xdrvoid.xdrDecode(xdr)`

The Remote Tea library also provides method to (de-) serialize vector data types of variable length, as shown below. To (de-) derialize fixed-size vectors, use the `...FixedVector()` variants and supply the protocol-defined size of the vector -- see the next table but one.

rpcgen / RFC 1832 | Java
`opaque<>` | 4 bytes size followed by ?? octets | `byte[]` | `xdr.xdrEncodeDynamicOpaque(byte[])` `byte[] = xdr.xdrDecodeDynamicOpaque()`
`char<>` `char short<>` | 4 bytes size followed by ?? chars | `byte[]` | `xdr.xdrEncodeByteVector(byte[])` `byte[] = xdr.xdrDecodeByteVector()`
`short<>` `unsigned short<>` | 4 bytes size followed by ?? shorts | `short[]` | `xdr.xdrEncodeShortVector(short[])` `short[] = xdr.xdrDecodeShortVector()`
`int<>` `unsigned int<>` | 4 bytes size followed by ?? ints | `int[]` | `xdr.xdrEncodeIntVector(int[])` `int[] = xdr.xdrDecodeIntVector()`
`long<>` `unsigned long<>` | 4 bytes size followed by ?? longs | `int[]` | `xdr.xdrEncodeIntVector(int[])` `int[] = xdr.xdrDecodeIntVector()`
`hyper<>` `unsigned hyper<>` | 4 bytes size followed by ?? hypers | `long[]` | `xdr.xdrEncodeLongVector(long[])` `long[] = xdr.xdrDecodeLongVector()`
`enum<>` | 4 bytes size followed by ?? enums | `int[]` | `xdr.xdrEncodeIntVector(int[])` `int[] = xdr.xdrDecodeIntVector()`
`bool<>` | 4 bytes size followed by ?? bools | `boolean[]` | `xdr.xdrEncodeBooleanVector(boolean[])` `boolean[] = xdr.xdrDecodeBooleanVector()`
`float<>` | 4 bytes size followed by ?? floats | `float[]` | `xdr.xdrEncodeFloatVector(float[])` `float[] = xdr.xdrDecodeFloatVector()`
`double<>` | 4 bytes size followed by ?? doubles | `double[]` | `xdr.xdrEncodeDoubleVector(double[])` `double[] = xdr.xdrDecodeDoubleVector()`

And now for (de-) serializing fixed-size vectors:

rpcgen / RFC 1832 | Java
`char[n]` `char short[n]` | 4 bytes size followed by n chars | `byte[]` | `xdr.xdrEncodeByteFixedVector(byte[], int n)` `byte[] = xdr.xdrDecodeByteFixedVector(int n)`
`short[n]` `unsigned short[n]` | 4 bytes size followed by n shorts | `short[]` | `xdr.xdrEncodeShortFixedVector(short[], int n)` `short[] = xdr.xdrDecodeShortFixedVector(int n)`
`int[n]` `unsigned int[n]` | 4 bytes size followed by n ints | `int[]` | `xdr.xdrEncodeIntFixedVector(int[], int n)` `int[] = xdr.xdrDecodeIntFixedVector(int n)`
`long[n]` `unsigned long[n]` | 4 bytes size followed by n longs | `int[]` | `xdr.xdrEncodeIntFixedVector(int[], int n)` `int[] = xdr.xdrDecodeIntFixedVector(int n)`
`hyper[n]` `unsigned hyper[n]` | 4 bytes size followed by n hypers | `long[]` | `xdr.xdrEncodeLongFixedVector(long[], int n)` `long[] = xdr.xdrDecodeLongFixedVector(int n)`
`enum[n]` | 4 bytes size followed by n enums | `int[]` | `xdr.xdrEncodeIntFixedVector(int[], int n)` `int[] = xdr.xdrDecodeIntFixedVector(int n)`
`bool[n]` | 4 bytes size followed by n bools | `boolean[]` | `xdr.xdrEncodeBooleanFixedVector(boolean[], int n)` `boolean[] = xdr.xdrDecodeBooleanFixedVector(int n)`
`float[n]` | 4 bytes size followed by n floats | `float[]` | `xdr.xdrEncodeFloatFixedVector(float[], int n)` `float[] = xdr.xdrDecodeFloatFixedVector(int n)`
`double[n]` | 4 bytes size followed by n doubles | `double[]` | `xdr.xdrEncodeDoubleFixedVector(double[], int n)` `double[] = xdr.xdrDecodeDoubleFixedVector(int n)`

For every structure you encounter in a .x file, write a Java class, which implements the `XdrAble` interface. For instance, taking this snippet from a rpcgen source file...

    struct foo {
        int bar;
        float baz;
        struct foo *next;
    };

...`struct foo` is translated into Java ONC/RPC babble as:

    class foo implements XdrAble {
       // members of foo structure
       public int bar;
       public float baz;
       public foo next;

       // serialize / encode foo
        public void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException {
            xdr.xdrEncodeInt(bar);
            xdr.xdrEncodeFloat(baz);
            if ( next == null ) {
                xdr.xdrEncodeBoolean(false);
            } else {
                xdr.xdrEncodeBoolean(true);
                next.xdrEncode(xdr);
            }
        }

        // deserialize / decode foo
        public void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            bar = xdr.xdrDecodeInt();
            baz = xdr.xdrDecodeFloat();
            if ( !xdr.xdrDecodeBoolean() ) {
                next = null;
            } else {
                next = new foo();
                next.xdrDecode(xdr);
            }
        }
    }

The previous example also shows how to deal with pointers (eeek!) in .x files. The are simply transformed into references -- quite a difference, really.

Tanslating a descriminated union is typically done the simple and silly way. Silly, because unions can not really be represented in the Java language. You need to transform them into a class (structure) instead, and this will lead to a rather ugly form.

    union foo switch (FOOTYPE type) {
        case BAR_CLASS:
            bar u_bar;
        case BAZ_CLASS:
            baz u_baz;
    }

should become

    class foo implements XdrAble {
        // descriminant value
        public int type;
        // arm declarations
        public bar u_bar;
        public baz u_baz;

        // descriminant-arm values
        public static int BAR_CLASS = 1;
        public static int BAZ_CLASS = 2;

        // serialize / encode foo
        public void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException {
            xdr.xdrEncodeInt(type);
            switch ( type ) {
            case BAR_CLASS:
                u_bar.xdrEncode(xdr); break;
            case BAZ_CLASS:
                u_baz.xdrEncode(xdr); break;
            }
        }

        // deserialize / decode foo
        public void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            type = xdr.xdrDecodeInt();
            switch ( type ) {
            case BAR_CLASS:
                u_bar = new bar(); u_bar.xdrDecode(xdr); break;
            case BAZ_CLASS:
                u_baz = new bar(); u_bar.xdrDecode(xdr); break;
            }
        }
    }

You can also take advantage of polymorphism when translating descriminated unions into a class hierarchy. You should then write an abstract base class with only one static member function capable of constructing the appropriate instance from the XDR stream. The tricky part about this is getting the descriminant value into the stream or out of it without having to duplicate the decoding code into the constructor. With the skeleton below you should be able to do this easily, but you should remember to never recycle an object reference and never deserialize the state of the object a second time from a XDR stream!

    abstract class foobase implements XdrAble {
        // construct a bar, baz,... class from XDR stream
        public static foobase xdrNew(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            foobase obj = null;
            switch ( xdr.xdrDecodeInt() ) {
            case BAR_CLASS:
                obj = new bar(); break;
            case BAZ_CLASS:
                obj = new baz(); break;
            }
            obj.xdrDecode(xdr);
            return obj;
        }

        public abstract void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException;
        public abstract void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException;

        // descriminant values
        public static int BAR_CLASS = 1;
        public static int BAZ_CLASS = 2;
    }

    class bar extends foobase {
        public void xdrEncode(XdrEncodingStream xdr)
               throws OncRpcException, IOException {
            // encode your members here...
            // dont forget to encode the descriminant value
            xdr.xdrEncodeInt(BAR_CLASS);
            xdr.xdrEncodeFloat(noah);
        }
        public void xdrDecode(XdrDecodingStream xdr)
               throws OncRpcException, IOException {
            // decode your members here...
            // but *NEVER* decode the descriminant value
            noah = xdr.xdrDecodeFloat();
        }
    }

This package is part of the ACPLT/KS ACPLTea Java Library package.

(c) 1999, 2006 Harald Albrecht.
(c) 1999, 2002 Lehrstuhl für Prozeßleittechnik, Aachen University of Technology, Germany.

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This library 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 Library General Public License for more details.

You should have received a copy of the GNU Library General Public License along with this program (see the file COPYING.LIB for more details); if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

- Interface Summary
  Interface | Description
  --- | ---
  OncRpcAcceptStatus | A collection of constants used to identify the acceptance status of ONC/RPC reply messages.
  OncRpcAuthConstants | A collection of constants related to authentication and generally usefull for ONC/RPC.
  OncRpcAuthStatus | A collection of constants used to identify the authentication status (or any authentication errors) in ONC/RPC replies of the corresponding ONC/RPC calls.
  OncRpcAuthType | A collection of constants used to identify the authentication schemes available for ONC/RPC.
  OncRpcBroadcastListener | The listener class for `receiving` `ONC/RPC broadcast reply events`.
  OncRpcConstants | A collection of constants generally usefull for ONC/RPC.
  OncRpcMessageType | A collection of constants used for ONC/RPC messages to identify the type of message.
  OncRpcPortmapServices | A collection of constants used for ONC/RPC messages to identify the remote procedure calls offered by ONC/RPC portmappers.
  OncRpcProtocols | A collection of protocol constants used by the ONC/RPC package.
  OncRpcRejectStatus | A collection of constants used to describe why a remote procedure call message was rejected.
  OncRpcReplyStatus | A collection of constants used to identify the (overall) status of an ONC/RPC reply message.
  OncRpcUdpRetransmissionMode | A collection of constants used to identify the retransmission schemes when using `UDP/IP-based ONC/RPC clients`.
  XdrAble | Defines the interface for all classes that should be able to be serialized into XDR streams, and deserialized or constructed from XDR streams.

- Class Summary
  Class | Description
  --- | ---
  OncRpcBroadcastAdapter | An abstract adapter class for `receiving` `ONC/RPC broadcast reply events`.
  OncRpcBroadcastEvent | The class `OncRpcBroadcastEvent` defines an event fired by `ONC/RPC UDP/IP-based clients` whenever replies to a `broadcast call` are received.
  OncRpcCallMessage | The `OncRpcCallMessage` class represents a remote procedure call message as defined by ONC/RPC in RFC 1831.
  OncRpcClient | The abstract `OncRpcClient` class is the foundation for protcol-specific ONC/RPC clients.
  OncRpcClientAuth | The `OncRpcClientAuth` class is the base class for handling all protocol issues of ONC/RPC authentication on the client side.
  OncRpcClientAuthNone | The `OncRpcClientAuthNone` class handles protocol issues of ONC/RPC `AUTH_NONE` authentication.
  OncRpcClientAuthUnix | The `OncRpcClientAuthUnix` class handles protocol issues of ONC/RPC `AUTH_UNIX` (and thus `AUTH_SHORT`) authentication.
  OncRpcClientCallMessage | The `OncRpcClientCallMessage` class represents a remote procedure call message on the client side.
  OncRpcClientReplyMessage | The `OncRpcReplyMessage` class represents an ONC/RPC reply message as defined by ONC/RPC in RFC 1831.
  OncRpcClientStub | The abstract `OncRpcClientStub` class is the base class to build ONC/RPC-program specific clients upon.
  OncRpcDumpResult | Objects of class `OncRpcDumpResult` represent the outcome of the PMAP_DUMP operation on a portmapper.
  OncRpcGetPortResult | The `OncRpcGetPortResult` class represents the result from a PMAP_GETPORT remote procedure call to the ONC/RPC portmapper.
  OncRpcHttpClient | ONC/RPC client which communicates with ONC/RPC servers over the network using the ISO/OSI level 7 application protocol HTTP as a tunnel.
  OncRpcMessage | The `OncRpcMessage` class is an abstract superclass for all the message types ONC/RPC defines (well, an overwhelming count of two).
  OncRpcPortmapClient | The class `OncRpcPortmapClient` is a specialized ONC/RPC client, which can talk to the portmapper on a given host using the famous UDP/IP datagram-oriented internet protocol.
  OncRpcReplyMessage | The `OncRpcReplyMessage` class represents an ONC/RPC reply message as defined by ONC/RPC in RFC 1831.
  OncRpcServerIdent | The class `OncRpcServerIdent` represents an tuple { program, version, protocol, port} uniquely identifying a particular ONC/RPC server on a given host.
  OncRpcTcpClient | ONC/RPC client which communicates with ONC/RPC servers over the network using the stream-oriented protocol TCP/IP.
  OncRpcTcpSocketHelper | Wraps JRE-specific networking code for TCP/IP-based client sockets.
  OncRpcUdpClient | ONC/RPC client which communicates with ONC/RPC servers over the network using the datagram-oriented protocol UDP/IP.
  OncRpcUdpSocketHelper | Wraps JRE-specific networking code for UDP/IP-based client sockets.
  XdrBoolean | Instances of the class `XdrBoolean` represent (de-)serializeable booleans, which are especially useful in cases where a result with only a single boolean is expected from a remote function call or only a single boolean parameter needs to be supplied.
  XdrBufferDecodingStream | The `XdrBufferDecodingStream` class provides the necessary functionality to `XdrDecodingStream` to retrieve XDR packets from a byte buffer.
  XdrBufferEncodingStream | The `XdrBufferEncodingStream` class provides a buffer-based XDR stream.
  XdrByte | Instances of the class `XdrByte` represent (de-)serializeable bytes, which are especially useful in cases where a result with only a single byte is expected from a remote function call or only a single byte parameter needs to be supplied.
  XdrBytes | Instances of the class `XdrBytes` represent (de-)serializeable bytes values, which are especially useful in cases where a result with only a single bytes value is expected from a remote function call or only a single bytes value parameter needs to be supplied.
  XdrChar | Instances of the class `XdrChar` represent (de-)serializeable chars, which are especially useful in cases where a result with only a single char is expected from a remote function call or only a single char parameter needs to be supplied.
  XdrDecodingStream | Defines the abstract base class for all decoding XDR streams.
  XdrDouble | Instances of the class `XdrDouble` represent (de-)serializeable doubles, which are especially useful in cases where a result with only a single double is expected from a remote function call or only a single double parameter needs to be supplied.
  XdrDynamicOpaque | Instances of the class `XdrDynamicOpaque` represent (de-)serializeable dynamic-size opaque values, which are especially useful in cases where a result with only a single opaque value is expected from a remote function call or only a single opaque value parameter needs to be supplied.
  XdrEncodingStream | Defines the abstract base class for all encoding XDR streams.
  XdrFloat | Instances of the class `XdrFloat` represent (de-)serializeable floats, which are especially useful in cases where a result with only a single float is expected from a remote function call or only a single float parameter needs to be supplied.
  XdrHttpDecodingStream | The `XdrHttpDecodingStream` class provides the necessary functionality to `XdrDecodingStream` to receive XDR data through HTTP tunnels.
  XdrInt | Instances of the class `XdrInt` represent (de-)serializeable integers, which are especially useful in cases where a result with only a single int is expected from a remote function call or only a single int parameter needs to be supplied.
  XdrLong | Instances of the class `XdrLong` represent (de-)serializeable longs (64 bit), which are especially useful in cases where a result with only a single long is expected from a remote function call or only a single long parameter needs to be supplied.
  XdrOpaque | Instances of the class `XdrOpaque` represent (de-)serializeable fixed-size opaque values, which are especially useful in cases where a result with only a single opaque value is expected from a remote function call or only a single opaque value parameter needs to be supplied.
  XdrShort | Instances of the class `XdrShort` represent (de-)serializeable shorts, which are especially useful in cases where a result with only a single short is expected from a remote function call or only a single short parameter needs to be supplied.
  XdrString | Instances of the class `XdrString` represent (de-)serializeable strings, which are especially useful in cases where a result with only a single string is expected from a remote function call or only a single string parameter needs to be supplied.
  XdrTcpDecodingStream | The `XdrTcpDecodingStream` class provides the necessary functionality to `XdrDecodingStream` to receive XDR records from the network using the stream-oriented TCP/IP.
  XdrTcpEncodingStream | The `XdrTcpEncodingStream` class provides the necessary functionality to `XdrEncodingStream` to send XDR records to the network using the stream-oriented TCP/IP.
  XdrUdpDecodingStream | The `XdrUdpDecodingStream` class provides the necessary functionality to `XdrDecodingStream` to receive XDR packets from the network using the datagram-oriented UDP/IP.
  XdrUdpEncodingStream | The `XdrUdpDecodingStream` class provides the necessary functionality to `XdrDecodingStream` to send XDR packets over the network using the datagram-oriented UDP/IP.
  XdrUnion | The abstract base class `XdrUnion` helps (de-)serializing polymorphic classes.
  XdrVoid | Instances of the class `XdrVoid` represent (de-)serializeable voids, which are especially useful in cases where no result is expected from a remote function call or no parameters are supplied.

- Exception Summary
  Exception | Description
  --- | ---
  OncRpcAuthenticationException | The class `OncRpcAuthenticationException` indicates an authentication exception.
  OncRpcException | The class `OncRpcException` indicates ONC/RPC conditions that a reasonable application might want to catch.
  OncRpcProgramNotRegisteredException | The class `OncRpcProgramNotRegisteredException` indicates that the requests ONC/RPC program is not available at the specified host.
  OncRpcTimeoutException | The class `OncRpcTimeoutException` indicates a timed out call exception.