Google
 

Trailing-Edge - PDP-10 Archives - BB-FB49A-RM - sources/sgatrm.b36
There are no other files named sgatrm.b36 in the archive.
%title 'SNA Gateway Access for SNT --  MACRO-20 Interface'

module SGATRM (ident = 'Version 1.09') =
begin

! Copyright (c) 1984, 1985 by
! DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts
!
! This software is furnished under a license and may be used and  copied
! only  in  accordance  with  the  terms  of  such  license and with the
! inclusion of the above copyright notice.  This software or  any  other
! copies  thereof may not be provided or otherwise made available to any
! other person.  No title to and ownership of  the  software  is  hereby
! transferred.
!
! The information in this software is subject to change  without  notice
! and  should  not  be  construed  as  a commitment by Digital Equipment
! Corporation.
!
! Digital assumes no responsibility for the use or  reliability  of  its
! software on equipment which is not supplied by Digital.


!++
! FACILITY:
!
!	SNA Gateway Access Module for SNT - Macro-20 Interface
!
! ABSTRACT:
!
!	The following Macro calls are supported by this module:
!
!	Call		Function
!	____		________
!
!	R_INI		Send an "Initiate Trace" Message
!	R_RSP		Service a trace message response from the gateway
!
! ENVIRONMENT:
!
!	TOPS-20 Operating Systems, user interface.
!
! AUTHOR:	Dennis Brannon, CREATION DATE: December 21, 1983
!
! MODIFIED BY:
!
! 	D. Brannon, 11-Oct-84 : VERSION 1.00
!
! 1.01  D. Brannon, 29-Oct-84
!       Replaced error code SNT$_INTERRHOS with SNT$_FATINTERR because
!       that was the wrong error code to return.
!
! 1.02  D. Brannon, 29-Oct-84
!       Replace SNT$_CONNECT with SNT$_CONNFAIL.
!
! 1.03  D. Brannon, 31-Jan-85
!       Break up the network file spec, so that the ;USERID: and ;PASSWORD:
!       don't get appended unless the user and password were specified in
!       the trace command line.
!
! 1.04  D. Brannon, 10-Feb-85
!       Added routine GAM$ABORT_REASON to handle the 3 byte abort codes sent
!       by the gateway as optional data on a disconnect.
!
! 1.05  D. Brannon, 10-Feb-85
!       Rewrote R_RSP to produce better error information.
!
! 1.06  D. Brannon, 19-Feb-85
!       In GAD$OPEN_LINK, fixed dot bug which prevented catching the case of
!       a nsp error:0 so that the true abort reason could be displayed.
!       Reorganized the test for nsp_code = 0 to make it clearer.
!
! 1.07  D. Brannon, 19-Feb-85
!       In GAD$OPEN_LINK, added a call to GAD$DISCONNECT to get rid
!       of the decnet link to the gateway after finding out the abort reason.
! 
! 1.08  D. Brannon, 21-Feb-85
!       In GAM$ABORT_REASON, added SNTMSG$K_ACCVERFAI to handle the abortcode
!       returned from the SNT server when access verification of the user
!       and password fail.
!
! 1.09  D. Brannon, 22-Feb-85
!       In GAM$ABORT_REASON, modified the $SNT_ERROR arguments for
!       SNT$_SRVLNKABO and SNT$_GATINTERR to correctly display the error codes.
!--
!
! TABLE OF CONTENTS
!

!
! INCLUDE FILES
!

library 'MONSYM';                       ! Monitor symbols
library 'SNTDEF';                       ! SNA Gateway Access common symbols
library 'SYS:TXTLIB';                   ! Text Processing Lib
library 'SNTLIB';                       ! SNT Protocol definitions

require 'JSYS';                         ! JSYS declarations

!
! MACROS
!

!
! FORWARD ROUTINE
!

forward routine
    GAM$ASCIZ: novalue,
    GAM$ASCIC: novalue,
    GAM$EXECUTE_REQUEST,
    GAM$SEND_REQUEST,
    GAM$RECEIVE_RESPONSE,
    GAM$ABORT_REASON,
    R_INI: MAC novalue,
    R_RSP: MAC novalue;

!
! EXTERNAL REFERENCES
!
external
     ST: SNTBLOCK,
     NSPT20;

external routine                        ! DECnet specific functions
    GAD$ABORT_LINK,
    GAD$DISCONNECT_LINK,
    GAD$LINK_STATUS,
    GAD$NETWORK_DESCRIPTOR,
    GAD$OPEN_LINK,
    GAD$OPEN_SERVER,
    GAD$PROTOCOL_TYPE,
    GAD$PSI_CHANNELS,
    GAD$RECEIVE_DATA,
    GAD$RECEIVE_INTERRUPT,
    GAD$SEND_DATA,
    GAD$SEND_INTERRUPT;

external routine                        ! Procotol parsing routines
    GAP$RI_PROTOCOL_TYPE;

external routine                        ! Protocol building routines
    GAP$RO_INI;

external routine
    MEM$GET,
    MEM$RETURN;
%routine ('GAM$EXECUTE_REQUEST') =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Function to execute a request for a SNTBLOCK.  The request
!       in the SNTBLOCK's output buffer is sent to the gateway and
!       the response returned is placed in the SNTBLOCK input buffer.
!
! FORMAL PARAMETERS:
!
!       ST	SNTBLOCK data base.
!
! IMPLICIT INPUTS:
!
!	.ST[ST_OUTPUT_BUFFER]
!	.ST[ST_OUTPUT_BUFFER_LEN]
!
! IMPLICIT OUTPUTS:
!
!	.ST[ST_INPUT_BUFFER]
!	.ST[ST_INPUT_BUFFER_LEN]
!
! ROUTINE VALUE:
!
!	0       Successful completion.
!
!       <0      Failed.
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    local
        JFN,
        LEN,
        LENGTH,
        STATUS;

    JFN = .ST[ST_JFN];                  ! Get the JFN for the network link

    GAD$LINK_STATUS (.JFN, STATUS);     ! Get link status

    if .STATUS<$(mo_syn)>               ! Link has been disconnected
    or .STATUS<$(mo_abt)>               ! Link is aborted
    then begin
        GAD$DISCONNECT_LINK (.JFN);     ! Close link
        return (-2);                    ! Return error
        end;

    if not .STATUS<$(mo_con)>           ! If link is still not connected
    then begin
         GAD$DISCONNECT_LINK (.JFN);    ! Close link
         return (-3);                   ! Return error
         end;

    $TRACE_MSG ('Sending ', .ST[ST_OUTPUT_BUFFER_LEN], .ST[ST_OUTPUT_BUFFER]);


    if not GAD$SEND_DATA (.ST[ST_JFN],
                          ch$ptr (.ST[ST_OUTPUT_BUFFER],,8),
                          .ST[ST_OUTPUT_BUFFER_LEN])
    then return (-4);

    ! Wait for response message from the Gateway
    ! Timeout while waiting.

    incr I from 1 to 30                  ! Wait for NICE response message
    do begin
       if jsys_sibe (.JFN; , LEN)       ! Is input buffer empty ?
       then jsys_disms (2000)           ! Yes, wait 2 seconds between tries
       else return (-5);                ! No, generate 60 sec timeout waiting
       end;                             ! for response from gateway

    LENGTH = INPUT_MESSAGE_SIZE;
    ST[ST_INPUT_BUFFER_LEN] = 0;
    if not GAD$RECEIVE_DATA (.ST[ST_JFN],
                             LENGTH,
                             ch$ptr (.ST[ST_INPUT_BUFFER],,8))
    then return (-5);
    ST[ST_INPUT_BUFFER_LEN] = .LENGTH;

    $TRACE_MSG ('  Received   ',.ST[ST_INPUT_BUFFER_LEN],.ST[ST_INPUT_BUFFER]);

    return (0);

    end;                                ! End of GAM$EXECUTE_REQUEST
%routine ('GAM$SEND_REQUEST') =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Function to send a message to the gateway.  The
!       message in the SNTBLOCK output buffer is sent.
!
! FORMAL PARAMETERS:
!
!       ST	SNA trace data base.
!
! IMPLICIT INPUTS:
!
!	.ST[ST_OUTPUT_BUFFER]
!	.ST[ST_OUTPUT_BUFFER_LEN]
!
! IMPLICIT OUTPUTS:
!
!
! ROUTINE VALUE:
!
!	SNT$_NORMAL       Successful completion.
!
!       SNT$_CONNFAIL      Error connecting to gateway
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    local
        JFN,
        LEN,
        LENGTH,
        STATUS;

    if (JFN = .ST[ST_JFN]) leq 0        ! Check SNTBLOCK JFN
    then return SNT$_FATINTERR;

    GAD$LINK_STATUS (.JFN, STATUS);     ! Get link status

    if .STATUS<$(mo_syn)>               ! Link has been disconnected
    or .STATUS<$(mo_abt)>               ! Link is aborted
    then begin
        GAD$DISCONNECT_LINK (.JFN);     ! Close link
        return SNT$_SRVLNKABO;            ! Return error
        end;

    if not .STATUS<$(mo_con)>           ! If link is still not connected
    then begin
         GAD$DISCONNECT_LINK (.JFN);    ! Close link
         return SNT$_CONNFAIL;           ! Return error
         end;

    $TRACE_MSG ('  Sending ',.ST[ST_OUTPUT_BUFFER_LEN],.ST[ST_OUTPUT_BUFFER]);

    if not GAD$SEND_DATA (.ST[ST_JFN],
                          ch$ptr (.ST[ST_OUTPUT_BUFFER],,8),
                          .ST[ST_OUTPUT_BUFFER_LEN])
    then return SNT$_TRANSMIT;

    return SNT$_NORMAL;

    end;                                ! End of GAM$SEND_REQUEST
%routine ('GAM$RECEIVE_RESPONSE') =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Function to receive a SNTBLOCK response from the gateway.
!
! FORMAL PARAMETERS:
!
!       ST	SNA Trace data base.
!
! IMPLICIT INPUTS:
!
!	none
!
! IMPLICIT OUTPUTS:
!
!	.ST[ST_INPUT_BUFFER]
!	.ST[ST_INPUT_BUFFER_LEN]
!
! ROUTINE VALUE:
!
!	SNT$_NORMAL       Successful completion.
!
!       SNT$_CONNFAIL      Error connecting to gateway
!       SNT$_RECEIVE      Receive Failed
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    local
        LEN,
        LENGTH,
        STATUS;

    if jsys_sibe (.ST[ST_JFN]; , LEN)   ! Is input buffer empty ?
    then return SNT$_FATINTERR;         ! Yes, should not happen

    LENGTH = INPUT_MESSAGE_SIZE * 4;    ! Max message length

    ST[ST_INPUT_BUFFER_LEN] = 0;        ! Actual length of received data
    if not GAD$RECEIVE_DATA (.ST[ST_JFN],
                             LENGTH,
                             ch$ptr (.ST[ST_INPUT_BUFFER],,8))
    then return SNT$_RECEIVE;

    ST[ST_INPUT_BUFFER_LEN] = .LENGTH;  ! Update with actual length

    $TRACE_MSG ('  Received   ',.ST[ST_INPUT_BUFFER_LEN],.ST[ST_INPUT_BUFFER]);

    return SNT$_NORMAL;

    end;                                ! End of GAM$RECEIVE_RESPONSE
%routine ('GAM$ABORT_REASON', JFN) =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Function to find the abort reason and signal it 
!
! FORMAL PARAMETERS:
!
!       JFN of logical link that has been disconnected
!
! IMPLICIT INPUTS:
!
!	none
!
! IMPLICIT OUTPUTS:
!
!	none
!
! ROUTINE VALUE:
!
!	SNT$_NORMAL       Successful completion.
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    local
       POINTER,
       LENGTH,
       STATUS,
       REASON,
       ABORTCODE,
       ABORTQ1,
       ABORTQ2;

    POINTER = ch$ptr (REASON,,8);

    jsys_mtopr (.JFN, $morda, .POINTER; ,,, LENGTH);  ! get the abort reason.

    if .LENGTH gtr 0
    then ABORTCODE = ch$rchar_a (POINTER) ! get the Abort reason code
    else ABORTCODE = 0;

    if .LENGTH gtr 1
    then ABORTQ1 = ch$rchar_a (POINTER)   ! get Server abort code
    else ABORTQ1 = 0;

    if .LENGTH gtr 2
    then ABORTQ2 = ch$rchar (POINTER)     ! get Server abort qualifier
    else ABORTQ2 = 0;

    GAD$ABORT_LINK (.JFN);  ! close and release the link

    !
    ! Determine the real reason for the link abort
    !

    Case .ABORTCODE from SNAMSG$K_MIN to SNAMSG$K_MAX of
        SET
        [SNAMSG$K_ABNSESTER]:  ! 100, Abnormal session termination
            STATUS = SNT$_ABNSESTER;
        [SNAMSG$K_CIRNOTAVA]:  ! 101, Circuit not available
            STATUS = SNT$_CIRNOTAVA;
        [SNAMSG$K_CIRTOOLON]:  ! 102, Circuit too long
            STATUS = SNT$_CIRTOOLON;
        [SNAMSG$K_ILLTRCTYP]:  ! 103, Illegal trace type
            STATUS = SNT$_ILLTRCTYP;
        [SNAMSG$K_INCVERNUM]:  ! 104, Incompatible version numbers
            STATUS = SNT$_INCVER;
        [SNAMSG$K_INSGATRES]:  ! 105, Insufficient gwy resources
            STATUS = SNT$_INSGATRES;
        [SNAMSG$K_INTERRHOS]:  ! 106, Gateway detected host error
            STATUS = SNT$_INTERRHOS;
        [SNAMSG$K_INTERRSER]:  ! 107, Internal software error
            begin
            STATUS = SNT$_GATINTERR;
            $SNT_ERROR (SNT$_GATINTERR, .ABORTQ1, .ABORTQ2);
            end;
        [SNAMSG$K_NO_SUCCIR]:  ! 108, No such circuit
            begin
            STATUS = SNT$_NOCIRCUIT;
            $SNT_ERROR (SNT$_NOCIRCUIT);
            end;
        [SNAMSG$K_NO_SUCSLU]:  ! 109, No such session
            begin
            STATUS = SNT$_NOSESSION;
            $SNT_ERROR (SNT$_NOSESSION);
            end;
        [SNAMSG$K_NOTINIMSG]:  ! 110, Not INIT message
            STATUS = SNT$_NOTINIMSG;
        [SNAMSG$K_SLUADDACT]:  ! 111, Session address in use
            STATUS = SNT$_SESIN_USE;
        [SNAMSG$K_SLUNOTAVA]:  ! 112, Session address not available
            STATUS = SNT$_SESNOTAVA;
        [SNAMSG$K_ACCVERFAI]:  ! 113, Access verification failed
            STATUS = SNT$_ACCVERFAI;
        [SNAMSG$K_CIRNOTSPE]:  ! 114, Circuit name not specified
            STATUS = SNT$_CIRNOTSPE;
        [INRANGE,
         OUTRANGE]:
            begin
            STATUS = SNT$_SRVLNKABO;
            $SNT_ERROR (SNT$_SRVLNKABO, .ABORTCODE, .ABORTQ1, .ABORTQ2);
            end;

        TES;
    $SNT_ERROR (.STATUS);
    return SNT$_NORMAL;
    end;                                ! End of GAM$ABORT_REASON
%routine ('GAM$ASCIZ', SOURCE, DESTINATION) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Function to copy ASCIZ string to a counted ASCII string buffer.
!
! FORMAL PARAMETERS:
!
!       SOURCE          Pointer to the source string.
!       DESTINATION     Pointer to the destination location.
!
! IMPLICIT INPUTS:
!
!	none
!
! IMPLICIT OUTPUTS:
!
!	none
!
! ROUTINE VALUE:
!
!       none
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    local
        LENGTH;

    LENGTH = (if (.SOURCE neq 0) and (ch$size (.SOURCE) gtr 0)
              then CH$LEN (.SOURCE)     ! Get LENGTH of the source string
              else 0);

    if .LENGTH leq 0
    then ch$wchar (%O'0', .DESTINATION) ! Null source string
    else begin
         local POINTER;

         POINTER = .DESTINATION;
         ch$wchar_a (.LENGTH, POINTER);
         ch$move (.LENGTH, .SOURCE, .POINTER);
         end;

    return;
    end;                                ! End of GAM$ASCIZ
%routine ('GAM$ASCIC', LENGTH, SOURCE, DESTINATION) : novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!       Function to copy string from user argument block to user data base.
!       If the source string empty, then zero out the destination location.
!
! FORMAL PARAMETERS:
!
!       LENGTH          LENGTH of the source string.
!       SOURCE          Pointer to the source string.
!       DESTINATION     Pointer to the destination location.
!
! IMPLICIT INPUTS:
!
!	none
!
! IMPLICIT OUTPUTS:
!
!	none
!
! ROUTINE VALUE:
!
!       none
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    if .LENGTH leq 0
    then ch$wchar (%O'0', .DESTINATION)
    else begin
         local POINTER;

         POINTER = .DESTINATION;
         ch$wchar_a (.LENGTH, POINTER);
         ch$move (.LENGTH, .SOURCE, .POINTER);
         end;

    return;
    end;                                ! End of GAM$ASCIC
%global_routine ('R_INI', ARGBLK: ref ARGUMENT_BLOCK) : MAC novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!       R%INI           Connect to Gateway and Send an "Initiate Trace" Message
!
! FORMAL PARAMETERS:
!
!	ARGBLK          Argument block address.
!
! IMPLICIT INPUTS:
!
!	none
!
! IMPLICIT OUTPUTS:
!
!	none
!
! COMPLETION CODES:
!
!	none
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    local
        CHANNEL,
        LENGTH,
        BUFFER,
        POINTER,
        SNT_SERVER,
        STATUS,
        WB: ref WORK_BUFFER;


    
    WB = .ARGBLK[INI_WORK_AREA];        ! Get work area

    $INITIALIZE_BLOCK (.WB, WORK_BUFFER_SIZE);  !  Initialize work buffer

    !
    ! Set up for an error
    !

    ARGBLK[INI_RETURN_CODE] = RC_ERR;   ! Error code
    ARGBLK[INI_RETURN_DATA_ADDRESS] = WB[WB_ERROR_BLOCK]; ! Error block
    ARGBLK[INI_RETURN_DATA_SIZE] = 2;   ! Size of error data

    BUFFER = MEM$GET (2);               ! Get a buffer for the DECnet logical
    POINTER = ch$ptr (.BUFFER);         ! string.

    TXT_WRITE (POINTER,
               $MEMORY_BUFFER_SIZE * 2 * 5,
               'DCN:%A-TASK-TRS....TRS',
               .ST[ST_GATEWAY]);


    if (.ST[ST_USER] nequ 0) and (.ST[ST_PASSWORD] nequ 0)
    then begin
         POINTER = ch$plus (.POINTER, -1);
         TXT_WRITE (POINTER,
                    $MEMORY_BUFFER_SIZE * 2 * 5,
                    ';USERID:%A;PASSWORD:%A',
                    .ST[ST_USER],
                    .ST[ST_PASSWORD]);
         end;                                
    SNT_SERVER = ch$ptr (.BUFFER);
    STATUS = GAD$OPEN_LINK (.SNT_SERVER, CHANNEL);
!
!	$TRUE   The DECnet link was established successfully.
!               The channel number is returned.
!	$FALSE  Failed to establish a network connection.
!               Reason: Connect failed after successive retries
!       -1      Failed to establish a network connection.
!               Reason: System error code returned in CHANNEL
!       -2      Failed to establish a network connection.
!               Reason: NSP error code returned the right half of CHANNEL
!                       JFN returned in the left half of CHANNEL
!

    if .STATUS neq $TRUE                ! STATUS could be $FALSE, -1, or -2
    then begin                          ! Failed to connect to the Gateway
         if .STATUS eql $FALSE
             then begin
                  $SNT_ERROR (SNT$_CONNFAIL, 0);
                  end;
         if .STATUS eql -1
            then begin
                 $SNT_ERROR (SNT$_JSYS, .CHANNEL, .CHANNEL);
                 end;
         if .STATUS eql -2
            then begin
                 local
                     JFN,
                     NSP_CODE;

                 NSP_CODE = .CHANNEL<0,18>;
                 JFN = .CHANNEL<18,18>;

                 if .NSP_CODE eqlu 0
                 then begin
                      GAM$ABORT_REASON (.JFN);     ! Close DECnet logical link 
                      end                          ! and display abort reason
                 else begin
                      GAD$DISCONNECT_LINK (.JFN);  ! Close DECnet logical link
                                                   ! and display NSP error code
                      $SNT_ERROR (SNT$_NSP, .NSP_CODE, .(NSPT20+.NSP_CODE));
                      end;
                 end;
         end
    else begin
         local LEN, PTR;
         ST[ST_JFN] = .CHANNEL;          ! Save DECnet logical link JFN
         if not GAD$PSI_CHANNELS (.CHANNEL, 2)
         then begin                     ! Failed to set up PSI channel
              $SNT_ERROR (SNT$_ASSIGN, 0);
              return;
              end;

!         POINTER = .ST[ST_GATEWAY];
!         CH$MOVZSTRING (POINTER, .ARGBLK[INI_GATEWAY_NAME]);


         ST[ST_STATE] = RS_INI;      ! Set state to initiate trace
         ST[ST_FLAGS] = 0;           ! Clear flags
         ST[ST_RSP_CODE] = 0;        ! Response code
         ST[ST_RSP_FLAGS] = 0;       ! Response flags
         ST[ST_WORK_AREA] = .WB;     ! Save user work area address
         ST[ST_INPUT_BUFFER] = WB[WB_INPUT_MESSAGE];
         ST[ST_OUTPUT_BUFFER] = WB[WB_OUTPUT_MESSAGE];
         ST[ST_ARGPTR_ADDRESS] = WB[WB_MESSAGE_ARGPTR];
         ST[ST_MESSAGE_BLOCK] = WB[WB_MESSAGE_BLOCK];
         ST[ST_ERRPTR_ADDRESS] = WB[WB_ERROR_ARGPTR];

         ST[ST_ERROR_BLOCK] = WB[WB_ERROR_BLOCK];

         end;

    !
    ! Build "Initiate Trace" message
    !

    GAP$RO_INI (ST, .ST[ST_OUTPUT_BUFFER], LENGTH);
    ST[ST_OUTPUT_BUFFER_LEN] = .LENGTH;

    !
    ! Send the "Initiate Trace message
    !

    STATUS = GAM$SEND_REQUEST (ST);

    if .STATUS neq SNT$_NORMAL
    then begin                         ! Error executing request
         $SNT_ERROR (.STATUS);
         return;
         end;

    ARGBLK[INI_RETURN_CODE] = RC_SUC;    ! Success
    ARGBLK[INI_RETURN_DATA_ADDRESS] = 0; ! No error block
    ARGBLK[INI_RETURN_DATA_SIZE] = 0;    ! Size of error data
    return;

    end;                                ! End of R_INI
%global_routine ('R_RSP', ARGBLK: ref ARGUMENT_BLOCK) : MAC novalue =

!++
! FUNCTIONAL DESCRIPTION:
!
!       R%RSP           Service SNA Trace Response
!
! FORMAL PARAMETERS:
!
!	ARGBLK          Argument block address.
!
! IMPLICIT INPUTS:
!
!	none
!
! IMPLICIT OUTPUTS:
!
!	none
!
! COMPLETION CODES:
!
!	none
!
! SIDE EFFECTS:
!
!	none
!
!--

    begin

    local
        LENGTH,
        STATUS,
        POINTER,
        COUNT,
        TIMER,
        ERROR;

    ST[ST_FLAGS] = 0;                   ! Initialize status flags
    ERROR = $FALSE;                     ! Assume no error
    !
    ! Set up for successful return
    !
    ARGBLK[RSP_RETURN_CODE] = RC_SUC;   ! Success code
    ARGBLK[RSP_FLAGS] = .ST[ST_FLAGS];  ! Status flags
    ARGBLK[RSP_RETURN_PROTOCOL_CODE] = ST$NUL;   ! No message available
    ARGBLK[RSP_RETURN_DATA_ADDRESS] = 0; ! No return data
    ARGBLK[RSP_RETURN_DATA_SIZE] = 0;   ! Size of return data block

    ! Initialize input buffer

    POINTER = ch$ptr (.ST[ST_INPUT_BUFFER],,8);
    $INITIALIZE_BLOCK (.ST[ST_INPUT_BUFFER], INPUT_MESSAGE_SIZE);

    ! If data is available on the logical link then process data

    while not .STATUS<$(mo_eom)>
    do begin

       ! Check the status of the logical link.

       GAD$LINK_STATUS (.ST[ST_JFN], STATUS);

       ! Check for error code in the right half of the status word.
       ! Return error if the logical link is aborted or closed without user's
       ! consent or knowledge

       if (.STATUS<$(mo_abt)> or .STATUS<$(mo_syn)>)
       then begin
            GAM$ABORT_REASON (.ST[ST_JFN]);
            end;

       if .ST[STOP_TRACE]     ! Has a ^Z been typed to stop tracing?
       then begin
            ARGBLK[RSP_RETURN_PROTOCOL_CODE] = ST$STP;   ! Stop tracing
            return;
            end;
    end;

    decr I from 10 to 1
       do begin
          STATUS = SNT$_NODATA;
          if (not jsys_sibe (.ST[ST_JFN]; , COUNT))
          and (.COUNT gtr 0)
          then begin
               STATUS = GAM$RECEIVE_RESPONSE (ST);
               EXITLOOP;
               end
          else jsys_disms (2000);      ! wait for 2 seconds
          end;
    if .STATUS = SNT$_NODATA
       then begin
            GAD$ABORT_LINK (.ST[ST_JFN]);
            $SNT_ERROR (SNT$_NODATA);
            end;
    if GAP$RI_PROTOCOL_TYPE (.POINTER, .COUNT)
    then begin                               ! Successful parse
         ARGBLK[RSP_RETURN_CODE] = RC_SUC;   ! Success code
         ARGBLK[RSP_FLAGS] = .ST[ST_FLAGS];  ! Status flags
         ARGBLK[RSP_RETURN_PROTOCOL_CODE] = .ST[ST_RSP_CODE];
         ARGBLK[RSP_RETURN_DATA_ADDRESS] = .ST[ST_DATA_BLOCK]; ! Data block
         ARGBLK[RSP_RETURN_DATA_SIZE] = .ST[ST_DATA_SIZE];   ! Size of data
         return;
         end;

    return;
    end;                                ! End of R_RSP
end                                   ! End of Module SGATRM
eludom
! Local Modes:
! Mode:BLISS
! Auto Save Mode:2
! Comment Column:40
! Comment Rounding:+1
! End: