*DECK RPCSREQ 
USETEXT TEXTIPL 
USETEXT TEXTRPC 
USETEXT TEXTXDR 
      PROC RPCSREQ (HANDLE, PROCNUM, INBUFFER, INBUFPOS, INBUFLEN,
        RPCSTATUS); 
*CALL COPYRITE
# TITLE RPCSREQ - GET RPC SERVER REQUEST                               #
  
      BEGIN                            # RPCSREQ                       #
# 
****  RPCSREQ  GET RPC SERVER REQUEST 
* 
*     THIS PROCEDURE RETURNS AN RPC SERVER REQUEST RECEIVED ON "HANDLE".
* 
*     PROC RPCSREQ
* 
*     ENTRY    HANDLE     = RPC HANDLE
* 
*     EXIT     PROCNUM    = RPC PROCEDURE NUMBER
*              INBUFFER   = ADDRESS OF (XDR) INPUT DATA FOR PROCNUM 
*              INBUFPOS   = POSITION OF FIRST BYTE IN INBUFFER
*              INBUFLEN   = LENGTH OF INBUFFER IN BYTES 
*              RPCSTATUS  = COMPLETION STATUS 
* 
*     METHOD   THE MESSAGE IS READ FROM THE SOCKET AND THE RPC HEADER 
*              IS VERIFIED. THE TRANSACTION ID IS SAVED FOR INSERTION 
*              INTO THE NEXT REPLY. SAVE THE CLIENT ADDRESS FOR USE 
*              WITH THE NEXT RESPONSE. THE PROCEDURE DATA IS RETURNED 
*              TO THE CALLER IN THE INPUT BUFFER. 
# 
  
# 
****  PROC RPCSREQ - XREF LIST
# 
      XREF
        BEGIN 
        PROC IPPRECV;    # RECEIVE DATA ON A SOCKET                    #
        PROC XDRINT;     # CONVERT INTEGERS TO XDR FORMAT              #
        END 
# 
**
# 
      BASED ARRAY CLIENTADD [0:0] S(1);;# CLIENT ADDRESS               #
      ITEM HANDLE              U;      # RPC HANDLE                    #
      ITEM PROCNUM             U;      # RPC PROCEDURE NUMBER          #
      ARRAY INBUFFER [0:15] S(1);;     # INPUT BUFFER                  #
      ITEM INBUFLEN            U;      # INPUT DATA LENGTH             #
      ITEM INBUFPOS            U;      # POSITION OF NXT BYTE IN BUFFER#
      ITEM RPCSTATUS   S:RPCSTAT;      # RETURN STATUS                 #
# 
**
# 
      ARRAY RPCBUFFER [0:15] S(1);;    # BUFFER FOR RPC HEADER         #
      ITEM RPCBUFPOS            U;     # RPC BUFFER POSITION           #
      ARRAY REQHEADER [0:9]  S(1);     # RPC MESSAGE HEADER            #
        ITEM REQUESTITM U(0,0,60);
      ITEM SOCKSTATUS  S:SOCKSTAT;     # SOCKET STATUS                 #
      CONTROL EJECT;
# 
****  START MAIN PROCEDURE
* 
****  VERIFY HANDLE ENTRY 
# 
      IF NOT RP$ACTIVE [HANDLE] THEN
        BEGIN 
        RPCSTATUS = S"HANDLEINACT"; 
        RETURN; 
        END 
# 
****  GET RPC CLIENT'S REQUEST. THE CLIENT'S ADDRESS IS SAVED IN THE
*     SERVER'S HANDLE.
# 
      P<CLIENTADD> = LOC (RP$ADDRESS [HANDLE]); 
      IPPRECV (RP$SOCKID [HANDLE], INBUFFER, INBUFLEN,
               CLIENTADD, SOCKSTATUS);
      IF SOCKSTATUS NQ S"OK"           # RECEIVE FAILED                #
      THEN
        BEGIN 
        IF SOCKSTATUS EQ S"NODATA"
        THEN
          RPCSTATUS = S"RPCTIMEOUT";
        ELSE
          RPCSTATUS = S"SOCKFAIL";
        RETURN;                        # RETURN WITH ERROR             #
        END 
# 
****  REMOVE RPC HEADER FROM CLIENT'S REQUEST AND VERIFY THE MESSAGE
*     TYPE AND RPC VERSION. 
* 
*     PROGRAM NUMBER AND PROTOCOL VERSION ARE ASSUMED TO BE CORRECT,
*     SINCE THEY WERE PROBABLY USED IN A PREVIOUS PORTMAPPER
*     "GETPORT" REQUEST IN ORDER TO GET THIS FAR. 
# 
      INBUFPOS = 0;                    # INITIALIZE BUFFER POSITION    #
      XDRINT (INBUFFER, INBUFPOS, REQHEADER, 10, XDROPER"READ");
      RP$XID [HANDLE] = REQUESTITM [0];# SAVE THE TRANSACTION ID       #
  
      IF (REQUESTITM [1] NQ RPCMSG"CALL") 
        OR (REQUESTITM [2] NQ RPCVERSION$)
      THEN
        BEGIN 
        RPCSTATUS = S"BADCALL"; 
        RETURN;                        # RETURN WITH ERROR             #
        END 
  
      PROCNUM = REQUESTITM [5]; 
  
      RPCSTATUS = S"OK";               # SET NORMAL STATUS             #
  
      RETURN;                          # RETURN TO CALLER              #
  
      END                              # RPCSREQ                       #
  
      TERM
