Using RPC under the OS9 operating system

# Example: VMS server for OS9 client

See also: running under OS9 , running under VMS .

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.

The package consists, in this case, of only one function. This is the definition file which describes it:

      PACKAGE OS9_SERVICE IS
         TYPE IN_STRING IS STRING(133);
         FUNCTION OS9_DCL( COMMAND : IN  IN_STRING)  RETURN RPC_LONG;
      END OS9_SERVICE;

The server is based on a FORTRAN subroutine to have the command exectuted by the LIB$SPAWN library call.

             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

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).

      #include <rpcrts.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);
       }

To gerenerate the executable:

          $! 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

Alternatively, the predefined server loop could have been used, with automatic initialisation of the stub:

          $! 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

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.

          #include <strings.h>
          #include <types.h>
          #include <rpcrts.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);
                   }

            }

You must compile and link on OS9 with the following commands

    	cc -rs -v=/m17/rpc filename
    	cc -x client.r clientstub.r /m17/rpc/rpclib.l -dOS9 -f=fileout

- 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.)
- If the include file rpcrts.h is has not been put in a standard directory, the option -v=
- (eg -v=/m17/rpc) can be used to tell the compiler where to find it.
- 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
- If more stack is needed, the option -m=10 may be needed.

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:

              DEFINE RPC_CLIENT_NAME *_5680.ETHERNET

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:

    	SETENV  OS9_SERVICE 0@AA_00_04_00_15_58_5680.ETHERNET

Now, Run the SERVER on the VAX, then Run the CLIENT on OS9.