*DECK RPCSUDP 
USETEXT TEXTIPL 
USETEXT TEXTRPC 
      PROC RPCSUDP (HANDLE, SOCKID, RPCSTATUS); 
*CALL COPYRITE
# TITLE RPCSUDP - CREATE UDP SERVER HANDLE                             #
  
      BEGIN                            # RPCSUDP                       #
# 
****  RPCSUDP  CREATE UDP SERVER HANDLE 
* 
*     THIS PROCEDURE CREATES A UDP SERVER HANDLE FOR REMOTE PROCEDURE 
*     CALLS.
* 
*     PROC RPCSUDP
* 
*     ENTRY    SOCKID     = SOCKET IDENTIFIER OF SERVER SOCKET IF IT HAS
*                           ALREADY BEEN OPENED, OTHERWISE 0. 
* 
*     EXIT     HANDLE     = RPC HANDLE (USED IN ASSOCIATED RPC CALLS) 
*              SOCKID     = SOCKET IDENTIFIER OF SERVER SOCKET
*              RPCSTATUS  = COMPLETION STATUS 
* 
*     METHOD   AN AVAILABLE RPC HANDLE IS FOUND AND INITIALIZED.
*              IF THE INPUT VALUE FOR SOCKID IS ZERO, A UDP SOCKET IS 
*              OPENED. ANY SOCKET OPENED BY THIS REQUEST WILL BE CLOSED 
*              BY A CALL TO RPCSDES.
* 
*              NOTE THAT IT IS THE CALLER'S RESPONSIBILITY TO REGISTER
*              THE PORT NUMBER WITH PORTMAPPER. 
# 
  
# 
****  PROC RPCSUDP - XREF LIST
# 
      XREF
        BEGIN 
        PROC IPPABOS;    # ABORT A SOCKET                              #
        PROC IPPBINS;    # BIND A UDP SOCKET                           #
        PROC IPPOPES;    # OPEN A UDP SOCKET                           #
        END 
# 
**
# 
      ITEM HANDLE              U;      # RPC HANDLE                    #
      ITEM SOCKID              U;      # SOCKET IDENTIFIER             #
      ITEM RPCSTATUS   S:RPCSTAT;      # RETURNED RPC STATUS           #
# 
**
# 
      ITEM IGNORE               U;     # IGNORE STATUS                 #
      ITEM INDEX                I;     # LOOP INDEX                    #
      ITEM SOCKET               U;     # INTERNAL SOCKET               #
      ARRAY SOCKADDR [0:0] S(ADDSIZE$);# SERVER ADDRESS                #
        ITEM SERVADDR C(0,0,40);
      ITEM SOCKSTATUS  S:SOCKSTAT;     # SOCKET STATUS                 #
      CONTROL EJECT;
# 
****  START MAIN PROCEDURE
* 
****  FIND AVAILABLE HANDLE ENTRY 
# 
      FOR INDEX = 1 STEP 1 UNTIL MAXHANDLE$ DO
        BEGIN 
        IF NOT RP$ACTIVE [INDEX] THEN 
          BEGIN 
          HANDLE = INDEX; 
          GOTO INIT$HANDLE; 
          END 
        END 
  
      RPCSTATUS = S"NOHANDLE";
      RETURN; 
  
    INIT$HANDLE:  
      RP$XID [HANDLE] = 0;
# 
****  OPEN A UDP SOCKET IF ONE IS NOT ALREADY OPEN. 
# 
      IF SOCKID EQ 0
      THEN
        BEGIN                          # OPEN A SOCKET                 #
        IPPOPES (SOCKET, (PTYPE"SOCKETUDP"), SOCKSTATUS); 
        IF SOCKSTATUS EQ S"OK"
        THEN
          BEGIN                        # BIND THE SOCKET (PORT = 0)    #
          IPPBINS (SOCKET, 0, SOCKSTATUS);
          IF (SOCKSTATUS EQ S"REQFAIL") 
          OR (SOCKSTATUS EQ S"ABORT") 
          THEN                         # BIND FAILED - CLOSE SOCKET    #
            IPPABOS (SOCKET, IGNORE); 
          END 
  
        IF SOCKSTATUS NQ S"OK"
        THEN
          BEGIN                        # RETURN IF ERROR ON SOCKET     #
          RPCSTATUS = S"SOCKFAIL";
          RETURN; 
          END 
  
        SOCKID = SOCKET;               # RETURN SOCKET ID              #
        RP$CLS$SOCK [HANDLE] = TRUE;   # MARK HANDLE TO DELETE SOCKET  #
        END 
      ELSE                             # SOCKID NQ 0                   #
        RP$CLS$SOCK [HANDLE] = FALSE;  # MARK HANDLE TO SAVE SOCKET    #
  
      RP$SOCKID [HANDLE] = SOCKID;     # SAVE SOCKET ID                #
      RP$ACTIVE [HANDLE] = TRUE;       # HANDLE INITIALIZED            #
      RPCSTATUS = S"OK";
      RETURN;                          # RETURN TO CALLER              #
  
      END                              # RPCSUDP                       #
  
      TERM
*WEOR 
