<!DOCTYPE SGMLguid>
<SET TAG=H1 ITEM=BODY VALUE=TOP>
<SET TAG=P ITEM=SK VALUE=0>
<SET TAG=XMP ITEM=IN VALUE=0>
<SET TAG=XMP ITEM=FONT VALUE=MONO>
<SET TAG=P ITEM=IN VALUE=0>
<SET TAG=UL ITEM=SK VALUE=0>
<SET TAG=H1 ITEM=FONT VALUE=TITLE>
<SET TAG=H2 ITEM=FONT VALUE=HEAD>
<SET TAG=H3 ITEM=FONT VALUE=HEAD>
<SET TAG=H4 ITEM=FONT VALUE=|roman10|>
<GDOC HY=USER>
<BIBID REFID=RPCIMP>
<BIBID REFID=VIR88>
<BIBID REFID=RTC87>
<BIBID REFID=Nelson>
<BIBID REFID=KOSTR85>
<BIBID REFID=XSOFTN3>
<BIBID REFID=COURIER>
<BIBID REFID=WINTCPADM>
<BIBID REFID=WINTCPREF>
<BIBID REFID=WAY>
..ti set
..tb 9 17 25 33 41 49 57 65 73
<FRONTM>
<TITLEP>
<TITLE STITLE="RPC User Manual">
<TITLE>RPC User Manual

 

<AUTHOR>T.J. Berners&hyphen.Lee   CERN DD/OC

 
<DATE>Version 3.0.0,  Last Revised April 1990
<COPYRIGHT>CERN 1986, 87, 88, 89, 90

Now includes: Use of the internet daemon,
Use of the WAY name server.

<HP1>(Details about how to acquire a
copy of this document are given in an appendix).
</HP1>
</TITLEP>
<TOC>
</FRONTM>
<BODY>
<H1>Introduction
This manual describes how to build a distributed system using the
Remote Procedure Call system developed in the Online Group
of the DD Division of CERN, the European Particle Physics Laboratory.
<h2> The system
The remote procedure call product consists of two essential parts:
an RPC compiler which is used during development of an application,
and the RPC run time system, which is part of the run time code.

Target systems supported are
<ul>
<li>VAX/VMS,
<li>Unix (Berkley 4.3 or Ultrix or equivalent)
<li>stand&hyphen.alone M680x0 (MoniCa) systems (Valet&hyphen.Plus, etc)
<li>stand&hyphen.alone M6809 systems
<li>M680x0 systems running RMS68K
<li>M680x0 systems running OS9
<li>The IBM&hyphen.PC running TurboPascal or Turbo-C
<li>The Macintosh running TurboPascal or MPW
</ul>

Application languages catered for explicitly are FORTRAN, C, Pascal and PILS.

The RPC system will operate over media including
DECNET, ISO Transport protocols, TCP/IP, RS232 lines, raw Ethernet,
and "CERN Host Interface" VAX-FASTBUS FASTBUS-VME and VAX-VME links.
Support for new target systems is added from time to time.

Development on VAX/VMS, BSD 4.2 Unix (or Ultrix), or IBM-PC MSDOS
host systems is described.
<H2> Using this Manual
This manual aims to be a complete reference text,
and is not intended to be read from cover to cover at one sitting.
<hp2> Most of it will not apply to you </hp2>
so just read the first few chapters, and then parts relevant to
your chosen operating
system and communication medium.

Detailed examples of the use of the compiler for different systems are
provided. The internals, construction and maintenance of the compiler and
run&hyphen.time systems are not covered. These are covered in the
Internals Guide <BIBREF REFID=RPCIMP>. 

For an introduction to Remote Procedure Call, see
<BIBREF REFID=VIR88>.
For a discussion of design choices made in the design of this
particular system, see <BIBREF REFID=RPCIMP> and <BIBREF REFID=RTC87>. 
  
For information on how to run an RPC application which has already been
written, skip to the chapter "Running an RPC system". That chapter also gives
details of supported systems, communications media and interface hardware. 

The steps involved in making a distributed system are dealt with,
in this manual, in roughly chronological order. They are:
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skippic1
<FIG ID=PICT1 PLACE=INLINE  FRAME=NONE>
<PICTURE NAME=PICT1$$S>
<FIGCAP><HP1>The steps in designing a distributed system
</HP1>
</FIG>
..go donepic1
...skippic1
<FIG ID=PICT1 PLACE=INLINE  FRAME=NONE>
<XMP>
     +-----------------------------------------------------------+
     |                     Design the system (Ch. 2)             |
     +-----------------------------+-----------------------------+
                                   |
     +-----------------------------+-----------------------------+
     |               Write a formal description of the           |
     |                  module interfaces (Ch. 3)                |
     +-----------------------------+-----------------------------+
                                   |
               +-------------------+--------------+
               |                                  |
               |                                  |
+--------------+----------------+     +-----------+-------------------+
|    Write the modules just     |     |  Generate "stub" code by      |
|  as though not distributed    |     |  running RPC compiler         |
|        (But see Ch. 6)        |     |         (Ch.4)                |
+--------------+----------------+     +-----------+-------------------+
               |                                  |
               +-----------------+----------------+
                                 |
     +---------------------------+-------------------------------+
     |     Compile and link the program modules with stubs       |
     |              and run&hyphen.time library (Ch. 5)          |
     +---------------------------+-------------------------------+
                                 |
     +---------------------------+-------------------------------+
     |            Define server addresses on client systems      |
     |         and client addresses on server system (Ch. 7)     |
     +---------------------------+-------------------------------+
                                 |
     +---------------------------+-------------------------------+
     |                      Run the programs                     |
     +-----------------------------------------------------------+
</XMP>
<FIGCAP><HP1>The steps in designing a distributed system
</HP1>
</FIG>
...donepic1
Chapter 8 describes special features of the RPC system.
The Appendices contain information for reference about the RPC
compiler, details of installation of the system, and pointers
to more information.
<H1>Designing a distributed system

<I1 IX=1>System design
<I1 IX=1>Designing the system
Distributed design using RPC starts with the design of a modular program.
It is wise (as in any system) to define the interfaces between the
modules before writing each module.
<h2> Design Rules
<I1 IX=1>Restrictions
In order that, in the final version, the modules can run on
different machines, various rules must be followed:
<OL>
<LI>
Control is not passed between modules except as a procedure call
<LI>
No data is to be passed between modules except explicitly
<fn>
In fact, mechanisms exist to have implicitly passed data
(such as FORTRAN COMMON blocks)
transferred as well. See the "PRAGMA external_marshalling"
</fn>
as parameters to procedures.
<LI>
It is better, for efficency, to make a few calls to a remote module
rather than lots of calls transfering a little data each time.
<LI>
Also for efficiency reasons, it is a bad idea to pass large
arrays unnecessarily.
</OL>

<I1 IX=1>Calling conventions
The calling conventions used for remote procedures
may be selected to be either FORTRAN, C, Pascal or PILS compatible,
when the system is generated.

Basically the RPC system can be easily used with most
high level languages.
There are some limitations imposed on data types:
variant records ("unions" in C) are not handled by the compiler, for
instance.
<fn>You can handle them using the "External Marshalling" (q.v.) feature.
</fn>
FORTRAN and PILS have their own inherent limitations on data types if used.
If pointers are passed from one machine to another, they may either be passed
as integers, so that they retain their value but not their usefulness,
or data structure to which they point can be transferred automatically,
in which case they retain their meaning but not their literal value.
Linked lists and trees of linked records may be passed so long
as they are not circular.
A full list of supported data types is given in an Appendix.
<h2> Component parts
Some of the code necessary to connect the local and remote parts of
the programs are already written, and are contained in a run&hyphen.time
library.
This includes an interface to the various communications systems used.

The remaining parts are the
<HP2>"stub"</HP2>
<I1 IX=1>Stub, definition of 
modules. These are generated specially for
each application by an RPC compiler (RPCC).
On the calling machine, there is a stub module
which emulates the called procedure,
and on the called machine there is a stub module
which emulates the calling program.

For ease of handling, related procedures are grouped into units
called
<I1 IX=1>Package, definition of 
<HP2>"packages"</HP2>.
The package is the unit of compilation of stub modules, and a unit
of addressing in the run&hyphen.time system.
For example, a graphics package might contain all the procedures
for graphics handling.
For each package, the designer must write a definition file, described below.

For each package, any module which calls the procedures is referred to as a
<HP2>"client"</HP2>,
<I1 IX=1>Client, definition of 
and the module which is called is referred to as a
<I1 IX=1>Server, definition of 
<HP2>"server"</HP2>.
<FIG ID=nFIG2 PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go sknfig2
<PICTURE NAME=NFIG2$$S>
..go donnfig2
...sknfig2
                        (diagram omitted)
...donnfig2
<FIGCAP><HP1>                  The software components of a remote call.
</HP1>
</FIG>
<H1>Writing the definition file

<I1 IX=1>Definition file
<I1 IX=1>Interface, definition file 
The RPC Compiler accepts a formal description of the procedures which are
called remotely, and their parameters. It produces as output
the necessary software to exchange data between your
local application and the remote one. The input language is called RPCL. The
<I1 IX=1>RPCL
RPCL syntax is a similar to the ADA language; a formal description is contained
in an appendix, to which the reader is referred for details.

<FIG ID=DEFNF PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk3
<PICTURE NAME=DEFNF$$S>
...timsk3
<FIGCAP><HP1>
The definition file defines the interface between two software
modules.
</HP1>
</FIG>
An example input file is
 
<xmp>
     PACKAGE myfacility IS
 
          TYPE    myarray IS ARRAY(1..20) OF RPC_LONG;
 
          PROCEDURE doit( xxx: IN RPC_SHORT; yyy: OUT myarray);
 
     END myfacility;
</xmp>
 
The package in this example contains a procedure to set the state of,
say, a remote valve.
The procedure takes three input parameters from the caller:
two integers
..bf mono
(func, index)
..pf
and a real. It does not alter the value
of these.
It has one output parameter which happens to be the last one,
a 32 bit status value
..bf mono
(stat).
..pf
The procedure does not use the initial value of
..bf mono
stat,
..pf
but a new value is returned to the caller.

(In the examples, the reserved words are given in upper case for clarity,
although in an input file upper and lower case are treated
the same.)

In general,  the input file is composed of two parts:
type declarations and procedure/function declarations.   In a type declaration
complicated types may, if necessary, be defined in terms of simpler types.

In the second part of the file,  the remote procedures and functions are defined
by giving,  for each one,  its name,  the number an type of parameters, their
direction and, for a function,  the type of value returned.   This is very
<i1>Procedure
<i1>Function
similar to the declaration of a external procedure in other high level
languages. 
 
<BOX>
<XMP>
--      Example: RPCL Definition of a FILE ACCESS PACKAGE
--
 
PACKAGE filer IS
 
--              Type declaration part:
 
  TYPE  my_int  IS      RPC_SHORT;
  TYPE  my_long IS      RPC_LONG;
  TYPE  my_subs IS      SUBSTRING(255);
  TYPE  my_type IS      ARRAY(1..4) OF RPC_CHAR;
 
--              Procedure declaration part:
 
  PROCEDURE f_init(     status:         OUT     my_long);
  PROCEDURE f_end(      status:         OUT     my_long);
 
  PROCEDURE f_open(     unitno:         IN      my_int;
                        name:           IN      my_subs;
                        mode:           IN      my_int;
                        nameuse:        IN      my_type;
                        status:         OUT     my_long);
 
  PROCEDURE f_close(unitno: IN my_int; status: OUT my_long);
 
  PROCEDURE f_getline(  unitno:         IN      my_int;
                        linebuf:        OUT     my_subs;
                        ch:             OUT     my_int;
                        status:         OUT     my_long);
 
  PROCEDURE f_putline(  unitno:         IN      my_int;
                        name:           IN      my_subs;
                        status:         OUT     my_long);
 
  PROCEDURE f_rename(name1, name2:      IN      my_subs;
                        t1, t2:         IN      my_type;
                        status:         OUT     my_long);
 
  PROCEDURE f_errmess(messno:           IN      my_long;
                        name:           OUT     my_subs;
                        status:         OUT     my_long);
END filer;
</XMP>
</BOX>
.pa
         Below are the equivalent Pascal declarations for each procedure
in the example above.
 
<XMP>
 
PROCEDURE f_init (                        PROCEDURE f_putline (
    VAR status : my_long);                      VAR unitno : my_int;
EXTERN;                                         VAR a_name : my_subs;
                                                VAR s_name : rpc_short;
PROCEDURE f_end (                               VAR l_name : rpc_short;
    VAR status : my_long);                      VAR status : my_long);
EXTERN;                                   EXTERN;
 
PROCEDURE f_open (                        PROCEDURE f_rename (
    VAR unitno : my_int;                        VAR a_name1 : my_subs;
    VAR a_name : my_subs;                       VAR s-name1 : rpc_short;
    VAR s_name : rpc_short;                     VAR l_name1 : rpc_short;
    VAR l_name : rpc_short;                     VAR a_name2 : my_subs;
    VAR mode : my_int;                          VAR s_name2 : rpc_short;
    VAR nameuse : my_type;                      VAR l_name2 : rpc_short;
    VAR status : my_long);                      VAR t1 : my_type;
EXTERN;                                         VAR t2 : my_type;
                                                VAR status : my_long);
PROCEDURE f_close (                       EXTERN;
    VAR unitno : my_int;
    VAR status : my_long);                PROCEDURE f_errmess (
EXTERN;                                         VAR messno : my_long;
                                                VAR a_name : my_subs;
PROCEDURE f_getline (                           VAR s_name : rpc_short;
    VAR unitno : my_int;                        VAR l_name : rpc_short;
    VAR a_linebuf : my_subs;                    VAR status : my_long);
    VAR s_linebuf : rpc_short             EXTERN;
    VAR l_linebuf : rpc_short
    VAR ch : my_int;
    VAR status : my_long);
EXTERN;
 
</XMP>
 
This list of declarations is automatically generated by
the RPC Compiler, as the .ext file described in the next section.
<h2> PRAGMAs
A PRAGMA is a statement in an RPC definition file which instructs
the compiler how to implement something, without fundamentally
changing the definition of the interface. A PRAGMA consists of
the word PRAGMA followed by the name of the pragma, followed by
(in brackets) the name of things to which it applies, and
any other parameters.
<i1 ix=1>PRAGMA
<h3> PRAGMA TIMEOUT

Syntax:
<xmp>
        PRAGMA TIMEOUT ( <procedure_name> , <value>  );
</xmp>
<I1 IX=1>Pragma TIMEOUT
<I1 IX=1>Timeout, pragma for each procedure
This specifies the absolute maximum time which the procedure could
possibly be expected to take, including any network delays.
The RPC system will check this time (when the underlying transport
service allows it) and if it expires will create and error.
This will halt the program unless a user Error Handler (q.v.)
or a Call Status parameter (q.v.) is used.

If this pragma is not used, the default will be no timeout, or
the value specified with the TIMEOUT compiler option, if that has
been given.

The procedure (or function) name given must already have been declared.

The value is given in units of 10ms as a decimal integer value.

<h3> PRAGMA CONCURRENT

Syntax:
<xmp>
        PRAGMA CONCURRENT ( <procedure_name> , { <procedure_name> }*   );
</xmp>

<I1 IX=1>Pragma CONCURRENT
<I1 IX=1>CONCURRENT pragma
<i1 ix=1>Asynchronous execution
the {braces}* indicating more than one (previously declared)
procedure name may be given.

This specifies that, once started, the procedure should continue execution
concurrently with the client.
The fact that the client continues processing after the procesdure
call does not, in this case, signify that the procedure is complete:
only, that it has started.
<FIG ID=CONCU PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk6
<PICTURE NAME=CONCU$$S>
...timsk6
<FIGCAP><HP1>The flow of control for a normal call and for a concurrent call.
</HP1>
</FIG>
The procedure (<hp2>not</hp2> function) name given must
already have been declared.
It may not have any return (OUT or INOUT) parameters.

This method provides concurrency between the caller and the called routine.
There are other methods of achieving concurrency, for example which allow a
separate server task to run concurrently with the client processes, and be
interrupted to service a remote call. These are described later under
"varieties of server".

See also PRAGMA CAST below.
<h3> PRAGMA CAST
..bx on 81
Syntax:
<xmp>
        PRAGMA CAST ( <procedure_name> , { <procedure_name> }*   );
</xmp>

<I1 IX=1>Pragma CAST: One way messages
<I1 IX=1>CAST pragma
<i1 ix=1>One&hyphen.way calls
<i1>Streamed RPCs (CASTs)
<i1>Broadcast calls
<i1>Multicast calls
<i1 ix=1>Asynchronous execution
the {braces}* indicating more than one (previously declared)
procedure name may be given.

This specifies that no return message should be sent at all.
The call message is sent and return is immediately made to the caller.

Over a reliable stream oriented medium (TCP, DECnet, ISO TP4, CHI etc.),
this allows information to be streamed between a client producing it
and a server receiving it. This may significantly increase the
efficiency in some applications.

Over a non-reliable medium (raw ethernet, UDP etc.),
this option supresses the protocol which ensures reliable transmission
of the data.There is no acknowledgement made at all.
This can <hp2>speed up</hp2> execution by a factor of two or more.

Pragma CAST also allows broadcast and multicast calls to be
made where the transport protocol supports it, for example over raw ethernet.

<FIG ID=CONCU PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk7
..fo off
              Client                     Server

                |
                |------- call message ----->
                |                           |
                |                           |
                |                           -  (There is no reply)
                |
                V
            execution continues
..fo on
...timsk7
<FIGCAP><HP1>The flow of control for a cast.
</HP1>
</FIG>
The procedure (<hp2>not</hp2> function) name given must
already have been declared.
It may not have any return (OUT or INOUT) parameters.
..bx off
<h3> PRAGMA CALL_STATUS

Syntax:
<xmp>
        PRAGMA CALL_STATUS ( <procedure_name> , <parameter_name>  );
</xmp>

<I1 IX=1>Call status parameter
<I1 IX=1>Status parameter for call status
<I1 IX=1>Error, return to user parameter
<I1 IX=1>Pragma, CALL_STATUS
This informs the compiler that the parameter indicated is a status
parameter for the return of any bad call status.
In this case, if any error (network failure, timeout, etc.,)
occurs during the call, a VMS&hyphen.style error code will be put
into this parameter and all the other OUT parameters (and return
value of a function) will be undefined.
In this case the RPC system will
<hp2>not</hp2>
take the normal error action (calling user error handlers or aborting
the program with an error message).

The procedure (or function) name given must already have been declared.

The parameter name must be the identifier of one of the parameters
of that procedure. The parameter must be OUT or INOUT, and of type
RPC_LONG.
<h3> PRAGMA EXTERNAL_MARSHALLING

Syntax:
<xmp>
        PRAGMA EXTERNAL_MARSHALLING ( <type_id> );
</xmp>

The type_id must refer to a previously defined type.

This tells the compiler that external procedures
..bf MONO
PCK_<type_id>
..pf
and
..bf MONO
UPK_<type_id>
..pf
will be used to marshal and unmarshal (respectively) the given type.
Marshalling is the process of taking data from the user space
and putting it into a message in the correct format for
transmission.

<I1 IX=1>Marshalling, external
<I1 IX=1>External marshalling
<I1 IX=1>User-defined marshalling
<I1 IX=1>COMMON blocks, automatic transfer
<I1 IX=1>Types, user defined
<I1 IX=1>Pragma, EXTERNAL_MARSHALLING
This pragma will allow types whose data type is a function of circumstance
(unions, private conventions, etc) to be transferred as RPC parameters.
It also allows the RPC system to send any related data which may be
required, such as to send over parts of a FORTRAN common block.
Also, side effects may be put into user marshalling routines,
such as parameter value checking,
rebinding of the client depending on a particular parameter value, etc.

The type must already be declared, and it is this declaration which will
decide how much memory is allocated to receive a variable
of this type in the server.

The marshaling routines must be provided by the user, or may be distributed
with a library for certain special types. Their format is
as follows:

<xmp>
--        Marshalling for type <type_id>

PROCEDURE PCK_<type_id> (
             rpc_p_buf: IN     rpc_buffer_pointer;      -- by reference
             variable:  IN     <type_id>);              -- by reference

--        Unmarshalling for type <type_id>

PROCEDURE UPK_<type_id> (
                rpc_p_buf:   IN    rpc_buffer_pointer; -- by reference
                variable:    OUT   <type_id>);         -- by reference
</xmp>
The writer of these routines is recommended to build them in terms
of the basic routines such as PCK_INTEGER etc which are defined
in the include files RPCSTUB.H (Pascal), rpcheader.h (for C).
(Under VMS, these files are under the RPC_INC directory).
<H1>Running the RPC Compiler
 
<I1 IX=1>Compiler RPC
<I1 IX=1>RPC compiler
<I1 IX=1>RPCC command
<I1 IX=1>RPC command
The syntax to invoke the compiler is:
 
Under VAX/VMS, or MSDOS:
<XMP>
        RPCC <source_file_name> [/option] [/option] ...
  or    RPC <source_file_name> [/option] [/option] ...
</XMP>
The first form produces stubs in Pascal, FORTRAN, PILS or C, which
you then compile.
The second form, only available under VMS, is used for Pascal,
and also runs the stubs though the preprocessor and
(for VMS/Pascal or CERNCROSS pascal) compiles them.
<FIG ID=COMPI PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk4
<PICTURE NAME=COMPI$$S>
...timsk4
<FIGCAP><HP1>
The RPCC command generates the souces for the stubs. The RPC command under VMS
performs all the functions in the dotted circle, for Pascal only).
</HP1>
</FIG>
Under Bsd UNIX, Ultrix: 
<I1 IX=1>Unix, command format 
<xmp>
        rpcc <source_file_name> [-option] [-option] ...
</xmp> 
 
The source file is the RPCL description file described in the previous section.
This file name can have any extension except '.ext'.
The compiler options are listed below.
 
The RPCC lists, on the standard output device,
the generated version number of the stub, (see the /VERSION option), and
a list of errors, if any.
If no error has been found, it produces three output files called, by default:
<xmp>
        cli<source_file_name>           (The client stub module)
 
        ser<source_file_name>           (The server stub module)
 
        <source_file_name>.ext          (A Pascal or C declaration file)
</xmp>
The '.ext' file contains a Pascal or C declaration of
the procedures declared in
<I1 IX=1>EXTernal declaration file
RPCL. This is a declaration of external procedures
<fn>
See also the TYPES option, later in this chapter.
</fn>
that you can use to include
in your client program if you are programming in Pascal or C.

Note that under VAX/VMS you must run a command file
(@DISK$D1:[RPC]RPC on VXCERN, on other machines it is @[...]SETUP in the
directory in which the RPC software has been installed)
to gain access to RPC commands,
while under UNIX BSD the 'rpcc' should be present in any directory of your PATH
shell variable.
<H2>Target environment options
The stub code produced by the RPCC may be in FORTRAN, C,
or in Pascal with INCLUDE preprocessor statements.
If the RPC command is used, the pascal will be put through the
INCLUDE preprocessor automatically, and compiled to object format where
a compiler exists on the machine.
 <I1 IX=1>Target selection
<I1 IX=1>Stub, source files 
 
The code may be tailored for one of the following compilers:
<UL>
<LI>A C compiler.
<LI>A FORTRAN77 compiler.
<li>A PILS compiler or interpreter
<LI>Omegasoft Pascal (version 2) for the M6809.
<LI>VAX/VMS PASCAL,
<LI>CERN Cross Software Pascal 2.5 for the Motorola 68000 family,
<LI>UNIX Berkeley (or Ultrix) Pascal compiler
<LI>IBM PC Turbo Pascal
<LI>A standard Pascal compiler without modular compilation,
</UL>
<I1 IX=1>C language
<I1 IX=1>PILS
<I1 IX=1>Omegasoft pascal
<I1 IX=1>Pascal Omegasoft
<I1 IX=1>Pascal VAX
<I1 IX=1>Unix , compiling stubs for
<I1 IX=1>Turbo Pascal
<I1 IX=1>Pascal, on the IBM PC 
<I1 IX=1>IBM PC , compiling stubs for
In all but the last case, separately compilable modules are produced
which can be simply linked to your application.
 
In the last case, standard Pascal
<I1 IX=1>monolithic compilation
<I1 IX=1>Pascal standard
code is provided for those applications that require
monolithic compilation. In such a case one must include (by hand using
the editor, or using a preprocessor) the code generated by RPCC in the main
program before compilation.
 
The target environment is specified separately for client and server
using the following options:
<xmp> 
        c<environment> [ =<filename> ]
</xmp>  
to specify the client (caller) environment, and the option
<xmp>
        s<environment> [ =<filename> ]
</xmp> 
to specify the server (called) environment.  The =<filename> clauses
are optional, and allow the name of the output file to be specified
explicitly, overriding the default This clause is not available for the
RPC form, only for RPCC.
 
The <environment> can be one of the following:
<DL TSIZE=15>
<DT>genericC
<DD>
A standard C compiler. The files produced refer to an include file,
rpcheader.h, which is supplied with the release.
Under VMS, compile the stubs using the
<P>
$ CC/INCLUDE=RPC_INC/DEFINE=VAXVMS
option to have access to this file and select the correct compilation option.
<DT>FORTRAN
<DD>
A FORTRAN77 compiler.
If structures are specified in the RPC definition file,
the FORTRAN stubs will have structures in VAX/FORTRAN format.
<DT>PILS
<dd>A PILS (Portable Interactive Language System) compiler or interpreter.
<DT>cerncross
<DD>
Cern Cross Pascal M680x0 compiler;
<DT>M6809
<DD>
Omegasoft M6809 Pascal Compiler;
<I1 IX=1>M6809, selecting target 
<DT>vaxpascal
<DD>
VAX/VMS Pascal compiler.
Strings are of type VARYING OF CHAR.
<DT>vaxvms
<DD>
VAX/VMS Pascal compiler (strings FORTRAN compatible).
This options is included for back-compatibility but is not recommended.
<DT>unixbsd
<DD>
Berkley Unix (or Ultrix) Pascal Compiler;
<I1 IX=1>Pascal, Unix Berkley 
<DT>pcturbo
<DD>
The Turbo Pascal system on the IBM&hyphen.PC
<DT>monolith
<DD>
A standard pascal compiler without modular compilation;
</DL>
 
You should put at most one option for the client environment and
one for the server environment.
If you want to generate stub code for several environments,
you must run the compiler several times giving different options each time.
 
<HP1>Example:
 
The following command under UNIX
generates pascal code for UNIX for the client side (into clifiler.rpc) and
VAX/VMS for the server side (into the file mysstub.pas).
It is supposed that input definition file is in
'filer.rpc'.</HP1>
<xmp>
                rpcc filer.rpc -cunixbsd -svaxvms=mysstub.pas
</xmp>
<HP1>The following command under VAX/VMS
generates object code for VAX/VMS for the client side (CLIFILER.OBJ) and
M680X0 for the server side (SERFILER.CUF) .
The input definition file is in
FILER.RPC.</HP1>
<xmp>
        $ RPC FILER.RPC  /CVAXVMS /SCERNCROSS
</xmp>
<H2>Calling convention, BYVALUE
<i1 ix=1>BYVALUE compiler option
<I1 IX=1>Calling conventions
This section does not apply to PILS or FORTRAN stubs.
In Pascal or C,
stubs may be generated to respect either the FORTRAN,
Pascal or C conventions.
Intermediate possibilities exist, or example for C programs which
are written to be FORTRAN callable.

The conventions used by the client stub should match
those of the client program,
and the conventions of the server stub must match those of the server routines.
By running the compiler twice, it is possible to generate stubs of
both types for the same package.
These will be able to communicate with each other, so, for instance,
a FORTRAN main program will be able to call subroutines written in C,
and vice&hyphen.versa.

The two chief areas of difference are in the way strings are passed,
and the way simple types are passed as IN parameters.

<ul>
<li>
For simple IN parameters, the deault is passing by address, for FORTRAN
compatability (whatever language the stubs are generated in).
The
..bf MONO
..bd BYVALUE
..pf
option allows them so be passed by immediate value.
<FN>
Not possible with SVAXVMS, CVAXVMS, SVAXPASCAL, CVAXPASCAL options.
This is because under VAX/VMS, the Pascal is FORTRAN compatible,
so a parameter is <hp1>always</hp1> passed by address, even if it is not "VAR".
Therefore, VAX/Pascal stubs will not be compatible with C code.
If C compatability is required, the stub should be generated using
the genericC opions.
</FN>
<li>
The string passing is determined solely by the language option chosen.
In C, the strings are null terminated, in Pascal they are passed
by native Pascal string type (where available),
by descriptor (VAXVMS option),
or otherwise as two arguments, an array and a length.
See the appendix on supported data types for details.
</ul>
 
<HP1>The following command under VAX/VMS generates C code for both stubs, which
will be compatible with C client and server modules.
</HP1> 
<xmp> 
        $ RPCC FILER.RPC  /CGENERICC=CLIFILER.C /SGENERICC=SFILER.C /BYVALUE 
</xmp>

To summarise the possible combinations,
<dl TSIZE=20>
<DT>Pascal
<DD>Default, FORTRAN compatible.
If the user program is in Pascal, all parameters must be passed "VAR".
<DT>Pascal, BYVALUE
<DD>Pascal compatible, with IN parameters not passed with pascal "VAR".
<DT>GenericC
<DD>This combination may be used to make stubs in C to be called
from FORTRAN, where a pascal compiler is not avilable (OS9),
but beware of the differences in string passing convention.
All parameters must be passed by address (with an "&" in C).
<DT>GenericC, BYVALUE
<DD>C compatible.
</dl><H2>Producing Type Declarations - TYPES
The option
..bf MONO
..bd TYPES
..pf
causes the user's type definitions to be included in the declaration
(.ext) file.
This is a convenient feature if the .ext file if to be used directly
as a basis for the client or server program.
If the user's types definitions already exist, or must be defined
in terms of other types not in the RPC definition file,
then this option will not be useful.
<H2>Auto&hyphen.Initialisation: NOAUTOINIT
<I1 IX=1>Initialisation automatic
This section applies in conjunction with
VAXVMS, VAXPASCAL, PILS, PCTUBO or MACTURBO client and server options only.
In these cases, normally, the client and
server stubs are initialised
<fn> Under VMS, the [INITIALIZE] attribute of a procedure is used
to cause initialisation code to be put into the LIB$INITIALIZE PSECT
so that the procedure will be called on image load.
Under PILS or TurboPascal, each module contains a main section which is
called initially before the main program.
</fn>
when a program is loaded,
and make contact with
each other automatically. Use of the
..bf MONO
NOAUTOINIT
..pf
<I1 IX=1>AUTOINIT
<I1 IX=1>NOAUTOINIT
option suppresses this
facility. In this case, the user is responsible for calling RPC_Open (on the
<I1 IX=1>RPC_Open called automatically
<I1 IX=1>RPC_Attach called automatically
client) and RPC_Attach (on the server) for each stub. See the section on
initialisation procedures.

The initialisation makes the RPC system totally invisible to the user code,
but you may wish to suppress it for portability, or for introducing your
own special initialisation code.
 
<HP1>Example:</HP1>
<XMP> 
                $ RPC FILER.RPC  /SVAXVMS /CVAXVMS /NOAUTOINIT
</XMP>
<H2>CONCURRENT Execution option
<I1 IX=1>CONCURRENT execution
 
The
..bf MONO
concurrent
..pf
option modifies the code produced by the compiler,
by making the
..bf mono
PRAGMA CONCURRENT
..pf
implicitly apply to all procedures which return no results, that is,
procedures (not functions) which have no OUT or INOUT
parameters.
For these procedures, the server stub is made to
reply immediately to the caller,
<HP1>before executing the called routine.</HP1>
See under "Pragmas".
 
<HP1>Example:</HP1>
<XMP> 
                $ RPCC FILER.RPC  /SFORTRAN=S.FOR /CFORTRAN=C.FOR /CONCURRENT
</xmp>
Users of this facility should bear in mind, however, that the semantics of a
<HP1>concurrent</HP1>
remote call differ from those of a local call.
 
<h2>LARGE parameter option 
Under VMS, and using the RPC (not RPCC) command only, stubs may be generated
with the parameter size extended to 8kB from 1.5kB.
When this is done,
<ol>
<li>When using the RPC
command and Pascal stubs, the
..bf MONO
LARGE
..pf
option must be specified.
(Not required for C or FORTRAN stubs).
<li>The resulting stubs must be linked with the RPC_LARGE library rather than
the RPC_LIB library. (These are logical names).
<li>Communication is not available over raw ethernet.
</ol>
<H2>Error messages and error recovery
 
<I1 IX=1>Error messages from compiler
When the RPCC finds an error it prints on the standard output the line number
in which the error occurred, then the offending input line with an arrow
below the first character of the word that was wrong and finally, on the
third line, the error meassage. Error messages are in English and
should be quite self&hyphen.explanatory so no other information is provided. In
general the RPCC tries to recover from the error without aborting. If the
error is not fatal, a semicolon forgotten for example, the compiler inserts
or deletes a word (token) and continues to parse the input. If the error
is not simple, a very malformed declaration for example, the compiler
skips the input until a meaningful structure is found. Sometimes this attempt
at
recovery can produce misleading error messages, so be careful, and try to
correct the very first error before going on.
 
If any errors at all are encountered, no code generation is performed.
 
<H1>Building An Example RPC Application
 
<I1 IX=1>Building a system
<I1 IX=1>Linking a system together
<I1 IX=1>Binding, compilation time
The following example shows the commands needed to build a RPC application,
a rather simple file server called "Filer".
VAX/VMS is used here for illustration:
There are further examples under the later sections which deal
with each environment.

Suppose we have a program called MYPROG.FOR written in FORTRAN and running on a
VAX under VMS. This needs to call procedures in a module called FILER written
in Pascal and running on an M68020 under MoniCa.
The interface between the two is described in
RPCL in the file FILER.RPC. Because this is an example we have deliberatly
chosen Fortran for the main program and Pascal for the server to show a mixed
language application: however, the modules could as well both have been
written in the same language, and run on the same type of machine.
 
<H2>Under VMS
 
First of all we compile the main program using the native FORTRAN
compiler, generating the file MYPROG.OBJ,
and we compile the server module using the cross Pascal compiler,
generating the file FILER.CUF.
 
We then generate the stub code for each system using the RPC Compiler:
 
<XMP>
        $ RPC  FILER.RPC /SCERNCROSS
        $ RPCC FILER.RPC /CFORTRAN=CLIFILER.FOR
</XMP>
 
These commands will produce (if no errors are found) the files:

<XMP>
           SERFILER.CUF    The server stub, in M680x0 object format
           FILER.EXT       The Pascal declaration file
           CLIFILER.FOR    The client stub in FORTRAN
</XMP>
The client stub is compiled:
<xmp>
        $ FORTRAN CLIFILER
</xmp>
Next, we link together the VAX image:
<XMP>
        $ LINK  MYPROG,  CLIFILER,  rpc_lib/OPT
</XMP>
We now have an executable file, MYPROG.EXE, which, when run,
will call the remote version of FILER.
 
 
To link the M68k object modules together, we have to first concatenate
<I1 IX=1>UNIPUSH
<I1 IX=1>CUFLINK
them into one file, then use CUFLINK, then format the result with UNIPUSH:
<XMP>
 
        $ COPY  FILER.CUF,  SERFILER.CUF   FILER.CCU
<P>
        $ CUFLINK  FILER.CCU,  rpc_lib68,  FILER, -
<P>
                 MYLOP,  MYOPT,  MYLMP
<P>
        $ UNIPUSH  FILER
</XMP>
..cm @@ Diagram: data flow
The result is FILER.ABS, a Motorola
"S&hyphen.format" loadable file which,
<I1 IX=1>ABSolute format
<I1 IX=1>S record format
when run, will provide the service required by MYPROG.EXE.
(The use of cross software under VAX/VMS, and the significance of the LOP, OPT
and LMP files, is described in
<BIBREF REFID=XSOFTN3>
and its references).
 
The name
..bf MONO
rpc_lib68
..pf
is a logical name.
<I1 IX=1>rpc_lib68
The actual file used to satisfy entry points into the RPC system
will depend on the target M680x0 system being used, typically the
MONICA.ROM file.
 
<H2>Stubs in C

This example is equivalent to the example above, but we assume that the
client and/or server routines will be written in C.
(The client stub should be produced in C if the client module is in C,
and the server module should be produced in C if the server module is
written in C. This does not stop a C client talking to a FORTRAN
server, for instance, as the communication format used between the stubs
is the same in all cases)

The RPCC command is used.
To make the VMS client, the commands would be

<xmp>
..fo off
 $ RPCC FILER.RPC /CGENERICC=CLIFILER.C/BYVALUE ! Make CLIFILER.C
 $ CC/INC=RPC_INC/DEFINE=VAXVMS CLIFILER        ! Make CLIFILER.OBJ
 $ LINK MYPROG, CLIFILER, rpc_lib/OPT           ! MAKE MYPROG.EXE
</xmp>

and to make ther server,
<xmp>
..fo off
 $ RPCC FILER.RPC /SGENERICC=SERFILER.C/BYVALUE ! Make SERFILER.C
 $ CC/INC=RPC_INC/DEFINE=VAXVMS SERFILER        ! Make SERFILER.OBJ
 $ LINK FILER, SERFILER, rpc_lib/OPT            ! Make FILER.EXE
</xmp>
..fo on
In this case, FILER must contain, apart from the server subroutines,
a small main program to attach the server stub to the run-time system,
and call the server loop. (See Chapter 6)

<H2>Explicit Post Processing of Pascal stubs
 
<I1 IX=1>Explicit post processing
<I1 IX=1>Post processing, explicit
(This section is only relevant to users making stubs in Pascal,
and who wish to modify them by hand).
 
The RPC command used above produces object modules via intermediate files
generated in Pascal.
In some cases, howver, one may wish to invoke the RPC compiler only to
produce source versions of the stub code, which can then
be modified before compilation.
In this case, the RPCC (two C's) command
is used, and the compiler produces the source files: in our example above,
these would be, by default,
<xmp>
                CLIFILER.RPC    The client stub, in M68020 Pascal
                SERFILER.RPC    The server stub, in VAX/VMS Pascal
                FILER.EXT       The Pascal declaration file (as before).
</xmp>
The .RPC files must be put through the INCLUDE preprocessor to make pascal
files, and these must in turn be compiled using a suitable pascal compiler.
In the example above, the operations required are as follows:
 
We compile the client stub using the INCLUDE preprocessor, and the native
VAX Pascal compiler.
<xmp>
        $ INCLUDE  CLIFILER.RPC  CLIFILER.PAS  +VAXVMS
        $ PASCAL  CLIFILER
</xmp>
This generates the object file
..bf MONO
CLIFILER.OBJ.
..pf
<FN>
(Theer is also an optional +ALIGN keyword, (See index "ALIGN")
as discussed in a later chapter,
but its inclusion is not recommended).
</FN>
on it.
(Note the upper case for all keywords).
 
To make the M68k code, we compile the server stub, SERFILER.RPC,
using the Cross PASCAL compiler and
the INCLUDE preprocessor:
<xmp>
        $ INCLUDE SERFILER.RPC  SERFILER.PAS  CERNCROSS
        $ NEWP68K SERFILER
</xmp>
generating the object file SERFILER.CUF for the M68k.
 
<I1 IX=1>INCLUDE program
The INCLUDE program is part of the CERN cross software suite for the
M680x0 processors, and is described in outline in
<BIBREF REFID=XSOFTN3>.
 
<H2>Under Unix
 
<I1 IX=1>Unix, development under 
If the development of the M68k part were to be done under Berkley Unix
or Ultrix,
the commands would have been similar to those used above, with
explicit post processing of the stubs:
 
<xmp>
        rpcc filer.rpc -ccerncross -svaxvms
        include CERNCROSS < serfiler.rpc > serfiler.p
        pasc68k serfiler
        cat filer.cuf clifiler.cuf > myprog.ccu
        cuflink myprog <RPC_library_path_name>
        unipush myprog
</xmp>
 
The file CERNCROSS.DFS is not needed in this case,
as the keywords are command line parameters.
This will similarly produce the file 'myprog.abs'.
 
Note that, whereas on the client side the user program is a
main program,
on the server side the user code is just a called module.
A main program module is, however, necessary on the server side,
to call the RPC system and ask it to service future requests.
In the example above it is assumed that this is part of FILER.CUF.
This module is normally quite simple, and is discussed in the next
chapter.
<H1>Initialisation procedures
On VAX/VMS systems using Pascal, on PILS systems, and on Turbopascal systems,
the stub modules are automatically called before the main program is run,
and so initialise themselves.
The application program need not, therefore, be aware that the
modules with which it has been linked are remote.
A server loop module which may serve as a main program is available
in the run&hyphen.time library.
See the example "VAX-VAX over Decnet"
later on.
Under Turbo Pascal, the user must include a "USES" clause in his
program referencing each stub his program uses.

On other target systems, the initialisation procedures must be called
explicitly from the application program, as follows.
<H2>General Initialisation
<I1 IX=1>Initialisation, manual
Not required for VAX/VMS, TurboPascal, PILS or MoniCa based systems.

If the RPC system is not built into the environment you are using
(such as MoniCa or a version RMS68K) it must be initialised
by calling RPC_Init (no parameters) before any other RPC routines.
<xmp>
..tb 9 17 25 33 41 49 57 65 73
        CALL RPC_INIT           ! in FORTRAN
        rpc_init();             /* in C */
        rpc_init;               { in pascal }
        rpc_init;               -- in ADA
</xmp>
<H2>Client Initialisation
 
In the client, all that is required is that for each server xxx to be used,
the procedure OPEN_xxx is called once, before any other calls are made.

..us Example (C)
<box><xmp>
        main()
        {
                open_filer;                /* Initialise FILER stub */
                ...                        /* rest of program */
        }
</xmp></box>
..us Example (FORTRAN)
<box><xmp>
              PROGRAM FRED
              CALL OPEN_FILER

        C     ... the rest of the client program ...
              END
</xmp></box>
If you want to explicitly give the rpc address of the server from your program,
for instance if you want to handle many servers of the same type,
see Section 8.3.2. and the library call RPC_Open.
<H2>Server Programs
 
For the server, a simple main program is required which will first attach the
stubs which are available to the run&hyphen.time support, and then call the
run&hyphen.time support routines to service any incoming requests.
<FIG ID=INITI PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go timsk5
<PICTURE NAME=INITI$$S>
...timsk5
<FIGCAP><HP1>The client stub (left) and the server stub (right)
both announce themselves to the Run Time Support library.
On the server side, a small main program calls a server loop in the
RTS.
</HP1>
</FIG>
An example server in C, and the equivalent in Pascal follows:
<box>
<xmp>
#include <rpcheader>
main() {
        int        status;

        rpc_init();                    /* (Not for VMS version or MoniCa) */

        attach_filer();                /* Declare stub */

        rpc_loop_server(&status,        /* Loop until fatal error */
                        "RPC_CLIENT_NAME                         ");
                        /* Note this name must be 40 characters long */

        rpc_report_error(status);        /* Report any error */
} /* end of main */
</xmp>
</box>
The equivalent pascal follows.
The *INCLUDE statements are to be processed by the INCLUDE preprocessor.
<box>
<XMP>
PROGRAM SERVERLOOP;                     { Example server program }
CONST
*INCLUDE RPC_CONST
TYPE
*INCLUDE RPC_TYPES                      { Define RPC types }
VAR     status:         rpc_status;
        client_name:    rpc_name;       { Clients for main loop }
 
*INCLUDE RPC_PROC                       { Declare library procedures }
 
PROCEDURE attach_filer; extern;         { Contained in SERFILER stub }
 
BEGIN
   attach_filer;                { Make stub known to run&hyphen.time system }
                                { Not necessary on VAX/VMS }
 
   client_name:= 'RPC_CLIENT_NAME                         ';  
   RPC_Loop_Server(status, client_name);                      
   rpc_report_error(status); 
END.
</XMP>
The following example is in VAX/FORTRAN. Note the %REF().
For deatails of passing parameters of different types to RPC_XXX routines,
see the introduction to appendix B.
<XMP>
C       VAX/FORTRAN example of a simple RPC server program

        PROGRAM SERVERLOOP

        INTEGER*4 STATUS
        CHARACTER*40 CLIENT

C       Attach the server stub to the RPC system:

        CALL ATTACH_FILER

C       Run a server loop indefinitely unless error occurs:

        CLIENT = 'RPC_CLIENT_NAME'
        CALL RPC_LOOP_SERVER(STATUS,%REF(CLIENT))
        CALL RPC_REPORT_ERROR(STATUS)
        END
</XMP>
</box>
If more complex configurations are required, they can be built,
as decribed later ("varieties of server", in Chapter 8).
<H1>Running an RPC system
You should read the general section of RPC addressing,
then the specific sections both for your communications medium,
and for each machine you are running on.
<H2>Defining server addresses
<I1 IX=1>Address server
When an RPC system is made, none of the modules have, built into them,
a knowledge of the addresses of other modules required.
Therefore, before running a distributed system,
this information must be set up, so that the run&hyphen.time support
system can make the necessary connections.
 
This is done by associating an address string with the name of each
remote package.
This address must be known on any machine that will need to access
that package.
 
On VAX/VMS, the logical name system is used.
Under OS9,
MSDOS or Unix, the "shell" evironment is used.
Under MoniCa, the
<I1 IX=1>DEFINE command
<I1 IX=1>Environment variables (OS9, Unix, MSDOS)
<I1 IX=1>Configuration file (Mac, M6809)
symbol table is
used.
On the Macintosh and on the M6809 under FLEX, no such device exists,
so the definitions are
stored in a file.
See the section relating to your particular system for details.

For VMS or MoniCa, the command to define the
server address to be used by the client is the same:
<xmp>
         DEFINE  <remote package name>   <server address>
</xmp>
Under Unix or OS9 it is
<xmp>
         setenv  <remote package name>   <server address>
</xmp>
Under MSDOS it is
<xmp>
         SET <remote package name>=<server address>
</xmp>
without any spaces surrounding the '=' sign.

<HP1>Example</HP1>:
<xmp> 
        VMS:     DEFINE   filer  "FILER@AA_00_04_00_2F_58.ETHERNET"
        MoniCa:  DEFINE   filer   FILER@AA_00_04_00_2F_58.ETHERNET
        OS9:     SETENV   filer   FILER@AA_00_04_00_2F_58.ETHERNET
        MSDOS:   SET filer=FILER@AA_00_04_00_2F_58.ETHERNET
        unix:    setenv FILER FILER@AA_00_04_00_2F_58.ETHERNET
</xmp>
(The "quotation marks" are necessary under VMS only, if the string contains
an @ sign.)

There is currently
a limit of 40 characters on the length of a logical or physical
name.
 
The  format of the <server address> is defined below.
A similar scheme is used to define the client(s) to which a server
process requests.  This is done (for the standard server) by defining
the name RPC_CLIENT_NAME to give the <medium address> of the client.
 
..cc 3
<HP1>Example</HP1>:
 
        DEFINE RPC_CLIENT_NAME        *.ETHERNET
<H2>RPC address format
The rpc address of a
<HP1>server</HP1>
has two parts. The first is a package name or number, used
to distinguish different packages attached to the same <medium address>.
<I1 IX=1>Address, medium
<xmp>
..tb 9 17 25 33 41 49 57 65 73
 <server address>       ::=       <package name> @ <medium address>
                        or        <package number> @ <medium address>
                        or        <medium address>
                        or        <package name>
</xmp>
<ol>
<li>In the first case, the <package name> must be the name used in the package
declaration. At initialisation time, the client machine will interrogate
the server machine, to acquire a corresponding number for use during actual
remote calls.
<li>In the second case, if the package number is known by the client in advance,
specifying it explicitly will save a little time and allow back-compatibility
with previous systems.
Package numbers are allocated by the server run&hyphen.time system,
as the packages are attached to the server, starting
from zero.
<li>In the third case, neither a name or number is given.  The RPC system
will assume that the logical name given was the package name, and use that.
For example, to define
<xmp>
        $ DEFINE FILER MYTASK.DECNET
</xmp>
is equivalent to defining
<xmp>
        $ DEFINE FILER "FILER@MYTASK.DECNET"
</xmp>
<li>In the last case, no <medium address> is specified, and so ".LOCAL"
is assumed (see below). Therefore, if no address is given,
the RPC system system will assume that the server stub (as well as the
client stub) is linked locally to the same program.
</ol>
A
<HP1>client</HP1>
is identified to a server by the <medium address> alone.
 
The second part, the medium address, is in turn composed of two
pieces.  The first is a network or similar address, in a format
depending on the medium. The second is the name of the medium.
 
        <medium address>        ::=     <net address> . <medium>
 
The format of <net address> depends on <medium>, and is given below,
<I1 IX=1>Address network
for each communication medium.
 
<H2>LOCAL routing
<I1 IX=1>Address LOCAL
<I1 IX=1>LOCAL address
It is possible, if your are using the advanced client features,
(described in next chapter) that one wants
a package to be either remote or local, as selected at runtime.
In this case, the <medium address> for a local call is simply
LOCAL .
 
<HP1>Example</HP1>:
<xmp>
                DEFINE PHI1 PHI1@LOCAL
</xmp>
<h2>Using the WAY Name Server
RPC implementations for Unix, OS9, MSDOS/TurboC, and VMS over TCP
allow the WAY ("Where Are You") name server to be used.
This allows clients to find servers automatically at run time.
To use an existing WAY server, all you have to do is know it's
address. To run your own WAY server, see the WAY manual
<BIBREF REFID=WAY>

There are two environment variables (logical names) which are looked
up to control the use of WAY. To allow clients to interrogate
WAY, just define
<xmp>
	way_request
</xmp>
as the RPC address of the name server.
To cause servers to automatically register themselves with
WAY, just define
<xmp>
	way_register
</xmp>
as the RPC address of the name server.
In the following example script file, both request and registration are
enabled, using a name server we imagine is running
on port 5678 on node priam.  The server is started to use any free TCP port.
It registers itself automatically when it runs. The serevr is forked off
as a seperate process, then the client is run. The client picks up the
actual port number from the name server when it runs.
<xmp>
	setenv way_request  'way@priam:5678.tcp'
	setenv way_register 'way@priam:5678.tcp'
	setenv RPC_CLIENT_NAME '*.tcp'
	my_server &
	my_client
</xmp>
WAY provides many other facilities,
for example the use of an initial WAY database. these are descibed in
<BIBREF REFID=WAY>.
..pa
<h2>Using the Internet: TCP and UDP
Remote procedure calls can run over TCP/IP and UDP/IP services.
This section gives common information about using TCP or UDP,
whatetever machine you are on.
You should also look up specific information about the machine you are
using, later in this chapter.
<h3>Introduction: Internet addressing
To use TCP or UDP, your RPC addresses must end in the
medium names .TCP or .UDP respectively.
TCP is a connection&hyphen.oriented protocol, whereas UDP is
a datagram protocol. The RPC system uses one or the other as
instructed.
UDP may be faster but is not available on some machines.
TCP is stream-oriented and so, when data flow is mainly in one
direction, PRAGMA CAST may used to stream messages for extra speed.
<dl tsize=10>
<dt>Node
<dd>A node on the internet is identified either by a name (e.g
..bf MONO
VXCRNA
..pf
), or if the
name is not known locally, by a set of four numbers separated by
dots (e.g.
..bf MONO
141.4.12.10
..pf
)
Node names are normally in lower case on systems where this is significant.
(See file /etc/hosts on unix).
<dt>Port
<dd>
A port is an endpoint of communication within a node.
Within a node there are many ports, identified by decimal numbers
0 to 32767.
Ports 0 to 1023 are reserved for so called "well known port" numbers.
(See file /etc/services on unix).
Priviledge (SYSPRV under VMS) is required to use a number below 1024.

Port numbers of 1024 and above are free for user applications,
although it is not possible to use one already in use.

To communicate, one side (normally the server)
must either establish a numbered port and the other side
(normally a client) must make a connection to it.

If a port number is unspecified for a server, the RPC system will
dynamically chose the first free port in the range 5000 to 5999 (decimal).
<dt>Connection
<dd>There may be many connections to a port.
A connection is normally established at initialisation time,
but is the RPC address is preceded by a "#" hash character,
the RPC system will open and close a connection for each call.
This will save connections when there are very many machines but take
more time.
</dl>
<h3>Defining the clientele for a server
A server may service multiple clients. The address of the
client it is to service starts with an asterisk "*" to indicate this.
Then follow the node number or name, a colon, and the number
of the port at which the server is to listen.
The server creates a local port of that number, and waits for connections from
the given node.
<xmp>
        *vxcrna:777.tcp         Service multiple clients on node vxcrna.
                                Establish a local port number 777.
                                Use TCP
</xmp>
If the node is omitted, the server will service connections from any node:
<xmp>
        *:777.tcp                Service multiple clients on any nodes.
                                Establish a local port number 777.
                                Use TCP
</xmp>
The colon ":" must always precede the port number.

If the colon and port number are omitted,
the server will dynamically find a free port number:
<xmp>
        *.tcp                   Service multiple clients on any nodes.
                                Find a free port starting at 5000.
                                Use TCP
</xmp>
In this case, a name server is necessary for the client to find the
correct port for the given service using a name server, for example.
<h3>Staring servers automatically : The Internet Daemon
It is possible to arrange for servers to be started automatically (under
unix or VMS, at least). This is done by the internet daemon process
which normally runs on a machine running TCP/IP.

In order to do this, you must arrange that your server program is in the
database used by the inet deamon, "inetd". This will require privilege. You
should read the documentation for your system
<fn>
On unix, see /etc/inetd.conf and <hp2>man inetd</hp2>.
On VMS, see TWG$TCP:[NETDIST.ETC]SERVERS.DAT and read
<BIBREF REFID=WINTCPADM>, around p154.
</fn>
for details of how to do this, and
how to start and stop the daemon if necessary. 

The program which is started by the daemon should be written as normal
RPC server program, with the clientelle <hp1>explicitly</hp1>
put in as
<xmp>
        .tcp                    Use connection handed down from
                                the internet daemon
</xmp>
In this case, when a connection is made to the server port given in the
deamon database, the daemon starts your server and passes it the connection.
The server program in this case handles only one client per task.
<h3>Defining a server for a client
On the client side, to define the address of a remote package,
one must quote the server port number and the node name:
<xmp>
        vxcrna:777.TCP            Node VXCRNA, port 777.

        121.12.2.1:777.TCP        Node 121.12.2.1, port 777

        #vxcrna:777.TCP           Node VXCRNA, port 777
                                  (reconnect for each call)
</xmp>
The port number quoted by the client must, of course, be the same
as the one established by the server.
..pa
<H2>Ethernet addressing
When using Ethernet in it's raw form, that is, without a standard protocol
running over it, the addressing facilities are cruder that those provided by
higher level protocols. This section describes what one can do. 
<h3>Introduction: Ethernet Header fields 
An ethernet packet has a header which contains three fields
<ol>
<li>
A six byte destination address
<li>
A six byte source address
<li>
A two byte "protocol type" field
</ol>

The source and destination addresses define the physical ethernet
interface which recieve or sent the packet, respectively.
These addresses are not, in general, modifiable by the user.

Therefore, in order to distinguish packets intended for different
logical destinations within the same machine, the protocol type
field is all that remains.
Normally, this field is used to select a higher level protocol,
such as UDP, TCP, or TP4, which then interprets part of the rest
of the packet as further subaddressing information in some format or other.
The user of raw ethernet packets, however, must use different protocol
types to distinuguish packets which would otherwise have identical headers.

Most drivers which allow access to raw ethernet packets allow one to
specify the partner address and/or the protocol type one wishes to use.
<h3> Address format
In the RPC address format, the peer address and protocol type
are specified in hexadecimal, with
a medium name of "ETHERNET".
<xmp>
..fo off
..tb 9 17 25 33 41 49 57 65 73
<rpc_address>	::=	<peer_address>  [ <protocol_type> ] .ETHERNET

<peer_address>	::=	*
		|	<byte><byte><byte><byte><byte><byte>

<protocol_type> ::=	<byte><byte>

<byte>		::=     [ _ ]   <hex_digit> <hex_digit>

</xmp>
<box>
..us Example
..bf MONO
		AA_00_04_00_2F_58_5050.ETHERNET
..pf

..us on
This refers to ethernet node AA_00_04_00_2F_58 (which might be a
particular VAX, for example) and protocol type 5050.
..us off
</box>

The default protocol type used by the RPC system is is 5050 hex.
This is assumed if none is given.

<box>
..us Example
..bf MONO
	AA_00_04_00_2F_58.ETHERNET
..pf
</box>
<h3> Wildcard address

In all cases, one must specify a protocol type (or the default is
assumed).
Normally, one also specifies the peer (partner) node address.
An exception to this is when a server listens to any other node,
in which case the peer address is replaced with a "*"
("$" is used under OS9, to prevent conflict with special meaning of "*")
<box>
..us Example
..bf MONO
	*.ETHERNET
..pf

This refers to any ethernet node, protocol type 5050.
It is known as a wildcard address.
</box>
<box>
..us Example
..bf MONO
	*_5055.ETHERNET
..pf

This refers to any ethernet node, protocol type 5055.
</box>

<H3>Rules
The following rules are necessary to prevent conflict:
<ul>
<li>
At CERN, RPC users should not use protocol types
outside the range 5000 to 51FF
hexadecimal (or a range allocated to their group),
as other values may conflict with other traffic on the
Ethernet and cause widespread chaos.
Type 5052 should also be avoided, as that is used for Valet&hyphen.Plus bootstrap
broadcast messages.
<li>
Two processes in one node which talk to the same partner node
must use different protocol types.
<li>
Under OS9 (with the driver written by Tim Charity),
no two tasks may use the same protocol type, even if they
are talking to different nodes.
<li>
No user should use a wildcard ethernet address on a multiuser machine
without ensuring that noone else on that node is using the
protocol type at all.
</ul>

It is clear that in a complex system, some thought is necessary for
the allocation of protocol types.
Two simple ways of allocating types are as follows.
<ol>
<li> For one&hyphen.to&hyphen.one communication between tasks,
specify both the protocol
type and the ethernet address of the partner.
The protocol type need only be unique within the process
(or node, for OS9).

<hp1> Example </hp1>
<xmp>
..fo off
Server refers to client as:	AA0004002F58_5050.ETHERNET
Client refers to server as:	AA0004004558_5050.ETHERNET
</xmp>
<li>For a server handling many clients, specify only the protocol type,
and leave the address wildcard.

<hp1> Example </hp1>
<xmp>
Server refers to client as:	*_5050.ETHERNET
Client refers to server as:	AA0004004558_5050.ETHERNET
</xmp>
..fo on
In this case, check that the server is the only process using that
protocol type on the node in question.
</ol>

The RPC system runs its own protocol over ethernet in order to ensure
reliable transmission.
<fn>
Note: When ethernet is used, the package number should not be given
explicitly in the RPC address: rather, the name should be given.
This forces the RPC system to make an initial call to discover
the package number. If it is not done, the first call (only) may be executed
twice.
</fn>
<h2>RS232 (V24) Communication
RS232 serial lines may be used for point to point communication between
two machines. In this case, the RPC system runs a simple protocol
over the line. There are various options available
to optimise the protocol given the capabilities of the systems in use.
The address format is
<xmp>
		< device > : <options>  .V24
</xmp>
The < device > is, under VAX/VMS a logical device name, but otherwise of the
form
..bf MONO
TTn
..pf
where n is the channel number:
<xmp>
                     IBM-PC       Macintosh    MoniCa
                     __________   __________   ___________
             TT1     COM1:        sPortA       Terminal
             TT2     COM2:        sPortB       Hostline
</xmp>
The options are optional single letters as follows.
They are not all supported on all systems.
<DL>
<DT>B
<DD>
Binary coding method: use all 8 bits of the communication path. This is
the default. This is faster than the alternative "L" option, but
is not possible with some systems because of operating system restrictions.
If the serial line runs over multiplexers, then they might also
restrict the use of the line so that 8 bit communication cannot be used.
In this case the alternative option (L) must be used.
<DT>L
<DD>
Printable ASCII coding method: use only the printable ASCII characters (seven
bits). This is slower, but does not require the operating system to pass
control characters undamaged.
<DT>R
<DD>A strict handshake is used for flow control,
for the benefit of those
systems with inadequate input buffering.
If both connected systems have sufficient input buffering,
the F option may be used to make the protocol run faster.
The default varies from system to system.
<DT>F
<DD>Disables the handshake protocol. Alternative to R.
<DT>C n
<DD>Selects (for PCs, Monica and Macintosh) the communications channel.
"n" is either 1 or 2.
<DT>S n
<DD>Selects, where this is possible, the baud rate. "n" must be the
baud rate required in decimal, e.g. S300 or S9600
</DL>
These options are specified in the RPC address string, just before
the ".V24" medium specifier. See details in the section about your
particular system below.
<h2>CERN Host Interface addressing
The CERN Host Interface is a system of fast 32 bit wide parallel
point&hyphen.to&hyphen.point links
between BI based VAXes, FASTBUS and VME systems.
On the VAX side, the module needed is a Digital Equipment DRB32 
interface. This is 32 bit parallel interface for the VAX BI.
It can be connected to another DRB32, or to the "HyperVIOR"
VME module, or to the "CHIFC"  FASTBUS module.

When using the CHI, the same addressing syntax is used on the VAXes as on
M680x0 systems.
The medium name is "DRB".
The communication facility is a standard transport service,
so it works by one side declaring itself to be a named access point (TSAP),
and then the other side making a connection by quoting that name.

Typically (but not necessarily) it will be the RPC server which declares
an access point name,
and the client which connects to it.
In this way, more than one client task (on
the VAX) can access the same server. The access point name is an alphanumeric
case insensitive string of a maximum of 32 characters. The syntax is similar to
that used with DECNET or ISO transport protocol:-

The format for declaring a server at access point "FRED" would be
<xmp>
			*FRED.DRB
</XMP>
The asterisk "*" indicates that an access point should be established with
the name "FRED", and any connections to that TSAP accepted.
The TSAP name is mandatory, and has a maxuimum length of 32 characters.

To refer to a package MYPACK2 on which is provided by that server, the
client side would specify
<xmp>
			MYPACK2@FRED.DRB
</xmp>
Notice there is no asterisk: the network address FRED.DRB means that this side
should actively request a connection to an existing TSAP called FRED on the
other side. In this case, therefore, the server must be started before the
client.

The CHI FASTBUS module has an RPC server permanently listening at access point
"BOOT", so any server package which has been attached (see the list
produced by the "PACKAGES" command) can be accessed from the VAX as
<xmp>
		<packagename> @BOOT.DRB
</xmp>
The physical DRB device used by the RPC system is defined by the logical name
DRB_Device. This may be set up for you by the system manager,
or by a setup command file which you run from your login.com file
to specify which CHI you are using. Alternatively, on the VAX, you can override
the device name by specifying it before the TSAP name:
<xmp>
	$ DEFINE RPC_CLIENT_NAME *UQA0:FRED.DRB
</xmp>
<h3>16 bit interfaces: DRQ and DRE&hyphen-11

When using a microvax or VAX without a BI (Backplane Interconnect),
the same software exists for 16 bit interfaces.
The DRE&hyphen-11 is used on UNIBUS, and the DRQ&hyphen.11 on QBUS.
In this case, <hp2>the medium name is still .DRB as above</hp2>
but the logical name DRB_DEVICE is changed to indicate a UU: device
rather than a UQ: device.  For example,
<xmp>
	$ DEFINE DRB_DEVICE _UUA0:
	$ DEFINE RPC_CLIENT_NAME *FRED.DRB

or
	$ DEFINE RPC_CLIENT_NAME *_UUA0:FRED.DRB
</xmp>

<h3>Run&hyphen.Time Libraries

The VAX library to be used should be logical CHI$LIB, (file CHILIB.OLB),
and not the usual RPC$LIB.  The CHI$LIB library allows the use of
DRB and DRQ interfaces, and also RS232, decnet and ethernet.

On the CHIFC itself, the entire library is available in ROM, so one
need only link to the symbol module CHI$ROM (file CHIMON.ROM).
Ensure that you have the version corresponding to the ROMs in your CHI.

On the Valet-Plus, the library for communication over the HVIOR is
also in ROM, and the usual MONICA.ROM file should be used.

For more information onthe CHIFC device, see the CHI User Manual.
..pa
<H2>VAX/VMS Run Time Support
<H3>Raw Ethernet
<I1 IX=1>Ethernet, under VAX/VMS 
Ethernet 2.0 may be used on VAX/VMS,
for communication with other VAXes or microprocessor systems, Personal
Computers, etc.

The addressing possibilities for ethernet are described in the general
section above.

Under VMS, the RPC system will attempt to find an ethernet device using the
following list of device names in order, until success:
<ol>
<li> RPC_ETHERNET_DEVICE (A logical name you may define)
<LI> XEA0: (For UNIBUS interfaces, DEUNA, DELUA)
<LI> XQA0: (For Qbus interfaces, DEQNA)
<LI> ESA0: (for Vaxstations)
<LI> ETA0: (for BI machines with DEBNT devices)
</ol>

You can define RPC_ETHERNET_DEVICE at system or process level if you will
to force a particular device to be used, or you wish to use one not in the list.
<H3>RS232 Serial Line
An asynchronous
<I1 IX=1>V24, under VAX/VMS 
<I1 IX=1>RS232, (see V24) 
<I1 IX=1>Serial links , (see V24)
<I1 IX=1>Asynchronous transmission , (see V24)
V24
<FN>
For readers outside Europe, CCITT recomendation V24 is the European
equivalent of
the RS232&hyphen.C standard.
</FN>
(RS232&hyphen.C)
line may be used for connecting two devices.
The <medium name> is V24.
The <net address> is the device name, or a logical name
which translates to the device name.
  A set of options may be specified
following a colon terminating the device or logical name specification.
The options currently supported are
<DL>
<DT>B
<DD>
Binary coding method: use all 8 bits of the communication path. This is
the default.
<DT>L
<DD>
Printable ASCII coding method: use only the printable ASCII characters (seven
bits).
<DT>F
<DD>
Disables the RTS/CTS protocol. By default (or with R specified),
a strict handshake is used for flow control,
for the benefit of those
systems with inadequate input buffering.
If both connected systems have sufficient input buffering,
the F option may be used to make the protocol run faster.
</DL>

<HP1>Examples</HP1>:
<P>
                TT:L.V24              7 bit working on the user's terminal
<P>
              _TTA6:.V24              8 bit working on _TTA6: device

<I1 IX=1>XON/XOFF
<HP1>Note that data overrun errors can occur when using 8 bit operation,
as XON/XOFF control is not used. This can be avoided by increasing the
size of the typeahead buffer under VMS, or, better, by using the
characteristic TT2$M_ALTYPEAHD on the line involved, which allows
the use of a larger typeahead buffer defined at system generation.
The non&hyphen.privileged user could avoid the data overrun errors by not
using the above mentioned F (Fast) option, and, if the problem persists,
by setting the line to a lower baud rate. </HP1>
 
<H3>DECnet
<I1 IX=1>DECNET
Between VAX machines under VMS,
a service may be provided over decnet, the server being automatically loaded
by the network server at the remote machine, or run explictly by command.
 
The <medium> is given as DECNET.
The <net address> for the server should be either
the DECNET address of an object, or an asterisk followed by
the decnet object name of an object to be created.
In the first case, a connection is requested to the given object.
In the second case, the program declares itself as being a given
object, and waits for incoming connections.
 
<HP3>Explicit DECNET addresses</HP3>
 
If the DECNET address of the remote server or client is known, that should be
<I1 IX=1>Address DECNET
given as the network address.
This comprises the nodename followed by the object specification:
 
                <machine>::"TASK= <object>"
 
or              <node>::"0=<object>"            (equivalent)
 
<HP1>Example</HP1>:
                $ DEFINE  filer  "0@VXCRNA::""0=FILER"".DECNET"
 
<HP1>(Note the double quotes necessary within a quoted string under VMS)</HP1>
 
There is a limit of 40 characters on any RPC address. You can avoid
exceeding this by defining a logical name for a long decnet address:
 
<HP1>Example</HP1>:
<XMP>
                $ DEFINE FILER  "0@HOST.DECNET"         ! 40 char. limit
 
                $ DEFINE HOST "VXIMAG""USER PASSWORD""::""TASK=IMAGE3"""
</XMP>
When such an address is used, a connection will be set up to
the named object on the remote node.
When this is done, the actions DECNET will take on the remote node as
as follows:
<ol>
<li>If a multiple client server (see below) is already running with
that object name, the connection will be made to that process.
<li>If not, then DECNET will look for a command file with the same
name as the object requested, and extension .COM.
The directory searched will be the home directory if access control
information is passed (user and password), otherwise the DECNET
directory.
If it finds that file, it will run it.
The file may start a multi-client server, or a
single client server using the address "SYS$NET.DECNET".
<li>If the .COM file is not found, DECNET will search for an executable file
(.EXE) and run that in the same way.
<li>If none of the above work, a "No such object at remote node" error
is returned to the client.
</ol>
For instance, in the example above,
if a server does not already exist which has network name
FILER, VMS will try to run a file FILER.COM or FILER.EXE on the remote machine. 
<HP3>Single&hyphen.client server</HP3>
 
If a process (a server, for instance), is automatically
started by DECNET as descibed above,
then within that process, the originating process may be addressed as
SYS$NET.
This is a logical name set up by VMS to point to the process which
made the connection.
<I1 IX=1>SYS$NET
In this way, the command file run by VMS can set up the RPC name
of the partner process:
 
<HP1>Example filer.com</HP1>:
 
                $ DEFINE   RPC_CLIENT_NAME   SYS$NET.DECNET
<P>
                $ RUN FILER.EXE
 
This method is normally used to make a server which will be activated
automatically when the client runs.
In this case,
if a second client tries to contact the same server,
a second copy of the server process will be created to service it.
 
It is equally possible to make a client program which is automatically
activated when the server runs.
This method may be useful which the server is interactive,
or when the server is to be debugged interactively.
 
<HP3>Wildcard addressing: Handling multiple connections</HP3>
<I1 IX=1>Wildcard Addressing
<I1 IX=1>Address wildcard
 
For a server wanting to service a number of clients of unknown address,
a wildcard network address may be given.
This consists of "*", followed by the network name by which the server
is to be known.
 
<HP1>Example filer.com</HP1>
 
                $ DEFINE RPC_CLIENT_NAME  *FILER.DECNET
<P>
                $ RUN FILER.EXE
 
In this example, when filer.com is run (by hand, or automatically by VMS
when the client accesses it) a network object is created which will
endure even when the first client has exited.
<I1 IX=1>Network object
A server set up with a wildcard client address may service requests
from many clients, who may be connected at the same time.
 
<I1 IX=1>SYSNAM
It is necessary for the process to have SYSNAM privilege under VAX/VMS
to use this facility.
 
A fuller example of decnet addressing is given at the end of the chapter.
<H3>Internet Protocols (TCP, UDP)

To use TCP/IP or UDP/IP
<fn>
Not available in the first release.
</fn>
 under VMS requires the installation of
an internet protocol
package such as the WIN/TCP.
To use this facility,
<ul>
<li>Use library RPCLIBC rather than RPCLIB, or RPCLIBC8K instead of
RPCLARGE.
<li>Produce the stubs with the GeniericC options of the compiler.
<li>Compile the stubs
<hp2>without the /DEFINE=VAXVMS qualifier.</hp2>
</ul>
The ability to declare a server using one's own "well known port number"
requires SYSPRV privilege.

See the section on Internet addressing above.
<H3>ISO Transport Protocol
<I1 IX=1>ISO protocol, On VAX/VMS
<I1 IX=1>TP4, on VAX/VMS 
<I1 IX=1>VOTS
ISO class 4 Transport Protocol ("TP4")
may be used.
This requires the installation of the VOTS
package under VAX/VMS.
<I1 IX=1>CATS
 
The <medium name> is
IEEE.CATS
<FN>
CATS is a standard calling sequence for a networking transport service.
Implementations under VMS include those for
ISO Transport Protocols over IEEE 802.3, DECNET, Mailboxes, and X.25 protocols.
The "IEEE" selects the protocol used, from those supported by the CATS
library.
</FN>.
 
 
For the client, <net address> is of the form
 
        <tsuf>@<ethernet address>
 
where the <tsuf> (transport suffix) identifies the process that will run
the server - it should be the same as the tsuf specified by the server;
and <ethernet address> gives the physical address of the
machine running the server.
The maximum length of a <tsuf> on DECnet is 12 characters.
The <net address> may optionally be preceded
by a "#", which causes the client to make a new transport connection for
each RPC call rather than to leave it open after the RPC_Open and only
close it when RPC_close is called. The "short&hyphen.connect" client is useful
<I1 IX=1>Short connect
<i1>Connect on call
when either the client or server can only have limited number of
connections open.
 
For the server, the address is of the form
<xmp> 
        *<tsuf>@IEEE.CATS
</xmp>
where the <tsuf>
identifies the current process to the network system.
 
<HP1>Examples</HP1>:
 
The following examples give two possible addresses for the client and
the corresponding address for the server.
<xmp>
 0@MYSERVER@AA000400DD58.IEEE.CATS         Normal client.
 0@#MYSERVER@AA-00-04-00-DD-58.IEEE.CATS   Short-connect client.

 *MYSERVER@ieee.cats                       Server.
</xmp> 
<h3>CERN Host Interface to VME or FASTBUS
This is a fast point to point communication link between VAXes,
VME and FASTBUS systems.
See the section above on CERN Host Interface addressing.
<H3>Debugging tools
 
The logical name (VAX/VMS)
..bf mono
rpc_trace_flag
..pf
controls diagnostic output.
To turn it on, this must be defined
as the output filename,
for instance
SYS$OUTPUT:
(with the colon).
If trace is on,
the RPC run&hyphen.time system will produce copious
<I1 IX=1>Trace information , under VAX/VMS
<I1 IX=1>Diagnostic output , (see Trace)
trace information about each transaction, including the contents
of each message received or transmitted, and the addresses involved.
 
Two commands are provided to manage this:
<DL>
<DT>$ TRON
<DD>
<I1 IX=1>TRON
Turn run&hyphen.time trace on
<DT>$ TROFF
<DD>
<I1 IX=1>TROFF
Turn run&hyphen.time trace off
</DL>
If a run time error occurs which you do not understand,
running the trace (perhaps to a file) may explain what went wrong
more clearly than the single error message.
<H3>Example: VAX-VAX over DECNET
 
Suppose, as above, that the program MYPROG uses the module FILER,
but let us suppose they are both on a VAX under VMS.
The program MYPROG is on decnet node NODEM, and FILER is on
NODEF.
 
<I1 IX=1>DECNET example
We build the system as described above, but to run under VMS on both sides:
The server program is the standard one (SERVERLOOP) provided in the library:
 
       $ RPC FILER /SVAXVMS /CVAXVMS
       $ LINK MYPROG, CLIFILER, rpc_lib/OPT
       $ LINK FILER, SERFILER, rpc_lib/INCLUDE=SERVERLOOP/LIB -
 		rpc_lib/opt
 
To run MYPROG on NODEM, we make a command file MYPROG.COM:
 
        $ DEFINE/USER MYTASK "NODEF""user password""::""0=FILER"""
<P>
        $ DEFINE/USER FILER "0@MYTASK.DECNET"
<P>
        $ RUN MYPROG.EXE
 
(The definition of MYTASK as a logical name allows one
to put in a long name without exceeding the limit of 40
characters on the RPC address string, FILER).
 
When this runs, it will attempt, over decnet, to contact the object
FILER on NODEF.
The DECNET software on NODEF, when it receives the request,
will look first for a task which has already declared a network
object called FILER.
If it can't find that, it will look for a command file (.COM), and run that.
It will look for the .COM file in the default directory associated
with the "user password" given, or otherwise in the default directory
(usually [DECNET]).
 
We therefore put, on NODEF, in the top level directory [user], the command
file FILER.COM containing the following commands:
<xmp>
        $ DEFINE/USER RPC_CLIENT_NAME SYS$NET.DECNET
        $ RUN FILER.EXE
</xmp>
Note that either
the username and password must be specified with the node name,
or a "proxy login" must be created for the remote (or even
<I1 IX=1>Proxy login
local) decnet access, or FILER.COM must be installed in the default network
user directory. See the DECNET manual for details.
 
When this file is run by the decnet network server on NODEF, it first
<I1 IX=1>SYS$NET
declares that FILER should service the client SYS$NET.  This is
is a logical name set up to allow access to the process which started
the job.  Then, the FILER program runs, and will service any requests
made by MYPROG.
 
The distributed system is then run by typing (on NODEM)
<xmp>
        $ @MYPROG
</xmp>
In this case, the server serves the one client, and exits when the
client process exits. If another identical client asks
for a connection to FILER, then a separate server process is started.
 
If the server command file had been
<xmp>
        $ DEFINE/USER RPC_CLIENT_NAME *FILER.DECNET
        $ RUN FILER.EXE
</xmp> 
then the server would have declared itself as a DECNET object "FILER".
It would have then serviced the client, but remained active even after
the client had exited, to server any other clients which might run.
In this case, if more than one client had requested a connection to FILER,
then they would all have been connected to the same initial server,
which would have serviced requests from all of them.
..pa
<H2>Unix Run Time Support
Under Berkley unix, DEC Ultrix or equivalent, the RPC system
can communicate over TCP/IP, UDP/IP, raw ethernet
<fn>
UDP, raw ethernet, RS232 not provided for Ultrix in the first release.
</fn>
or RS232 links.
See the sections above on TCP, etc for details of addressing.
The shell environment (see setenv, printenv commands) is used to
define rpc addresses.
The RPC compiler is available to run in these environments.

Support in this environment is currently for C compatible
software, FORTRAN can be made be avialble if required.
The stubs should be generated using GenericC or FORTRAN options
of the compiler, and then compiled using the resident C compiler.
They must be linked with the rpclib.o module and rpc_rts_for
if in FORTRAN.

The stubs must be initialised (See Chapter 6) by calls to open_xxx and
attach_xxx in the client and server programs respectively.
<h3>Defining addresses
See the earlier sections in this chapter for the format of
RPC addreses.

The setenv command must be used (under csh)
or and equate (a=b) syntax under the shell 'sh'.
For example,
<xmp>
        setenv TESTPACKAGE CERNVAX:777.TCP

        setenv RPC_CLIENT_NAME '*:777.TCP'
</xmp>
Note that in the last example, the single quotes were necessary
to stop the shell interpreting the "*" character.
<h3>Example
Imagine we have written a file server called "FILER". The interface
is described by a file "filer.rpc".
The simple IN variables are passed by value as in normal in C.
The client application program is called myclient.c and the filer server
itself is filer.c.

First, we generate the server program. Here, filer.c contains a simple main
program which calls attach_filer() to initialise the stub, and then
rpc_loop_server(..) to run the server. It also, of course, contains the
file access routines themselves.
<xmp>
	rpcc -sgenericc=filer_server_stub.c -byvalue filer.rpc
	cc -o filer filer.c filer_server_stub.c rpcrts.o ts.o
	chmod +x filer
</xmp>
Next, we generate the client. The client in this example has a call to
open_filer() before it uses any remote routines.
<xmp>
	rpcc -cgenericc=filer_client_stub.c -byvalue filer.rpc
	cc -o myclient myclient.c filer_client_stub.c rpcrts.o ts.o
	chmod +x myclient
</xmp>
Now we run the server, asking it to wait for any connections to TCP
port 1789:
<xmp>
	setenv RPC_CLIENT_NAME '*:1789.TCP'
	filer &
</xmp>
We can leave that running and go start the client:
<xmp>
	setenv FILER mynode:1789.TCP
	myclient
</xmp>
where mynode is the internet name of the node on which the server is running.
Here, the port number was chosen to be random but greater than 1024.
See the section on TCP addressing.
<h3>Diagnostic trace output
If there is a problem, the RPC sytem will normally print an error message.
If this is insufficient to determine what has gone wrong, then the same
program may be run with the runtime trace turned on. This is
done by setting the environment variable RPC_TRACE_FLAG to the
name of the file to be used. For example,
<xmp>
	setenv RPC_TRACE_FLAG rpc.trace
or
	setenv RPC_TRACE_FLAG /dev/tty
</xmp>

Trace information will be appended to the given file.
To turn the trace back off, the command is
<xmp>
	unsetenv RPC_TRACE_FLAG
</xmp>
(Don't use
..bf MONO
setenv RPC_TRACE_FLAG /dev/null
..pf
which will just slow down the
RPC system to no purpose)

<h3>Installation
The files available are
<dl tsize=15>
<dt>rpcc
<dd>The rpc compiler
<dt>rpcc.p
<dd>The source of rpcc for compilation under different systems.
<dt>rpcheader.h
<dd>The general include file
<dt>rpc_ts.h
<dd>An include file for ts.c
<dt>rpc_code.h
<dd>An include file for rpc code modules
<dt>rpcrts.c
<dd>The runtime kernel source
<dt>ts.c
<dd>The transport service interface module
<dt>cm_env.c
<dd>The configuration manager
<dt>rpc_rts_for.c
<dd>The fortran runtime interface
<dt>system_sepcific.h
<dd>An include file which selects a suitable xxx_specific.h file
<dt>unix_specific.h
<dd>Include file with the characteristics of unix.
</dl>
The C files must all be compiled and put into library rpclib.o.
The separate library, rpclibc8k.o , is made in the same way but
using the C compiler switch -DRPC_BUFFER_SIZE=8096.

If you ever need to make any modifications to this software to run it
on your system, please notify the changes to the address in the appendix
"More Information". Thanks.
..pa
<H2>M680X0 Run Time Support under MoniCa or RMS68K
 
<I1 IX=1>M680x0, Run Time Support 
Software exists to support RPC on the M68000/M68020 family,
in a single task environment or an RMS68k multitask environment.
 
The runtime library modules to be used will depend on the system.
If the RPC library is already burnt into ROM, applications
may be linked directly to the stubs and the rom entry point file.

Application software may be in C, Pascal, FORTRAN or PILS,
with stubs generated in styles GENERICC, CERNCROSS, FORTRAN or PILS.

On the Valet&hyphen.Plus
<fn>This is a standard test system for High Energy Physics
built in VME equipment practice
</fn>
the RPC syetem and PILS are all available in ROM.

The MoniCa (or RMON) debugger is used in two ways,
either of which may be suppressed
if MoniCa is not available.
<I1 IX=1>MoniCa symbols
It is used to manage a symbol table used for translation,
for which a dummy may be provided if MoniCa is not present.
<I1 IX=1>MIOS
The MoniCa I/O system (MIOS) is used only for RS232 communication.
<H3>Raw Ethernet
<I1 IX=1>Ethernet, on M68k 
Ethernet 2.0 may be used  using the AMD "Lance" interface chip.
(This is the chip used, for example on the LRT "Filtabyte" 25.1 board).
 
The ethernet address format is described above (Sect 7.4).
<H3>RS232 Serial Line
An asynchronous
<I1 IX=1>V24, on M680x0 
V24
<FN>
For readers outside Europe, CCITT recomendation V24 is the European
equivalent of
the RS232&hyphen.C standard.
</FN>
(RS232&hyphen.C)
line may be used for connecting two devices.
The <medium name> is V24.

Under MoniCa there are two standard serial channels,
<I1 IX=1>MoniCa serial channels
thus allowing for two possible basic values of <net address>:
<DL>
<DT>TT1
<DD>
The primary V24 line ("Terminal")
<DT>TT2
<DD>
The auxiliary V24 line ("Hostline")
</DL>

Inside the <net address> a set of options may be specified after the above
mentioned serial channel specifications. The options currently supported are:
<DL>
<DT>B
<DD>
Binary coding method: use all 8 bits of the communication path. This is
the default.
<DT>L
<DD>
Printable ASCII coding method: use only the printable ASCII characters (seven
bits).
<DT>F
<DD>
Disables the RTS/CTS protocol. By default,
a strict handshake is used for flow control,
the benefit of those
systems with inadequate input buffering.
If both connected systems have sufficient input buffering,
the F option may be used to make the protocol to run faster.
</DL>
<HP1>Example</HP1>:
<P>
       TT2B.V24      8 bit operation over the auxilliary channel
 
<H3>Under RMS68k
 
The RPC run&hyphen.time system is shareable and reentrant.
 
The following restrictions apply under RMS68k
to the use of advanced RPC facilities.
<UL>
<LI>
If a user error handle is declared, it will apply to all tasks,
and so must be written to be shareable.
<LI>
The facilities for finding the name of the last caller
(RPC_Caller_Address and the x@CALLER and x@CALLBACK format)
<I1 IX=1>CALLBACK addressing, under RMS68k 
<I1 IX=1>CALLER addressing, under RMS68k 
cannot be used if there is more than one server task in the system
</UL>
 
The following restrictions apply to any RMS68K tasks which use RPC.
See the RMS68k manual for explanations of terms, and how to set up
tables.
<I1 IX=1>ASQ under RMS68k
<UL>
<LI>
The task must have an ASQ (Asynchronous Service Queue).
<LI>
Register stacking for ASRs must be enabled.
<LI>
If a default ASQ buffer is used, then it must be permanently enabled
and of length at least 24 bytes.
</UL>
 
Stub modules are
<HP1>NOT</HP1>
shareable, and so if two different tasks use the same client stub,
each must be prelinked with a separate copy.
 
As there is only one symbol table for all tasks, one may
define a task&hyphen.wide symbol by prefixing it with the
name of the task. For example
 
        define RMON_PHI1  0@AA0004003558_5050.ETHERNET
<P>
        define TSK2_PHI1  0@AA0004003558_5062.ETHERNET
 
specifies that the task RMON will access a PHI1 server
AS SERVER 0 at address AA0004003558
using ethernet protocol type 5045,
but that task TSK2 will access
it using ethernet protcol type 5062.
<H3>Debugging tools
<I1 IX=1>Trace information , on M680x0
The MoniCa symbol rpc_trace_flag
controls diagnosic output.
To turn it on, under Monica, this must be defined
as "TRUE".
 
If trace is on,
the RPC run&hyphen.time system will produce copious
trace information about each transaction, including the contents
of each message received or transmitted, and the addresses involved.
 
Under MoniCa (but not RMS68k), detailed diagnostics of the ethernet
driver are controlled by the global (integer) flag
_DEBUG.
This may take values from 0 to 5, giving increasing amounts of trace
information:
<P>
        0       Trace only transmit errors, or internal hardware errors.
<P>
        1       Trace also initialisation. (Still no output at interrupt level)
<P>
        2       Trace all above plus error conditions at interrupt level
<P>
        3       Trace all above plus normal Transmit interrupts
<P>
        4       Trace all above plus normal Receive interrupts
 
The flag is normally 0, or 1 if rpc_trace_flag is defined as TRUE. 
It may be set to other values by hand.
The output is always sent to the local terminal, even if a remote
terminal is running over RPC. 

If a fatal error, or an error when debug output is enabled, then a message
may be output to the terminal with two bytes in hexadecimal.
<xmp>
        * LANCE: Transmit error, status = 43, error = 04
</xmp>
For a receive error, the status bits are as follows:
<dl compact=2>
<dt>Bit 0
<dd>ENP: Buffer includes the packet end.
<dt>Bit 1
<dd>STP: Buffer includes the packet start. Both bits 0 and 1 indicate a whole
packet, which is normal.
<dt>Bit 2
<dd>BUFF: (Chained buffer access error.
Should never occur, as chaining is not used.)
<dt>Bit 3
<dd>CRC: CRC error on incoming packet
<dt>Bit 4
<dd>OFLO: Overflow: The interface could not access memory fast enough to empty
its FIFO buffer as the packet arrived.
<dt>Bit 5
<dd>FRAM: CRC error and non&hyphen.integeral number of bytes in packet.
<dt>Bit 6
<dd>ERR: An error has occured, at least one of FRAM, OFLO, CRC, BUFF is set.
<dt>Bit 7
<dd>The buffer is in use bythe interface.
</dl>

For a transmission error, the status bits are:
<dl compact=2>
<dt>Bit 0
<dd>ENP: Buffer includes the packet end.
<dt>Bit 1
<dd>STP: Buffer includes the packet start. Both bits 0 and 1 indicate a whole
packet, which is normal.
<dt>Bit 2
<dd>DEFF: It was necessary to defer when trying to transmit.
<dt>Bit 3
<dd>ONE: Exactly one retry was necessary to transmit the packet.
<dt>Bit 4
<dd>MORE: More than one retry was necessary to transmit the packet.
<dt>Bit 5
<dd>Always zero.
<dt>Bit 6
<dd>An error (LCAR, UFLO or RTRY) condition occured.
<dt>Bit 7
<dd>The buffer is in use by the interface.
</dl>
The interesting bits in the acompanying transmit "error" field are:
<dl compact=2>
<dt>Bit 2
<dd>RTRY: 16 attempts were made to send the packet, all
failing due to collisions on the ethernet.
Note that apparent collisions can also be caused by a badly terminated
cable, as well as by severe overload of the ethernet.
<dt>Bit 3
<dd>LCAR: Loss of carrier during transmission.
<dt>Bit 4
<dd>LCOL: Late collision. A collision has occured afterthe slot time
of the channel has elapsed. No retry is performed in this case.
<dt>Bit 5
<dd>RES: Always zero.
<dt>Bit 6
<dd>UFLO: Underflow: data could not be read from memory fast enough to
fill the packet.
<dt>Bit 7
<dd>BUFF: Buffer chaining error. Should not occur.
</dl>
<H3>Development Tools
 
Some utility programs which run under VAX/VMS have been developed
to aid the development of remote microprocessor systems which
include RPC software.
 
These include facilities for interrogation of tasks and memory in the target
task, starting and stopping of tasks, and file load and dump.
These are described elsewhere.
..pa
<H2>M6809 Run Time Support
<I1 IX=1>M6809, Run Time Support 
As operating system and langauge support on the M6809 is not so complete as
on 32 bit processors, a little more work has to be done by the user. The
code which must be put in the client and server programs is discussed below.
The run&hyphen.time system on the M6809 was written for the
<I1 IX=1>FLEX
FLEX operating
system running on the
<I1 IX=1>G64
G64 system. Hence the supported transport media are for the G64 system.
However, apart from the configuration manager, which uses the file system to
read in the configuration file (see below), the system should work under other
operating systems. The stubs produced by the RPC compiler (with the
/xM6809 option) are for the Omegasoft Pascal compiler, which is available
for both the FLEX and
<I1 IX=1>OS9, on the M6809 
OS9 operating systems. 
 
Before the RPC system can be used, the procedure
<I1 IX=1>RPC_INIT, on M6809 
RPC_Init must be called. Apart from initialising the RPC system, RPC_Init
will read in the configuration file from disk (
2.CM.DAT,
or if not found,
0.CM.DAT,
otherwise no configuration file is used). The configuration file contains a
list of equivalences for RPC addresses and address fields, that is intended as
a substitute for the VMS logical name system. It is free&hyphen.format: name
followed by equivalence, separated by one or more spaces. Comments are preceded
by an exclamation mark (!).
 
If an address or the equivalence of an address (translation is
repeated until there is no equivalence available) is of the form
ASK"prompt"[default]
(eg.
ASK"Node"[VXDEOP]
), then the user
is prompted for the equivalence. If RETURN is pressed, then the
default is used (specifying a default is optional). This mechanism
is limited by the 40 character maximium size of the address.
 
<HP1>Example</HP1>:
<XMP>
! Example of a configuration file: CM.DAT
!   Name                                Equivalence
!   ====                                ===========
    vxdeop                              AA000400DD58
    vxcrna                              AA0004002F58
    filer_client_name                   *FILER@IEEE.CATS
! The following two names cause the user to be prompted for the remote
! node name, while supplying the rest of the RPC address.
    filer_server_name                   0@FILER@NODE.IEEE.CATS
    node                                ASK"Node"[VXDEOP]
</XMP>
 
<H3>Client program
<I1 IX=1>Initialisation, on M6809 
For each package that is to be accessed, an integer
(16 bit) variable h_xxx (where xxx is the package name) must be declared in
the MAIN program as ENTRY. This is the handle. Before the package can be
used,
 
<I1 IX=1>RPC_OPEN, on M6809 
        RPC_Open (status, h_xxx, name)
 
must be called. Status is of type RPC_status,
<I1 IX=1>Handle
h_xxx is the handle, and name is of type RPC_name and must be equated to a
40 character long string or character array (padded on the right with
spaces) which is the server address. The server address and the fields within
it are translated (iteratively) as described above.
Before exiting the program a call to
 
<I1 IX=1>RPC_CLOSE, on M6809 
        RPC_Close(status, handle);
 
must be made. This is particularly important if the connection is to
ethernet, since even if the program exits, the ethernet card will keep the
connection open.
 
In any program modules that need to call RPC run&hyphen.time routines
(such as RPC_Init or RPC_Open), it is necessary to include
RPC_const, RPC_types, and RPC_proc in the constant, type, and procedure
declaration parts of the program respectively. These files are accessable,
either as input (via *INCLUDE) to the INCLUDE preprocessor on the VAX
under these logical names (ie. RPC_const, etc.), or as Pacsal include files
on the G64. In the latter case (often the more convenient) they have FLEX
filenames
RPCCONST.INC, RPCTYPES.INC,
and
RPCPROC.INC
respectivly.
 
In addition, unlike on other systems, it is necessary to include the file
rpc$var (or, on the G64:
RPCVAR.INC
) in the variable declaration section of the
<HP1>main</HP1>
program. This will declare as ENTRY the global
variables required by the RPC run&hyphen.time system (this is necessary because
of a bug in the Omegasoft Pascal compiler that fails to allocate space on the
stack for global variables in modules that are not also declared in the main
program).
 
You must compile and assemble the client stub and include it as one of the
<HP1>"Additional files to load"</HP1>
when you link. The RPC library (RPCLIB.RO) must be included as one of the
<HP1>"Additional library files"</HP1>.
 
 
<XMP>
..us Example using package name FILER:
PROGRAM FILER (input, output);       { Example client program on M6809 }

CONST
{$iRPCconst.inc                        Include RPC constant definitions}
TYPE

VAR

{$iRPCvar.INC                          Include RPC global variables}

      h_filer:    integer entry;     { Handle onto server }

      status:     RPC_status;
      address:    RPC_name;          { Server address }

{$iRPCproc.INC                         Include RPC procedure declarations}
 
BEGIN

   RPC_Init;                         { Initialise RPC system }
 
{  Open a connection to the server. We use an address that we hope will be
   translated by the configuration manager. See the example configuration file
   above for a possible translation for filer_client_name. }
   address:= 'filer_client_name                       ';
   RPC_Open (status, h_filer, address); { open connection to server }
   RPC_Report_Error (status);
 
{Instead of inserting the main program in here, we put in a call to a
   procedure MAIN (defined in this file). This allows us to separate the
   calls to the RPC run-time system from the rest of the program.
{
   main;
 
   RPC_Close (status, h_filer);      { close connection to server }

   RPC_Report_Error (status);
END.
</XMP>
<H3>Server program
The procedure attach_xxx is not defined on the M6809. Thus you must call
 
        RPC_Attach_Stub (status, integer(addr(r_xxx)), service, prog_no)
<I1 IX=1>RPC_ATTACH_STUB, on M6809 
 
where r_xxx (with xxx being the package name) is declared INTEGER PCR and
service is of type RPC_name and contains the space&hyphen.padded package name,
and prog_no is an integer (16&hyphen.bit).
 
As for the client program, the server main program must include the file
RPCVAR.INC
in the VAR section. Any modules that use RPC run&hyphen.time
routines (eg. RPC_Loop_Server) must also include
..bf MONO
RPCCONST.INC, RPCTYPES.INC,
..pf
and
..bf MONO
RPCPROC.INC.
..pf

You must compile and assemble your server procedures and the server stub,
both of which must be included as
<HP1>"Additional files to load"</HP1>
when you link. The RPC library (RPCLIB.RO) must be included as one of the
<HP1>"Additional library files".</HP1>
 
<HP1>Example using package name FILER</HP1>:
<XMP>
PROGRAM MAIN (input, output);        { Example server program on M6809 }
CONST
{$iRPCconst.inc                        Include RPC constant definitions}
TYPE
{$iRPCtypes.inc                        Include RPC type declarations}
VAR
{$iRPCvar.inc                          Include RPC global variables}
      r_filer:     integer pcr;      { Server stub address }
      status:      RPC_status;
      package:     RPC_name;         { package name }
      address:     RPC_name;         { Address of client }
      prog_no:     integer;          { Returned package number }
{$iRPCproc.inc                         Include RPC procedure declarations}
 
BEGIN
   RPC_Init;                         { Initialise RPC system }
 
   package:= 'filer                                   ';
   RPC_Attach_Stub (status, integer(addr(r_filer)), package, prog_no);
   RPC_Report_Error (status);
 
   address:= 'filer_server_name                       ';
   RPC_Loop_Server (status, address);   { Service RPC requests }
   RPC_Report_Error (status);
END.
</XMP>
<H3>Example: VAX-G64 over ethernet, ISO TP4 protocol
<I1 IX=1>FLEX
<I1 IX=1>Omegasoft Pascal
<I1 IX=1>Building a system , under FLEX on G64
 
The following example shows the commands needed to build a RPC
application. Suppose we have a program called
MYPROG.FOR
written in FORTRAN and running on a VAX under VMS. This needs to call
procedures in a module called
FILER.TXT
written in Omegasoft Pascal and running on the G64 running the FLEX operating
system. The interface between the two is described in RPCL in the file
FILER.RPC.
 
First of all we compile the main program using the VAX/FORTRAN
compiler, generating the file
MYPROG.OBJ:
 
        $ FORTRAN MYPROG
 
We then generate the stub code for each system using the RPC Compiler:
 
        $ RPC FILER.RPC /CVAXVMS /SM6809
 
Now the RPCC will produce (if no errors are found) the files:
 
        CLIFILER.OBJ    The client stub for VAX/VMS
<P>
        SERFILER.PAS    The server stub: Omegasoft Pascal
 
We can then link together the VAX image:
 
        $ LINK MYPROG, CLIFILER, rpc_lib/opt
 
We now have an executable file, MYPROG.EXE, which, when run, will call
the remote version of FILER.
 
To create the executable file on the G64, the file
SERFILER.PAS
must then be downloaded to the G64. Note that the default filetype
for source files under FLEX is .TXT so when the file is downloaded, the output
filespec should be specified as
SERFILER.TXT
(also filename must not be more than 8 characters long).
The server stub must then be compiled and assembled:
 
        +++PASCAL <SERFILER > O
<P>
        +++RA <SERFILER.CO >SERFILER.RO O
 
The server routines (that we wrote) in
FILER.TXT
must also be compiled and assembled:
 
        +++PASCAL <FILER > O
<P>
        +++RA <FILER.CO >FILER.RO O
 
Finally these must both be linked in with a main program (say,
MAIN.TXT
) that will simply initialise the RPC system and call a routine like
RPC_Loop_Server (which simply services remote procedure calls forever).
An example main server program is given above.
The main program can be compiled and linked with the chain file produced
by the LC command:
<XMP>
   +++LC "MAIN" F
<P>
  Linkage Creator Version 2.11
<P>
  Copyright 1982 by Omegasoft
<P>
   Auto setup ? Y                  Let LC decide where to put the stack
<P>
   System stack size : 400         (in hex) Better to overestimate!
<P>
   Starting load location : 0      The start of the program in hex
<P>
   Library drive number : 0        Drive on which RL.RO can be found
<P>
   Additional files to load : SERFILER     Sever stub
<P>
   Additional files to load : FILER        Server routines
<P>
   Additional library files : RPCLIB       G64 RPC library
<P>
   Load options :                  Options for the LL command line
<P>
   Map options :                   Use F for a full map listing
<P>
   Additional command :            FLEX command to follow Link step.
</XMP>
The command
CHAIN MAIN
will execute the chain file and produce the executable file
2.MAIN.BIN,
which may be executed by the command
2.MAIN.BIN .
Remember that the file
CM.DAT
should be present on either disk 2 or 0, so that the definitions for
filer_server_name and filer_client_name (used in the client and server main
programs respectively) are present.
 
<H3>RS232 serial line
<I1 IX=1>V24, on G64 
<I1 IX=1>G64
<I1 IX=1>ACIA
An asynchronous
V24
<FN>
For readers outside Europe, CCITT recomendation V24 is the European
equivalent of the RS232&hyphen.C standard.
</FN>
(RS232&hyphen.C) line may be used for connecting two devices. The G64 system
has two types of RS232 chip, the SCN2661 (the older type - used on the
"asynchrone" board) and the SCN2681 (supplied with the new paged&hyphen.RAM CPU
card) which provides two asynchronous channels. The format of <medium address>
is similar for the two chips. The <medium name> is V24. The <net address> gives
the four&hyphen.digit hexadecimal address of the memory&hyphen.mapped RS232
controller preceded by a "$". For the SCN2681, this is followed by "_A" or "_B"
depending which of the two channels of the
<I1 IX=1>DUART
DUART is to be used.
 
 
The <net address> may have a suffix giving the baud rate.
This defaults to 9600 baud.
 
<HP1>Examples</HP1>:
<XMP>
        $E020_B.4800.V24        Second terminal line on CPU board
                                run at 4800 baud.
 
        $E000.V24               First chip on the Dual Asynchrone board.
</XMP>
The implimentation of V24 communications for other systems allow both
7- and 8-bit communications. Only 8-bit communications is supported on
the G64, and consequently those systems that the G64 communicates with
via RS232 should also be configured to use 8-bit.
 
<H3>OSI Transport Service over ethernet
<I1 IX=1>OSI
<I1 IX=1>Cheapernet
<I1 IX=1>Ethernet, on M6809 
 
For Ethernet/Cheapernet communication on the G64, the
<I1 IX=1>G64, Cheapernet card 
<I1 IX=1>Cheapernet, card for G64 
cheapernet interface card (produced by CERN/DD) is required on the G64 crate.
ISO class 4 Transport Protocol ("TP4")
<I1 IX=1>TP4, on G64 
is used.
If communicating with the VAX, the
<I1 IX=1>VOTS
VOTS package is required on the VAX.
<I1 IX=1>CATS
(The software uses a
CATS
<FN>
CATS is a standard calling sequence for a transport service.
Implementations existing include those running over
IEEE 802.3 (Ethernet/Cheapernet) on the VAX/VMS and
G64; and DECNET, Mailbox, and X.25 protocols on the VAX,
and over the CERN Host Interface.
</FN>
library to access the communications service).
 
The <medium name> is CATS. The <net address> has a suffix to indicate
which medium CATS is to use. Currently only IEEE is supported on the G64
(IEEE, DECNET, X25, and MBX are supported on the VAX).
 
 
For the client, <net address> is of the form
 
        <tsuf>@<ethernet address>.IEEE
 
where the <tsuf> (transport suffix) identifies the process that will run
the server - it should be the same as the tsuf specified by the server; and <ethernet address> gives the physical address of the
machine running the server. The <net address> may optionally be preceded
by a "#", which causes the client to make a new transport connection for
each RPC call rather than to leave it open after the RPC_Open and only
close it when RPC_close is called. The "short&hyphen.connect" client is useful
<I1 IX=1>Short connect
when either the client or server can only have limited number of
connections open.
 
For the server, <net address> is of the form
 
        *<tsuf>@IEEE
 
where the <tsuf> identifies the current process to the network system. On the
G64 - not a multi&hyphen.tasking system - only one <tsuf> may be used at a
time.
 
<HP1>Examples</HP1>:
 
The following examples give two possible addresses for the client and
the corresponding address for the server.
<XMP>
 0@MYSERVER@AA000400DD58.IEEE.CATS         Normal client.
 0@#MYSERVER@AA-00-04-00-DD-58             Short-connect client.
        *MYSERVER@ieee.cats                       Server.
</XMP>
On the G64, .IEEE and .CATS are default and may be omitted.
 
<H3>Debugging tools
<I1 IX=1>Trace information , on M6809
 
If the RPCLIB.RO library was compiled with tracing messages included, then
rpc_trace_flag is translated using the configuration file by RPC_Init. If it
translates to Y, then tracing messages are displayed on each call. If
ASK"Enable Tracing?"[Y]
is included in the configuration file, then the user will be prompted at
run&hyphen.time.
 
 
Tracing may be turned on or off from within the program by setting
rpc_trace_flag (a global variable defined in rpc$var)
to false. The tracing output goes to the output stream
errlog
(a global text file also defined in rpc$var)
which is setup by RPC_Init to be routed to the terminal output
stream.
 
If the RPC run&hyphen.time system has been generated with tracing disabled,
then no tracing output can be obtained.
 
 
<H3>Further comments
<OL>
<LI>Since the heap is used by the RPC run&hyphen.time system, it is
important that Omegasoft Pascal's
mark
and
release
routines do not
come on either side of a call to the RPC run&hyphen.time system.
ie.
mark(i); ... RPC_open(); ... release(i);
is a
<HP1>bad move</HP1>.
<LI>
Currently
there is no support for asynchronous calls on the M6809. Consequently
RPC_Start_Server, RPC_Queue_Server, and RPC_Service are not defined. RPC_Accept
with a timeout of zero is a useful mechanism for polling for an RPC request
while carrying out other tasks.
<LI>
In
order to save memory space, versions of the M6809 RPC library can be
created without support for all the transport media, or for debugging
messages.
</OL>
..pa
<H2>IBM&hyphen.PC Run Time Support
<I1 IX=1>Turbo Pascal , Run time support
<I1 IX=1>IBM-PC , Run time support
<I1 IX=1>PC, IBM , Run time support
The RPC compiler and runtime system are both
available toi run under MSDOS, using TurboPascal.

The RPC compiler command line syntax is the same as for VMS.

The stubs should be generted with the /CPCTURBO or /SPCTURBO option,
and compiled using TurboPascal.
(No INCLUDE preprocessing is required.)

The program should declare the name of any stubs which it uses
in a "USES" clause. This will cause the stubs to be linked in
and automatically initialised
<fn>
The NOAUTOINIT option of the compiler may be used to inhibit this.
See the chapter on "Running the compiler".
</fn>
at run time.
The library files provided in the release must be made available to
turbopascal for linking.

Communication may be over
<dl>
<dt>Ethernet
<dd>See the section on ethernet addressing for the address format.
<dt>RS232
<dd>The addressing format is the same as for the M680x0 under
MoniCa. 
<dt>ISO Tranport protocol class 4, running over ethernet.
<dd>The address format is the same as under VMS, but with a medium name
of "IEEE" (not IEEE.CATS).
</dl>
For either raw ethernet or TP4 communication, the BICC "ISOLAN" card
is used.

<hp1>
In the initial release,
a separate library must be used for ISO tranport
communication, from the one or ethernet and RS232 communication.
</hp1>
<h3>Hardware required
The system runs over RS232 ports (COM1: or CONM2:), or over raw ethernet,
or over ISO TP4 protocol. For the latter two options, a BICC ethernet
interface card is required.
<h3>Defining the RPC addresses
<i1>Addresses on the PC

Under MSDOS, the RPC address strings are defined using the environment
variables. The command is SET:
<xmp>
	>  SET <logical>=<physical>
</xmp>
This takes the place of the DEFINE command, for example, under VMS.
Note that there should bve no spaces on either side of the = sign.
For example,
<xmp>
	> SET RPC_TRACE_FLAG=TRUE

	> SET RPC_CLIENT_NAME=*_5150.ETHERNET

	> SET MYPKG=GRAPHICS@AA0004007758_5150.ETHERNET
</xmp>
The address syntax for RPC addresses is the same as for other
systems.
..pa
<h2>Macintosh Run Time Support
<I1 IX=1>Turbo Pascal, on Mac
<i1>MPW, Macintosh Programmer's Workshop
<I1 IX=1>PC, Macintosh , Run time support
 
RPC is available for the Macintosh, using either TurboPascal or
MPW Pascal.

<h3>Program building.
The stubs should be generted with the CMACTURBO or SMACTURBO option,
and compiled using TurboPascal or MPW Pascal.
(No INCLUDE preprocessing is required.)

The program should declare the name of any stubs which it uses
in a "USES" clause.

The stubs will be automatically initialised under TurboPascal
<fn>
The NOAUTOINIT option of the compiler may be used to inhibit this.
See the chapter on "Running the compiler".
</fn>
at run time,
but not under MPW, when initialisation calls should be inserted
in the main program as shown in he examples.

The library files provided in the release must be made available to
turbopascal or MPW for linking.
The dependecies between the modules are as follows:
<xmp>
                Client                     Server
                program                   program
                   |                         |
                   |                _________|__________
                   |                |                  |
             CLIENT STUB        SERVER STUB          Server
                   |________________|                routines
                            |
                          RPCRTS
                 ___________|___________
                |                       |
            RPCSTUB                 TSTURBO
                |_______________________|
                            |
                        RPCMACPAS
</xmp>
Because of the 32kbyte limitation on the size of any one program segment,
you will need to put at least one RPC library module into its own segment
using the $S directive as shown below.
The client program header will be of the form:
<box><xmp>
..tb 9 17 25 33 41 49 57 65 73
program Client;              {Main client program}

{$S+}                        {Enable segmentation}
{$U RPCMacPas}               { Mac-specific runtime support }
{$U RPCStub}                 { Run time support for stubs }
{$U TSTurbo}                 { Run time support transport }
{$U RPCRTS}                  { Run time support kernel }
{$U clitest}		     { Client stub in this example }

uses MemTypes,
     QuickDraw,
     OSIntf,
     ToolIntf,
     RPCMacPas,               { RPC system starts here }
     RPCStub,
     TSTurbo,
     {$S SEGRTS}  RPCRTS,     { Put RPC RTS into different segment }
     clitest;                 { The client stub }

var
       ...
    
begin
    RPCMacPas_Init;	{ MPW only }
    RPC_Init;		{ MPW only }
    Open_test;		{ MPW only }

    ...

    if (rpc_trace) then close(errlog);      
end.
</xmp></box>
A typeical server program is:
<box><xmp>
..tb 9 17 25 33 41 49 57 65 73
program Server;		{Main server program}

{$S+}			{Enable segmentation}
{$U RPCMacPas}
{$U RPCStub}
{$U TSTurbo}
{$U RPCRTS}
{$U test}
{$U sertest}

uses MemTypes,
     QuickDraw,
     OSIntf,
     ToolIntf,
     RPCMacPas,
     RPCStub,
     TSTurbo,
     {$S SEGRTS}  RPCRTS,	{ RPC runtime system }
     test,			{ Server subroutines }
     {$S testseg} sertest;	{ Server stub }

var
    status :    RPC_status;
    address :   RPC_name;
    
begin
    RPCMacPas_Init;	{ MPW only }
    RPC_Init;		{ MPW only }
    Open_test;		{ MPW only }
    Attach_test;	{ MPW only }

    address := 'test                                    ';
    RPC_Loop_Server (status,address);
    RPC_Report_Error (status);    
    close(errlog);
end.
</xmp></box>
<h3> Configuration file
<i1 ix=1>Configuation file (Mac)
As there is no shell environment on the Mac,
RPC addresses must be defined in a file called RPC_Cfg.
You can edit this with the turbopascal editor.
The format is
<xmp>
        < name > = < address >
        < name > = < address >
        . . .
</xmp>
For example,
<xmp>
	RPC_TRACE_FLAG=rpc_trace_file
	TEST=0@TT1:F.V24
</xmp>
A file in this case is produced for trace information.
The user program must close this file, if it is used, before
exiting the program (or it will be unreadable).

Communication may be over
RS232 only at the moment, and the
address modifiers for changing baud rate, etc., are not supported.
..pa
<H2>OS9 Run Time support for M680x0
<I1 IX=1>OS9, runtime support 
Under Microware's OS9 operating system,
RPC is available to run over TCP/IP, ethernet or RS232 serial links.
<fn>
RPC running over ISO transport protocol is under development.
</fn>
Release notes distributed with the files describe how to make smaller
libraries which support only a subset of these media.
<h3>Running over TCP/IP
For this, you will need to link with the socket library as well as the
rpc library. The socket library is available from Microware.

See the earlier section on TCP addressing. 
<h3>Running over Ethernet
For ethernet, the 'elan' driver
<fn>T. Charity, CERN/EP.  If you are using the Aleph network disks,
you will already have this driver.
</fn>
is used.
See the section above on ethernet addressing for the address format.
<h3>Running over RS232
For RS232 (V24) working,
the port device descriptors must be in a modifiable address space.
This is not the case if they are loaded from EPROM.
You can check that it is writable by using the XMODE command to make
a change, and then checking that the change has taken effect.
Also, all processes must be removed
which are in any way connected to the serial port (usually only "tsmon").
See the section above on RS232 addressing.
<H3> Langauges and stub generation
As C is the dominant language in this environment,
stubs in C should be used.
 
Programs written in C to run under OS9 may communicate with server and
clients on other systems, no matter what langauge they are written in.

The genericC
option of the compiler (see chapter 4) should be used to generate stubs.
The "byvalue" qualifier should also be used for C compatibility,
while omitting it will give stubs more compatible with FORTRAN.

If you are using FORTRAN, you should use the
RTF compiler by Hans Von der Schmitt.
The stubs are compiled without the "byvalue" qualifier.
In this case, you should avoid passing strings, as they will be
passed using the C convention which is not compatible with FORTRAN.
<fn>
To mix OS9 and C and FORTRAN, you will need
a special module
..bf MONO
rtfcstart.a
..pf
and a special link command
..bf MONO
lnc
..pf
developed in OPAL.
This allows FORTRAN programs to call C subroutines (including RPC stubs).
</fn>

Until the RPC compiler has been ported to run under OS9, the stubs
must be generated under VAX/VMS or Ultrix and then copied
(using FTP, OSWRITE, etc) to OS9
for compilation.  This will only have to be repeated if the package definition
file is changed, which should happen infrequently.
<H3> Linking

A client or server must be linked with stubs and with the runtime library
files.
Examples of the creation of a client and a server for OS9 are given below.
<h3>Diagnostics
If your have problems, the RPC system will give you an error message or
a bad (even) status return. To get more information, turn on tracing with
the command
<xmp>
	setenv RPC_TRACE_FLAG <file>
</xmp>
giving the filename of your choice. Use the
<xmp>
	printenv
</xmp>
command to see all environment variables.
Setting RPC_TARCE_FLAG to the same thing as PORT will give you trace
on the terminal screen.

The trace shows everything the RPC system does on your behalf.
You can see all the messages (in hexadecimal), and all the stages in the
setting up of the communications.  If you report a problem with which you
need help, it is useful if you include in your report a copy of the trace
file (from both client and server is possible).

The command
<xmp>
	unsetenv RPC_TRACE_FLAG
</xmp>
turns the tracing off again.
<H3> Installation
The file are available in a VMS save set, and may be picked up with the
command
<xmp>
  $BACKUP VXCERN::DISK$D1:[RPC.DISTRIBUTION_KIT]RPC_OS9vvu.A/SAV []
</XMP>
where vvu is 024 for version 2.4 etc.
The save set also contains a file of release notes.
Read these for further instructions.
Files may be copied to OS9 using the OS9PUT utility.
The header file
..bf MONO
rpcheader.h
..pf
should be put into the standard directory which will
be searched by the C compiler.
The source files are distributed in source (C) form for portability,
and must then be compiled as described in the release notes.

<H3> Example 1: VMS server for OS9 client

This example gives the code used to make a server which would allow
an OS9 user to give any VMS DCL command for execution on
a host VAX.  The code essential to
an understanding of the RPC is shown, although other details have been
removed for clarity. Copies of the original files are available if required.

..bd The Package definition

The package consists, in this case, of only one function.
This is the definition file which describes it:
<box><xmp>
  PACKAGE OS9_SERVICE IS
     TYPE IN_STRING IS STRING(133);
     FUNCTION OS9_DCL( COMMAND : IN  IN_STRING)  RETURN RPC_LONG;
  END OS9_SERVICE;
</xmp></box>
..bd The server subroutine

The server is based on a FORTRAN subroutine to have the command
exectuted by the LIB$SPAWN library call.
<box><XMP>                                        
         INTEGER FUNCTION OS9_DCL(COMMAND)
 C       execute a VAX command from OS9
         CHARACTER *(*) COMMAND
         OS9_DCL = LIB$SPAWN(  COMMAND       ,  !command
      +                                      ,  !input file
      +                                      ,  !output file   
      +                     )                   !many other params
 C       keep a record of action and status
         OPEN(35,FILE='OS9_DCL.OUT',FORM='FORMATTED',
      +       STATUS='UNKNOWN',ACCESS='APPEND')
         WRITE(35,10) COMMAND, OS9_DCL
   10    FORMAT(//,2X,'Command was: ',A,/,2X,'Status: ',I10,/)
         CLOSE(35)
         RETURN
         END  
</XMP></box>
..bd The server main program

This is a simple server loop, along the lines given in the section
on initialisation in this manual. In this example it is written in C
for variety. Note the 40 character name which matches
data type rpc_name.
This is only given as an example: in fact, the predefined serverloop
module could have been used (see below).
<box><xmp>
..tb 9 17 25 33 41 49 57 65 73
  #include <rpcheader.h>
  #include <stdio.h>
      extern attach_os9_service();    /* comes from server stub */

  main()
  {
     /* the name between " " must be EXACTLY 40 char long. It will be
	translated to the address to be used by the server. */

     rpc_status status;
     attach_os9_service(); 		/* See chapter 6 */
     rpc_loop_server(&status,
	"RPC_CLIENT_NAME                         ");
     rpc_report_error(&status);      
   }
</xmp></box>
..bd Commands to make the VMS server

<xmp>
      $! PRODUCE STUBS (SERDCL.OBJ AND CLIDCL.RPC)
      $ rpc dcl.rpc /svaxvms /cgenericc /noautoinit /byvalue
      $! LINK THE SERVER ROUTINES ASSUMING THEY HAVE BEEN COMPILED 
      $ link/debug os9_dcl.obj, serdcl.obj, -
           rpc_lib/include=serverloop, rpc_lib/opt
</xmp>
Alternatively, the predefined server loop could have been used, with
automatic initialisation of the stub:
<xmp>
      $! PRODUCE STUBS (SERDCL.OBJ AND CLIDCL.RPC)
      $ rpc dcl.rpc /svaxvms /byvalue
      $! LINK THE SERVER ROUTINES ASSUMING THEY HAVE BEEN COMPILED 
      $ link/debug os9_dcl.obj, serdcl.obj, rpc_lib/inc=serverloop -
		rpc_lib/lib
</xmp>
..bd Client Program

This is the program which runs under OS9. It takes one command line
parameter, the VMS DCL command to be executed by the VMS server.
<box><xmp>
      #include <strings.h>
      #include <types.h>
      #include <rpcheader.h>
    
         extern void open_os9_service();
         extern void rpc_init();
         extern rpc_long os9_dcl();  /* see DCL.EXT file produced by RPCC */
      
      main (argc,argv)
      int argc;
      char *argv[];
      {
         int i, j, istat;
         char command[133], temp[133];
         static char *next_call = {"command_is"};
    
         rpc_init();
         open_os9_service();
         istat = os9_dcl(next_call);               /*send the command     */
         if (istat == 1) 
             printf(" On this end (muVAX and OS9) all is fine&bsol;n");
         else {
               printf(" SORRY, there has been a problem! Please, see&bsol;n");
               printf("        an expert and report ISTAT = %d&bsol;n",istat);
               }
    
        }
    
</xmp></box>
..bd Copying the Client Stub to OS9

You must compile and link on OS9 with the following commands
<xmp>
	cc -rs -v=/m17/rpc filename
	cc -x client.r clientstub.r /m17/rpc/rpclib.l -dOS9 -f=fileout
</xmp>
<ul>
<li>It is useful to set the environment variables CDEFS and CLIB
to the directory name for .h files  (e.g. /m14/defs)
and .l files (e.g. /m14/lib) respectively.)
<li>If the include file rpcheader.h is has not been put in a standard directory,
the option -v=<directory> (eg -v=/m17/rpc) can be used to tell the
compiler where to find it.
<li>The -dOS9 defines a preprocessor symbol to select apropriate code from this
file, and is not necessary under the latest (v3) release of RPC for OS9
<li>If more stack is needed, the option
..bf mono
-m=10
..pf
may be needed.
</ul>
..bd Defining addresses on the VAX

Define the logical name used by the SERVERLOOP program. The Protocol type
here is a number between 5680 and 56FF hex (at CERN, this protocol type is
reserved for OPAL RPC).
for this example:
<xmp>
          DEFINE RPC_CLIENT_NAME *_5680.ETHERNET
</xmp>
..bd Defining addresses on the OS9 system

Here, you set the environment variable for the client. By default the 
varaible name is the PACKAGE name. On OS9 you MUST use UPPERCASE
letters.
In this example talking with UXOPCJ:
<xmp>
	SETENV  OS9_SERVICE 0@AA_00_04_00_15_58_5680.ETHERNET
</xmp>

Now, Run the SERVER on the VAX, then Run the CLIENT on OS9.
  
<h3> Example 2: Client on VMS, server on OS9.
The general procedure is as above
<ol>
<li>Write the server, client, and variable declaration files
<li>RPC the declaration file with correct options
<li>Link the client modules on the VAX (for this application)
<li>Port the server routines, compile, and link with RPC files
<li>Define the logical/environment variables(=addresses)
<li>Run the application
</ol>
.bd CLIENT program
The client program
is as follows:
<xmp>

     #include <stdio.h>
     #include <rpcheader.h>
     	extern void open_test_2();
        extern rpc_long testfun_2();
     
     main()
     {
        int a,b;
     
        open_test_2();		/* connect us to the server */
     
        a = 1;
        b = 9;
        printf("&bsol;n A = %d   B = %d", a, b);
        printf("&bsol;n A + B =  %d", testfun_2(a,b));
     }

</xmp>
..bd Package Definition
The pacakge definition file is as follows:
<xmp>
      PACKAGE TEST_2 IS
              FUNCTION TESTFUN_2 (
              		P1 : IN RPC_LONG;
			P2 : IN RPC_LONG)
			RETURN RPC_LONG;
      END TEST_2;
</xmp>
..bd Server routines
<xmp>
          
     #include <rpcheader.h>
     #include <stdio.h>
     #include <types.h>
     
         extern void attach_test_2();
         extern void rpc_init();
     
     main()
     {
        rpc_status status;
       
        rpc_init();
        attach_test_2(); 
        
        rpc_loop_server(&status,"RPC_CLIENT_NAME                        ");
        rpc_report_error(&status);      
     }
     
     
     testfun_2(p1,p2)
     int     p1,p2;
     {
        return(p1 + p2);
     }
   
</xmp>
..bd To run it

Define the addresses, under OS9:
<xmp>
	SETENV RPC_CLIENT_NAME  AA_00_04_00_15_58_5680.ETHERNET
</xmp>
or, to service requests from any address,
<xmp>
	SETENV RPC_CLIENT_NAME  $_5680.ETHERNET
</xmp>
and on the VAX:
<xmp>
        VAX:  DEFINE TEST_2 0@02_60_86_00_04_4E_5680.ETHERNET     
</xmp>
Then start the server and run the client.
..pa
<H1>Advanced Use of RPC
 
This chapter describes facilities in the RPC kernel which may be called
by users wishing to perform more than transparent procedure calls.
This chapter need not be read by users who are building straightforward
distributed programs. Topics covered are
<ul>
<li>Task to task communication and object oriented programming
<li>Handling of multiple clients
<li>Handling of multiple servers
<li>User error handling
<li>Setting timeouts on RPC calls
<li>Controlling stub version number checking
</ul>
Details of parameters of each library procedure are given in an appendix.

<H2>Varieties of server
 
<I1 IX=1>Server, building different types 
This section describes a method of building servers which look to the client
like ordinary procedures, but in fact are something more complicated.
It describes how task to task communication may be performed with RPC.
 
<H3>Server loop
 
The simplest server is a program which waits in a loop, servicing each request
as it comes in.  The procedure <hp2>RPC_Loop_Server</hp2>,
in the run&hyphen.time library,
<I1 IX=1>Server loop
implements such a loop. This takes as a parameter the medium address(es) to
which it is to listen. This may be used in a situation where a task can
be dedicated to servicing remote calls.
<FIG ID=FIG1 PLACE=FLOAT FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig1
<PICTURE NAME=FIG1$$$S>
..go donefig1
...skipfig1 
..tb 9 17 25 33 41 49 57 65 73
+---------------------->|
|			|
|		+-------+-------+
|		|  wait for a 	|
|		|   request	|
|		+---------------+
|			|
|	+-------+-------+-------+-------+
|	|	|	|	|	|
|     +---+   +---+   +---+   +---+   +---+	service the
|     |   |   |   |   |   |   |   |   |   |	 particular
|     +---+   +---+   +---+   +---+   +---+	  request
|	|	|	|	|	|
|	+-------+-------+-------+-------+
|			|
 ------------<----------
...donefig1
<FIGCAP><HP1>A simple server loop
</HP1>
</FIG>
The RPC_loop_server procedure is
used in the default main program module "SERVERLOOP" provided with the
VAX/VMS run time library.

<h3> Object Oriented Programming
<I1 IX=1>Object oriented programming
<I1 IX=1>Task&hyphen.Task communication

A powerful and convenient way of designing a multitask system is to
use "Object oriented programming".
It means that for a data object, or physical object,
you write a bunch of procedures for performing operations on that object.

In a real&hyphen.time system, as well as a bunch of procedures,
you probably want
a controlling program which runs as an independent process, with overall
responsability for the object.  The smart step is to make some of
the operations on the object available to other processes by RPC:
<FIG ID=FIG2 PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig2
<PICTURE NAME=FIG2$$$S>
..go donefig2
...skipfig2
..tb 9 17 25 33 41 49 57 65 73
	+---------------+
	|  Controlling	|
	|   program	|		+---------------+
	+---------------+		|  remote	|
		|			|    program	|
		| 			+---------------+
		|			    /
		|			   /
		|   ______________________/
		|  /		(RPC)
		| /
		|/
	+---------------+
	|  Access	|
	|   procedures	|
	+---------------+
		|
	    database
	  &/or physical
	     object
...donefig2
<FIGCAP><HP1>A local controlling program allows a remote program to
access some of it's procedures asynchonously.
</HP1>
</FIG>
The access procedures are linked with the main program, and share its data
structures.
<ul>
<li>The remote program uses the access routines like any other
routine
<li>The control program can enable or disable access from outside
for exclusive access to the object at any time.
<li>The access routines may affect data structures, and
synchronisation primitives, and so modify the way the main program
behaves. (For instance, access routine can release
the main program from a wait state).
</ul>

..cc 20
Task to task communication may be set up between two or more
processes, each one providing a set of routines which may be called
by the other.
<FIG ID=FIG3 PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig3
<PICTURE NAME=FIG3$$$S>
..go donefig3
...skipfig3
..tb 9 17 25 33 41 49 57 65 73
	+---------------+		+---------------+
	|  Program 1	|		|   Program 2	|
	+---------------+		+---------------+
		|&bsol;			      /	|
		| &bsol;			     /  |
		|  &bsol;__________		    /	|
		|	      &bsol;		   /	|
		|   ___________&bsol;__________/	|
		|  /	rpc	&bsol;		|
		| /		 &bsol;_____________	|
		|/		   rpc	       &bsol;|	
	+---------------+		+---------------+
	|  Access	|		|   Access	|
	|   procedures	|		|   procedures  |
	+---------------+		+---------------+
		|				|
		|				|
	      Object 1			     Object 2
...donefig3
<FIGCAP><HP1>Interprocess communication by RPC between
processes responsible for different objects.
</HP1>
</FIG>
In the example program "battleships" (available on demand)
two instances of the same program communicate in this
way, to implement a simple game of battleships.  Each program manages
an object which is a fleet of ships.
 
An object manager may be implemented either by polling, or by asynchronous
reponse to incoming requests. The next two sections describe these alternatives.
 
<H3>Polling Server
 
<I1 IX=1>Server, with common processing 
A variation of the simple server loop allows the server program to service one
call at a time, and perform processing in between.
It allows the object oriented approach in environments
where asynchronous servers are not supported. (M6809, IBM PC/MSDOS etc)
<FIG ID=FIG4 PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig4
<PICTURE NAME=fig4$$$S>
..go donefig4
...skipfig4
..tb 9 17 25 33 41 49 57 65 73
+-------------->|
|		|
|	+-------+-------+
|	|  wait for a 	|(request)
|	|   request	|----------------->
|	+---------------+		   |
|		|(timeout)
|		|			   |
|		|		+-------+-------+-------+
|		|		|	|	|	|
|		|	      +---+   +---+   +---+   +---+ service the
|		|	      |   |   |   |   |   |   |   | particular
|		|	      +---+   +---+   +---+   +---+ request
|		|		|	|	|	|
|		|		+-------+-------+-------+
|		|			   |
|		|<-------------------------
|		|
|	+-------------------------------+
|	|	Other activities 	|
|	|				|
|	+-------------------------------+
|		|
 ------------<--
...donefig4
<FIGCAP><HP1>A polling server using RPC_Accept
</HP1>
</FIG>
A call to the
run&hyphen.time system <hp2>RPC_Accept</hp2> routine
<i1> RPC_Accept
causes a wait for the next request, and the servicing of
the called procedure. The procedures called in this way 
may share data with the user program and communicate in other ways.
 
The library procedure <hp2>RPC_Create_Server</hp2>
must be used to initialise
<i1> RPC_Create_Server
the server before RPC_Accept can be called, in order to
the open communication channel.

It may be that the "other activities"
are not related to the service procedures, if there are
other things for which the task is
responsible, as may be the case, for example, in
a microprocessor without a multitasking kernel.

It may also be that the "other activities" are very related to the
service procedures. They may be fed commands by the service procedures,
they may share data areas with the service procedures, and they
may even call the same service procedures themselves.

This method may also be appropriate if the server
is regarded as a state machine,
when requests from different clients must interact in some way, as in a
resource manager. (This form of server is analoguous to an Ada task with
"entries": examples of its use may be found in Ada tutorials.)

<H3>Asynchronous Server
 
<I1 IX=1>Server, Asynchronous
This method of designing a server allows a user program
on the server side
to run continuously, at the same time as the client process(es).
The user program simply asks the run&hyphen.time system
to service any incoming requests asynchronously.
The <hp2>RPC_Start_Server</HP2> routine is used once to set this up.
<i1> RPC_Start_Server
From that time on, whenever a call arrives, the user task will be interrupted,
the called procedure will execute as though it had been called from
the user program at that point, and then the user program will continue.
(Under VMS, the procedure is run at AST level; on the M68k it is run
<I1 IX=1>AST level
in an equivalent way, not at interrupt level).
<FIG ID=FIG5 PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig5
<PICTURE NAME=fig5$$$S>
..go donefig5
...skipfig5
..tb 9 17 25 33 41 49 57 65 73
+-------------->|
|		|
|	+-------+-------+
|	|		|
|	|		|
|	|		|
|	|     User	|  ------------> Interrupted
|	|   program	|		 by request arriving
|	|     loop	|			|
|	|		|			|
|	|		|	+-------+-------+-------+
|	|		|	|	|	|	|
|	|		|     +---+   +---+   +---+   +---+ service the
|	|		|     |   |   |   |   |   |   |   | particular
|	|		|     +---+   +---+   +---+   +---+ request
|	|		|	|	|	|	|
|	|		|	+-------+-------+-------+
|	|		|			|
|	|		|  <--------------------  reenter loop where it
|	|		|			  left off
|	+---------------+
|		|
|		|
 -----<---------

...donefig5
<FIGCAP><HP1>An asynchronous server using RPC_Start_Server
</HP1>
</FIG>
This is the most powerful form of server, and may be the easiest to use.
It is only available where the environment supports asynchronous response
to events.
It is useful for object oriented programming,
to also allow RPC to control an otherwise autonomous process,
or in a single tasking system, to provide a little
concurrency. 

When accessing common data structures, the user program may temparaily
disable asynchronous calls be calling the
..bf MONO
SETAST
..pf
system service provided under VMS and on the Valet&hyphen.Plus,
or the equivalent.
 
<H3>Multi&hyphen.threaded server: Identifying the client
 
<I1 IX=1>Multiple clients
If there are multiple clients for the same service, we can distinguish three
cases:
<ol>
<li>If each
service is a self&hyphen.contained operation, and no state information is held
about the client, then one server task may be directly shared by many clients.
("<hp2>Idempotent</hp2>" operations).
<I1> Idempotent operations
<li>If some calls leave the server state changed, as, for
example, when an "open" call to a file server leaves a file open,
one solution is to dedicate a separate server task to each client. This is
reasonable when a small number of clients will each use the server
intensively.
<li>If it is not practicable to
dedicate a separate process to serving each client,
and some state information must be kept by the server on behalf of each
client,
then the server must be able to determine the identity of the client.
</ol>

In the last case, the server may find, for his own information,
the address of a caller using the <hp2>RPC_caller_address</hp2> procedure.
<i1> RPC_Caller_Address
<box>
<HP1>Example</HP1> (VAX/FORTRAN)
<XMP>
        SUBROUTINE MY_REMOTE_PROCEDURE
        CHARACTER*40 CALLER_ADR
        INTEGER STATUS
	...
        CALL RPC_CALLER_ADDRESS(STATUS, %REF(CALLER_ADR))
        ...
        END
</XMP>
</box>
<H3>Making your own service ASTs
 
This section is not intended for the general user.
The routines mentioned allow specialised servers to be made,
for instance which fork extra processes off for different clients.
(This is used in the MODEL TCS system.)
The <hp2>RPC_Queue_Server</hp2> procedure allows a user program
<I1>RPC_queue_server
to queue its own AST procedure to service the next request.

<I1 IX=1>RPC_Service
<hp2>RPC_service</hp2> is a procedure taking one rpc_message parameter.
It will handle one incoming call message, deallocate the message
buffer passed to it, and return. It is a suitable AST routine to be passed
to RPC_Queue_Server, or may be called from a specially written user routine.
See the description of these routines in the appendix.

<H3>LOCAL servers
 
<I1 IX=1>LOCAL addressing
<I1 IX=1>Address LOCAL
It is possible that one wants
a package to be either remote or local, as selected at runtime.
 
In this case, one has to link (bind) the server and client into the
same program.
<FIG ID=FIG6 PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig6
<PICTURE NAME=fig6$$$S>
..go donefig6
...skipfig6
..tb 9 17 25 33 41 49 57 65 73
         +---------------------------------------+
         |      Application (client)             |
         +---------------------------------------+
            entry points->   |
         +---------------------------------------+
         |      Client stub                      |
         +---------------------------------------+
                                       |
                          +---------------------------------------+
                          |          RPC Run Time Support         |
                          +---------------------------------------+
                                       |
         +---------------------------------------+
         |      Server stub                      |
         +---------------------------------------+
         same entry points-> |
         +---------------------------------------+
         |      Server Routines                  |
         +---------------------------------------+
...donefig6
<FIGCAP><HP1>A LOCAL call is made to a procedure which is in fact part of
the same process. The Server routines and the client stub provide
entry points with the same name.
</HP1>
</FIG>
<I1 IX=1>Binding, local servers 
This has to be done carefully, as two sets of entry points
with the same name will exist.
This is because the client stub provides the same routine
names as the server module.
Logically, what must be done is as follows.
The client must call entry points in the client stub, rather
than call the server module directly.
Therefore, the client and client stub should be linked togther as one
part,
and the server and server stub must be linked together as another.
Then, these two resulting parts are linked together into one whole.
The method of performing this logical operation differs from
system to system, and is not discussed here in detail.
 
Now, the system may be set up so that the client and server stubs
are directly connected.  In this case, when the client stub is called,
the message it produces is passed straight to the server stub,
which calls the procedure in question.
The <medium address> used to set this up is
LOCAL .
 
If a different RPC address is used, and RPC_Switch called, for example,
calls will be redirected to a remote process.
<H2>Calls within calls - CALLBACK
<I1 IX=1>CALLBACK addressing
The RPC system is reentrant, so that one remote procedure may
call another remote procedure.

A useful special case of this is when a remote procedure
calls back routines in the caller. This is known as "CALLBACK".
For example, a routine to display the state of a remote moinitoring
task might call back a routine in the caller to print out each line.
In that way, whoever calls the procedure, the output will arrive in
the correct place.

<FIG ID=FIG7 PLACE=INLINE  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig7
<PICTURE NAME=fig7$$$S>
..go donefig7
...skipfig7
..tb 9 17 25 33 41 49 57 65 73
		Machine A			Machine B

		+-------+
		| Appl.	|
		| prog.	|
		+-------+
			 ------- call ------>
						+-------+
						|DISPLAY|
						|STATE	|
						+-------+
			  <----- callback -----
		+-------+
		|PRINT	|
		| LINE	|
		+-------+
...donefig7
<FIGCAP><HP1>Callback allows the server to call routines in the client's
process. Each process is therefor a client (c) of one call and a server (s)
of the other.
</HP1>
</FIG>

This takes advantage of the fact that
<hp2>any client, while waiting for a reply, automatically behaves as
a server.</hp2>

The package called back must be defined as a separate package,
and separate client stubs (for machine B) and server stubs (machine A)
generated and linked in.
On machine B,
the special syntax for the address of the callback package address
is
<xmp>
		<package number> @ CALLBACK
</xmp>
In this case,
<ul>
<li>The package number must be explicitly stated (normally 0).
(This is because the address is only valid within an RPC.
If you don't give the package number explicitly, the RPC
system would have to query the other side at initialisation time
to determine the package number. It can't do that because at
initialisation time, no caller is defined.)
<li>The initialisation on machine B (RPC_open or open_xxx) only
happens once;
<li>Callback calls may ONLY be made from within remote procedures:
the address is
effectively undefined outside these.
<li>The RPC system will use the same connection for the call back as
for the original call (over DECNET for example).
</ul>
This system is not suitable if you want the server process to call the
client back outside (some time after) the original call.
In this case, a new channel must be opened with the "@CALLER"
syntax (q.v.).
<H2>Client facilities for selecting servers
<FIG ID=FIG8 PLACE=FLOAT  FRAME=NONE>
..if "&SYSTERMT" ne "APA6670" and "&SYSTERMT" ne "I3820" ..th ..go skipfig8
<PICTURE NAME=fig8$$$S>
..go donefig8
...skipfig8
..tb 9 17 25 33 41 49 57 65 73
			+--------+
			|        |
			| Client |
			|        |
			+----|---+
		             |
	    . . . . . . . . .+--------------+ . . . . . . . .
	    .               .               |               .
	+-------+	+-------+	+---|---+	+-------+
	|	|	|	|	|	|	|	|
	| Server|	| Server|	| Server|	| Server|
	|   A	|	|   B	|	|   C	|	|   D	|
	+-------+	+-------+	+-------+	+-------+
...donefig8
<FIGCAP><HP1>A client may wish to select one from a set of
similar servers dynamically.
</HP1>
</FIG>
This section applies when there may be
more than one instance of the same type of server
in the system.
In this case, the client program may wish
to select one particular server at run time.
 
<I1 IX=1>Multiple servers
<I1 IX=1>Servers, multiple
<I1 IX=1>Binding, run time
There are two ways of doing this.
The first method (using RPC_Switch)
allows communication to be set up with one server at a time.
The second method (using RPC_Open and RPC_close)
allows communication to be established with more than one
server at once, the client being able to switch rapidly between them.
 
The "binding" of the client to the server refers to the resolution
of the server address, and the setting up of communication channels to
the server.
This is normally done by the stub itself when the open_xxxx routine
in the stub is called at initialisation time.
<fn>
Under VMS and TurboPascal, binding is performed automatiaclly by the client
stub at initialisation time.
If explicit binding is to be done by the user program,
the NOAUTOINIT option should be used when the client stub is compiled,
to disable automatic binding.
</fn>
<i1 ix=1> NOAUTOINIT, for explicit binding
The result is a reference number called a <hp2>handle</hp2> which
refers to the open connection. This is stored in a global variable
called h_xxxx where xxxx is the name of the package.
<h3> Reconfiguring the system
The
<hp2>RPC_configure</hp2>
<I1 IX=1>RPC_configure
<I1 IX=1>Reconfiguration
call allows one client to use more than one identical server in turn.
The effect is for the connections to all open servers to be closed and reopened
with the translation of their logical names being perfomed according to
new values which may have been set up.
 
A client process which wishes to use several identical servers may therefore
repeatedly redefine the logical names which give the addresses of those servers,
and call RPC_configure to cause future calls to be directed to the new
servers.

<hp1>Note that if RPC_Configure returns a bad status, then one or all of the
handles will be invailidated. In this case, as the user has no way of
knowing which are valid and  which are invalid, all he can do is exit.
The use of RPC_Configure is not, therefore, recommended.
</hp1>

The <hp2>RPC_Switch</hp2>
<I1 IX=1>RPC_Switch
<I1 IX=1>Binding, run time 
<I1 IX=1>Handle switching
routine performs the reconfiguration function on a single package,
referenced by a handle. The package must be already open
(for the handle to be valid).
The value of the handle is unchanged.
 
<h3> Explicit binding

The RPC_Open and RPC_Close routines allow the user to perform the
binding himself, and overwrite the handle used by the stub.

The <hp2>RPC_Open</hp2>
<i1 ix=1>RPC_Open
<i1> Binding, explicit
routine allows a client to open communication with a specific server.
A string parameter describes the remote service required. It may be a formatted
physical address (program name or number, network address, etc) or it may
be a logical name which is converted by the run&hyphen time system into
an appropriate address.
 
The handle value returned is used in all future reference to the
service by the client.
If this value is put into the handle variable used by the stub,
the stub will be directed to refer to the server in question.
The handle variable used by the stub should be accessed as an external variable
h_xxx where xxx is the package name.

The client program may, however, perform RPC_Open serveral times,
and keep a record of each of the handle values returned.
It may then switch rapidly between servers by overwriting the stub's
handle variable with the handle to the server it wants to access.
 
Every server which has been opened must be closed again by calling
<hp2>RPC_Close</hp2>.
<i1 ix=1>RPC_Close 
 
<H2>User Error Handling
<I1 IX=1>RPC_Establish
<I1 IX=1>Errors, user handler 
<I1 IX=1>User error handler
<I1 IX=1>Handler, user error 
 
The <hp2>RPC_Establish</hp2> procedure may be used in
a client program to handle errors occuring in remote procedure calls.
By default, if an unrecoverable error occurs in the communication with the
server, a message is displayed and the client program is stopped.
($EXIT occurs under VAX/VMS, a pascal halt on other systems.)
 
If the user wishes to handle the error himself, he passes the address of
his error handler to RPC_Establish.
If this has been done, his handler will be called
<HP1>instead</HP1>
of the default handler.
 
<I1 IX=1>Errors, default handler 
In order to revert to the default handler, RPC_Establish is called with
a value of zero.

<box>
<HP1>Example</HP1>  (VAX FORTRAN):
<XMP>
		EXTERNAL HANDLER
                ...
                CALL RPC_ESTABALISH(HANDLER)
                CALL MY_REMOTE_PROCEDURE
                CALL RPC_Establish(0)
                ...
</XMP>
</box>
The user error  handler is a routine taking one parameter,
which is the rpc_message in  question.   If the user is programming in
pascal, he will find the offending error status in the m_status
field of the rpc_message.

<box>
<HP1>Example</HP1>  (VAX Pascal):
<XMP>
   VAR     global_status:  [VOLATILE] rpc_status;  { error flag }
 
   ...
 
   [UNBOUND, ASYNCHRONOUS] PROCEDURE handler(p: rpc_message_pointer);
   BEGIN
           global_status := p^.m_status;           {record bad status }
   END;
        ...
</XMP>
 
  
<HP1>In main program</HP1>:
<XMP>
        global_status := SS$_NORMAL;    { Initialise error flag }
        RPC_Establish(handler);         { Establish my error handler }
        my_remote_procedure;            { Try calling remote module }
        RPC_Establish(%IMMED 0);        { Reselect default handler }
        IF not odd(global_status)       { Check error flag }
                THEN ...
</XMP>
Note that [UNBOUND],  [ASYNCHRONOUS],  [VOLATILE]  are
all attributes which prevent the VAX Pascal  compiler overoptimising the error
handler, so that it will still work when called out of context.
</box> 
<H2>Message format control - The ALIGN option.
 
<I1 IX=1>ALIGN
This option controls the formatting
(invisible to the user) of messages sent by the stubs.
/ALIGN selects or deselects word alignment of parameter values
which is less space&hyphen.efficient, but Courier compatible.
It is not recommended.
 
The ALIGN option MUST be the same for corresponding client and server stubs.
 
For microprocessor stubs, the ALIGN choice is built into the
runtime library, and cannot be selected by the stub.
The microprocessor libraries provided with the RPC
software are generated without ALIGN.
 
For VAX/VMS, the ALIGN option may be selected when building the stub:
<OL>
<LI>
If using the RPC command, NOALIGN is the default, and /ALIGN must be specified
as a command line parameter
if Courier compatability is required.
<LI>If you are using explicit postprocessing of the stubs (discussed below),
NOALIGN is the default, unless the keyword ALIGN is included in the
<I1 IX=1>INCLUDE
INCLUDE keyword list.
</OL>

<H2>Timeouts on remote calls
 
<I1 IX=1>Timeouts, on RPCs 
In some cases, where the communication medium and protocol used
is unreliable, or where
the remote software may be unreliable, one wants to specify the
maximum time for execution of a remote routine.

The timeout may be specified in two ways.
PRAGMA TIMEOUT <hp1>(q.v.)</hp1> may be specified in the RPC definition file,
in which case it is given separately for each procedure.

Alternatively, the defualt timeout for the package may be specified on the
compiler command line when generating the client stubs, using the option
<xmp>
		TIMEOUT=nnnn
</xmp>
where nnnn is the time limit
<hp2>in units of 10ms</hp2>.
For example, the option
..bf MONO
TIMEOUT=1000
..pf
selects a timeout of ten seconds.
 
Allowance should be made for any delays which could occur in the transmission
of messages, or due a machine being heavily loaded.
This ensures that timeouts only
occur when a real problem has arisen.
 
If a timeout occurs on a remote call, it is treated as an error.
That is, the client program will stop with an error message, unless a
user error handler (discussed above) is declared,
or a call_status (q.v.) parameter is given.
<H2>Stub Version Numbers
 
By default, the RPC compiler generates a version number from the
RPC interface definition file.
This 4 digit number is displayed on the
standard output by the compiler, and inserted as a comment into the
external definition (.ext) file produced.
It is also compiled into the stub code.
 
At run time, the client stub sends a version number to the server stub,
which checks it against its own version number.
If the version numbers do not match the request is rejected,
and the error message "incompatible versions" is produced at the client.
This ensures that the two stubs were generated from the same definition file,
and will therefore refer to compatible modules.
The version number is formed from a checksum of the non&hyphen.comment
characters in the definition,
and so will change when a material alteration to the package definition
is made.
 
In some cases, it is possible to make a small change to a package
which will not cause serious compatabilty problems.
For instance, the procedure names may be changed,
another procedure is added
<HP1>to the end</HP1> of
the package definition,
or a modification is made to a procedure which has in fact never yet been used.
In this case it is possible to force the stubs to a have a particular
version number, with the
version=
<number> option.  The version number must be an integer between 1 and
32767. Numbers between 1 and 999 will not be generated automatically
by the compiler, and so may be used for a private version numbering scheme.
 
<HP1>Example</HP1>:
 
Suppose there is a requirement that the procedure names on the client
machine should differ from those on the server.
This may be required to prevent a clash, for example, between
local and remote versions of the same procedure, so that the same
program can access either.
 
In this case, two RPCL files are made, which differ only in the
procedure names. The server stub is compiled first, with an
automatically generated version number, and then the client stub is compiled
with the version number forced to be compatible.
<XMP>
        $ RPC MYSTUB1.RPC /SVAXVMS
<P>
          RPCC: Generated stub version number is 2765
<P>
        $ RPC MYSTUB2.RPC /CVAXVMS /VERSION=2765
</XMP>
<I1 ix=1>Version numbers
<HP1>[The option
version=0
causes the RPCC to generate "unsafe" stubs with no version number check.
If use of this option later allows the inadvertent
connection of incompatible stubs,
run&hyphen.time errors
(access violations etc) may occur without the cause
of the problem being obvious.
This may lead to wasted debugging time, and so is not recommended.]</HP1>

<Appendix>
<H1> RPC Compiler command options
<i1 ix=1>Compiler, command options
<i1 ix=1>command options for compiler
The following is a list of command options accepted by the RPC compiler, RPCC.
The options must be preceded by "/" under VMS or MSDOS, "-" under Unix
or OS9.
The option names are not case sensitive.
See the chapter "Running the RPC Compiler" for more details and examples,
and also the chapter "Advanced use of RPC".
<dl TSIZE=20>
<DT>NOAUTOINIT
<DD>Suppress the automatic initialisation of the stubs
(Under VMS, PILS or TurboPascal only)
<DT>BYVALUE
<dd>Pass simple IN arguments to routines by value,
rather than by address.
This removes FORTRAN compatibility, but is normally
necessary for C compatability.
Should not be used with the SFORTRAN or CFORTRAN options.
<DT>CONCURRENT
<DD>Allow those procedures (not functions) which do not return
any results to be executed after the reply message has been
sent back, concurrently with the calling program.
See also PRAGMA CONCURRENT.
<dt>TIMEOUT=<value>
<dd>Specify the maximum time to be allowed for the completion
(at run time) of any one procedure call in this package.
An error "RPC Timeout" occurs if this time is exceeded.
The timeout value is decimal, in in units of 10ms.
[Default=no timeout]
See section 8,
and also see PRAGMA TIMEOUT.
<DT>TYPES
<DD>Causes definitions of the user-defined types (in C or Pascal)
to be included in the external declaration (.ext) file generated.
See section 8.
<DT>ALIGN
<dd>Adds an extra alignment byte in the cannonical form after
each RPC_BYTE or RPC_CHAR type. RPC command only, not RPCC.
Not recommended.
<DT>VERSION
<I1 ix=1>Version numbers
<DD>Force the version number to a specified value.
If zero is specified, supresses version number checking.
See section 8.
<lp> The following options select the generation of client stub files.
Each may optionally be followed by an equals sign and a filename e.g.
..bf MONO
cgeneric=clixxx.c
..pf
<fn>The filename may not be included with the alternative "RPC" command
described in chapter 4, only with "RPCC".
</fn>
<dt>CGENERICC
<dd>Produce a client stub file
in C langage. Note this is normally used with the BYVALUE option.
<dt>CFORTRAN
<dd>Produce a client stub in FORTRAN.
<dt>CPILS
<dd>Produce a client stub in PILS (Portable Interactive Language System)
<dt>CCERNCROSS
<dd>Produce a client stub file
in Pascal suitable for the CERN cross software.
<dt>CM6809
<dd>Produce a client stub file
suitable for the Omegasoft Pascal compiler for the M6809.
<dt>CVAXVMS
<dd>Produce a client stub file
suitable for the VAX/VMS pascal compiler 'VAX/Pascal'.
<dt>CUNIXBSD
<dd>Produce a client stub file
suitable for the Berkley Unix 4.2, 4.3 pascal compiler 'pc'.
<dt>CPCTURBO
<dd>Produce a client stub file
suitable for a TurboPascal (IBM PC or Macintosh) compiler.
<DT>CMONOLITH
<dd>Produce a client stub file
suitable for a non&hyphen.module monolithic Pascal compilation.

<lp> The following options select the generation of server stub files.
Each may optionally be followed by an equals sign and a filename eg
..bf MONO
sgeneric=serxxx.c
..pf
<fn>The filename may not be included with the alternative "RPC" command
described in chapter 4, only with "RPCC".
</fn>
<DT>SGENERICC
<dd>Produce a server stub file
in C langage.
<dt>SFORTRAN
<dd>Produce a server stub in FORTRAN.
<dt>SPILS
<dd>Produce a server stub in PILS (Portable Interactive Language System)
<DT>SCERNCROSS
<dd>Produce a server stub file
in Pascal suitable for the CERN cross software.
<DT>SM6809
<dd>Produce a server stub file
suitable for the Omegasoft Pascal compiler for the M6809.
<DT>SVAXVMS
<dd>Produce a server stub file
suitable for the VAX/VMS pascal compiler 'VAX/Pascal'.
<DT>SUNIXBSD
<dd>Produce a server stub file
suitable for the Berkley Unix 4.2, 4.3 pascal compiler 'pc'.
<DT>SPCTURBO
<dd>Produce a server stub file
suitable for a TurboPascal (IBM PC or Macintosh) compiler.
<DT>SMONOLITH
<dd>Produce a server stub file
suitable for a non&hyphen.module monolithic Pascal compilation.

<lp> The following options are only useful for development and maintenance of
the compiler. They show the operation of the compiler at some low level
and are of no interest for the normal user. Their setting does not
influence the operation of the compiler itself and the output code
obtained with these switches set is unaffected.
These options can be mixed in any combination.
<DT>DTREE
<DD>Prints the tree of types and blocks. The compiler generates on the
standard output a list of type and procedures definitions after the input
parsing. This could be useful if you want to check whether the compiler really
understood your definitions. The file '.ext' produced by the compiler is
another way to check this consistency.

The maximum and minimum estimated sizes of parameters passed to and
from each routine are also listed.
<DT>DLEX
<DD>For debugging lexical analiser. Print each input line and the tokens that
are extracted from this line. Only useful for upgrading and maintenance.
<DT>DLEXHOT
<DD>For debugging the lexical analiser. Print each character read from input.
Only useful for upgrading and maintenance.

</dl>
<H1> RPC Library Routines Reference

There follows a list of those library routines which may be called
by application code in order to perform functions above those of
pure remote procedure call.  The methods and reasons for calling these
are described in earlier chapters.
Many of these routines are documented here only for completeness,
and will never be called by the user.

Note that although the stubs produced by the RPC compiler
are deliberately matched to FORTRAN or C calling conventions,
these library routines exist only in one form, and the caller is
required to ensure that the calling conventions outlined below are met.

<h2> Types
The data types refered to in this chapter are as follows.
For pascal, a declaration file (logical name rpc_proc)
exists. If you use a different language, ensure that the data types
and calling conventions match,
given the operating system and language you are using.

<box>
* Under VMS, The simple types which are normally passed by value are in
fact always passed by address when using the libraries rpc$lib or rpc$large.
(A feature of VMS Pascal, for FORTRAN compatibility).
See also notes under rpc_name and entry_point types.
</box>

<dl>
<DT>rpc_status
<DD>A 32 bit integer. This is normally passed by address, as it is
returned from the procedure.
<DT>rpc_name
<DD>A 40 character fixed length string,
padded with spaces. This is always passed by address.

Users of VAX FORTRAN must be sure to include a %REF() around the
parameter to prevent it being passed by descriptor.

If you are calling these routines from C, and using
a library which is not in C (ie RPC$LIB, RPC$LARGE under VMS,
and libraries for M6809, MoniCa, RMS68k), you must always
provide 40 characters.
The RPC library in C (rpc$libc and rpc$libc8k on vms, and
libraries on unix, os9 and the PC) will also accept zero-terminated strings
up to a maximum of 40 characters plus terminator as IN parameters.
Also be aware that the RPC system will not
add a '&bsol;0' null character on the end of a returned string.
<DT>socket
<dd>The RPC system uses a 32 bit
"socket"
<I1 IX=1>Socket, definition of 
to refer to a communication
channel to a remote task.
This is just a reference number used by the commmunications code
within the RPC system.
<DT>handle
<I1 IX=1>Handle, definition of 
<DD>A different reference number, which on a client machine refers to
one remote package.
There is a handle (32 bit) for each package. It is a global
variable, and accessible as h_ followed by the package name.
For example, the handle for the FILER package is h_filer.
<DT>rpc_message_pointer
<DD>The system uses a data structure called an
<hp2>"rpc_message"</HP2>
<I1 IX=1>rpc_message, definition of
to hold
all the information about a remote call. This includes its status
and pointers to the socket which is being used for communication with
the remote party.
It is not normally necessary for the user to know the format of this
structure, but in some cases he may want to pass a pointer
to it from
one routine to another.
 
(For the format of an rpc_message, see the rpc_types include file,
as this contains several fields used internally by the RPC RTS, which may be
changed between versions.  It is not recommended that user code uses this
buffer directly, but calls RPC_Service to have it serviced.)

An rpc_message_pointer is a pointer to an rpc_message.
<dt>entry_point
<dd>This is the address of a routine.

Under VAX/FORTRAN, the parameter must be enclosed in %LOC() in order
to simulate its being passed as a VAX11 bound procedure value.
</dl>

<h2> Library Routines

The routines are listed for reference in alphabetical order.
For a pascal declaration file for these routines, see the file
rpcproc.h (logical name rpc_proc under VMS).
<box>
..bf TITLE
..ra RPC_ACCEPT
<I1 PG=MAJOR> RPC_accept
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status	by address
<li>IN	s	socket		by value*
<li>IN	timeout	integer		by value*
</ol>
<DT>Effect
<DD>This routine
waits for a single request on the given socket, and services it
according to the currently attached stub modules.

The socket, s, must be a value returned by a previous call to
rpc_create_server.
  
The timeout is specified in units of 10ms. If no request arrives during
the timeout period, then a status value of RPC_s_timeout is returned.
A timeout value of 0 allows an outstanding request to be serviced without
waiting for a new one. A value of -1 may be used to specify an infinite
timeout.

A maximum of one request is handled per call to RPC_accept.
</dl></box>

<box>
..bf TITLE
..ra RPC_ATTACH_STUB
<I1 PG=MAJOR> RPC_attach_stub
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status		rpc_status	by address
<li>IN	stub		entry_point	by value*
<li>IN	service		rpc_name	by address
<li>OUT	pkg_no		integer	by address
</ol>
<DT>Effect
<DD>The server stub is declared. The 'stub' parameter must be the
entry point of the server stub routine.
The 'service' parameter must be the name of the service
(normally as declared in the package definition file).
The returned 'pkg_no' parameter is the package number allocated
to the stub (0 for the first one, 1 for the next, etc) which may
be used by the client as an explicit address, or may be passed to
RPC_DETACH_STUB.
<DT>Note
<DD>Called by stubs only. Not called by user application code.
</dl></box>

<box>
..bf TITLE
..ra RPC_CALL
<I1 PG=MAJOR> RPC_call
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>IN		handle	integer			by address
<li>IN OUT	p_buf	rpc_message_pointer	by address
<li>IN		timeout	integer			by value*
</ol>
<DT>Effect
<DD>A remote call is made. The 'handle' parameter must be a value
previously returned by a call to RPC_OPEN. The p_buf parameter is
a pointer to the buffer.

If an error occurs, the program is stopped with a message, or a user
error handler is called. In the latter case, the stack is unwound
to cause a premature exit from the caller (the stub)
as to continue to unpack parameters could cause further errors.
<DT>Note
<DD>Called by stubs only. Not normally called by user application code.
</dl></box>

<box>
..bf TITLE
..ra RPC_CALL_STATUS
<I1 PG=MAJOR> RPC_call_status
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>IN		handle	integer			by address
<li>IN OUT	p_buf	rpc_message_pointer	by address
<li>IN		timeout	integer			by value*
</ol>
<DT>Return value
<DD>Call status, type rpc_status, VMS format
<DT>Effect
<DD>A remote call is made. The 'handle' parameter must be a value
previously returned by a call to RPC_OPEN. The p_buf parameter is
a pointer to the buffer.

If an error occurs, it is reflected in an even return value
with the VMS (facility, message, severity) format.
If no error occurs, the return value is RPC_S_NORMAL (=1).
<DT>Note
<DD>Called by stubs only. Not normally called by user application code.
</dl></box>

<box>
..bf TITLE
<I1 PG=MAJOR> RPC_caller_address
..ra RPC_CALLER_ADDRESS
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT		status	rpc_status	by address
<li>OUT		name	rpc_name	by address
</ol>
<DT>Effect
<DD>Returns the RPC address of the process which called the current
procedure.
The format for an ethernet connection will be in the normal RPC format
with an explicit packet type, for example
<xmp>
		AA0004002F58_5050.ETHERNET
</xmp>

For a DECNET connection to a multiclient server, the address will be
the RPC address of the client process, assuming that it has started
a server with the name of the process as DECNET object name:
<xmp>
		VXCRNA::"0=FRED".DECNET
</xmp>
<DT>Note
<DD>Called by application code in a server procedure to find out
the name of the client who called it.
This routine must be called from within a remote procedure,
as only then is the "current client" defined.
Returns an RPC address blank
filled.
<DT>Note
<DD>Not available on M6809.
</dl></box>

<box>
..bf TITLE
..ra RPC_CLOSE
<I1 PG=MAJOR> RPC_close
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status	by address
<li>IN	handle	handle_type	by value*
</ol>
<DT>Effect
<DD>The reverse of RPC_OPEN. The handle specified becomes invalid
for use in future calls.
</dl></box>

<box>
..bf TITLE
..ra RPC_CONFIGURE
<I1 PG=MAJOR> RPC_configure
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status	by address
</ol>
<DT>Effect
<DD>Retranslates the logical name of each open package.
For each one which has changed, closes the communication channel and
reopens it with the new address. See also RPC_switch.
<DT>Note
<DD>Called by a client program.
</dl></box>

<box>
..bf TITLE
..ra RPC_CREATE_SERVER
<I1 PG=MAJOR> RPC_create_server
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status		by address
<li>IN	client	rpc_name		by address
<li>OUT	s	socket			by address
</ol>
<DT>Effect
<DD>Initialises a server, opening the communication channel where
necessary. The socket returned may be used by future calls to RPC_ACCEPT.
Used when writing a "polling server".
</dl></box>

<box>
..bf TITLE
..ra RPC_DETACH_STUB
<I1 PG=MAJOR> RPC_detach_stub
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>IN	pkg_no	integer		by value*
</ol>
<DT>Effect
<DD>Opposite to RPC_ATTACH_STUB. The server stub is disconneted from the
RPC system, and can no longer be accessed by a client.
<DT>Note
<DD>Called by server stubs only. Not called by user application code.
</dl></box>

<box>
..bf TITLE
..ra RPC_DISPOSE
<I1 PG=MAJOR> RPC_dispose
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>IN	P	rpc_message_pointer	by value*
</ol>
<DT>Effect
<DD>Opposite of rpc_new. The message buffer is deallocated (returned
to the pool).
<DT>Note
<DD>Called by client stubs only. Not called by user application code.
</dl></box>

<box>
..bf TITLE
..ra RPC_EARLY_RETURN
<I1 PG=MAJOR> RPC_early_return
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>INOUT	P	rpc_message_pointer	by address
</ol>
<DT>Effect
<DD>The message is returned to the caller.
This is normally done automatically by the runtime system, but in
some cases (/concurrent option) the stub may wish to force an early
return, before futher processing.
<DT>Note
<DD>Called by server stubs only. Not called by user application code.
</dl></box>

<box>
..bf TITLE
..ra RPC_ESTABLISH
<I1 PG=MAJOR> RPC_establish
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>IN	handler		entry_point	by value*
</ol>
<DT>Effect
<DD>Deletes any previous user error handler. Establishes the specified handler
such that whenever a fatal error occurs during an RPC call,
the user error handler will be called, and passed the offending message
as a parameter.
On return from the user error handler (under VMS or on the M680x0), the
stack will be unwound to prevent the rest of the stub from executing,
and return will be made to directly to the user program after the remote call.
</dl></box>

<box>
..bf TITLE
..ra RPC_HARDWARE_RESET
<I1 PG=MAJOR> RPC_hardware_reset
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status		rpc_status	by address
<li>IN	handle		integer	by address
</ol>
<DT>Effect
<DD>Finds the physical address of the hardware of the server in use,
and performs (if possible) a physical reset function on it.
</dl></box>

<box>
..bf TITLE
..ra RPC_INIT
<I1 PG=MAJOR> RPC_init
..pf
<dl>
<DT>Parameters
<DD>None
<DT>Effect
<DD>Initialises the entire RPC run time system.
<DT>Note
<DD>Need not be called under VAX/VMS or Turbopascal.
</dl></box>

<box>
..bf TITLE
..ra RPC_LOOP_SERVER
<I1 PG=MAJOR> RPC_loop_server
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status	by address
<li>IN	client	rpc_name	by address
</ol>
<DT>Effect
<DD>A communication channel is opened, and any requests received
serviced. The routine loops until an error occurs, then closes the
communication channel.
<DT>Note
<DD>This is the routine called by the default SERVERLOOP main program.
</dl></box>

<box>
..bf TITLE
..ra RPC_NEW
<I1 PG=MAJOR> RPC_new
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	p	rpc_message_pointer	by address
<li>IN	size	integer			by value*
</ol>
<DT>Effect
<DD>Allocates an rpc buffer for a future call. The size parameter is
currently ignored.
<DT>Note
<DD>Called by stubs only. Not called by user application code.
</dl></box>

<box>
..bf TITLE
..ra RPC_OPEN
<I1 PG=MAJOR> RPC_open
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status	by address
<li>OUT	handle	integer		by address
<li>IN	service	rpc_name	by address
</ol>
<DT>Effect
<DD>This is the binding routine.
It establishes communication with a server for the package specified
in the 'service' parameter. This may be a logical name or a physical
RPC address.  The 'handle' parameter returned is used by the stub in all
calls, and in any call to RPC_CLOSE.
</dl></box>

<box>
..bf TITLE
..ra RPC_QUEUE_SERVER
<I1 PG=MAJOR> RPC_queue_server
..pf
<dl>
<DT>Note
<DD>This is only used when one is making a special multitask server.
(Eg MODEL TCS Terminal Control System).
Not normally called by user code.
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status		rpc_status	by address
<li>IN	s		socket		by value*
<li>IN	action		entry_point	by value*
<li>IN	dummy		integer		by value*
</ol>
<DT>Effect
<DD>An asynchronous receive request is queued for the server socket
given, such that the 'action' routine will be called when the next
request arrives.
(The last parameter is dummy).

This routine queues an asynchronous user routine (AST) to be called when the
next request arrives on the given socket (see RPC_Create_Server). It allocates
space for the incoming message, and passes the address of this to the AST
routine.
<I1 IX=1>AST user
The user AST
routine has entry point astadr and is passed by address one parameter
(M, of type RPC_message).
This parameter is suitable to be passed to RPC_Service (see below).
 
This parameter is all that is required by the service routine below: the user
program may, however, want to perform some pre- or post- processing, such
as forking off other tasks to handle the requests, or application functions.
</dl></box>

<box>
..bf TITLE
..ra RPC_REPORT_ERROR
<I1 PG=MAJOR> RPC_report_error
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>IN	status	rpc_status	by address
</ol>
<DT>Effect
<DD>Logs an error message corresponding to the given status code.
Under VAX/VMS, causes an image EXIT, with the status code as
exit status.
</dl></box>

<box>
..bf TITLE
..ra RPC_SERVICE
<I1 PG=MAJOR> RPC_service
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>IN	p	rpc_message_pointer	by address
</ol>
<DT>Effect
<DD>Services the request specified in the message pointer to by 'p'.
The return message is sent. Note that on VMS, pointer is passed by address,
unlike the parameter to the user AST routine of RPC_Queue_Service.
</dl></box>

<box>
..bf TITLE
..ra RPC_START_SERVER
<I1 PG=MAJOR> RPC_start_server
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status	by address
<li>IN	client	rpc_name	by address
</ol>
<DT>Effect
<DD>An asynchronous server is started.
That is, a communication channel is opened,
and an asynchronous read request is queued on that channel.
When the read completes, the RPC system services the request and queues
another read, so that the server continues to run.

The set of clients to be serviced is identified by the string
parameter, which
may in some cases include wildcards.  The procedure
returns immediately, but from then on any requests coming in
are serviced asynchronously.
The effect is as though RPC_Accept (q.v.) were called automatically
whenever a request arrives.
</dl></box>

<box>
..bf TITLE
..ra RPC_SWITCH
<I1 PG=MAJOR> RPC_switch
..pf
<dl>
<DT>Parameters
<DD><OL COMPACT=1>
<li>OUT	status	rpc_status	by address
<li>IN	handle	integer		by address
</ol>
<DT>Effect
<DD>Retranslates the logical name of the package.
If it has changed, closes the communication channel and reopens it.
</dl></box>

<H1>Supported data types
 
<I1 IX=1>Data types
<I1 IX=1>Calling conventions
The following types are supported by the RPC Compiler.
For each type, the representation in each high level language is given.
 
The principal constraint is that variable length arrays must be passed
as two parameters, firstly an array, and secondly the number of elements
in that array.  This is refered to as a SEQUENCE.
<I1 IX=1>SEQUENCE
<I1 IX=1>Array, variable length 
<H2>Simple Types
<DL>
<DT>RPC_BYTE
<DD>
An unsigned 8 bit long value.
<I1 IX=1>BYTE
<DL TSIZE=20>
<DT>C
<DD>
..bf MONO
unsigned char
..pf
<DT>Standard Pascal
<DD>
..bf MONO
1..255
..pf
<DT>M68k Pascal
<DD>
..bf MONO
PACKED 1..255
..pf
<DT>Omegasoft Pascal
<DD>
..bf MONO
BYTE
..pf
<DT>TurboPascal
<DD>
..bf MONO
BYTE
..pf
<DT>VAX/FORTRAN
<DD>
..bf MONO
BYTE or LOGICAL*1
..pf
</DL>
<DT>RPC_CHAR
<DD>
<I1 IX=1>Character single
A character in the local coding
convention, converted by the RPC system if necessary
to/from ASCII.
<DL TSIZE=20>
<DT>C
<DD>
..bf MONO
char
..pf
<DT>Pascal
<DD>
..bf MONO
CHAR
..pf
<DT>FORTRAN
<DD>
..bf MONO
CHARACTER*1
..pf
</DL>
 
<DT>RPC_SHORT
<DD>
A 2's complement 16 bit long value.
<DL TSIZE=20>
<DT>C
<DD>
..bf MONO
short int
..pf
<DT>Standard Pascal
<DD>
..bf MONO
-32768..32767 (on 32 bit machine)
..br
INTEGER (on 16 bit machine)
..pf
<DT>M68k Pascal
<DD>
..bf MONO
PACKED -32768..32767 
..pf
<DT>VAX/FORTRAN
<DD>
..bf MONO
INTEGER*2
..pf
</DL>
 
<DT>RPC_LONG
<DD>
<I1 IX=1>long integer
<I1 IX=1>integer short
A 2's complement 32 bit long value.
<DL TSIZE=20>
<DT>C
<DD>
..bf MONO
long int
..pf
<DT>Standard Pascal
<DD>
..bf MONO
INTEGER
..pf
(32 bit machine)
(normally a record on 16 bit machine).
<DT>M68k Pascal
<DD>
..bf MONO
INTEGER
..pf
<DT>Omegasoft Pascal
<DD>
..bf MONO
LONGINTEGER
..pf
<DT>TurboPascal
<DD>
..bf MONO
LONGINT
..pf
<DT>VAX/FORTRAN
<DD>
..bf MONO
INTEGER*4
..pf
</DL>
 
<DT>RPC_INTEGER
<DD>
<I1 IX=1>integer generic
A 2's complement 16 bit long value which is represented in the machine
in the local standard integer length (32 bit for M68k and VAX/VMS).
This allows 16 bit and 32 bit systems to exchange data between programs
which each use the local INTEGER type.
Only 16 bits are actually transferred.
If an attempt is made to pass more than 16 bits, the upper 16 bits are
simply lost, and no error is generated.
 
<HP1>Experience shows that using RPC INTEGER where appropriate
(as opposed to RPC LONG or RPC SHORT)
leads to smoother porting of software between systems</HP1>.
<DL TSIZE=20>
<DT>C
<DD>
..bf MONO
int
..pf
(32 or 16 bit machine)
<DT>Any Pascal
<DD>
..bf MONO
INTEGER (32 or 16 bit machine)
..pf
<DT>FORTRAN
<DD>
..bf MONO
INTEGER
..pf
</DL>
 
<DT>RPC_REAL32
<DD>
Real numbers, 32 bit.
 
These are passed in the local representation
and converted by the RPC system if necessary.
In the future, RPC_REAL48, RPC_REAL64 and RPC_REAL128 may be
supported too.
Consult the documentation for the compiler of your
machine about the floating point number format.
 
As format conversion may take place in transferring real numbers,
it is possible that small rounding errors occur.
As the ranges of real numbers differ, very small numbers may be
rounded down to zero, and large ones may cause an "overflow"
conversion error.
<DL TSIZE=20>
<DT>C
<DD>
..bf MONO
float
..pf
<DT>Turbo Pascal
<DD>
..bf MONO
SINGLE
..pf
<DT>Other Pascal
<DD>
..bf MONO
REAL
..pf
<DT>FORTRAN
<DD>
..bf MONO
REAL
..pf
</DL>
</DL>
<H2>Structured Types
 
<DL>
<DT>STRING
<DD>
<I1 IX=1>String
<I1 IX=1>Character, string of 
A string is a variable length array of characters.
Its declaration in RPCL must specify the maximum number of characters
which are ever going to be passed, so that the compiler knows how much
space to allocate at the receiving end.
 
With the exceptions noted below, a string is passed as
two parameters,
the first to give the character array, and the second the length.
The first parameter is an array  of CHAR.
The second parameter is of type RPC_INTEGER, and indicates the
number of valid characters actually in the string.
 
In C, a string is passed as one paremeter, a pointer to
its first character.
The string is terminated by a '&bsol;0'  (null) character.
 
For VAX/FORTRAN (options FORTRAN or VAXVMS),
the string is passed as one parameter,
a string descriptor.
This is the standard for VAX/FORTRAN, but not for the
other
<FN>
In the client, to call a procedure with a string
parameter from VAX/Pascal, it is necessary to include the %STDESCR
before the parameter to force FORTRAN conventions, but then any Pascal
string or varying of char can be passed.
In a server, in order to write a
Pascal procedure which takes a string parameter, it is necessary to declare
the parameter
as a RECORD with the string descriptor format, and explicitly access the
length and pointer within it.
See the VAX/VMS manual for
futher details.
</FN>
VMS languages.
The length field of a string descriptor is never changed. If an OUT string
has a different length from the receiving descriptor on the client,
it is truncated or
blank filled.
On the server, for an IN parameter, a descriptor is generated
the same length as the client's string.
The string should be declared in the RPCL with a length greater than or
equal to the maximum string size which will ever be used for that parameter,
in the client or in the server.
 
On the M6809, and under TurboPascal,
the string is passed as a single STRING argument, a byte array
with the current length in position 0 and the characters in positions
1 to <length>, with a maximum length of 126.

The figure of 80 below is used only as an example: the only upper limit
imposed by the RPC system is 32767.
 
<DL>
<DT>RPCL
<DD>
..bf MONO
TYPE mystring IS STRING(80);
<P>
PROCEDURE proc_name(..; thestring: IN OUT mystring; ...);
..pf
<DT>C
<DD>
..bf MONO
typedef char mystring[81];
<P>
proc_name(..., the string, ...);
<P>
 ...
<P>
mystring thestring;
<P>
..pf
<DT>Pascal
<DD>
..bf MONO
TYPE mystring  = PACKED ARRAY [1..80] OF CHAR;
<P>
PROCEDURE proc_name(...
<P>
       VAR s: mystring,
<P>
       VAR l: RPC_SHORT, ..);
..pf
<DT>VAX/Pascal
<DD>
..bf MONO
In client:
 
    TYPE mystring  = PACKED ARRAY [1..80] OF CHAR;
<P>
                    - or VARYING OF CHAR }
<P>
    PROCEDURE proc_name(... VAR s: %STDESCR mystring; ...);

            EXTERN;
In server:
<P>
    TYPE mystring = PACKED ARRAY [1..80] OF CHAR;
<P>
         descriptor = RECORD
<P>
         strlen: [word]0..80;
<P>
            dum1, dum1: [byte] 0..255;
<P>
            stradr: ^mystring
<P>
    END;
 
    PROCEDURE proc_name(... VAR d: descriptor; ...);
<P>
     BEGIN
<P>
            ...
<P>
     END;
..pf
<DT>FORTRAN
<DD>
..bf MONO
SUBROUTINE PROC_NAME(..., THESTRING, ...)
<P>
CHARACTER *(*) THESTRING
..pf
<DT>Omegasoft Pascal, TurboPascal
<DD>
..bf MONO
TYPE mystring = STRING[80];
<P>
PROCEDURE proc_name(... VAR s: mystring);
..pf
</DL>
 
<DT>SUBSTRING
<DD>
The substring type has been introduced to allow a more efficient implementation
of the PILS remote host interface. A substring is a
packed array of char in which the valid characters are between two indices. The
first index, START, indicates the first valid element in the array, while the
second, LENGTH, indicates the number of valid characters that follow (and
including) the START.
<DL> 
<DT>RPCL
<DD>
..bf MONO
TYPE mysub IS SUBSTRING(80);
<P>
PROCEDURE proc_name(..; mysubstring : IN OUT mysub; ...);

..pf
<DT>C
<DD>
..bf MONO
typedef char mysubs[80]
<P>
proce_name(..., a_thesubs, s_thesubs, l_thesubs, ...)
<P>
 ...
<P>
mysubs a_thesubs;
<P>
int *s_thesub, *l_thesub;
<P>
 ...
..pf
<DT>Pascal
<DD>
..bf MONO
TYPE mysub     = PACKED ARRAY [1..80] OF CHAR;
<P>
PROCEDURE proc_name(.., VAR thesub: mysub;
<P>
       VAR start, len: RPC_INTEGER, ...);
..pf
</DL>
 
<DT>ARRAY
<DD>
A sequence of SIMPLE type like RPC_CHAR or RPC_LONG.
It may be multidimensional
and must have a specified size for each dimension.
<HP1>(Note that the example below, although illustrating
different aspects of array types, would in practice
be too big for the limit currently imposed by the runtime support
of about 1450 bytes per call</HP1>.)
<DL>
<DT>RPCL
<DD>
..bf MONO
TYPE myarray IS array (1..256, -15..23, 10..15) of rpc_long;
<p>
PROCEDURE proc_name(..; the_array: IN OUT myarray; ..);
 
..pf
<DT>C
<DD>
..bf MONO
typedef int myarray[256][39][6]
..pf
<DT>Pascal
<DD>
..bf MONO
TYPE myarray = ARRAY [1..256, -15..23, 10..15] OF INTEGER;
<P>
PROCEDURE proc_name(.. VAR a: myarray; ...);
 
..pf
<DT>FORTRAN
<DD>
..bf MONO
SUBROUTINE PROC_NAME(..., IARRAY, ..)
<P>
INTEGER IARRAY(256, 39, 6)
..pf
<DD>
</DL>
Arrays of the same sizes on different machines are compatible,
even if the starting index is not the same.
For example, a FORTRAN array(1..10) may
be passed to a C array(0..9).
 
Arrays are of  fixed length:
the same amount of  data is transferred every time.
An array which contains a varying
amount of dat
should be described as a sequence.
 
(Under VAX/FORTRAN, ARRAY type cannot be used to pass arrays of
CHARACTER.  Use the STRING type instead).
<DT>SEQUENCE
<DD>
A sequence is a general variable&hyphen.length array.
It represents a one&hyphen.dimensional collection of data, whose type
and maximum number are specified at compile time but whose
actual number and value are specified at run&hyphen.time.
 
A sequence is always passed as two parameters, a length and an array,
although it is specified in RPCL as one logical parameter.
<DL> 
<DT>RPCL
<DD>
..bf MONO
TYPE myseq IS sequence (80) of rpc_long;
<P>
procedure proc_name(..; theseq: IN OUT myseq; ...);
 
..pf
<DT>C
<DD>
..bf MONO
typdef int myseq[80];
<P>
proc_name(..., a_theseq, l_theseq, ...);
<P>
 ...
<P>
myseq   a_theseq;
<P>
int     * l_theseq;
<P>
 ...
..pf
<DT>Pascal
<DD>
..bf MONO
TYPE myseque   = ARRAY [1..80] OF INTEGER;
<P>
PROCEDURE proc_name(...
<P>
      VAR thearr: myseq;
<P>
      VAR thelen: INTEGER; ...);
 
..pf
<DT>Fortran
<DD>
..bf MONO
SUBROUTINE PROC_NAME( ..., THESEQ, THELEN, ...)
<P>
INTEGER THESEQ (80)
<P>
INTEGER THELEN
..pf
<DD>
 
<HP1>
Note that under VAX/VMS, for a SEQUENCE(...)OF RPC CHAR,
the array must be a pure array:  it may not be a FORTRAN string passed by
descriptor.  If a FORTRAN string is used in the client, it must be passed
with a %REF qualifier.  A FORTRAN string cannot be used for
the array in the called routine.
 
The STRING type (above) is available for passing strings, although
with FORTRAN this will result in the entire length of the string
being passed every time, as FORTRAN strings are fixed length</HP1>.
</DL>
<DT>RECORD
<DD>A record is a data structure consisting of a set of named fields.
<DL>
<DT>RPCL
<dd>
<xmp>
	TYPE myrec IS
	RECORD
		field1:	RPC_INTEGER;
		field2:	RPC_INTEGER;
	END RECORD;
</xmp>
<DT>Pascal
<dd>
<xmp>
	TYPE MYREC =
	RECORD
		FIELD1:	INTEGER;
		FIELD2:	INTEGER;
	END;
	VAR X: MYREC;
</xmp>
<DT>C
<DD>
<xmp>
	struct {
		int field_1;
		int field_2;
		} myrec;
	struct myrec x;
</xmp>
<DT>VAX/FORTRAN
<dd>
<xmp>
	STRUCTURE /MYREC/
		INTEGER FIELD1
		INTEGER FIELD2
	END STRUCTURE
	RECORD /MYREC/ X
</xmp>
<DT>PILS
<DD>	(There is no concept of records in PILS.)
</DL>
<DT>Pointers
<DD>A pointer type, if explcitly declared as such,
is assumed to be NIL (null) or to point to valid data.
In the later case, the data is transfered to the other side,
and a pointer to it is generated.
This will occur recursively, so that linked lists and trees
may be passed. Self-referencial data structues (circular lists etc)
are not allowed.

For an INOUT parameter, the called routine may modify the structure.
On the client side, the RPC system completely destroys the structure
(returning it to the heap) and rebuilds (from the heap) the structure
returned from the server.

For IN parameters, the RPC system does not touch the structure
or pointer on the client side at all.

For OUT parameters, the RPC system allocates a new structure on the
client side, and it is the responsability of the caller eventually to
return it to the heap.
The original value of the pointer is ignored, and simply overwritten with
a pointer to the new structure.
<dl>
<dt>RPCL
<DD>
..bf mono
TYPE mypo IS ACCESS myrec;
..pf
<dt>Pascal
<DD>
..bf mono
TYPE mypo = ^myrec;
..pf
<dt>C
<DD>
..bf mono
typedef struct myrec *x;
..pf
<dt>FORTRAN
<DD>There is no concept of pointer in FORTRAN.
<dt>PILS
<DD>There is no concept of pointer in PILS.
</dl>
</DL>
<H1>RPCL Language Definition
 
<I1 IX=1>RPCL, definition 
<I1 IX=1>Interface, definition file  format
There follows a Backus&hyphen.Naur Form (BNF)
definition of the RPC language, RPCL Version 1.0.
This is a reference definition and should be used
to solve any ambiguity or error that could arise when writing in RPCL.
 
Reserved keywords are in upper case. Words inside angle
brackets are productions: that is, they may be replaced by the part on the
right of the '::=' of their own definition. The sign '|' means 'exclusive or',
that is one form or the other may be used.

..bf MONO
..fo off
..tb 9 17 25 33 41 49 57 65 73
<rpcl_program>	::=     PACKAGE <ident> IS
                                 { <type_dec> ; }*
                                 { <other_dec> ; }*
                        END <ident> ;
 
<type_dec>      ::=     TYPE <ident> IS <type>

		|	<pragma>
 
<other_dec>     ::=     PROCEDURE <ident> <formal_params>

                |       FUNCTION <ident> <formal_params>  RETURN <simple_type>

                |       <pragma>

<formal_params>	::=     ( <formal_def> { ; <formal_def> }* )

                |       <void>
 
<formal_def>	::=     <identlist> : <direction> <type>
 
<direction>     ::=     IN
                |       OUT
                |       IN OUT

<pragma>        |       PRAGMA EXTERNAL_MARSHALLING( <identlist> );

	        |       PRAGMA CONCURRENT ( <identlist> )
                |       PRAGMA CAST ( <identlist> )
                |       PRAGMA TIMEOUT ( <ident> , <number> )
                |       PRAGMA CALL_STATUS ( <ident> , <ident> )

<identlist>     ::=     <ident> {, <ident>}*
 
<type>          ::=     <simple_type>
                 |      <structured_type>
        	 |	ACCESS <subtype>

<subtype>       ::=     <ident>
                 |      <simple type>
 
<simple_type>	::=     RPC_CHAR
                 |      RPC_BYTE
                 |      RPC_SHORT
                 |      RPC_INTEGER
                 |      RPC_LONG
                 |      RPC_REAL32
                 |      RPC_REAL48
                 |      RPC_REAL64
                 |      RPC_REAL128
 
<structured_type>::=    ARRAY  (range  { ,  <range>  }*)  OF <subtype>
		 |      RECORD { <identlist> : <subtype> }* END RECORD
                 |      SEQUENCE (index) OF <subtype>
                 |      STRING ( [index] )
                 |      SUBSTRING ( [index] )
 
 <range>         ::=    [index] ..  [index]
 
 <number>        ::=    < A number in 1 ..  65536>

 <ident>         ::=     < A Pascal&hyphen.like identifier>
 
..us Where
	         ::=     means "may be composed of"
                 |       means "or"
                 { }*    means zero or more times;
		 <void>  means no characters at all
..fo on
..pf
<hp2>Notes:</hp2>
<OL>
<LI>
Comments in RPCL start with two dashes '--' and end at the end of the line.
Comments can be put anywhere except inside keywords or identifiers.
<LI>
STRING is not equivalent to a type SEQUENCE OF RPC_CHAR,
because a special (more efficient) Courier message format is used to
represent objects of type STRING and SUBSTRING.
<LI>
The maximum length of identifier is limited to 25 characters.
<LI>
RPCL is case independent, meaning that you can
write your desciption file in any mixture of upper and lower case. The
identifiers 'VAR_ONE' and 'var_one' are, for example, the same,
as are the keywords "String" and "STRING".
 
<LI>
Identifiers may not be reserved words in any language in which stubs
are to be generated.
In order to avoid clashes within the stubs, one should also avoid
identifiers starting with any of:
<XMP>
 abort_  call_   m_      reject_         return_         rpc_
</xmp> 
or the identifiers:
<xmp>
        b               header                  procedure_number
        program_number  version_number          which
        why
</XMP>
The package should not have the same name as any of the procedures within
it.
</OL>
 
<H1>Installation of the RPC tools
 
<I1 IX=1>Installation
This is a list with which the user need not generally concern himself.
It details the files which must be available on the machine in order
to compile and link distributed programs.
 
Under VAX/VMS, a single command (@DISK$D1:[RPC]RPC on VXCRNA) sets up all
the other commands and logical names required, and may be put in
<I1 IX=1>login file
your login file.
 
Under UNIX BSD the compiler 'rpcc' should be present in
any directory of your PATH shell variable.
The header file rpcheader.h should be in one of the system (or user)
header file areas searched by the compiler.
 
The files forming part of release 2.4 on VAXVMS are as follows
 
<DL TSIZE=13>
<DT>include.com
<DD>The include preprocessor command file.
<DT>include.exe
<DD>The include preprocessor, used by the RPC.COM command file for stubs
in Pascal.
<DD>lnkdef.com
<DT>A command file used by setup.com for defining the
<dt>rpc.com
<dd>The command file used by the RPC command.
<DT>rpc.hlb
<DD>
A VAX/VMS help library
<DT>rpc.hlp
The RPC help library.
If your want the .HLP file, extract it from this with LIB/HELP/EXTRACT.
<DT>rpcc.exe
<DD>
The rpc compiler
<DT>rpcc.obj
<DD>
The rpc compiler in object form, so that you can link it to run on an old
version of VMS if necessary. The command is LINK/NOTRACEBACK RPCC
<DT>rpcconst.h
<DD>
A pascal include file.
Contains some basic definitions of constants.
<DT>rpcheader.h
<DD>
An include file in C language.
Contains all constants, types, and (un)marshaling procedures.
<DT>rpclarge.olb
<DD>
The run&hyphen.time library, version for DECNET, ethernet, V24, ISO TP4, X24
8k byte buffers.
Logical name is rpc_large
<DT>rpclib.olb
<DD>
The run&hyphen.time library, version for DECNET, ethernet, V24, ISO TP4, X24
etc.
Logical name is rpc_lib
<DT>rpclibc.olb
<DD>
The run&hyphen.time library, version for TCP/IP working.
Logical name is rpc_libc
<DT>rpclibc8k.olb
<DD>
The run&hyphen.time library, version for TCP/IP working.
8kB buffer version.
Logical name is rpc_libc
#
<DT>rpclarge.opt
<DD>
Link options file, version for DECNET, ethernet, V24, ISO TP4, X24
8k byte buffers.
Logical name is rpc_large
<DT>rpclib.opt
<DD>
Link options file, version for DECNET, ethernet, V24, ISO TP4, X24
etc.
Logical name is rpc_lib
<DT>rpclibc.opt
<DD>
Link options file, version for TCP/IP working.
Logical name is rpc_libc
<DT>rpclibc8k.opt
<DD>
Link options file, version for TCP/IP working.
8kB buffer version.
Logical name is rpc_libc
<dt>rpcmsg.exe
<dd>An error file. $SET ERROR RPCMSG will allow VMS to translate RPC
error numbers into text strings.
Any program linked with RPC can do this anyway, as the same information
is in a module RPC_ERRS in the library.
<DT>rpcproc.h
<DD>
A pascal include file.
Contains external declaration of routines used to transport
messages to the counterpart side.
<DT>rpcstub.h
<DD>
A pascal include file.
Contains system dependent library routines to marshal and unmarshal
parameters.
<DT>rpctypes.h
<DD>
A pascal include file.
contains system dependent type definitions.
<dt>rpc_vms024.release_notes
<dd>A set of notes describing differences between this and previous releases,
and how to install the product.
<DT>setup.com
<DD>
Login command file to set up logical names and symbols. Put a call to this
into the login.com for each user wishing to develop programs using RPC.
(No changes are required for those users using programs built with RPC.)
</DL>
<H1>More Information
 
If you would like a copy of this document,
mail Anne Perrelle at CERN.
<xmp>
        Internet:       PERRELLE@CERNVM.CERN.CH
        UUCP:           cernvax!cernvm!perrelle
        DECNET:         VXCERN::MINT"PERRELLE@CERNVM"
        BITNET:         PERRELLE AT CERNVM
</xmp>
<HP2>On&hyphen.line help</HP2>
 
Some of the information in this document is available on&hyphen.line
under a VMS "HELP" scheme. The help library is released with the
VAX/VMS software.
 
<HP2>VAX/NOTES Conference</HP2>
 
For up to date release information, bug reports and user feedback,
see the VAX/NOTES conference VXCERN::RPC.
If you have NOTES installed but haven't used it, to access the conference
first type (under VAX/VMS)
<xmp>
        $ NOTES
        > ADD ENTRY VXCERN::RPC
        > OPEN RPC
        > SET SEEN
        > DIR *.*
	> EXIT
</xmp> 

To find out what's new on future occasions, type
<xmp> 
        $ NOTES RPC
</xmp>
<HP2>Electronic Mail</HP2>
 
Please send any suggestions, comments or problems by mail to
<xmp>
        Internet:    RPC@VXCERN.CERN.CH
        UUCP:        cernvax!vxcern!rpc
        DECNET:      VXCERN::RPC
        BITNET:      RPC%VXCERN AT CERNVAX
</xmp> 
<H1>Acknowledgements

Many people have helped in the construction and support of the RPC
system (and this manual), whilst at or passing through CERN.
Many brought in specialist knowledge of particular systems,
and all have shown the patience and tolerance which is required
as part of such a widely distributed and loosely coupled team.

Antonio Pastore, a technical student at CERN in 1986, wrote the RPC compiler
(in a remarkably short time)
and wrote code to test it on the M68000 and the IBM&hyphen.PC.
 
Nici Schraudolph, a summer student at CERN in 1987, enhanced the compiler
(also in a very short time)
to include several new features, including the production of C code as an
alternative to Pascal.
 
Tim Adye from the Rutherford Lab ported the system to the M6809 and
wrote the machine&hyphen.dependent run&hyphen.time support
for that.
He has also been a source of numerous useful suggestions and additions to
both the code and the documentation.
 
Bob Jones (CERN/DD) extended the functionality of the DECNET interface
to allow a server to handle multiple clients.
 
Ignacio Martinez (Univ of Santander) added ISO TP4 communications
under VAX/VMS, and Angel Camacho (Atlas Energias, Santander)
has continued that work.

Dirk Gosman, visiting CERN/DD from NIKHEF&hyphen.H,
has provided communications
support in an RMS68K multitasking environment,
using Kik Piney's "ET" driver.
 
Johannes Raab, working with the OPAL online group, debugged the C
version of the system, and ported it to OS9.

Peter Lorenz of the Delphi experiment ported the system to the IBM PC,
and interfaced it to the OSI transport software from BICC.

Roberto Bagnara, a technical student at CERN in 1988,
enhanced the RS232 communication format for speed and reliability,
and extended the PC implementation to include RS232 and raw ethernet
handling as well as Class 4 transport.

Louis Tremblet (CERN/DD) wrote the code generator for stubs in PILS.

Anne Perrelle has been invaluable for her help in creating
and distrubuting this and other RPC documents.
..ce Trademarks
 
Ada is a trademark of the US Government, Ada Joint Program Office.
OmegaSoft is a trademark of Certified Software Corporation.
OS&hyphen.9 is a trademark of Microware Systems Corporation.
Unix is a trademark of Bell Laboratories.
Ultrix, VAX, VMS, UNIBUS and DECnet
are trademarks of Digital Equipment Corporation.
We apologize for any inadvertent omission to acknowledge any
trademarks as such.
</BODY>
</APPENDIX>
<BACKM>
<H1>References
<BL>
<BIB ID=RPCIMP>
T.J. Berners&hyphen.Lee CERN/DD,
"RPC Internals"  version 2.3.1, formerly "RPC Implementation Guide"
<BIB ID=VIR88>
T.J. Berners&hyphen.Lee, CERN/DD,
"Programming Distributed Systems: Remote Procedure Call"
<hp1>Proceedings of the conference on VMEbus In Research, Z&uuml;rich,1988</hp1>
An introduction to the basic concepts of RPC.
<BIB ID=RTC87>
T.J. Berners&hyphen.Lee, CERN/DD,
"Experience with Remote Procedure Call in Data Acquisition and Control",
<hp1> IEEE Transaction on Nuclear Science,</hp1> Vol NS&hyphen.34, No. 4
August 1987
<BIB ID=NELSON>
B.J. Nelson, "Remote Procedure Call", XEROX PARC CSL&hyphen.81&hyphen.9,
May 1981
<BIB ID=KOSTR85>
K. Kostro, CERN/DD, "Portable Communication with Remote Procedure Call
Protocols", private communication, copies from the author.
<BIB ID=XSOFTN3>
J.D. Blake, "User of Microprocessor Cross Software under VAX VMS",
CERN PRIAM Note XSOFT/N3, June 86. Under Wylbur, type
HELP PRIAM MICDOC P, then quote reference XSOFT/N3 when asked.
<BIB ID=COURIER>
"Courier: The Remote Procedure Call Protocol", XEROX Corporation,
XSIS 038112, December 1981.
<BIB ID=WINTCPADM>
<hp1>WIN/TCP Administrator's Guide</hp1>
GEC Software Ltd.,
<BIB ID=WINTCPREF>
<hp1>WIN/TCP Reference Manual</hp1>
GEC Software Ltd.
<BIB ID=WAY>
R.Bagnara, University of Pisa,
<hp1>WAY User Manual</hp1>
(in preparation Sept 89)
</BL>
<INDEX IX=1>Index
</BACKM>
</GDOC>
