?? RIGHT := 110 ??
?? NEWTITLE := 'NAM/VE: Session Application Interface Layer' ??
MODULE nam$se_external_interface;
?? RIGHT := 110 ??

?? NEWTITLE := '  Global Declarations Referenced by this Module' ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$job_paged_literal
*copyc oss$network_paged
*copyc oss$task_private
*copyc osd$integer_limits
*copyc ame$device_class_validation
*copyc ame$improper_file_id
*copyc ame$ring_validation_errors
*copyc cle$ecc_lexical
*copyc fme$file_management_errors
*copyc nae$application_interfaces
*copyc nae$internal_interactive_appl
*copyc fst$file_reference
*copyc jmt$timesharing_signal
*copyc nat$connection_descriptor
*copyc nat$connection_state
*copyc nat$create_attributes
*copyc nat$network_address
*copyc nat$network_message_priority
*copyc nat$receiver_request
*copyc nat$se_event_element_queue
*copyc nat$se_supervisory_event_queue
*copyc nat$sender_request
*copyc nlt$cc_connection
*copyc nlt$se_max_active_connections
*copyc nlt$sl_event
*copyc nlt$sl_inventory_report
*copyc nlt$sl_pdu_header
*copyc ost$activity_status
*copyc ost$caller_identifier
*copyc ost$hardware_subranges
*copyc ost$wait
?? POP ??
*copyc amp$return
*copyc amp$set_file_instance_abnormal
*copyc baf$task_file_entry_p
*copyc clp$convert_str_to_path_handle
*copyc fmp$clear_switch_offer
*copyc fmp$convert_status
*copyc fmp$create_network_file
*copyc fmp$get_connect_time_interval
*copyc fmp$get_connection_identifier
*copyc fmp$open_network_file
*copyc fmp$process_disconnect
*copyc fmp$record_nominal_disconnect
*copyc fmp$register_nominal_connection
*copyc fmp$remove_connection_id
*copyc fmp$set_switch_offer
*copyc fmp$simulate_connection_broken
*copyc fmp$store_connection_id
*copyc fmp$unsimulate_connection_broke
*copyc nap$condition_handler_trace
*copyc nap$delete_connection
*copyc nap$gt_close_job_connections
*copyc nap$gt_delete_job_saps
*copyc nap$move_data_to_user_data_area
*copyc nap$move_user_data_to_data_area
*copyc nap$namve_system_error
*copyc nap$process_connect_indication
*copyc nap$reset_received_message_list
*copyc nlp$al_deliver_data
*copyc nlp$al_fragment_data
*copyc nlp$al_get_data_length
*copyc nlp$al_get_data_requirements
*copyc nlp$al_initialize_data_descrip
*copyc nlp$bm_concatenate_messages
*copyc nlp$bm_create_message
*copyc nlp$bm_flush_message
*copyc nlp$bm_get_message_length
*copyc nlp$bm_get_message_prefix
*copyc nlp$bm_get_message_resources
*copyc nlp$bm_release_message
*copyc nlp$bm_valid_message_id
*copyc nlp$cancel_timer
*copyc nlp$cl_activate_layer
*copyc nlp$cl_activate_receiver
*copyc nlp$cl_activate_sender
*copyc nlp$cl_clear_exclusive_access
*copyc nlp$cl_create_connection
*copyc nlp$cl_deactivate_layer
*copyc nlp$cl_deactivate_receiver
*copyc nlp$cl_deactivate_sender
*copyc nlp$cl_get_connection_processor
*copyc nlp$cl_get_exclusive_via_cid
*copyc nlp$cl_get_layer_connection
*copyc nlp$cl_get_sap_processor
*copyc nlp$cl_initialize_template
*copyc nlp$cl_release_exclusive_access
*copyc nlp$osi_get_outbound_capacity
*copyc nlp$select_timer
*copyc nlp$sk_process_job_recovery
*copyc nlp$sl_call_request
*copyc nlp$sl_call_response
*copyc nlp$sl_clear_request
*copyc nlp$sl_close_sap
*copyc nlp$sl_data_request
*copyc nlp$sl_initialize
*copyc nlp$sl_interrupt_request
*copyc nlp$sl_open_sap
*copyc nlp$sl_synch_request
*copyc nlp$sl_synch_response
*copyc nlp$ta_report_undelivered_data
*copyc nlp$timer_expired
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$copy_local_status_to_status
*copyc osp$disestablish_cond_handler
*copyc osp$establish_condition_handler
*copyc osp$format_message
*copyc osp$increment_locked_variable
*copyc osp$is_caller_system_privileged
*copyc osp$pop_inhibit_job_recovery
*copyc osp$push_inhibit_job_recovery
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc osp$set_status_from_condition
*copyc pmp$continue_to_cause
*copyc pmp$get_executing_task_gtid
*copyc pmp$get_job_monitor_gtid
*copyc pmp$ready_task
*copyc pmp$send_signal
*copyc syp$cycle
*copyc bav$last_tft_entry
*copyc bav$task_file_table
*copyc bav$tft_entry_assignment
*copyc jmv$connection_acquired
*copyc jmv$executing_within_system_job
*copyc nav$global_statistics
*copyc nav$namve_active
*copyc nav$network_paged_heap
*copyc nlv$bm_null_message_id
*copyc osv$task_private_heap
?? OLDTITLE ??
?? NEWTITLE := '  Global Declarations Declared by this Module' ??

  CONST
    nac$maximum_connect_data = 512,
    nac$maximum_termination_data = 512,
    nac$inactive_receiver_timeout = 600000000;

{ nat$vtp_output_data is used only in nap$process_sap_events.  It is needed for
{ any error messages that are sent to the TIP.

  TYPE
    nat$vtp_output_data = packed record
      message_type: 0 .. 0ff(16),
      formatting_mode: 0 .. 0ff(16),
      filler1: 0 .. 1f(16),
      suppress_echoplex: boolean,
      suppress_end_of_line_partition: boolean,
      partial_output: boolean,
      filler2: 0 .. 0ff(16),
    recend;

  VAR
    nav$eoi_message: [STATIC, READ, oss$job_paged_literal] nat$eoi_message := [4, '*EOI'],

    nav$se_initialized_connection: [STATIC, READ, oss$job_paged_literal] nat$connection_descriptor := [
{ SENDER_REQUEST                } * ,
{ RECEIVER_REQUEST              } * ,
{ SEND_TIMEOUT                  } FALSE,
{ RECEIVE_TIMEOUT               } FALSE,
{ CONNECTION_STATE              } * ,
{ WAIT_STATE                    } nac$inactive_wait,
{ AWAIT_SERVER_RESPONSE_TASK_ID } * ,
{ AWAIT_SERVER_RESPONSE         } FALSE,
{ INTERMEDIATE_PUT_PARTIAL      } FALSE,
{ SEND_PUT_PARTIAL              } FALSE,
{ RECORD_LENGTH                 } 0,
{ TRANSFER_COUNT                } 0,
{ CLIENT                        } FALSE,
{ APPLICATION_NAME              } * ,
{ SIMULATED_CONNECTION_BROKEN   } FALSE,
{ BREAK_CONDITION_ACTIVE        } FALSE,
{ BREAK_CONNECTION_RECEIVE      } FALSE,
{ BREAK_CONNECTION_SEND         } FALSE,
{ DISCARD_TO_END_OF_MESSAGE     } FALSE,
{ SYNCHRONIZE_RECEIVE           } FALSE,
{ SYNCHRONIZE_SEND              } FALSE,
{ SYNCHRONIZE_REQUEST_RECEIVE   } FALSE,
{ SYNCHRONIZE_REQUEST_SEND      } FALSE,
{ NOMINAL_CONNECTION            } FALSE,
{ NOMINAL_CONNECTION_TASK_ID    } * ,
{ RECEIVE_SYNCHRONIZE_COUNT     } 0,
{ SEND_SYNCHRONIZE_COUNT        } 0,
{ RECEIVE_FILE_IDENTIFIER       } * ,
{ SEND_FILE_IDENTIFIER          } * ,
{ TOTAL_DATA_QUEUED             } 0,
{ TOTAL_MESSAGE_BUFFERS         } 0,
{ EVENT_TIMER                   } * ,
{ RECEIVE_TIMER                 } * ,
{ SEND_TIMER                    } * ,
{ TIMESHARING_DISCONNECT_SENT   } FALSE,
{ JOB_MONITOR_TASK_ID           } * ,
{ LOCAL_FILE_NAME               } ' ',
{ CLIENT_IDENTITY               } [' ', ' '],
{ CONNECT_DATA                  } NIL,
{ DATA_TRANSFER_TIMEOUT         } 60000,
{ EOI_MESSAGE_ENABLED           } FALSE,
{ EOI_MESSAGE                   } NIL,
{ EOI_PEER_TERMINATION          } FALSE,
{ LOCAL_ADDRESS                 } * ,
{ PEER_ACCOUNTING_INFORMATION   } NIL,
{ PEER_ADDRESS                  } * ,
{ PEER_CONNECT_DATA             } NIL,
{ PEER_TERMINATION_DATA         } NIL,
{ RECEIVE_WAIT_SWAPOUT          } FALSE,
{ TERMINATION_DATA              } NIL,
{ TERMINATION_REASON            } * ,
{ PROTOCOL                      } nac$cdna_session,
{ DATA_QUEUE                    } [0, NIL, NIL],
{ SUPERVISORY_EVENT_QUEUE       } [NIL, NIL],
{ EVENT                         } * ],

    nav$null_data: [STATIC, READ, oss$job_paged_literal] array [1 .. 1] of nat$data_fragment := [[NIL, 0]],
    application_kind: [STATIC, READ, oss$job_paged_literal] array [boolean] of
          nat$application_type := [nac$server_application, nac$client_application],
    invalid_file_identifier: [STATIC, READ, oss$job_paged_literal] string (23) := 'Invalid file identifier';

?? TITLE := ' Internal Declarations', EJECT ??

  TYPE
    nat$se_condition_cause = (nac$application_data, nac$application_event, nac$activity_status,
          nac$request_not_cause);

?? TITLE := 'Global Debug Declarations', EJECT ??
*copyc osp$decrement_locked_variable
*copyc nav$debug_mode

  VAR
    nav$multiple_namve_hndler_calls: [XREF] integer,
    nav$namve_tsk_hndl_active_count: [XREF] integer;

?? TITLE := 'NAP$SE_REQUEST_CONNECTION' ??
?? NEWTITLE := '    TERMINATE_REQUEST_CONNECTION -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL] nap$se_request_connection
    (    sap_id: nat$generic_sap_identifier;
         server: nat$network_address;
         client: nat$application_name;
         file: fst$file_reference;
         attributes: ^nat$create_attributes;
         sap_priority: nat$network_message_priority;
     VAR connection_id: nat$connection_id;
     VAR status: ost$status);


    PROCEDURE terminate_request_connection
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = mmc$segment_access_condition, pmc$system_conditions =
        IF cl_connection <> NIL THEN
          connection^.connection_state := nac$terminated;
          terminate_connection (connection, cl_connection);
          nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
          nlp$cl_clear_exclusive_access (cl_connection);
          fmp$remove_connection_id (file, local_status);
          amp$return (file, local_status);
        IFEND;
        osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
        EXIT nap$se_request_connection; {----->
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      = pmc$block_exit_processing =
        IF cl_connection <> NIL THEN
          connection^.connection_state := nac$terminated;
          terminate_connection (connection, cl_connection);
          nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
          nlp$cl_clear_exclusive_access (cl_connection);
          fmp$remove_connection_id (file, local_status);
          amp$return (file, local_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_request_connection;
?? OLDTITLE, EJECT ??

    VAR
      cl_connection: ^nlt$cl_connection,
      condition_cause: nat$se_condition_cause,
      connection: ^nat$connection_descriptor,
      connection_exits: boolean,
      data_fragment: nat$data_fragment,
      evaluated_file_reference: fst$evaluated_file_reference,
      layer_active: boolean,
      local_status: ost$status;

    status.normal := TRUE;
    condition_cause := nac$request_not_cause;
    #SPOIL (condition_cause);
    cl_connection := NIL;
    #SPOIL (cl_connection);
    osp$establish_condition_handler (^terminate_request_connection, TRUE);
    IF server.kind = nac$osi_transport_address THEN
      nlp$cl_create_connection (nlc$osi_session_interface, cl_connection);
    ELSE
      osp$set_status_condition (nae$unsupported_address, status);
      osp$disestablish_cond_handler;
      RETURN; {----->
    IFEND;
    IF cl_connection <> NIL THEN
      nlp$cl_activate_layer (cl_connection^.application_layer, cl_connection);
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      #SPOIL (connection);
      connection^ := nav$se_initialized_connection;
      nlp$cancel_timer (connection^.send_timer);
      connection^.receive_timer := connection^.send_timer;
      connection^.event_timer := connection^.send_timer;
      connection^.peer_address := server;
      connection^.local_address.kind := nac$osi_sap_identifier;
      connection^.local_address.identifier := sap_id.osi_sap_identifier;
      connection^.protocol := nac$cdna_session;
      connection^.connection_state := nac$connection_request_sent;
      connection^.application_name := client;
      connection^.client := TRUE;
      pmp$get_job_monitor_gtid (connection^.job_monitor_task_id, local_status);
      clp$convert_str_to_path_handle (file, {delete_allowed=} TRUE, {resolve_path=} TRUE,
            {include_open_position=} TRUE, connection^.local_file_name, evaluated_file_reference, status);
      connection_id := cl_connection^.identifier;
      REPEAT
        ALLOCATE connection^.data_queue.beginning IN nav$network_paged_heap^;
        IF connection^.data_queue.beginning = NIL THEN
          syp$cycle;
        IFEND;
      UNTIL connection^.data_queue.beginning <> NIL;
      connection^.data_queue.ending := connection^.data_queue.beginning;
      connection^.data_queue.beginning^.next_element := NIL;
      create_network_file (file, attributes, cl_connection^.identifier, connection, status);
      IF status.normal THEN
        data_fragment.address := connection^.connect_data;
        IF connection^.connect_data <> NIL THEN
          data_fragment.length := #SIZE (connection^.connect_data^);
        ELSE
          data_fragment.length := 0;
        IFEND;
        nlp$sl_call_request (cl_connection, sap_id, server, client, data_fragment, sap_priority, status);
        IF NOT status.normal THEN
          connection^.connection_state := nac$terminated;
          terminate_connection (connection, cl_connection);
          nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
          nlp$cl_release_exclusive_access (cl_connection);
          fmp$remove_connection_id (file, local_status);
          amp$return (file, local_status);
        ELSE
          nlp$cl_release_exclusive_access (cl_connection);
        IFEND;
      ELSE
        FREE connection^.data_queue.beginning IN nav$network_paged_heap^;
        nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
        nlp$cl_release_exclusive_access (cl_connection);
        IF (status.condition = nae$unknown_attribute) OR (status.condition = nae$max_data_length_exceeded) OR
              (status.condition = nae$invalid_eoi_message_size) THEN
          fmp$remove_connection_id (file, {ignore} local_status);
          amp$return (file, {ignore} local_status);
        IFEND;
      IFEND;
    ELSE
      osp$set_status_condition (nae$namve_max_connection_limit, status);
    IFEND;
    osp$disestablish_cond_handler;

  PROCEND nap$se_request_connection;
?? TITLE := 'NAP$CREATE_NETWORK_FILE' ??
?? NEWTITLE := '    TERMINATE_CREATE_NETWORK_FILE -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL] nap$create_network_file
    (    file: fst$file_reference;
         attributes: ^nat$create_attributes;
         connection_id: nat$connection_id;
         timesharing_connection_switch: boolean;
     VAR status: ost$status);


    PROCEDURE terminate_create_network_file
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          IF NOT timesharing_connection_switch THEN
            fmp$remove_connection_id (file, ignore_status);
            amp$return (file, ignore_status);
          IFEND;
        IFEND;
        osp$pop_inhibit_job_recovery;
        osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
        EXIT nap$create_network_file; {----->
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_create_network_file;
?? OLDTITLE, EJECT ??

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      evaluated_file_reference: fst$evaluated_file_reference,
      ignore_status: ost$status,
      layer_active: boolean;

    status.normal := TRUE;
    IF NOT timesharing_connection_switch THEN
      cl_connection := NIL;
      osp$push_inhibit_job_recovery;
      osp$establish_condition_handler (^terminate_create_network_file, FALSE);
      nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
      IF connection_exists THEN
        nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active,
              connection);
        IF layer_active THEN
          create_network_file (file, attributes, connection_id, connection, status);
          IF status.normal THEN
            pmp$get_job_monitor_gtid (connection^.job_monitor_task_id, status);
            clp$convert_str_to_path_handle (file, {delete_allowed=} TRUE, {resolve_path=} TRUE,
                  {include_open_position=} TRUE, connection^.local_file_name, evaluated_file_reference,
                  status);
            nlp$cl_release_exclusive_access (cl_connection);
          ELSE
            nlp$cl_release_exclusive_access (cl_connection);
            IF (status.condition = nae$unknown_attribute) OR (status.condition =
                  nae$max_data_length_exceeded) OR (status.condition = nae$invalid_eoi_message_size) THEN
              fmp$remove_connection_id (file, ignore_status);
              amp$return (file, ignore_status);
            IFEND;
          IFEND;
        ELSE
          nlp$cl_release_exclusive_access (cl_connection);
          osp$set_status_condition (nae$connection_terminated, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      osp$pop_inhibit_job_recovery;
    ELSE { IF timesharing_connection_switch THEN
      osp$push_inhibit_job_recovery;
      nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
      IF connection_exists THEN
        nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active,
              connection);
        IF layer_active THEN
          pmp$get_job_monitor_gtid (connection^.job_monitor_task_id, status);
          clp$convert_str_to_path_handle (file, {delete_allowed=} TRUE, {resolve_path=} TRUE,
                {include_open_position=} TRUE, connection^.local_file_name, evaluated_file_reference, status);
        IFEND;
        nlp$cl_release_exclusive_access (cl_connection);
      IFEND;
      osp$pop_inhibit_job_recovery;
      fmp$store_connection_id (file, connection_id, status);
      IF NOT status.normal THEN
        IF status.condition = fme$no_cycle_description THEN
          osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, 'NAP$CREATE_NETWORK_FILE ', status);
        IFEND;
      IFEND;
    IFEND;
  PROCEND nap$create_network_file;

?? TITLE := 'CREATE_NETWORK_FILE', EJECT ??

  PROCEDURE [INLINE] create_network_file
    (    file: fst$file_reference;
         attributes: ^nat$create_attributes;
         connection_id: nat$connection_id;
         connection: ^nat$connection_descriptor;
     VAR status: ost$status);

    VAR
      attribute_p: ^nat$create_attribute,
      error_string: string (256),
      i: integer,
      length: integer,
      local_status: ost$status;

    status.normal := TRUE;
    fmp$create_network_file (file, connection_id, connection^.connection_state, status);
    IF status.normal THEN
      IF attributes <> NIL THEN
        FOR i := LOWERBOUND (attributes^) TO UPPERBOUND (attributes^) DO
          attribute_p := ^attributes^ [i];
          CASE attribute_p^.kind OF
          = nac$connect_data =
            IF ((attribute_p^.connect_data <> NIL) AND (#SIZE (attribute_p^.connect_data^) <=
                  nac$maximum_connect_data)) OR (attribute_p^.connect_data = NIL) THEN
              nap$move_user_data_to_data_area (attribute_p^.connect_data, connection^.connect_data);
            ELSE
              STRINGREP (error_string, length, nac$maximum_connect_data, ' for NAC$CONNECT_DATA');
              osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, error_string, status);
            IFEND;
          = nac$data_transfer_timeout =
            connection^.data_transfer_timeout := attribute_p^.data_transfer_timeout;
          = nac$eoi_message =
            IF attribute_p^.eoi_message.size <= 31 {nac$maximum_eoi_size} THEN
              IF connection^.eoi_message = NIL THEN
                REPEAT
                  ALLOCATE connection^.eoi_message IN nav$network_paged_heap^;
                  IF connection^.eoi_message = NIL THEN
                    syp$cycle;
                  IFEND;
                UNTIL connection^.eoi_message <> NIL;
              IFEND;
              connection^.eoi_message^ := attribute_p^.eoi_message;
            ELSE
              osp$set_status_abnormal (nac$status_id, nae$invalid_eoi_message_size, '31'
                    {nac$maximum_eoi_size} , status);
            IFEND;
          = nac$eoi_message_enabled =
            connection^.eoi_message_enabled := attribute_p^.eoi_message_enabled;
          = nac$eoi_peer_termination =
            connection^.eoi_peer_termination := attribute_p^.eoi_peer_termination;
          = nac$null_attribute =
          = nac$receive_wait_swapout =
            connection^.receive_wait_swapout := attribute_p^.receive_wait_swapout;
          = nac$termination_data =
            IF ((attribute_p^.termination_data <> NIL) AND (#SIZE (attribute_p^.termination_data^) <=
                  nac$maximum_termination_data)) OR (attribute_p^.termination_data = NIL) THEN
              nap$move_user_data_to_data_area (attribute_p^.termination_data, connection^.termination_data);
            ELSE
              STRINGREP (error_string, length, nac$maximum_termination_data, ' for NAC$TERMINATION_DATA');
              osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, error_string, status);
            IFEND;
          ELSE
            osp$set_status_abnormal (nac$status_id, nae$unknown_attribute, ' for CREATE NETWORK FILE ',
                  status);
            RETURN; {----->
          CASEND;
        FOREND;
      IFEND;
    IFEND;

  PROCEND create_network_file;
?? TITLE := '  [XDCL] NAP$CHECK_SERVER_RESPONSE', EJECT ??

  PROCEDURE [XDCL] nap$check_server_response
    (    file: fst$file_reference;
     VAR activity_complete: boolean;
     VAR status: ost$status);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      connection_id: nat$connection_id,
      layer_active: boolean,
      processing_task: ost$global_task_id,
      switch_offer_pending: boolean;

    status.normal := TRUE;
    activity_complete := TRUE;
    fmp$get_connection_identifier (file, connection_id, switch_offer_pending, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A CHECK SERVER RESPONSE ', status);
      ELSEIF status.condition <> ame$improper_device_class THEN
        status.normal := TRUE;
      IFEND;
      RETURN; {----->
    IFEND;

    IF switch_offer_pending THEN
      osp$set_status_abnormal (nac$status_id, nae$switch_offer_pending, file, status);
      RETURN; {----->
    IFEND;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.connection_state = nac$connection_request_sent THEN
          pmp$get_executing_task_gtid (processing_task);
          IF connection^.await_server_response THEN
            IF processing_task <> connection^.await_server_response_task_id THEN
              osp$set_status_abnormal (nac$status_id, nae$multiple_waits_attempted, file, status);
            ELSE
              activity_complete := FALSE;
            IFEND;
          ELSE
            activity_complete := FALSE;
            connection^.await_server_response := TRUE;
            connection^.await_server_response_task_id := processing_task;
          IFEND;
        IFEND;
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nap$check_server_response;

?? TITLE := '  [XDCL] NAP$REMOVE_WAIT_SERVER_RESPONSE', EJECT ??

  PROCEDURE [XDCL] nap$remove_wait_server_response
    (    file: fst$file_reference);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      connection_id: nat$connection_id,
      layer_active: boolean,
      processing_task: ost$global_task_id,
      switch_offer_pending: boolean,
      status: ost$status;

    fmp$get_connection_identifier (file, connection_id, switch_offer_pending, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A REMOVE SERVER RESPONSE WAITS ',
              status);
      IFEND;

      RETURN; {----->
    IFEND;

    IF switch_offer_pending THEN
      RETURN; {----->
    IFEND;

    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active AND (connection^.connection_state <> nac$terminated)
{   } AND (connection^.await_server_response) THEN
        pmp$get_executing_task_gtid (processing_task);
        IF processing_task = connection^.await_server_response_task_id THEN
          connection^.await_server_response := FALSE;
        IFEND;
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    IFEND;

  PROCEND nap$remove_wait_server_response;
?? TITLE := '  [XDCL] NAP$CHECK_DATA_AVAILABLE', EJECT ??

  PROCEDURE [XDCL] nap$check_data_available
    (    file_identifier: amt$file_identifier;
     VAR activity_complete: boolean;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      file_instance: ^bat$task_file_entry,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      processing_task: ost$global_task_id;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    activity_complete := TRUE;
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r2 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, nac$await_data_available,
            '', status);
      RETURN; {----->
    IFEND;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.wait_state = nac$inactive_wait THEN
          IF (connection^.supervisory_event_queue.beginning <> NIL) OR
                ((connection^.data_queue.count > 0) AND ((connection^.total_data_queued >= 4096
                {nac$min_await_data_avail} ) OR (connection^.data_queue.beginning^.
                event_element [connection^.data_queue.beginning^.first].event.end_of_message) OR
                (connection^.total_message_buffers_queued >= 4))) THEN
            activity_complete := TRUE;
          ELSEIF (connection^.connection_state <> nac$terminated) AND
                (NOT connection^.break_condition_active) AND (NOT connection^.simulated_connection_broken)
                THEN
            nlp$cl_activate_receiver (cl_connection);
            connection^.wait_state := nac$waiting_for_data_available;
            activity_complete := FALSE;
          IFEND;
        ELSEIF connection^.wait_state = nac$waiting_for_data_available THEN
          pmp$get_executing_task_gtid (processing_task);
          IF processing_task <> cl_connection^.message_receiver.task THEN
            osp$set_status_condition (nae$multiple_waits_attempted, status);
          ELSE
            activity_complete := FALSE;
          IFEND;
        ELSE {IF connection^.wait_state = nac$wait_to_receive_data THEN
          osp$set_status_condition (nae$multiple_waits_attempted, status);
        IFEND;
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nap$check_data_available;
?? TITLE := '  [XDCL] NAP$REMOVE_WAIT_DATA_AVAILABLE', EJECT ??

  PROCEDURE [XDCL] nap$remove_wait_data_available
    (    file_identifier: amt$file_identifier);

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      file_instance: ^bat$task_file_entry,
      layer_active: boolean,
      processing_task: ost$global_task_id,
      status: ost$status;

    #CALLER_ID (caller_id);
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r2 THEN
      RETURN; {----->
    IFEND;

    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active AND (connection^.connection_state <> nac$terminated)
{   } AND (connection^.wait_state = nac$waiting_for_data_available) THEN
        pmp$get_executing_task_gtid (processing_task);
        IF processing_task = cl_connection^.message_receiver.task THEN
          nlp$cl_deactivate_receiver (cl_connection);
          connection^.wait_state := nac$inactive_wait;
        IFEND;
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    IFEND;

  PROCEND nap$remove_wait_data_available;
?? TITLE := ' [XDCL] nlp$se_initialize', EJECT ??
*copyc nlh$se_initialize

  PROCEDURE [XDCL] nlp$se_initialize;

    VAR
      sap_processor: nlt$cl_event_processor,
      connection_processor: nlt$cl_event_processor;

    nlp$cl_initialize_template (nlc$osi_session_interface, nlc$osi_session_interface,
          #SIZE (nat$connection_descriptor), 0, sap_processor, nac$monitor_server_connections
          { This is for nam$application_management} , connection_processor, nac$se_evaluate_io_timers);
    nlp$sl_initialize (nac$se_process_sap_event, nac$se_process_connection_event, nlc$osi_session_interface);

  PROCEND nlp$se_initialize;
?? TITLE := '  [XDCL] NLP$SE_CLOSE_SAP', EJECT ??

  PROCEDURE [XDCL] nlp$se_close_sap
    (    sap: nat$generic_sap_identifier;
     VAR status: ost$status);

    status.normal := TRUE;
    osp$push_inhibit_job_recovery;
    nlp$sl_close_sap (sap, status);
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$se_close_sap;
?? TITLE := ' [XDCL] NLP$SE_OPEN_SAP', EJECT ??
*copyc nlh$se_open_sap

  PROCEDURE [XDCL] nlp$se_open_sap
    (    sap_timer_evaluator: nat$network_procedure;
         accept_connect_events: boolean;
         maximum_active_connections: nlt$se_max_active_connections;
     VAR status: ost$status);

    VAR
      sap_processor: nlt$cl_event_processor,
      connection_processor: nlt$cl_event_processor;

    IF NOT nav$namve_active THEN
      osp$set_status_condition (nae$network_inactive, status);
      RETURN; {----->
    IFEND;

    status.normal := TRUE;
    IF ((maximum_active_connections > 0) AND (maximum_active_connections <=
          UPPERVALUE (nlt$se_max_active_connections))) THEN
      osp$push_inhibit_job_recovery;
      nlp$cl_initialize_template (nlc$osi_session_interface, nlc$osi_session_interface,
            #SIZE (nat$connection_descriptor), 0, sap_processor, sap_timer_evaluator, connection_processor,
            nac$se_evaluate_io_timers);
      nlp$sl_open_sap (nac$se_process_sap_event, nac$se_process_connection_event, nlc$osi_session_interface,
            accept_connect_events, maximum_active_connections, status);
      osp$pop_inhibit_job_recovery;
    ELSEIF (maximum_active_connections = 0) THEN
      osp$set_status_condition (nae$max_active_connections_0, status);
    ELSE
      osp$set_status_condition (nae$max_active_conn_exceeded, status);
    IFEND;
  PROCEND nlp$se_open_sap;
?? TITLE := '  [XDCL] NLP$SE_ACCEPT_CONNECTION', EJECT ??

  PROCEDURE [XDCL] nlp$se_accept_connection
    (    cl_connection: ^nlt$cl_connection;
     VAR status: ost$status);

    VAR
      connection: ^nat$connection_descriptor,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      layer_active: boolean,
      message_id: nlt$bm_message_id;

    status.normal := TRUE;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
    IF layer_active THEN
      IF connection^.connection_state = nac$connection_request_received THEN
        IF connection^.connect_data <> NIL THEN
          data_fragments [1].address := connection^.connect_data;
          data_fragments [1].length := #SIZE (connection^.connect_data^);
        ELSE
          data_fragments [1] := nav$null_data [1];
        IFEND;
        nlp$sl_call_response (cl_connection, data_fragments, status);
        IF status.normal THEN
          connection^.connection_state := nac$established;
        IFEND;
      ELSEIF connection^.connection_state = nac$terminated THEN
        osp$set_status_condition (nae$connection_terminated, status);
      ELSE
        osp$set_status_condition (nae$invalid_request, status);
      IFEND;
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$se_accept_connection;

?? TITLE := '[XDCL] nap$get_connect_time_interval', EJECT ??

*copy nah$get_connect_time_interval

  PROCEDURE [XDCL] nap$get_connect_time_interval
    (    file: fst$file_reference;
     VAR connect_time: ost$non_negative_integers;
     VAR status: ost$status);

    osp$push_inhibit_job_recovery;
    fmp$get_connect_time_interval (file, connect_time, status);
    osp$pop_inhibit_job_recovery;

  PROCEND nap$get_connect_time_interval;

?? TITLE := '  [XDCL] NAP$GET_CONNECTION_IDENTIFIER', EJECT ??

  PROCEDURE [XDCL] nap$get_connection_identifier
    (    file: fst$file_reference;
     VAR connection_id: nat$connection_id;
     VAR status: ost$status);

    VAR
      switch_offer_pending: boolean;

    fmp$get_connection_identifier (file, connection_id, switch_offer_pending, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A GET CONNECTION IDENTIFIER ', status);
      IFEND;
    IFEND;

  PROCEND nap$get_connection_identifier;
?? TITLE := '  [XDCL, #GATE] nap$get_connection_state', EJECT ??

  PROCEDURE [XDCL, #GATE] nap$get_connection_state
    (    connection_id: nat$connection_id;
     VAR connection_state: nat$connection_state;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection_exists: boolean,
      connection: ^nat$connection_descriptor,
      layer_active: boolean;

    #CALLER_ID (caller_id);
    IF caller_id.ring > 3 THEN
      osp$set_status_abnormal ('NA', nae$insufficient_privilege, 'nap$get_connection_state', status);
      RETURN; {----->
    IFEND;

    status.normal := TRUE;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        connection_state := connection^.connection_state;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
  PROCEND nap$get_connection_state;
?? TITLE := '  [XDCL] NAP$REMOVE_CONNECTION_ID', EJECT ??

  PROCEDURE [XDCL] nap$remove_connection_id
    (    file: fst$file_reference;
     VAR status: ost$status);

    fmp$remove_connection_id (file, status);

  PROCEND nap$remove_connection_id;
?? TITLE := '  [XDCL] NAP$CLEAR_SWITCH_OFFER', EJECT ??

  PROCEDURE [XDCL] nap$clear_switch_offer
    (    file: fst$file_reference;
         switch_complete: boolean;
     VAR status: ost$status);

    fmp$clear_switch_offer (file, switch_complete, status);

  PROCEND nap$clear_switch_offer;
?? TITLE := '  [XDCL] NAP$SET_SWITCH_OFFER', EJECT ??

  PROCEDURE [XDCL] nap$set_switch_offer
    (    file: fst$file_reference;
         timesharing_connection_switch: boolean;
     VAR connection_id: nat$connection_id;
     VAR application_name: nat$application_name;
     VAR status: ost$status);

    fmp$set_switch_offer (file, timesharing_connection_switch, application_name, connection_id, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A OFFER SWITCH ', status);
      IFEND;
    IFEND;

  PROCEND nap$set_switch_offer;
?? TITLE := '  [XDCL] NLP$SWITCH_OFFER_SET', EJECT ??

  PROCEDURE [XDCL] nlp$switch_offer_set
    (    connection_id: nat$connection_id;
     VAR application_name: nat$application_name;
     VAR status: ost$status);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      layer_active: boolean;

    status.normal := TRUE;
    application_name := ' ';
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF NOT connection^.nominal_connection THEN
          application_name := connection^.application_name;
        ELSE
          osp$set_status_condition (nae$nominal_connection, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$switch_offer_set;
?? TITLE := '  [XDCL] NLP$REGISTER_NOMINAL_CONNECTION', EJECT ??

  PROCEDURE [XDCL] nlp$register_nominal_connection
    (    file: fst$file_reference;
     VAR status: ost$status);

    fmp$register_nominal_connection (file, status);

  PROCEND nlp$register_nominal_connection;
?? TITLE := '  [XDCL] NLP$NOMINAL_CONN_REGISTRATION', EJECT ??

  PROCEDURE [XDCL] nlp$nominal_conn_registration
    (    connection_id: nat$connection_id;
     VAR status: ost$status);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      ignore_status: ost$status,
      layer_active: boolean;

    status.normal := TRUE;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN

        ; {do not allow request if synch_confirm is required

        IF NOT connection^.nominal_connection THEN
          IF connection^.simulated_connection_broken THEN
            connection^.simulated_connection_broken := FALSE;
          IFEND;
          connection^.nominal_connection := TRUE;
          pmp$get_job_monitor_gtid (connection^.nominal_connection_task_id, ignore_status);
          IF connection^.supervisory_event_queue.beginning <> NIL THEN
            process_nominal_connect_events (connection, cl_connection);
          IFEND;
        ELSE
          osp$set_status_condition (nae$nominal_connection, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$nominal_conn_registration;
?? TITLE := '  [XDCL] NLP$SIMULATE_CONNECTION_BROKEN', EJECT ??

  PROCEDURE [XDCL] nlp$simulate_connection_broken
    (    file: fst$file_reference;
     VAR status: ost$status);

    fmp$simulate_connection_broken (file, status);

  PROCEND nlp$simulate_connection_broken;
?? TITLE := '  [XDCL] NLP$CONNECTION_SIMULATED_BROKEN', EJECT ??

  PROCEDURE [XDCL] nlp$connection_simulated_broken
    (    connection_id: nat$connection_id;
     VAR status: ost$status);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      layer_active: boolean;

    status.normal := TRUE;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.nominal_connection THEN
          IF NOT connection^.break_condition_active THEN
            connection^.nominal_connection := FALSE;
            connection^.simulated_connection_broken := TRUE;
            IF connection^.wait_state = nac$waiting_for_data_available THEN
              pmp$ready_task (cl_connection^.message_receiver.task, {ignore} status);
              nlp$cl_deactivate_receiver (cl_connection);
              connection^.wait_state := nac$inactive_wait;
            ELSEIF connection^.wait_state = nac$waiting_to_receive_data THEN
              connection^.break_connection_receive := TRUE;
              activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
            IFEND;
            IF cl_connection^.message_sender.active THEN
              connection^.break_connection_send := TRUE;
              activate_sender_task (cl_connection, cl_connection^.message_sender.task);
            IFEND;
            status.normal := TRUE;
          ELSE
            osp$set_status_condition (nae$break_condition_active, status);
          IFEND;
        ELSE
          osp$set_status_condition (nae$not_nominal_connection, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$connection_simulated_broken;
?? TITLE := '  [XDCL] NLP$UNSIMULATE_CONNECTION_BROKE', EJECT ??

  PROCEDURE [XDCL] nlp$unsimulate_connection_broke
    (    file: fst$file_reference;
     VAR status: ost$status);

    fmp$unsimulate_connection_broke (file, status);

  PROCEND nlp$unsimulate_connection_broke;
?? TITLE := '  [XDCL] NLP$CONNECT_UNSIMULATED_BROKEN', EJECT ??

  PROCEDURE [XDCL] nlp$connect_unsimulated_broken
    (    connection_id: nat$connection_id;
     VAR status: ost$status);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      layer_active: boolean;

    status.normal := TRUE;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.simulated_connection_broken THEN
          connection^.simulated_connection_broken := FALSE;
        IFEND;
        IF connection^.connection_state = nac$terminated THEN
          osp$set_status_condition (nae$connection_terminated, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$connect_unsimulated_broken;
?? TITLE := '  [XDCL] NLP$RECORD_NOMINAL_DISCONNECT', EJECT ??

  PROCEDURE [XDCL] nlp$record_nominal_disconnect
    (    file: fst$file_reference;
     VAR status: ost$status);

    fmp$record_nominal_disconnect (file, status);

  PROCEND nlp$record_nominal_disconnect;
?? TITLE := '  [XDCL] NLP$NOMINAL_DISCONNECT_RECORD', EJECT ??

  PROCEDURE [XDCL] nlp$nominal_disconnect_record
    (    connection_id: nat$connection_id;
     VAR status: ost$status);

    VAR
      active_file: boolean,
      application_name: nat$application_name,
      cl_connection: ^nlt$cl_connection,
      client: boolean,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      delete_connection: boolean,
      ignore_status: ost$status,
      layer_active: boolean;

    status.normal := TRUE;
    delete_connection := FALSE;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      client := (connection^.client = TRUE);
      application_name := connection^.application_name;
      IF layer_active THEN
        IF connection^.connection_state = nac$terminated THEN
          IF connection^.nominal_connection THEN
            IF (connection^.wait_state <> nac$inactive_wait) OR (cl_connection^.message_sender.active) THEN
              osp$set_status_condition (nae$connection_active, status);
            ELSE
              ; { DEACTIVATE LAYER
              delete_connection := TRUE;
              terminate_connection (connection, cl_connection);
              nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
            IFEND;
          ELSE
            osp$set_status_condition (nae$not_nominal_connection, status);
          IFEND;
        ELSE
          osp$set_status_condition (nae$connection_active, status);
        IFEND;
      ELSE
        delete_connection := TRUE;
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    IF delete_connection THEN
      nap$delete_connection (application_name, application_kind [client], connection_id, active_file,
            ignore_status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$nominal_disconnect_record;
?? TITLE := '  [XDCL, #GATE] NAP$ACCEPT_CONNECTION', EJECT ??

  PROCEDURE [XDCL, #GATE] nap$accept_connection
    (    file: fst$file_reference;
     VAR status: ost$status);

*copyc nah$accept_connection

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      connection_id: nat$connection_id,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      switch_offer_pending: boolean;

    fmp$get_connection_identifier (file, connection_id, switch_offer_pending, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'AN ACCEPT CONNECTION ', status);
      IFEND;
      RETURN; {----->
    IFEND;

    IF switch_offer_pending THEN
      osp$set_status_condition (nae$switch_offer_pending, status);
      RETURN; {----->
    IFEND;

    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.connection_state = nac$connection_request_received THEN
          IF connection^.connect_data <> NIL THEN
            data_fragments [1].address := connection^.connect_data;
            data_fragments [1].length := #SIZE (connection^.connect_data^);
          ELSE
            data_fragments [1] := nav$null_data [1];
          IFEND;
          nlp$sl_call_response (cl_connection, data_fragments, status);
          IF status.normal THEN
            connection^.connection_state := nac$established;
          IFEND;
        ELSEIF connection^.connection_state = nac$terminated THEN
          osp$set_status_condition (nae$connection_terminated, status);
        ELSE
          osp$set_status_condition (nae$accept_not_pending, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;

  PROCEND nap$accept_connection;
?? TITLE := '[XDCL, #GATE] nlp$se_get_available_byte_count', EJECT ??

  PROCEDURE [XDCL, #GATE] nlp$se_get_available_byte_count
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);

    VAR
      byte_count: nat$data_length,
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      file_instance: ^bat$task_file_entry,
      internal_status: ost$status,
      layer_active: boolean;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    internal_status.normal := TRUE;
    byte_count := 0;

    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r2 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.wait_state = nac$inactive_wait THEN
          byte_count := connection^.total_data_queued;
        ELSE
          osp$set_status_condition (nae$receive_outstanding, internal_status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, internal_status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, internal_status);
    IFEND;
    osp$pop_inhibit_job_recovery;
    osp$copy_local_status_to_status (internal_status, status);
    call_block.se_get_available_byte_count^ := byte_count;
  PROCEND nlp$se_get_available_byte_count;

?? TITLE := '  DELIVER_CONNECTION_EVENTS', EJECT ??

  PROCEDURE deliver_connection_events
    (    connection: ^nat$connection_descriptor;
         cl_connection: ^nlt$cl_connection;
     VAR delivery_complete: boolean;
     VAR condition_cause: nat$se_condition_cause;
     VAR status: ost$status);

    VAR
      delivered_message_buffers: nat$data_length,
      event: nat$se_peer_operation,
      event_element_p: ^nat$se_event_element,
      remaining_buffer_capacity: nat$data_length,
      supervisory_element_p: ^nat$se_supervisory_element;

    delivery_complete := FALSE;
    IF (connection^.data_queue.count > 0) OR (connection^.supervisory_event_queue.beginning <> NIL) THEN
      IF connection^.supervisory_event_queue.beginning = NIL THEN
        IF NOT connection^.discard_to_end_of_message THEN

{ Fragment and Deliver Queued Data

          event_element_p := ^connection^.data_queue.beginning^.
                event_element [connection^.data_queue.beginning^.first];
          IF event_element_p^.queued_data_length > connection^.receiver_request.remaining_buffer_capacity THEN
            remaining_buffer_capacity := connection^.receiver_request.remaining_buffer_capacity;
            condition_cause := nac$application_data;
            #SPOIL (condition_cause);
            CASE connection^.receiver_request.application_buffer.description_kind OF
            = nac$fixed =
              IF connection^.receiver_request.remaining_buffer_capacity > 0 THEN
                nlp$al_deliver_data (event_element_p^.message_id,
                      connection^.receiver_request.application_buffer.fixed_description,
                      connection^.receiver_request.remaining_buffer_capacity, delivered_message_buffers);
              IFEND;
            = nac$allocated =
              IF connection^.receiver_request.remaining_buffer_capacity > 0 THEN
                nlp$al_deliver_data (event_element_p^.message_id,
                      connection^.receiver_request.application_buffer.allocated_description^,
                      connection^.receiver_request.remaining_buffer_capacity, delivered_message_buffers);
              IFEND;
              FREE connection^.receiver_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            CASEND;
            connection^.total_data_queued := connection^.total_data_queued - remaining_buffer_capacity;
            connection^.total_message_buffers_queued := connection^.total_message_buffers_queued -
                  delivered_message_buffers;
            event_element_p^.queued_data_length := event_element_p^.queued_data_length -
                  remaining_buffer_capacity;
            event_element_p^.queued_message_buffers := event_element_p^.queued_message_buffers -
                  delivered_message_buffers;
            connection^.receiver_request.bytes_moved := connection^.receiver_request.bytes_moved +
                  remaining_buffer_capacity;
            event_element_p^.total_bytes_moved := event_element_p^.total_bytes_moved +
                  remaining_buffer_capacity;
            connection^.transfer_count := connection^.transfer_count + remaining_buffer_capacity;
            connection^.record_length := connection^.record_length + remaining_buffer_capacity;
            IF connection^.receiver_request.operation = nac$se_receive_data_req THEN
              connection^.receiver_request.peer_operation^.kind := nac$se_send_data;
              connection^.receiver_request.peer_operation^.end_of_message := FALSE;
              connection^.receiver_request.peer_operation^.qualified_data :=
                    event_element_p^.event.qualified_data;
              connection^.receiver_request.peer_operation^.data_length := connection^.transfer_count;
            ELSEIF connection^.receiver_request.operation = amc$get_next_req THEN
              condition_cause := nac$application_event;
              #SPOIL (condition_cause);
              connection^.receiver_request.file_position^ := amc$mid_record;
              connection^.receiver_request.transfer_count^ := connection^.transfer_count;
            ELSEIF connection^.receiver_request.operation = amc$get_partial_req THEN
              condition_cause := nac$application_event;
              #SPOIL (condition_cause);
              connection^.receiver_request.file_position^ := amc$mid_record;
              connection^.receiver_request.transfer_count^ := connection^.transfer_count;
              connection^.receiver_request.record_length^ := connection^.record_length;
            IFEND;
            delivery_complete := TRUE;
            event_element_p^.start_of_data_sequence := FALSE;
          ELSE

{ Deliver Queued Data

            delivery_complete := (event_element_p^.event.end_of_message) OR
                  ((connection^.connection_state = nac$terminated) AND
                  (NOT event_element_p^.event.end_of_message));
            IF event_element_p^.queued_data_length > 0 THEN
              condition_cause := nac$application_data;
              #SPOIL (condition_cause);
              CASE connection^.receiver_request.application_buffer.description_kind OF
              = nac$fixed =
                nlp$al_deliver_data (event_element_p^.message_id,
                      connection^.receiver_request.application_buffer.fixed_description,
                      connection^.receiver_request.remaining_buffer_capacity, delivered_message_buffers);
              = nac$allocated =
                nlp$al_deliver_data (event_element_p^.message_id,
                      connection^.receiver_request.application_buffer.allocated_description^,
                      connection^.receiver_request.remaining_buffer_capacity, delivered_message_buffers);
                IF delivery_complete THEN
                  FREE connection^.receiver_request.application_buffer.allocated_description IN
                        nav$network_paged_heap^;
                IFEND;
              CASEND;
              connection^.total_data_queued := connection^.total_data_queued -
                    event_element_p^.queued_data_length;
              connection^.total_message_buffers_queued := connection^.total_message_buffers_queued -
                    delivered_message_buffers;
              connection^.receiver_request.bytes_moved := connection^.receiver_request.bytes_moved +
                    event_element_p^.queued_data_length;
              event_element_p^.total_bytes_moved := event_element_p^.total_bytes_moved +
                    event_element_p^.queued_data_length;
              connection^.transfer_count := connection^.transfer_count + event_element_p^.queued_data_length;
              connection^.record_length := connection^.record_length + event_element_p^.queued_data_length;
              event_element_p^.queued_data_length := 0;
              event_element_p^.queued_message_buffers := 0;
            IFEND;
            IF delivery_complete THEN
              event := event_element_p^.event;
              IF (event_element_p^.event.end_of_message) OR ((connection^.connection_state =
                    nac$terminated) AND (NOT event_element_p^.event.end_of_message)) THEN
                dequeue_data_event (connection^);
                event_element_p := NIL;
                #SPOIL (event_element_p);
              ELSE
                event_element_p^.start_of_data_sequence := FALSE;
              IFEND;
              condition_cause := nac$application_event;
              #SPOIL (condition_cause);
              IF connection^.receiver_request.operation = nac$se_receive_data_req THEN
                connection^.receiver_request.peer_operation^ := event;
                connection^.receiver_request.peer_operation^.data_length := connection^.transfer_count;
              ELSEIF connection^.receiver_request.operation = amc$get_next_req THEN
                IF (connection^.connection_state = nac$terminated) AND (NOT event.end_of_message) THEN
                  connection^.receiver_request.file_position^ := amc$mid_record;
                ELSE
                  connection^.receiver_request.file_position^ := amc$eor;
                IFEND;
                connection^.receiver_request.transfer_count^ := connection^.transfer_count;
              ELSEIF connection^.receiver_request.operation = amc$get_partial_req THEN
                IF (connection^.connection_state = nac$terminated) AND (NOT event.end_of_message) THEN
                  connection^.receiver_request.file_position^ := amc$mid_record;
                ELSE
                  connection^.receiver_request.file_position^ := amc$eor;
                IFEND;
                connection^.receiver_request.transfer_count^ := connection^.transfer_count;
                connection^.receiver_request.record_length^ := connection^.record_length;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      ELSE

{ Deliver Supervisory Event

        IF connection^.receiver_request.operation = nac$se_receive_data_req THEN
          IF (connection^.receiver_request.bytes_moved = 0) OR
                ((connection^.supervisory_event_queue.beginning^.event.kind = nac$se_synchronize) AND
                ((connection^.supervisory_event_queue.beginning^.event.direction =
                nac$se_synchronize_all_data) OR (connection^.supervisory_event_queue.beginning^.event.
                direction = nac$se_synchronize_send_data))) THEN

            IF connection^.receiver_request.application_buffer.description_kind = nac$allocated THEN
              FREE connection^.receiver_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            IFEND;
            condition_cause := nac$application_data;
            #SPOIL (condition_cause);
            connection^.receiver_request.peer_operation^ := connection^.supervisory_event_queue.beginning^.
                  event;
            supervisory_element_p := connection^.supervisory_event_queue.beginning;
            connection^.supervisory_event_queue.beginning := supervisory_element_p^.next_element;
            FREE supervisory_element_p IN nav$network_paged_heap^;
            delivery_complete := TRUE;
          ELSE
            IF connection^.receiver_request.application_buffer.description_kind = nac$allocated THEN
              FREE connection^.receiver_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            IFEND;
            delivery_complete := TRUE;
          IFEND;
        ELSE
          IF ((connection^.receiver_request.bytes_moved > 0) AND
                (((connection^.supervisory_event_queue.beginning^.event.kind = nac$se_synchronize) AND
                (connection^.supervisory_event_queue.beginning^.event.direction =
                nac$se_synchronize_receive_data)) OR (connection^.supervisory_event_queue.beginning^.event.
                kind = nac$se_synchronize_confirm) OR (connection^.supervisory_event_queue.beginning^.event.
                kind = nac$se_interrupt))) THEN
            ; {terminate receive normally
          ELSE
            osp$set_status_condition (nae$unexpected_peer_operation, status);
          IFEND;
          IF connection^.receiver_request.application_buffer.description_kind = nac$allocated THEN
            FREE connection^.receiver_request.application_buffer.allocated_description IN
                  nav$network_paged_heap^;
          IFEND;
          delivery_complete := TRUE;
        IFEND;
      IFEND;
    ELSEIF connection^.connection_state = nac$terminated THEN
      osp$set_status_condition (nae$connection_terminated, status);
      delivery_complete := TRUE;
    IFEND;

    IF delivery_complete THEN
      nlp$cancel_timer (connection^.receive_timer);
    IFEND;

  PROCEND deliver_connection_events;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] NLP$SE_RECEIVE_DATA' ??

  PROCEDURE [XDCL, #GATE] nlp$se_receive_data
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
         start_time: integer;
     VAR request_started: boolean;
     VAR wait_time: nat$wait_time;
     VAR receive_wait_swapout: boolean;
     VAR activity_status: ^ost$activity_status;
     VAR status: ost$status);

    VAR
      buffer_length: integer,
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      cl_connection_id: nlt$cl_connection_id,
      condition_cause: nat$se_condition_cause,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      current_time: integer,
      data: array [1 .. 1] of nat$data_fragment,
      data_area: ^nat$data_fragments,
      data_length: integer,
      delivery_complete: boolean,
      description_upperbound: integer,
      event_element_p: ^nat$se_event_element,
      file_instance: ^bat$task_file_entry,
      file_is_valid: boolean,
      ignore_status: ost$status,
      layer_active: boolean,
      message_buffers_dequeued: nat$data_length,
      request_complete: boolean,
      supervisory_element_p: ^nat$se_supervisory_element;

?? NEWTITLE := '    TERMINATE_RECEIVE -- CONDITION HANDLER', EJECT ??

    PROCEDURE terminate_receive
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF ((condition_cause = nac$application_data) OR (condition_cause = nac$application_event) OR
              (condition_cause = nac$activity_status)) THEN
          IF cl_connection <> NIL THEN
            nlp$cl_deactivate_receiver (cl_connection);
            connection^.wait_state := nac$inactive_wait;
            IF file_instance^.receiver_active THEN
              IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.receiver_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              file_instance^.receiver_active := FALSE;
            IFEND;
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$se_receive_data; {----->
        ELSE
          ; { causes the task to abort because this is probably a system
          ; {  programing error. Locks are   left locked or problem might  not be
          ; {  found.
          osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          IF cl_connection <> NIL THEN
            nap$namve_system_error (TRUE, 'NLP$SE_RECEIVE_DATA ', ^condition_status);
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
          osp$pop_inhibit_job_recovery;
        IFEND;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;

    PROCEND terminate_receive;
?? OLDTITLE ??
?? EJECT ??
    #CALLER_ID (caller_id);
    status.normal := TRUE;
    activity_status^.status.normal := TRUE;
    activity_status^.complete := TRUE;
    request_complete := TRUE;

    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;
    #SPOIL (file_instance);

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r2 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    IF call_block.operation = nac$se_receive_data_req THEN
      data_area := call_block.se_receive_data_req.buffer;
    ELSE
      IF call_block.operation = amc$get_next_req THEN
        data [1].length := call_block.getn.working_storage_length;
        data [1].address := call_block.getn.working_storage_area;
        call_block.getn.byte_address^ := 0;
      ELSE
        data [1].length := call_block.getp.working_storage_length;
        data [1].address := call_block.getp.working_storage_area;
        call_block.getp.byte_address^ := 0;
      IFEND;
      data_area := ^data;
    IFEND;

    IF UPPERBOUND (data_area^) > nac$max_data_fragment_count THEN
      osp$set_status_condition (nae$maximum_data_fragments, status);
      RETURN; {----->
    IFEND;

    nlp$al_get_data_requirements (data_area^, buffer_length, description_upperbound);
    IF buffer_length > nac$max_data_length THEN
      osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, 'nac$max_data_length', status);
      RETURN; {----->
    IFEND;

    cl_connection := NIL;
    condition_cause := nac$request_not_cause;
    #SPOIL (condition_cause, cl_connection);
    osp$push_inhibit_job_recovery;
    osp$establish_condition_handler (^terminate_receive, FALSE);

    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);

    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        #SPOIL (connection);
        IF NOT connection^.break_condition_active THEN

          IF connection^.wait_state = nac$inactive_wait THEN

{ Process Supervisory Event

            IF connection^.supervisory_event_queue.beginning <> NIL THEN
              IF call_block.operation = nac$se_receive_data_req THEN
                condition_cause := nac$application_event;
                #SPOIL (condition_cause);
                call_block.se_receive_data_req.peer_operation^ :=
                      connection^.supervisory_event_queue.beginning^.event;
                supervisory_element_p := connection^.supervisory_event_queue.beginning;
                connection^.supervisory_event_queue.beginning := supervisory_element_p^.next_element;
                FREE supervisory_element_p IN nav$network_paged_heap^;
              ELSE
                osp$set_status_condition (nae$unexpected_peer_operation, status);
              IFEND;

            ELSE
              event_element_p := ^connection^.data_queue.beginning^.
                    event_element [connection^.data_queue.beginning^.first];

{ Process Queued Data
              IF (connection^.data_queue.count > 0) AND (event_element_p^.event.end_of_message) AND
                    (event_element_p^.queued_data_length <= buffer_length) AND
                    (event_element_p^.start_of_data_sequence) THEN

                IF call_block.operation = nac$se_receive_data_req THEN
                  condition_cause := nac$application_event;
                  #SPOIL (condition_cause);
                  call_block.se_receive_data_req.peer_operation^ := event_element_p^.event;
                  call_block.se_receive_data_req.peer_operation^.data_length :=
                        event_element_p^.queued_data_length;
                  condition_cause := nac$application_data;
                  #SPOIL (condition_cause);
                  nlp$bm_flush_message (data_area^, event_element_p^.message_id, data_length, ignore_status);
                  message_buffers_dequeued := event_element_p^.queued_message_buffers;
                  event_element_p^.queued_data_length := 0;
                  event_element_p^.queued_message_buffers := 0;
                  dequeue_data_event (connection^);
                  event_element_p := NIL;
                  #SPOIL (event_element_p);
                ELSEIF call_block.operation = amc$get_next_req THEN
                  IF (file_instance^.eoi_message_enabled) AND (f$eoi_message
                        (file_instance^.eoi_message, event_element_p^.message_id)) THEN
                    condition_cause := nac$application_event;
                    #SPOIL (condition_cause);
                    call_block.getn.file_position^ := amc$eoi;
                    call_block.getn.transfer_count^ := 0;
                    nlp$bm_release_message (event_element_p^.message_id);
                    data_length := event_element_p^.queued_data_length
                  ELSE
                    condition_cause := nac$application_event;
                    #SPOIL (condition_cause);
                    call_block.getn.file_position^ := amc$eor;
                    call_block.getn.transfer_count^ := event_element_p^.queued_data_length;
                    condition_cause := nac$application_data;
                    #SPOIL (condition_cause);
                    nlp$bm_flush_message (data_area^, event_element_p^.message_id, data_length,
                          ignore_status);
                  IFEND;
                  message_buffers_dequeued := event_element_p^.queued_message_buffers;
                  event_element_p^.queued_data_length := 0;
                  event_element_p^.queued_message_buffers := 0;

                  dequeue_data_event (connection^);
                  event_element_p := NIL;
                  #SPOIL (event_element_p);
                ELSE
                  IF (file_instance^.eoi_message_enabled) AND (f$eoi_message
                        (file_instance^.eoi_message, event_element_p^.message_id)) THEN
                    condition_cause := nac$application_event;
                    #SPOIL (condition_cause);
                    call_block.getp.file_position^ := amc$eoi;
                    call_block.getp.transfer_count^ := 0;
                    call_block.getp.record_length^ := 0;
                    nlp$bm_release_message (event_element_p^.message_id);
                    data_length := event_element_p^.queued_data_length;
                  ELSE
                    condition_cause := nac$application_event;
                    #SPOIL (condition_cause);
                    call_block.getp.file_position^ := amc$eor;
                    call_block.getp.transfer_count^ := event_element_p^.queued_data_length;
                    call_block.getp.record_length^ := event_element_p^.queued_data_length;
                    condition_cause := nac$application_data;
                    #SPOIL (condition_cause);
                    nlp$bm_flush_message (data_area^, event_element_p^.message_id, data_length,
                          ignore_status);
                  IFEND;
                  message_buffers_dequeued := event_element_p^.queued_message_buffers;
                  event_element_p^.queued_data_length := 0;
                  event_element_p^.queued_message_buffers := 0;
                  dequeue_data_event (connection^);
                  event_element_p := NIL;
                  #SPOIL (event_element_p);
                IFEND;
                connection^.total_data_queued := connection^.total_data_queued - data_length;
                connection^.total_message_buffers_queued := connection^.total_message_buffers_queued -
                      message_buffers_dequeued;
                nlp$ta_report_undelivered_data (cl_connection, connection^.total_message_buffers_queued);

              ELSE

{ Setup Receive Coroutine

                IF (connection^.connection_state = nac$terminated) AND (connection^.nominal_connection) AND
                      (connection^.data_queue.count = 0) AND (connection^.supervisory_event_queue.beginning =
                      NIL) AND (connection^.wait_state <> nac$waiting_to_receive_data) AND
                      (NOT cl_connection^.message_sender.active) THEN
                  osp$set_status_condition (nae$interactive_cond_interrupt, status);
                ELSE
                  nlp$cl_activate_receiver (cl_connection);
                  connection^.wait_state := nac$waiting_to_receive_data;
                  condition_cause := nac$application_data;
                  #SPOIL (condition_cause);
                  connection^.receive_file_identifier := file_identifier;
                  file_instance^.receiver_activity_status := activity_status;
                  file_instance^.receiver_active := TRUE;
                  connection^.receiver_request.operation := call_block.operation;
                  IF call_block.operation = nac$se_receive_data_req THEN
                    connection^.receiver_request.peer_operation :=
                          call_block.se_receive_data_req.peer_operation;
                  ELSEIF call_block.operation = amc$get_next_req THEN
                    connection^.receiver_request.transfer_count := call_block.getn.transfer_count;
                    connection^.receiver_request.file_position := call_block.getn.file_position;
                  ELSE
                    connection^.receiver_request.transfer_count := call_block.getp.transfer_count;
                    connection^.receiver_request.record_length := call_block.getp.record_length;
                    connection^.receiver_request.file_position := call_block.getp.file_position;
                  IFEND;
                  connection^.receiver_request.remaining_buffer_capacity := buffer_length;
                  connection^.receiver_request.bytes_moved := 0;
                  IF description_upperbound <= nac$fixed_fragments THEN
                    connection^.receiver_request.application_buffer.description_kind := nac$fixed;
                    nlp$al_initialize_data_descrip (data_area^, buffer_length,
                          connection^.receiver_request.application_buffer.fixed_description);
                  ELSE
                    connection^.receiver_request.application_buffer.description_kind := nac$allocated;
                    REPEAT
                      ALLOCATE connection^.receiver_request.application_buffer.allocated_description:
                            [1 .. description_upperbound] IN nav$network_paged_heap^;
                      IF connection^.receiver_request.application_buffer.allocated_description = NIL THEN
                        syp$cycle;
                      IFEND;
                    UNTIL connection^.receiver_request.application_buffer.allocated_description <> NIL;
                    nlp$al_initialize_data_descrip (data_area^, buffer_length,
                          connection^.receiver_request.application_buffer.allocated_description^);
                  IFEND;

                  connection^.transfer_count := 0;
                  IF ((connection^.data_queue.count > 0) AND (NOT event_element_p^.start_of_data_sequence) AND
                        ((call_block.operation = amc$get_next_req) OR
                        ((call_block.operation = amc$get_partial_req) AND
                        (call_block.getp.skip_option = amc$skip_to_eor)))) THEN

                    connection^.record_length := 0;
                    IF event_element_p^.event.end_of_message THEN
                      dequeue_data_event (connection^);
                      event_element_p := NIL;
                      #SPOIL (event_element_p);
                    ELSE
                      IF event_element_p^.queued_data_length > 0 THEN
                        nlp$bm_release_message (event_element_p^.message_id);
                        connection^.total_data_queued := connection^.total_data_queued -
                              event_element_p^.queued_data_length;
                        connection^.total_message_buffers_queued :=
                              connection^.total_message_buffers_queued -
                              event_element_p^.queued_message_buffers;
                        event_element_p^.queued_data_length := 0;
                        event_element_p^.queued_message_buffers := 0;
                      IFEND;
                      IF NOT connection^.discard_to_end_of_message THEN
                        connection^.discard_to_end_of_message := TRUE;
                      IFEND;
                    IFEND;
                  ELSEIF (connection^.data_queue.count = 0) OR ((connection^.data_queue.count > 0) AND
                        (event_element_p^.start_of_data_sequence)) THEN
                    connection^.record_length := 0;
                  IFEND;
                  deliver_connection_events (connection, cl_connection, delivery_complete, condition_cause,
                        status);
                  condition_cause := nac$request_not_cause;
                  #SPOIL (condition_cause);
                  nlp$ta_report_undelivered_data (cl_connection, connection^.total_message_buffers_queued);
                  IF delivery_complete THEN
                    nlp$cl_deactivate_receiver (cl_connection);
                    connection^.wait_state := nac$inactive_wait;
                    file_instance^.receiver_active := FALSE;
                  ELSE
                    current_time := #FREE_RUNNING_CLOCK (0);
                    wait_time := file_instance^.data_transfer_timeout;
                    IF (file_instance^.data_transfer_timeout > ((current_time - start_time) DIV 1000)) THEN
                      request_started := TRUE;
                      receive_wait_swapout := connection^.receive_wait_swapout;
                      nlp$select_timer ((file_instance^.data_transfer_timeout * 1000) -
                            (current_time - start_time), 0, connection^.receive_timer);
                      activity_status^.complete := FALSE;
                    ELSE
                      ; {deactivate request
                      IF ((connection^.receiver_request.application_buffer.description_kind =
                            nac$allocated) AND (connection^.receiver_request.application_buffer.
                            allocated_description <> NIL)) THEN
                        FREE connection^.receiver_request.application_buffer.allocated_description IN
                              nav$network_paged_heap^;
                      IFEND;
                      nlp$cl_deactivate_receiver (cl_connection);
                      connection^.wait_state := nac$inactive_wait;
                      file_instance^.receiver_active := FALSE;
                      osp$set_status_condition (nae$data_transfer_timeout, status);
                      activity_status^.status := status;
                      activity_status^.complete := TRUE;
                    IFEND;
                    cl_connection_id := cl_connection^.identifier;
                  IFEND;
                IFEND;
              IFEND;
            IFEND;

            IF (connection^.connection_state = nac$terminated) AND
                  (NOT connection^.timesharing_disconnect_sent) AND (connection^.nominal_connection) AND
                  (connection^.data_queue.count = 0) AND (connection^.supervisory_event_queue.beginning =
                  NIL) AND (connection^.wait_state <> nac$waiting_to_receive_data) AND
                  (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
              ; {send signal
              connection^.timesharing_disconnect_sent := TRUE;
              send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id,
                    NIL);
            IFEND;
          ELSE
            IF (call_block.operation = nac$se_receive_data_req) AND
                  (call_block.se_receive_data_req.wait = osc$nowait) THEN
              osp$set_status_condition (nae$receive_outstanding, status);
            ELSE
              request_started := FALSE;
              wait_time := file_instance^.data_transfer_timeout;
              receive_wait_swapout := connection^.receive_wait_swapout;
              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              activity_status^.complete := FALSE;
            IFEND;
          IFEND;
        ELSE
          osp$set_status_condition (nae$interactive_cond_interrupt, status);
        IFEND;

        IF connection^.wait_state <> nac$waiting_to_receive_data THEN
          IF (connection^.data_queue.count = 0) AND (connection^.supervisory_event_queue.beginning = NIL) THEN
            nlp$cancel_timer (connection^.event_timer);
          ELSE
            nlp$select_timer (nac$inactive_receiver_timeout, 0, connection^.event_timer);
          IFEND;
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;

    osp$pop_inhibit_job_recovery;
    IF (NOT status.normal) AND (status.condition = nae$connection_terminated) THEN
      fmp$convert_status (file_instance^.local_file_name, status);
    IFEND;

  PROCEND nlp$se_receive_data;
?? OLDTITLE ??
?? TITLE := '  [XDCL] NAP$SE_DELIVER_EVENT_HANDLER' ??
?? NEWTITLE := '    TERMINATE_DELIVERY -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL] nap$se_deliver_event_handler
    (    originator: ost$global_task_id;
         signal: pmt$signal);

    VAR
      cl_connection: ^nlt$cl_connection,
      cl_connection_id: ^nlt$cl_connection_id,
      condition_cause: nat$se_condition_cause,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      delivery_complete: boolean,
      layer_active: boolean,
      processing_task: ost$global_task_id,
      status: ost$status;


    PROCEDURE terminate_delivery
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
{Debug Code
      = pmc$block_exit_processing =
        osp$decrement_locked_variable (nav$namve_tsk_hndl_active_count, 1, actual_value, ignore_error);
{End Debug Code
      = pmc$system_conditions, mmc$segment_access_condition =
        IF (condition_cause = nac$application_data) OR (condition_cause = nac$application_event) THEN
          IF cl_connection <> NIL THEN
            nlp$cl_deactivate_receiver (cl_connection);
            connection^.wait_state := nac$inactive_wait;
            IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                  (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
              FREE connection^.receiver_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            IFEND;
            osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
            condition_cause := nac$activity_status;
            #SPOIL (condition_cause);
            osp$establish_condition_handler (^terminate_delivery, FALSE);
            complete_activity (receive, connection^.receive_file_identifier, ^condition_status);
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
          condition_status.normal := TRUE;
          osp$pop_inhibit_job_recovery;
          EXIT nap$se_deliver_event_handler; {----->
        ELSEIF condition_cause = nac$activity_status THEN
          IF cl_connection <> NIL THEN
            IF (connection^.wait_state = nac$waiting_to_receive_data) AND
                  (cl_connection^.message_receiver.task = processing_task) THEN
              nlp$cl_deactivate_receiver (cl_connection);
              connection^.wait_state := nac$inactive_wait;
              IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.receiver_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              terminate_io (receiver, connection^.receive_file_identifier);
            IFEND;
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
          osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
        ELSE
          osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          IF cl_connection <> NIL THEN
            nap$namve_system_error (TRUE, 'NAP$SE_DELIVER_EVENT_HANDLER ', ^condition_status);
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
        IFEND;
        osp$pop_inhibit_job_recovery;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_delivery;
?? OLDTITLE, EJECT ??
{Debug Code

    VAR
      actual_value: integer,
      ignore_error: boolean;

    osp$increment_locked_variable (nav$namve_tsk_hndl_active_count, 0, actual_value);
    IF actual_value > 1 THEN
      osp$increment_locked_variable (nav$multiple_namve_hndler_calls, 0, actual_value);
      IF nav$debug_mode > nac$no_debug THEN
        nap$namve_system_error (TRUE {=recoverable} ,
              'NAP$SE_DELIVER_EVENT_HANDLER invoked while another handler active.', NIL);
      IFEND;
    IFEND;
{End Debug Code

    status.normal := TRUE;
    cl_connection_id := #LOC (signal.contents);
    cl_connection := NIL;
    condition_cause := nac$request_not_cause;
    #SPOIL (condition_cause, cl_connection);
    osp$push_inhibit_job_recovery;
*if false
    osp$establish_condition_handler (^terminate_delivery, FALSE);
*ifend
{Debug Code
    osp$establish_condition_handler (^terminate_delivery, TRUE);
{End Debug Code

    nlp$cl_get_exclusive_via_cid (cl_connection_id^, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        #SPOIL (connection);
        pmp$get_executing_task_gtid (processing_task);
        IF (connection^.wait_state = nac$waiting_to_receive_data) AND
              (cl_connection^.message_receiver.task = processing_task) THEN
          IF (connection^.connection_state = nac$terminated) AND
                (connection^.supervisory_event_queue.beginning = NIL) AND
                (connection^.data_queue.count = 0) THEN
            IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                  (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
              FREE connection^.receiver_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            IFEND;
            nlp$cl_deactivate_receiver (cl_connection);
            connection^.wait_state := nac$inactive_wait;
            ; {set_activity_status  nae$connection_terminated
            IF NOT connection^.nominal_connection THEN
              osp$set_status_condition (nae$connection_terminated, status);
            ELSE
              osp$set_status_condition (nae$interactive_cond_interrupt, status);
            IFEND;
            condition_cause := nac$activity_status;
            #SPOIL (condition_cause);
            complete_activity (receive, connection^.receive_file_identifier, ^status);
          ELSE
            IF NOT connection^.break_connection_receive THEN
              IF (connection^.supervisory_event_queue.beginning <> NIL) OR
                    (connection^.data_queue.count > 0) THEN
                IF (connection^.synchronize_request_receive) OR (connection^.synchronize_receive) THEN
                  ; {redo buffer
                  connection^.synchronize_request_receive := FALSE;
                  connection^.synchronize_receive := FALSE;
                IFEND;
                ; {continue normal processing
                condition_cause := nac$application_data;
                #SPOIL (condition_cause);
                deliver_connection_events (connection, cl_connection, delivery_complete, condition_cause,
                      status);
                condition_cause := nac$request_not_cause;
                #SPOIL (condition_cause);
                nlp$ta_report_undelivered_data (cl_connection, connection^.total_message_buffers_queued);
                IF delivery_complete THEN
                  nlp$cl_deactivate_receiver (cl_connection);
                  connection^.wait_state := nac$inactive_wait;
                  condition_cause := nac$activity_status;
                  #SPOIL (condition_cause);
                  complete_activity (receive, connection^.receive_file_identifier, ^status);
                IFEND;
              IFEND;
            ELSE
              ; {deactive_receive
              IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.receiver_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              nlp$cl_deactivate_receiver (cl_connection);
              connection^.wait_state := nac$inactive_wait;
              connection^.break_connection_receive := FALSE;

              connection^.synchronize_request_receive := FALSE;

              connection^.synchronize_receive := FALSE;
              IF NOT cl_connection^.message_sender.active THEN
                send_timesharing_signal (jmc$timesharing_synchronize, connection^.
                      nominal_connection_task_id, ^connection^.event);
              IFEND;
              ; { nae$interactive_cond_interrupt
              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              osp$set_status_condition (nae$interactive_cond_interrupt, status);
              complete_activity (receive, connection^.receive_file_identifier, ^status);
            IFEND;
            IF (connection^.wait_state = nac$waiting_to_receive_data) AND (connection^.receive_timeout) THEN
              IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.receiver_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              nlp$cl_deactivate_receiver (cl_connection);
              connection^.wait_state := nac$inactive_wait;
              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              osp$set_status_condition (nae$data_transfer_timeout, status);
              complete_activity (receive, connection^.receive_file_identifier, ^status);
            IFEND;
            IF connection^.wait_state <> nac$waiting_to_receive_data THEN
              IF ((connection^.data_queue.count > 0) OR (connection^.supervisory_event_queue.beginning <>
                    NIL)) THEN
                nlp$select_timer (nac$inactive_receiver_timeout, 0, connection^.event_timer);
              ELSE
                nlp$cancel_timer (connection^.event_timer);
              IFEND;
            IFEND;
          IFEND;
        IFEND;
        IF (connection^.connection_state = nac$terminated) AND
              (NOT connection^.timesharing_disconnect_sent) AND (connection^.nominal_connection) AND
              (connection^.data_queue.count = 0) AND (connection^.supervisory_event_queue.beginning = NIL) AND
              (connection^.wait_state <> nac$waiting_to_receive_data) AND
              (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
          ; {send signal
          connection^.timesharing_disconnect_sent := TRUE;
          send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id, NIL);
        IFEND;
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    IFEND;
    osp$pop_inhibit_job_recovery;

{Debug Code
    osp$disestablish_cond_handler;
    osp$decrement_locked_variable (nav$namve_tsk_hndl_active_count, 1, actual_value, ignore_error);
{End Debug Code

  PROCEND nap$se_deliver_event_handler;
?? TITLE := '  SEND_DATA', EJECT ??

  PROCEDURE [inline] send_data
    (    cl_connection: ^nlt$cl_connection;
         connection: ^nat$connection_descriptor);

    VAR
      capacity: nat$data_length,
      end_of_message: boolean,
      fragment_size: nat$data_length,
      qualified_data: boolean,
      description_upperbound: integer,
      ignore_rb: integer,
      ignore_status: ost$status,
      message: ^array [1 .. * ] of nat$data_fragment;

  /send_block/
    WHILE connection^.sender_request.remaining_bytes_to_send > 0 DO
      nlp$osi_get_outbound_capacity (cl_connection, capacity);
      IF capacity > connection^.sender_request.remaining_bytes_to_send THEN
        fragment_size := connection^.sender_request.remaining_bytes_to_send;
      ELSEIF capacity > 0 THEN
        fragment_size := capacity;
      ELSE
        EXIT /send_block/; {----->
      IFEND;

      CASE connection^.sender_request.application_buffer.description_kind OF
      = nac$fixed =
        nlp$al_get_data_requirements (connection^.sender_request.application_buffer.fixed_description.
              fragment, ignore_rb, description_upperbound);
        PUSH message: [1 .. description_upperbound];
        nlp$al_fragment_data (fragment_size, connection^.sender_request.application_buffer.fixed_description,
              connection^.sender_request.remaining_bytes_to_send, message^);
      = nac$allocated =
        nlp$al_get_data_requirements (connection^.sender_request.application_buffer.allocated_description^.
              fragment, ignore_rb, description_upperbound);
        PUSH message: [1 .. description_upperbound];
        nlp$al_fragment_data (fragment_size, connection^.sender_request.application_buffer.
              allocated_description^, connection^.sender_request.remaining_bytes_to_send, message^);
        IF connection^.sender_request.remaining_bytes_to_send = 0 THEN
          FREE connection^.sender_request.application_buffer.allocated_description IN nav$network_paged_heap^;
        IFEND;
      CASEND;
      qualified_data := (connection^.sender_request.operation = nac$se_send_data_req) AND
            connection^.sender_request.qualified_data;
      IF connection^.sender_request.remaining_bytes_to_send = 0 THEN
        nlp$cl_deactivate_sender (cl_connection);
        IF connection^.sender_request.operation = nac$se_send_data_req THEN
          end_of_message := connection^.sender_request.end_of_message;
        ELSE
          end_of_message := (connection^.sender_request.operation = amc$put_next_req) OR
                ((connection^.sender_request.operation = amc$put_partial_req) AND
                (connection^.sender_request.term_option = amc$terminate));
        IFEND;
        nlp$cancel_timer (connection^.send_timer);
      ELSE
        end_of_message := FALSE;
      IFEND;
      nlp$sl_data_request (cl_connection, qualified_data, end_of_message, message^, ignore_status);
    WHILEND /send_block/;

  PROCEND send_data;
?? TITLE := '  [XDCL] NLP$SE_SEND_DATA' ??
?? NEWTITLE := '    TERMINATE_SEND -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL, #GATE] nlp$se_send_data
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
         start_time: integer;
     VAR request_started: boolean;
     VAR wait_time: nat$wait_time;
     VAR activity_status: ^ost$activity_status;
     VAR status: ost$status);


    PROCEDURE terminate_send
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      condition_status.normal := TRUE;
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF (condition_cause = nac$application_data) OR (condition_cause = nac$activity_status) THEN
          IF cl_connection <> NIL THEN
            nlp$cl_deactivate_sender (cl_connection);
            IF file_instance^.sender_active THEN
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              file_instance^.sender_active := FALSE;
            IFEND;
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$se_send_data; {----->
        ELSE
          ; { causes the task to abort because this is probably a system
          ; {  programing error. Locks are   left locked or problem might  not be
          ; {  found.
          osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          IF cl_connection <> NIL THEN
            nap$namve_system_error (TRUE, 'NLP$SE_SEND_DATA ', ^condition_status);
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
          osp$pop_inhibit_job_recovery;
        IFEND;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_send;
?? OLDTITLE, EJECT ??

    VAR
      bytes_to_send: integer,
      caller_id: ost$caller_identifier,
      capacity: nat$data_length,
      cl_connection: ^nlt$cl_connection,
      condition_cause: nat$se_condition_cause,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      current_time: integer,
      data: array [1 .. 1] of nat$data_fragment,
      data_area: ^nat$data_fragments,
      description_upperbound: integer,
      file_instance: ^bat$task_file_entry,
      layer_active: boolean;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    activity_status^.status.normal := TRUE;
    activity_status^.complete := TRUE;
    request_started := TRUE;

    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;
    #SPOIL (file_instance);

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r1 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    IF call_block.operation = nac$se_send_data_req THEN
      data_area := call_block.se_send_data_req.data;
    ELSE
      IF call_block.operation = amc$put_next_req THEN
        data [1].length := call_block.putn.working_storage_length;
        data [1].address := call_block.putn.working_storage_area;
        call_block.putn.byte_address^ := 0;
      ELSE
        data [1].length := call_block.putp.working_storage_length;
        data [1].address := call_block.putp.working_storage_area;
        call_block.putp.byte_address^ := 0;
      IFEND;
      data_area := ^data;
    IFEND;

    IF UPPERBOUND (data_area^) > nac$max_data_fragment_count THEN
      osp$set_status_condition (nae$maximum_data_fragments, status);
      RETURN; {----->
    IFEND;

    nlp$al_get_data_requirements (data_area^, bytes_to_send, description_upperbound);
    IF bytes_to_send > nac$max_data_length THEN
      osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, 'nac$max_data_length', status);
      RETURN; {----->
    IFEND;
    cl_connection := NIL;
    condition_cause := nac$request_not_cause;
    #SPOIL (condition_cause, cl_connection);
    osp$push_inhibit_job_recovery;
    osp$establish_condition_handler (^terminate_send, FALSE);
    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        #SPOIL (connection);
        IF connection^.connection_state = nac$established THEN
          IF connection^.send_synchronize_count = 0 THEN
            IF NOT cl_connection^.message_sender.active THEN
              IF (connection^.send_put_partial_termination) OR
                    ((connection^.intermediate_put_partial) AND ((call_block.operation <>
                    amc$put_partial_req) OR ((call_block.operation = amc$put_partial_req) AND
                    (call_block.putp.term_option = amc$start)))) THEN
                nlp$osi_get_outbound_capacity (cl_connection, capacity);
                IF capacity > 0 THEN
                  nlp$sl_data_request (cl_connection, FALSE {qualified_data} , TRUE {END_OF_MESSAGE} ,
                        nav$null_data, status);
                  connection^.intermediate_put_partial := FALSE;
                  connection^.send_put_partial_termination := FALSE;
                ELSE
                  connection^.intermediate_put_partial := FALSE;
                  connection^.send_put_partial_termination := TRUE;
                IFEND;
              IFEND;

              ; {It is possible to get a non-zero capacity if the previous capacity was zero.

              nlp$osi_get_outbound_capacity (cl_connection, capacity);
              IF (capacity > 0) AND (capacity >= bytes_to_send) AND
                    (NOT connection^.send_put_partial_termination) THEN
                condition_cause := nac$application_data;
                #SPOIL (condition_cause);
                IF call_block.operation = nac$se_send_data_req THEN
                  nlp$sl_data_request (cl_connection, call_block.se_send_data_req.qualified_data,
                        call_block.se_send_data_req.end_of_message, data_area^, status);
                ELSEIF (call_block.operation = amc$put_partial_req) AND
                      ((call_block.putp.term_option = amc$start) OR
                      (call_block.putp.term_option = amc$continue)) THEN
                  nlp$sl_data_request (cl_connection, FALSE {qualified_data} , FALSE {END_OF_MESSAGE} ,
                        data_area^, status);
                  connection^.intermediate_put_partial := TRUE;
                ELSEIF (call_block.operation = amc$put_partial_req) AND
                      (call_block.putp.term_option = amc$terminate) THEN
                  nlp$sl_data_request (cl_connection, FALSE {qualified_data} , TRUE {END_OF_MESSAGE} ,
                        data_area^, status);
                  connection^.intermediate_put_partial := FALSE;
                ELSE
                  nlp$sl_data_request (cl_connection, FALSE {qualified_data} , TRUE {END_OF_MESSAGE} ,
                        data_area^, status);
                IFEND;
              ELSE
                nlp$cl_activate_sender (cl_connection);
                connection^.sender_request.operation := call_block.operation;
                IF call_block.operation = nac$se_send_data_req THEN
                  connection^.sender_request.end_of_message := call_block.se_send_data_req.end_of_message;
                  connection^.sender_request.qualified_data := call_block.se_send_data_req.qualified_data;
                ELSEIF call_block.operation = amc$put_partial_req THEN
                  connection^.sender_request.term_option := call_block.putp.term_option;
                  IF ((call_block.putp.term_option = amc$start) OR
                        (call_block.putp.term_option = amc$continue)) AND
                        (NOT connection^.intermediate_put_partial) THEN
                    connection^.intermediate_put_partial := TRUE;
                  IFEND;
                  IF (call_block.putp.term_option = amc$terminate) AND
                        (connection^.intermediate_put_partial) THEN
                    connection^.intermediate_put_partial := FALSE;
                  IFEND;
                IFEND;
                file_instance^.sender_activity_status := activity_status;
                file_instance^.sender_active := TRUE;
                connection^.sender_request.remaining_bytes_to_send := bytes_to_send;
                connection^.send_file_identifier := file_identifier;
                condition_cause := nac$application_data;
                #SPOIL (condition_cause);
                IF description_upperbound <= nac$fixed_fragments THEN
                  connection^.sender_request.application_buffer.description_kind := nac$fixed;
                  nlp$al_initialize_data_descrip (data_area^, connection^.sender_request.
                        remaining_bytes_to_send, connection^.sender_request.application_buffer.
                        fixed_description);
                ELSE
                  connection^.sender_request.application_buffer.description_kind := nac$allocated;
                  REPEAT
                    ALLOCATE connection^.sender_request.application_buffer.allocated_description:
                          [1 .. description_upperbound] IN nav$network_paged_heap^;
                    IF connection^.sender_request.application_buffer.allocated_description = NIL THEN
                      syp$cycle;
                    IFEND;
                  UNTIL connection^.sender_request.application_buffer.allocated_description <> NIL;
                  nlp$al_initialize_data_descrip (data_area^, connection^.sender_request.
                        remaining_bytes_to_send, connection^.sender_request.application_buffer.
                        allocated_description^);
                IFEND;
                IF (capacity > 0) AND (connection^.send_put_partial_termination) THEN
                  nlp$sl_data_request (cl_connection, FALSE {qualified_data} , TRUE {END_OF_MESSAGE} ,
                        nav$null_data, status);
                  connection^.send_put_partial_termination := FALSE;
                IFEND;
                send_data (cl_connection, connection);
                IF cl_connection^.message_sender.active THEN
                  current_time := #FREE_RUNNING_CLOCK (0);
                  wait_time := file_instance^.data_transfer_timeout;
                  IF (file_instance^.data_transfer_timeout > ((current_time - start_time) DIV 1000)) THEN
                    request_started := TRUE;
                    nlp$select_timer ((file_instance^.data_transfer_timeout * 1000) -
                          (current_time - start_time), 0, connection^.send_timer);
                    activity_status^.complete := FALSE;
                  ELSE
                    ; {deactivate request
                    IF connection^.sender_request.application_buffer.description_kind = nac$allocated THEN
                      FREE connection^.sender_request.application_buffer.allocated_description IN
                            nav$network_paged_heap^;
                    IFEND;
                    nlp$cl_deactivate_sender (cl_connection);
                    file_instance^.sender_active := FALSE;
                    osp$set_status_condition (nae$data_transfer_timeout, status);
                    condition_cause := nac$activity_status;
                    #SPOIL (condition_cause);
                    activity_status^.status := status;
                  IFEND;
                IFEND;
              IFEND;
            ELSE
              IF (call_block.operation = nac$se_send_data_req) AND
                    (call_block.se_send_data_req.wait = osc$nowait) THEN
                osp$set_status_condition (nae$send_outstanding, status);
              ELSE
                request_started := FALSE;
                wait_time := file_instance^.data_transfer_timeout;
                activity_status^.complete := FALSE;
              IFEND;
            IFEND;
          ELSE
            IF connection^.nominal_connection THEN
              osp$set_status_condition (nae$interactive_cond_interrupt, status);
            ELSE
              osp$set_status_condition (nae$se_synchronize_in_progress, status);
            IFEND;
          IFEND;
        ELSE
          IF connection^.nominal_connection THEN
            osp$set_status_condition (nae$interactive_cond_interrupt, status);
            IF (NOT connection^.timesharing_disconnect_sent) AND
                  (connection^.supervisory_event_queue.beginning = NIL) AND
                  (connection^.wait_state <> nac$waiting_to_receive_data) THEN
              connection^.timesharing_disconnect_sent := TRUE;
              send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id,
                    NIL);
            IFEND;
          ELSE
            osp$set_status_condition (nae$connection_terminated, status);
          IFEND;
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
    IF (NOT status.normal) AND (status.condition = nae$connection_terminated) THEN
      fmp$convert_status (file_instance^.local_file_name, status);
    IFEND;
  PROCEND nlp$se_send_data;

?? TITLE := '  [XDCL] NAP$SE_SEND_DATA_HANDLER' ??
?? NEWTITLE := '    TERMINATE_SEND -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL] nap$se_send_data_handler
    (    originator: ost$global_task_id;
         signal: pmt$signal);


    PROCEDURE terminate_send
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
{Debug Code
      = pmc$block_exit_processing =
        osp$decrement_locked_variable (nav$namve_tsk_hndl_active_count, 1, actual_value, ignore_error);
{End Debug Code
      = pmc$system_conditions, mmc$segment_access_condition =
        IF condition_cause = nac$application_data THEN
          IF cl_connection <> NIL THEN
            nlp$cl_deactivate_sender (cl_connection);
            IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                  (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
              FREE connection^.sender_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            IFEND;
            osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
            condition_cause := nac$activity_status;
            #SPOIL (condition_cause);
            osp$establish_condition_handler (^terminate_send, FALSE);
            complete_activity (send, connection^.send_file_identifier, ^condition_status);
            condition_status.normal := TRUE;
            nlp$cl_clear_exclusive_access (cl_connection);
            osp$pop_inhibit_job_recovery;
            EXIT nap$se_send_data_handler; {----->
          ELSE
            osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          IFEND;
        ELSEIF condition_cause = nac$activity_status THEN
          IF cl_connection <> NIL THEN
            IF (cl_connection^.message_sender.active) AND (cl_connection^.message_sender.task =
                  processing_task) THEN
              nlp$cl_deactivate_sender (cl_connection);
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              terminate_io (sender, connection^.send_file_identifier);
            IFEND;
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
          osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
        ELSE
          osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          IF cl_connection <> NIL THEN
            nap$namve_system_error (TRUE, 'NAP$SE_SEND_DATA_HANLDER ', ^condition_status);
            nlp$cl_clear_exclusive_access (cl_connection);
          IFEND;
        IFEND;
        osp$pop_inhibit_job_recovery;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_send;
?? OLDTITLE, EJECT ??

    VAR
      cl_connection: ^nlt$cl_connection,
      cl_connection_id: ^nlt$cl_connection_id,
      condition_cause: nat$se_condition_cause,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      capacity: nat$data_length,
      layer_active: boolean,
      processing_task: ost$global_task_id,
      status: ost$status;

{Debug Code

    VAR
      actual_value: integer,
      ignore_error: boolean;

    osp$increment_locked_variable (nav$namve_tsk_hndl_active_count, 0, actual_value);
    IF actual_value > 1 THEN
      osp$increment_locked_variable (nav$multiple_namve_hndler_calls, 0, actual_value);
      IF nav$debug_mode > nac$no_debug THEN
        nap$namve_system_error (TRUE {=recoverable} ,
              'NAP$SE_SEND_DATA_HANDLER invoked while another handler active.', NIL);
      IFEND;
    IFEND;
{End Debug Code

    status.normal := TRUE;
    cl_connection_id := #LOC (signal.contents);
    cl_connection := NIL;
    condition_cause := nac$request_not_cause;
    #SPOIL (condition_cause, cl_connection);
    osp$push_inhibit_job_recovery;
*if false
    osp$establish_condition_handler (^terminate_send, FALSE);
*ifend
{Debug Code
    osp$establish_condition_handler (^terminate_send, TRUE);
{End Debug Code

    nlp$cl_get_exclusive_via_cid (cl_connection_id^, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      pmp$get_executing_task_gtid (processing_task);
      IF layer_active THEN
        #SPOIL (connection);
        IF cl_connection^.message_sender.active AND (cl_connection^.message_sender.task = processing_task)
              THEN
          IF connection^.connection_state = nac$established THEN

            IF connection^.break_connection_send THEN
              ; {deactive_send
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              connection^.break_connection_send := FALSE;
              nlp$cl_deactivate_sender (cl_connection);

              connection^.synchronize_request_send := FALSE;

              connection^.synchronize_send := FALSE;

              IF connection^.wait_state <> nac$waiting_to_receive_data THEN
                send_timesharing_signal (jmc$timesharing_synchronize, connection^.
                      nominal_connection_task_id, ^connection^.event);
              IFEND;
              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              ; {nae$interactive_cond_interrupt
              osp$set_status_condition (nae$interactive_cond_interrupt, status);
              complete_activity (send, connection^.send_file_identifier, ^status);

            ELSEIF connection^.synchronize_request_send THEN
              ; {deactivate_send
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              nlp$cl_deactivate_sender (cl_connection);
              ; {terminate normally
              connection^.synchronize_request_send := FALSE;

              connection^.synchronize_send := FALSE;

              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              complete_activity (send, connection^.send_file_identifier, NIL);

            ELSEIF connection^.synchronize_send THEN
              connection^.synchronize_send := FALSE;
              ; {deactivate_send
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              nlp$cl_deactivate_sender (cl_connection);
              ; {terminate normally
              connection^.synchronize_send := FALSE;
              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              complete_activity (send, connection^.send_file_identifier, NIL);
            ELSE
              ; {continue normal processing
              nlp$osi_get_outbound_capacity (cl_connection, capacity);
              IF capacity > 0 THEN
                IF connection^.send_put_partial_termination THEN
                  nlp$sl_data_request (cl_connection, FALSE {qualified_data} , TRUE {END_OF_MESSAGE} ,
                        nav$null_data, status);
                  connection^.send_put_partial_termination := FALSE;
                IFEND;
                condition_cause := nac$application_data;
                #SPOIL (condition_cause);
                send_data (cl_connection, connection);
                IF NOT cl_connection^.message_sender.active THEN
                  condition_cause := nac$activity_status;
                  #SPOIL (condition_cause);
                  complete_activity (send, connection^.send_file_identifier, NIL);
                IFEND;

                condition_cause := nac$request_not_cause;
                #SPOIL (condition_cause);

              IFEND;
            IFEND;
            IF (cl_connection^.message_sender.active) AND (connection^.send_timeout) THEN
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              nlp$cl_deactivate_sender (cl_connection);
              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              osp$set_status_condition (nae$data_transfer_timeout, status);
              complete_activity (send, connection^.send_file_identifier, ^status);
            IFEND;
          ELSEIF connection^.connection_state = nac$terminated THEN
            ; {deactivate send nae$connection_teminated
            IF cl_connection^.message_sender.active THEN
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              nlp$cl_deactivate_sender (cl_connection);
              IF NOT connection^.nominal_connection THEN
                osp$set_status_condition (nae$connection_terminated, status);
              ELSE
                osp$set_status_condition (nae$interactive_cond_interrupt, status);
              IFEND;
              condition_cause := nac$activity_status;
              #SPOIL (condition_cause);
              complete_activity (send, connection^.send_file_identifier, ^status);
            IFEND;
          IFEND;
        IFEND;
        IF (connection^.connection_state = nac$terminated) AND
              (NOT connection^.timesharing_disconnect_sent) AND (connection^.nominal_connection) AND
              (connection^.data_queue.count = 0) AND (connection^.supervisory_event_queue.beginning = NIL) AND
              (connection^.wait_state <> nac$waiting_to_receive_data) AND
              (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
          ; {send signal
          connection^.timesharing_disconnect_sent := TRUE;
          send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id, NIL);
        IFEND;
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    IFEND;
    osp$pop_inhibit_job_recovery;

{Debug Code
    osp$disestablish_cond_handler;
    osp$decrement_locked_variable (nav$namve_tsk_hndl_active_count, 1, actual_value, ignore_error);
{End Debug Code

  PROCEND nap$se_send_data_handler;

?? TITLE := '  [XDCL, #GATE] NLP$SE_SEND_INTERRUPT' ??
?? NEWTITLE := '    TERMINATE_SEND_INTERRUPT -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL, #GATE] nlp$se_send_interrupt
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);


    PROCEDURE terminate_send_interrupt
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          IF nlp$bm_valid_message_id (message_id) THEN
            nlp$bm_release_message (message_id);
          IFEND;
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$se_send_interrupt; {----->
        ELSE
          IF nlp$bm_valid_message_id (message_id) THEN
            nlp$bm_release_message (message_id);
          IFEND;
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$se_send_interrupt; {----->
        IFEND;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_send_interrupt;
?? OLDTITLE, EJECT ??

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      data: array [1 .. 1] of nat$data_fragment,
      data_length: nat$data_length,
      file_instance: ^bat$task_file_entry,
      ignore: integer,
      ignore_status: ost$status,
      layer_active: boolean,
      message_id: nlt$bm_message_id;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r1 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    data [1].address := call_block.se_interrupt_data;
    data [1].length := #SIZE (call_block.se_interrupt_data^);
    nlp$al_get_data_length (data, data_length);
    IF (data_length <= nac$se_max_interrupt_data_len) AND (data_length >= nac$se_min_interrupt_data_len) THEN
      cl_connection := NIL;
      message_id := nlv$bm_null_message_id;
      osp$push_inhibit_job_recovery;
      osp$establish_condition_handler (^terminate_send_interrupt, FALSE);
      nlp$bm_create_message (data, message_id, ignore_status);
      nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
            network_connection_id, connection_exists, cl_connection);
      IF connection_exists THEN
        nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active,
              connection);
        IF layer_active THEN
          IF connection^.connection_state = nac$established THEN
            nlp$sl_interrupt_request (cl_connection, message_id, status);

{! statistics begin
            IF status.normal THEN
              osp$increment_locked_variable (nav$global_statistics.session.interrupt_requests_sent, 0,
                    ignore);
            IFEND;
{! statistics end

          ELSE
            nlp$bm_release_message (message_id);
            osp$set_status_condition (nae$connection_terminated, status);
          IFEND;
        ELSE
          nlp$bm_release_message (message_id);
          osp$set_status_condition (nae$connection_terminated, status);
        IFEND;
        nlp$cl_release_exclusive_access (cl_connection);
      ELSE
        nlp$bm_release_message (message_id);
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      osp$pop_inhibit_job_recovery;
    ELSE
      osp$set_status_condition (nae$se_interrupt_length_error, status);
      osp$append_status_integer (osc$status_parameter_delimiter, nac$se_max_interrupt_data_len, 10, FALSE,
            status);
      osp$append_status_integer (osc$status_parameter_delimiter, nac$se_min_interrupt_data_len, 10, FALSE,
            status);
    IFEND;
  PROCEND nlp$se_send_interrupt;
?? TITLE := '  [XDCL, #GATE] NLP$SE_SYNCHRONIZE' ??
?? NEWTITLE := '    TERMINATE_SYNCHRONIZE -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL, #GATE] nlp$se_synchronize
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);


    PROCEDURE terminate_synchronize
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          IF nlp$bm_valid_message_id (message_id) THEN
            nlp$bm_release_message (message_id);
          IFEND;
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$se_synchronize; {----->
        ELSE
          IF nlp$bm_valid_message_id (message_id) THEN
            nlp$bm_release_message (message_id);
          IFEND;
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$se_synchronize; {----->
        IFEND;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_synchronize;
?? OLDTITLE, EJECT ??

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      data: array [1 .. 1] of nat$data_fragment,
      file_instance: ^bat$task_file_entry,
      ignore: integer,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      processing_task: ost$global_task_id;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r1 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    IF (#SIZE (call_block.se_synchronize_req.data^) <= nac$se_max_synch_data_length) AND
          (#SIZE (call_block.se_synchronize_req.data^) >= nac$se_min_synch_data_length) THEN
      data [1].address := call_block.se_synchronize_req.data;
      data [1].length := #SIZE (call_block.se_synchronize_req.data^);
      message_id := nlv$bm_null_message_id;
      cl_connection := NIL;
      osp$push_inhibit_job_recovery;
      osp$establish_condition_handler (^terminate_synchronize, FALSE);
      ; {release message_id if condition_handler gets called
      nlp$bm_create_message (data, message_id, {ignore} status);
      status.normal := TRUE;
      nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
            network_connection_id, connection_exists, cl_connection);
      IF connection_exists THEN
        nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active,
              connection);
        IF layer_active THEN
          IF connection^.connection_state = nac$established THEN
            IF call_block.se_synchronize_req.direction = nac$se_synchronize_all_data THEN
              nlp$sl_synch_request (cl_connection, nlc$sl_discard_send_receive, message_id, status);
            ELSEIF call_block.se_synchronize_req.direction = nac$se_synchronize_send_data THEN
              nlp$sl_synch_request (cl_connection, nlc$sl_discard_send, message_id, status);
            ELSEIF call_block.se_synchronize_req.direction = nac$se_synchronize_receive_data THEN
              nlp$sl_synch_request (cl_connection, nlc$sl_discard_receive, message_id, status);
            ELSE
              osp$set_status_condition (nae$se_unknown_synch_direction, status);
            IFEND;
            IF status.normal THEN
              IF (call_block.se_synchronize_req.direction = nac$se_synchronize_all_data) OR
                    (call_block.se_synchronize_req.direction = nac$se_synchronize_receive_data) THEN
                {OK} connection^.receive_synchronize_count := connection^.receive_synchronize_count + 1;
                release_data_queue (connection^);
                nlp$ta_report_undelivered_data (cl_connection, 0);
                IF connection^.wait_state = nac$waiting_to_receive_data THEN
                  IF NOT connection^.synchronize_request_receive THEN
                    connection^.synchronize_request_receive := TRUE;
                  IFEND;
                  activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
                IFEND;
              IFEND;
              IF (call_block.se_synchronize_req.direction = nac$se_synchronize_all_data) OR
                    (call_block.se_synchronize_req.direction = nac$se_synchronize_send_data) THEN
                connection^.intermediate_put_partial := FALSE;
                connection^.send_put_partial_termination := FALSE;
                IF cl_connection^.message_sender.active THEN
                  nlp$cancel_timer (connection^.send_timer);
                  connection^.synchronize_request_send := TRUE;
                  pmp$get_executing_task_gtid (processing_task);
                  IF cl_connection^.message_sender.task = processing_task THEN
                    terminate_send_data (connection, cl_connection, NIL);
                  ELSE
                    activate_sender_task (cl_connection, cl_connection^.message_sender.task);
                  IFEND;
                IFEND;
              IFEND;

{! statistics begin
              osp$increment_locked_variable (nav$global_statistics.session.synchronize_requests_sent, 0,
                    ignore);
{! statistics end

            IFEND;
          ELSE
            nlp$bm_release_message (message_id);
            osp$set_status_condition (nae$connection_terminated, status);
          IFEND;
        ELSE
          nlp$bm_release_message (message_id);
          osp$set_status_condition (nae$connection_terminated, status);
        IFEND;
        nlp$cl_release_exclusive_access (cl_connection);
      ELSE
        nlp$bm_release_message (message_id);
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      osp$pop_inhibit_job_recovery;
    ELSE
      osp$set_status_condition (nae$se_synchronize_length_error, status);
      osp$append_status_integer (osc$status_parameter_delimiter, nac$se_max_synch_data_length, 10, FALSE,
            status);
      osp$append_status_integer (osc$status_parameter_delimiter, nac$se_min_synch_data_length, 10, FALSE,
            status);
    IFEND;
  PROCEND nlp$se_synchronize;
?? TITLE := '  [XDCL, #GATE] NLP$SE_SYNCHRONIZE_CONFIRM', EJECT ??

  PROCEDURE [XDCL, #GATE] nlp$se_synchronize_confirm
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      file_instance: ^bat$task_file_entry,
      layer_active: boolean;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r1 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.connection_state = nac$established THEN
          IF connection^.send_synchronize_count > 0 THEN
            nlp$sl_synch_response (cl_connection, status);
            IF status.normal THEN
              {OK} connection^.send_synchronize_count := connection^.send_synchronize_count - 1;
              connection^.break_condition_active := FALSE;
              IF (connection^.nominal_connection) AND (connection^.supervisory_event_queue.beginning <> NIL)
                    THEN
                process_nominal_connect_events (connection, cl_connection);
              IFEND;
            IFEND;
          ELSE
            osp$set_status_condition (nae$se_no_synch_in_progress, status);
          IFEND;
        ELSE
          IF connection^.send_synchronize_count > 0 THEN
            connection^.send_synchronize_count := connection^.send_synchronize_count - 1;
            connection^.break_condition_active := FALSE;
            IF (connection^.nominal_connection) AND (connection^.supervisory_event_queue.beginning <> NIL)
                  THEN
              process_nominal_connect_events (connection, cl_connection);
            IFEND;
          IFEND;
          IF (connection^.connection_state = nac$terminated) AND
                (NOT connection^.timesharing_disconnect_sent) AND (connection^.nominal_connection) AND
                (connection^.data_queue.count = 0) AND (connection^.supervisory_event_queue.beginning =
                NIL) AND (connection^.wait_state <> nac$waiting_to_receive_data) AND
                (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
            ; {send signal
            connection^.timesharing_disconnect_sent := TRUE;
            send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id, NIL);
          IFEND;
          osp$set_status_condition (nae$connection_terminated, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$se_synchronize_confirm;

?? TITLE := '  [XDCL] NAP$STORE_CLIENT_IDENTITY', EJECT ??

  PROCEDURE [XDCL] nap$store_client_identity
    (    connection_id: nat$connection_id;
         client_identity: nat$client_identity;
     VAR status: ost$status);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      layer_active: boolean;

    status.normal := TRUE;
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        connection^.client_identity := client_identity;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nap$store_client_identity;

?? TITLE := '  [XDCL, #GATE] NLP$FETCH_ATTRIBUTES' ??
?? NEWTITLE := '    TERMINATE_FETCH_ATTRIBUTES -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL, #GATE] nlp$fetch_attributes
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);


    PROCEDURE terminate_fetch_attributes
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$fetch_attributes; {----->
        IFEND;
        osp$pop_inhibit_job_recovery;
        osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_fetch_attributes;
?? OLDTITLE, EJECT ??

    VAR
      attribute_p: ^nat$get_attribute,
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      file_instance: ^bat$task_file_entry,
      i: integer,
      layer_active: boolean,
      optimum_transfer_size: nat$data_length;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r2 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    cl_connection := NIL;
    osp$push_inhibit_job_recovery;
    osp$establish_condition_handler (^terminate_fetch_attributes, FALSE);
    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF call_block.fetch_attributes <> NIL THEN

        /attribute_loop/
          FOR i := LOWERBOUND (call_block.fetch_attributes^) TO UPPERBOUND (call_block.fetch_attributes^) DO
            attribute_p := ^call_block.fetch_attributes^ [i];
            CASE attribute_p^.kind OF
            = nac$client_identity =
              attribute_p^.client_identity := connection^.client_identity;
            = nac$connect_data =
              IF connection^.connect_data <> NIL THEN
                nap$move_data_to_user_data_area (connection^.connect_data, attribute_p^.connect_data,
                      attribute_p^.connect_data_length, status.normal);
                IF NOT status.normal THEN
                  osp$set_status_condition (nae$data_area_too_small, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, 'See NAC$CONNECT_DATA.',
                        status);
                IFEND;
              ELSE
                attribute_p^.connect_data_length := 0;
              IFEND;
            = nac$connection_state =
              attribute_p^.connection_state := connection^.connection_state;
            = nac$data_transfer_timeout =
              attribute_p^.data_transfer_timeout := file_instance^.data_transfer_timeout;
            = nac$eoi_message =
              IF file_instance^.eoi_message <> NIL THEN
                attribute_p^.eoi_message := file_instance^.eoi_message^;
              ELSE
                attribute_p^.eoi_message := nav$eoi_message;
              IFEND;
            = nac$eoi_message_enabled =
              attribute_p^.eoi_message_enabled := file_instance^.eoi_message_enabled;
            = nac$eoi_peer_termination =
              attribute_p^.eoi_peer_termination := file_instance^.eoi_peer_termination;
            = nac$local_address =
              attribute_p^.local_address := connection^.local_address;
            = nac$null_attribute =
            = nac$optimum_transfer_unit_incr =
              get_optimum_transfer_size (cl_connection, optimum_transfer_size);
              attribute_p^.optimum_transfer_unit_incr := optimum_transfer_size - #SIZE (nlt$sl_pdu_header);
            = nac$optimum_transfer_unit_size =
              get_optimum_transfer_size (cl_connection, optimum_transfer_size);
              attribute_p^.optimum_transfer_unit_size := optimum_transfer_size - #SIZE (nlt$sl_pdu_header);
            = nac$peer_accounting_information =
              IF connection^.peer_accounting_information <> NIL THEN
                nap$move_data_to_user_data_area (connection^.peer_accounting_information,
                      attribute_p^.peer_accounting_information, attribute_p^.peer_accounting_info_length,
                      status.normal);
                IF NOT status.normal THEN
                  osp$set_status_condition (nae$data_area_too_small, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        'See NAC$PEER_ACCOUNTING_INFORMATION.', status);
                IFEND;
              ELSE
                attribute_p^.peer_accounting_info_length := 0;
              IFEND;
            = nac$peer_address =
              attribute_p^.peer_address := connection^.peer_address;
            = nac$peer_connect_data =
              IF connection^.peer_connect_data <> NIL THEN
                nap$move_data_to_user_data_area (connection^.peer_connect_data,
                      attribute_p^.peer_connect_data, attribute_p^.peer_connect_data_length, status.normal);
                IF NOT status.normal THEN
                  osp$set_status_condition (nae$data_area_too_small, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, 'SEE NAC$PEER_CONNECT_DATA.',
                        status);
                IFEND;
              ELSE
                attribute_p^.peer_connect_data_length := 0;
              IFEND;
            = nac$peer_termination_data =
              IF connection^.peer_termination_data <> NIL THEN
                nap$move_data_to_user_data_area (connection^.peer_termination_data,
                      attribute_p^.peer_termination_data, attribute_p^.peer_termination_data_length,
                      status.normal);
                IF NOT status.normal THEN
                  osp$set_status_condition (nae$data_area_too_small, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        'See NAC$PEER_TERMINATION_DATA.', status);
                IFEND;
              ELSE
                attribute_p^.peer_termination_data_length := 0;
              IFEND;
            = nac$protocol =
              attribute_p^.protocol := connection^.protocol;
            = nac$receive_wait_swapout =
              attribute_p^.receive_wait_swapout := connection^.receive_wait_swapout;
            = nac$termination_data =
              IF connection^.termination_data <> NIL THEN
                nap$move_data_to_user_data_area (connection^.termination_data, attribute_p^.termination_data,
                      attribute_p^.termination_data_length, status.normal);
                IF NOT status.normal THEN
                  osp$set_status_condition (nae$data_area_too_small, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, 'See NAC$TERMINATION_DATA.',
                        status);
                IFEND;
              ELSE
                attribute_p^.termination_data_length := 0;
              IFEND;
            = nac$termination_reason =
              attribute_p^.termination_reason := connection^.termination_reason;
            ELSE
              osp$set_status_abnormal (nac$status_id, nae$unknown_attribute, ' on FETCH_ATTRIBUTES ', status);
            CASEND;
            IF NOT status.normal THEN
              EXIT /attribute_loop/; {----->
            IFEND;
          FOREND /attribute_loop/;
        IFEND;

      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;

  PROCEND nlp$fetch_attributes;
?? TITLE := '  [XDCL, #GATE] NLP$STORE_ATTRIBUTES' ??
?? NEWTITLE := '    TERMINATE_STORE_ATTRIBUTES -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL, #GATE] nlp$store_attributes
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);


    PROCEDURE terminate_store_attributes
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nlp$store_attributes; {----->
        IFEND;
        osp$pop_inhibit_job_recovery;
        osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_store_attributes;
?? OLDTITLE, EJECT ??

    VAR
      attribute_p: ^nat$change_attribute,
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      error_string: string (256),
      file_instance: ^bat$task_file_entry,
      file_is_valid: boolean,
      i: integer,
      layer_active: boolean,
      length: integer;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF file_instance^.device_class <> rmc$network_device THEN
      osp$set_status_condition (ame$improper_device_class, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r1 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;
    cl_connection := NIL;
    osp$push_inhibit_job_recovery;
    osp$establish_condition_handler (^terminate_store_attributes, FALSE);
    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF call_block.store_attributes <> NIL THEN
          FOR i := LOWERBOUND (call_block.store_attributes^) TO UPPERBOUND (call_block.store_attributes^) DO
            attribute_p := ^call_block.store_attributes^ [i];
            CASE attribute_p^.kind OF
            = nac$connect_data =
              IF connection^.connection_state = nac$connection_request_received THEN
                IF ((attribute_p^.connect_data <> NIL) AND (#SIZE (attribute_p^.connect_data^) <=
                      nac$maximum_connect_data)) OR (attribute_p^.connect_data = NIL) THEN
                  nap$move_user_data_to_data_area (attribute_p^.connect_data, connection^.connect_data);
                ELSE
                  STRINGREP (error_string, length, nac$maximum_connect_data, ' for NAC$CONNECT_DATA');
                  osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, error_string, status);
                IFEND;
              ELSE { invalid state
                osp$set_status_condition (nae$invalid_connect_data_change, status);
              IFEND;
            = nac$data_transfer_timeout =
              file_instance^.data_transfer_timeout := attribute_p^.data_transfer_timeout;
            = nac$eoi_message =
              IF attribute_p^.eoi_message.size <= 31 {nac$maximum_eoi_size} THEN
                IF file_instance^.eoi_message = NIL THEN
                  ALLOCATE file_instance^.eoi_message IN osv$task_private_heap^;
                IFEND;
                file_instance^.eoi_message^ := attribute_p^.eoi_message;
              ELSE
                osp$set_status_abnormal (nac$status_id, nae$invalid_eoi_message_size, '31'
                      {nac$maximum_eoi_size} , status);
              IFEND;
            = nac$eoi_message_enabled =
              file_instance^.eoi_message_enabled := attribute_p^.eoi_message_enabled;
            = nac$eoi_peer_termination =
              file_instance^.eoi_peer_termination := attribute_p^.eoi_peer_termination;
            = nac$null_attribute =
            = nac$receive_wait_swapout =
              connection^.receive_wait_swapout := attribute_p^.receive_wait_swapout;
            = nac$termination_data =
              IF ((attribute_p^.termination_data <> NIL) AND (#SIZE (attribute_p^.termination_data^) <=
                    nac$maximum_termination_data)) OR (attribute_p^.termination_data = NIL) THEN
                nap$move_user_data_to_data_area (attribute_p^.termination_data, connection^.termination_data);
              ELSE
                STRINGREP (error_string, length, nac$maximum_termination_data, ' for NAC$TERMINATION_DATA');
                osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, error_string, status);
              IFEND;
            ELSE
              osp$set_status_abnormal (nac$status_id, nae$unknown_attribute, ' on STORE ATTRIBUTES ', status);
            CASEND;
          FOREND;
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;

  PROCEND nlp$store_attributes;

?? TITLE := 'NAP$GET_ATTRIBUTES', EJECT ??

  PROCEDURE [XDCL, #GATE] nap$get_attributes
    (    file: fst$file_reference;
     VAR attributes: {input, output} nat$get_attributes;
     VAR status: ost$status);

*copyc nah$get_attributes

?? NEWTITLE := '    TERMINATE_GET_ATTRIBUTES -- CONDITION HANDLER', EJECT ??

    PROCEDURE terminate_get_attributes
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nap$get_attributes; {----->
        IFEND;
        osp$pop_inhibit_job_recovery;
        osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_get_attributes;
?? OLDTITLE, EJECT ??

    VAR
      attribute_p: ^nat$get_attribute,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      connection_id: nat$connection_id,
      i: integer,
      layer_active: boolean,
      optimum_transfer_size: nat$data_length,
      switch_offer_pending: boolean;

    fmp$get_connection_identifier (file, connection_id, switch_offer_pending, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A GET ATTRIBUTES ', status);
      IFEND;
      RETURN; {----->
    IFEND;

    IF switch_offer_pending THEN
      osp$set_status_condition (nae$switch_offer_pending, status);
      RETURN; {----->
    IFEND;

    cl_connection := NIL;
    osp$push_inhibit_job_recovery;
    osp$establish_condition_handler (^terminate_get_attributes, FALSE);
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN

      /attribute_loop/
        FOR i := LOWERBOUND (attributes) TO UPPERBOUND (attributes) DO
          attribute_p := ^attributes [i];
          CASE attribute_p^.kind OF
          = nac$client_identity =
            attribute_p^.client_identity := connection^.client_identity;
          = nac$connect_data =
            IF connection^.connect_data <> NIL THEN
              nap$move_data_to_user_data_area (connection^.connect_data, attribute_p^.connect_data,
                    attribute_p^.connect_data_length, status.normal);
              IF NOT status.normal THEN
                osp$set_status_condition (nae$data_area_too_small, status);
                osp$append_status_parameter (osc$status_parameter_delimiter, 'See NAC$CONNECT_DATA.', status);
              IFEND;
            ELSE
              attribute_p^.connect_data_length := 0;
            IFEND;
          = nac$connection_state =
            attribute_p^.connection_state := connection^.connection_state;
          = nac$data_transfer_timeout =
            attribute_p^.data_transfer_timeout := connection^.data_transfer_timeout;
          = nac$eoi_message =
            IF connection^.eoi_message <> NIL THEN
              attribute_p^.eoi_message := connection^.eoi_message^;
            ELSE
              attribute_p^.eoi_message := nav$eoi_message;
            IFEND;
          = nac$eoi_message_enabled =
            attribute_p^.eoi_message_enabled := connection^.eoi_message_enabled;
          = nac$eoi_peer_termination =
            attribute_p^.eoi_peer_termination := connection^.eoi_peer_termination;
          = nac$local_address =
            attribute_p^.local_address := connection^.local_address;
          = nac$null_attribute =
          = nac$optimum_transfer_unit_incr =
            get_optimum_transfer_size (cl_connection, optimum_transfer_size);
            attribute_p^.optimum_transfer_unit_incr := optimum_transfer_size - #SIZE (nlt$sl_pdu_header);
          = nac$optimum_transfer_unit_size =
            get_optimum_transfer_size (cl_connection, optimum_transfer_size);
            attribute_p^.optimum_transfer_unit_size := optimum_transfer_size - #SIZE (nlt$sl_pdu_header);
          = nac$peer_accounting_information =
            IF connection^.peer_accounting_information <> NIL THEN
              nap$move_data_to_user_data_area (connection^.peer_accounting_information,
                    attribute_p^.peer_accounting_information, attribute_p^.peer_accounting_info_length,
                    status.normal);
              IF NOT status.normal THEN
                osp$set_status_condition (nae$data_area_too_small, status);
                osp$append_status_parameter (osc$status_parameter_delimiter,
                      'See NAC$PEER_ACCOUNTING_INFORMATION.', status);
              IFEND;
            ELSE
              attribute_p^.peer_accounting_info_length := 0;
            IFEND;
          = nac$peer_address =
            attribute_p^.peer_address := connection^.peer_address;
          = nac$peer_connect_data =
            IF connection^.peer_connect_data <> NIL THEN
              nap$move_data_to_user_data_area (connection^.peer_connect_data, attribute_p^.peer_connect_data,
                    attribute_p^.peer_connect_data_length, status.normal);
              IF NOT status.normal THEN
                osp$set_status_condition (nae$data_area_too_small, status);
                osp$append_status_parameter (osc$status_parameter_delimiter, 'See NAC$PEER_CONNECT_DATA.',
                      status);
              IFEND;
            ELSE
              attribute_p^.peer_connect_data_length := 0;
            IFEND;
          = nac$peer_termination_data =
            IF connection^.peer_termination_data <> NIL THEN
              nap$move_data_to_user_data_area (connection^.peer_termination_data,
                    attribute_p^.peer_termination_data, attribute_p^.peer_termination_data_length,
                    status.normal);
              IF NOT status.normal THEN
                osp$set_status_condition (nae$data_area_too_small, status);
                osp$append_status_parameter (osc$status_parameter_delimiter, 'See NAC$PEER_TERMINATION_DATA.',
                      status);
              IFEND;
            ELSE
              attribute_p^.peer_termination_data_length := 0;
            IFEND;
          = nac$protocol =
            attribute_p^.protocol := connection^.protocol;
          = nac$receive_wait_swapout =
            attribute_p^.receive_wait_swapout := connection^.receive_wait_swapout;
          = nac$termination_data =
            IF connection^.termination_data <> NIL THEN
              nap$move_data_to_user_data_area (connection^.termination_data, attribute_p^.termination_data,
                    attribute_p^.termination_data_length, status.normal);
              IF NOT status.normal THEN
                osp$set_status_condition (nae$data_area_too_small, status);
                osp$append_status_parameter (osc$status_parameter_delimiter, 'See NAC$TERMINATION_DATA.',
                      status);
              IFEND;
            ELSE
              attribute_p^.termination_data_length := 0;
            IFEND;
          = nac$termination_reason =
            attribute_p^.termination_reason := connection^.termination_reason;
          ELSE
            osp$set_status_abnormal (nac$status_id, nae$unknown_attribute, ' on GET ATTRIBUTES ', status);
          CASEND;
          IF NOT status.normal THEN
            EXIT /attribute_loop/; {----->
          IFEND;
        FOREND /attribute_loop/;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;

  PROCEND nap$get_attributes;

?? TITLE := 'NAP$CHANGE_ATTRIBUTES', EJECT ??

  PROCEDURE [XDCL, #GATE] nap$change_attributes
    (    file: fst$file_reference;
         attributes: nat$change_attributes;
     VAR status: ost$status);

*copyc nah$change_attributes

?? NEWTITLE := '    TERMINATE_CHANGE_ATTRIBUTES -- CONDITION HANDLER', EJECT ??

    PROCEDURE terminate_change_attributes
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nap$change_attributes; {----->
        IFEND;
        osp$pop_inhibit_job_recovery;
        osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_change_attributes;
?? OLDTITLE, EJECT ??

    VAR
      attribute_p: ^nat$change_attribute,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      connection_id: nat$connection_id,
      error_string: string (256),
      i: integer,
      layer_active: boolean,
      length: integer,
      switch_offer_pending: boolean;

    fmp$get_connection_identifier (file, connection_id, switch_offer_pending, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A CHANGE ATTRIBUTES ', status);
      IFEND;
      RETURN; {----->
    IFEND;

    IF switch_offer_pending THEN
      osp$set_status_condition (nae$switch_offer_pending, status);
      RETURN; {----->
    IFEND;

    cl_connection := NIL;
    osp$push_inhibit_job_recovery;
    osp$establish_condition_handler (^terminate_change_attributes, FALSE);
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        FOR i := LOWERBOUND (attributes) TO UPPERBOUND (attributes) DO
          attribute_p := ^attributes [i];
          CASE attribute_p^.kind OF
          = nac$connect_data =
            IF connection^.connection_state = nac$connection_request_received THEN
              IF ((attribute_p^.connect_data <> NIL) AND (#SIZE (attribute_p^.connect_data^) <=
                    nac$maximum_connect_data)) OR (attribute_p^.connect_data = NIL) THEN
                nap$move_user_data_to_data_area (attribute_p^.connect_data, connection^.connect_data);
              ELSE
                STRINGREP (error_string, length, nac$maximum_connect_data, ' for NAC$CONNECT_DATA');
                osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, error_string, status);
              IFEND;
            ELSE { invalid state
              osp$set_status_condition (nae$invalid_connect_data_change, status);
            IFEND;
          = nac$data_transfer_timeout =
            connection^.data_transfer_timeout := attribute_p^.data_transfer_timeout;
          = nac$eoi_message =
            IF attribute_p^.eoi_message.size <= 31 {nac$maximum_eoi_size} THEN
              IF connection^.eoi_message = NIL THEN
                REPEAT
                  ALLOCATE connection^.eoi_message IN nav$network_paged_heap^;
                  IF connection^.eoi_message = NIL THEN
                    syp$cycle;
                  IFEND;
                UNTIL connection^.eoi_message <> NIL;
              IFEND;
              connection^.eoi_message^ := attribute_p^.eoi_message;
            ELSE
              osp$set_status_abnormal (nac$status_id, nae$invalid_eoi_message_size, '31'
                    {nac$maximum_eoi_size} , status);
            IFEND;
          = nac$eoi_message_enabled =
            connection^.eoi_message_enabled := attribute_p^.eoi_message_enabled;
          = nac$eoi_peer_termination =
            connection^.eoi_peer_termination := attribute_p^.eoi_peer_termination;
          = nac$null_attribute =
          = nac$receive_wait_swapout =
            connection^.receive_wait_swapout := attribute_p^.receive_wait_swapout;
          = nac$termination_data =
            IF ((attribute_p^.termination_data <> NIL) AND (#SIZE (attribute_p^.termination_data^) <=
                  nac$maximum_termination_data)) OR (attribute_p^.termination_data = NIL) THEN
              nap$move_user_data_to_data_area (attribute_p^.termination_data, connection^.termination_data);
            ELSE
              STRINGREP (error_string, length, 'the maximum allowed termination_data length of ',
                    nac$maximum_termination_data, ' for NAC$TERMINATION_DATA');
              osp$set_status_abnormal (nac$status_id, nae$max_data_length_exceeded, error_string, status);
            IFEND;
          ELSE
            osp$set_status_abnormal (nac$status_id, nae$unknown_attribute, ' on CHANGE ATTRIBUTES ', status);
          CASEND;
        FOREND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;

  PROCEND nap$change_attributes;
?? TITLE := '  [INLINE] ACTIVATE_SENDER_TASK', EJECT ??

  PROCEDURE [INLINE] activate_sender_task
    (    cl_connection: ^nlt$cl_connection;
         task: ost$global_task_id);

    VAR
      cl_connection_id: ^nlt$cl_connection_id,
      signal: pmt$signal,
      status: ost$status;

    signal.identifier := nac$se_send_data_signal;
    cl_connection_id := #LOC (signal.contents);
    cl_connection_id^ := cl_connection^.identifier;
    pmp$send_signal (task, signal, status);
    IF NOT status.normal THEN
      nlp$cl_deactivate_sender (cl_connection);
    IFEND;
  PROCEND activate_sender_task;
?? TITLE := '  [INLINE] ACTIVATE_RECEIVER_TASK', EJECT ??

  PROCEDURE [INLINE] activate_receiver_task
    (    cl_connection: ^nlt$cl_connection;
         task: ost$global_task_id);

    VAR
      cl_connection_id: ^nlt$cl_connection_id,
      signal: pmt$signal,
      status: ost$status;

    signal.identifier := nac$se_deliver_data_signal;
    cl_connection_id := #LOC (signal.contents);
    cl_connection_id^ := cl_connection^.identifier;
    pmp$send_signal (task, signal, status);
  PROCEND activate_receiver_task;
?? TITLE := '[INLINE] send_disconnect_signal', EJECT ??

  PROCEDURE [INLINE] send_disconnect_signal
    (    cl_connection: ^nlt$cl_connection;
         task: ost$global_task_id);

    VAR
      cl_connection_id: ^nlt$cl_connection_id,
      signal: pmt$signal,
      status: ost$status;

    signal.identifier := nac$se_disconnect_signal;
    cl_connection_id := #LOC (signal.contents);
    cl_connection_id^ := cl_connection^.identifier;
    pmp$send_signal (task, signal, status);
  PROCEND send_disconnect_signal;
?? TITLE := '  PROCESS_CONNECTION_EVENT' ??
?? NEWTITLE := '    CONTINUE_SEND_DATA' ??
?? NEWTITLE := '      TERMINATE_SEND -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL] nap$se_process_connection_event
    (    cl_connection: ^nlt$cl_connection;
         event: nlt$sl_event;
     VAR inventory_report: nlt$sl_inventory_report);


    PROCEDURE continue_send_data
      (    connection: ^nat$connection_descriptor;
           cl_connection: ^nlt$cl_connection);

      VAR
        condition_cause: nat$se_condition_cause;

      PROCEDURE terminate_send
        (    condition: pmt$condition;
             ignore_condition_descriptor: ^pmt$condition_information;
             sa: ^ost$stack_frame_save_area;
         VAR condition_status: ost$status);

        VAR
          status: ost$status;

        nap$condition_handler_trace (condition, sa);
        CASE condition.selector OF
        = pmc$system_conditions, mmc$segment_access_condition =
          IF condition_cause = nac$application_data THEN
            nlp$cl_deactivate_sender (cl_connection);
            IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                  (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
              FREE connection^.sender_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            IFEND;
            osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
            condition_cause := nac$activity_status;
            #SPOIL (condition_cause);
            osp$establish_condition_handler (^terminate_send, FALSE);
            complete_activity (send, connection^.send_file_identifier, ^status);
            EXIT continue_send_data; {----->
          ELSEIF condition_cause = nac$activity_status THEN
            IF (cl_connection^.message_sender.active) AND (cl_connection^.message_sender.task =
                  processing_task) THEN
              nlp$cl_deactivate_sender (cl_connection);
              IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.sender_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              terminate_io (sender, connection^.send_file_identifier);
            IFEND;
            osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          ELSE
            osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          IFEND;

        = pmc$user_defined_condition =
          IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
            pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          IFEND;
          condition_status.normal := TRUE;

        ELSE
          condition_status.normal := TRUE;
        CASEND;

      PROCEND terminate_send;
?? OLDTITLE, EJECT ??

      VAR
        capacity: nat$data_length;

      ; {continue normal processing
      nlp$osi_get_outbound_capacity (cl_connection, capacity);
      IF (capacity > 0) THEN
        condition_cause := nac$application_data;
        #SPOIL (condition_cause);
        osp$establish_condition_handler (^terminate_send, FALSE);
        IF connection^.send_put_partial_termination THEN
          nlp$sl_data_request (cl_connection, FALSE {qualified_data} , TRUE {END_OF_MESSAGE} , nav$null_data,
                ignore_status);
          connection^.send_put_partial_termination := FALSE;
        IFEND;
        send_data (cl_connection, connection);
        IF NOT cl_connection^.message_sender.active THEN
          condition_cause := nac$activity_status;
          #SPOIL (condition_cause);
          complete_activity (send, connection^.send_file_identifier, NIL);
        IFEND;

        condition_cause := nac$request_not_cause;
        #SPOIL (condition_cause);

      IFEND;
    PROCEND continue_send_data;
?? TITLE := '    CONTINUE_RECEIVE_DATA' ??
?? NEWTITLE := '      TERMINATE_CONTINUE_RECEIVE_DATA -- CONDITION HANDLER', EJECT ??

    PROCEDURE continue_receive_data
      (    connection: ^nat$connection_descriptor;
           cl_connection: ^nlt$cl_connection);

      VAR
        condition_cause: nat$se_condition_cause;


      PROCEDURE terminate_continue_receive_data
        (    condition: pmt$condition;
             ignore_condition_descriptor: ^pmt$condition_information;
             sa: ^ost$stack_frame_save_area;
         VAR condition_status: ost$status);

        VAR
          status: ost$status;

        nap$condition_handler_trace (condition, sa);
        CASE condition.selector OF
        = pmc$system_conditions, mmc$segment_access_condition =
          IF (condition_cause = nac$application_data) OR (condition_cause = nac$application_event) THEN
            nlp$cl_deactivate_receiver (cl_connection);
            connection^.wait_state := nac$inactive_wait;
            IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                  (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
              FREE connection^.receiver_request.application_buffer.allocated_description IN
                    nav$network_paged_heap^;
            IFEND;
            osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
            condition_cause := nac$activity_status;
            #SPOIL (condition_cause);
            osp$establish_condition_handler (^terminate_continue_receive_data, FALSE);
            complete_activity (receive, connection^.receive_file_identifier, ^status);
            EXIT continue_receive_data; {----->
          ELSEIF condition_cause = nac$activity_status THEN
            IF (connection^.wait_state = nac$waiting_to_receive_data) AND
                  (cl_connection^.message_receiver.task = processing_task) THEN
              nlp$cl_deactivate_receiver (cl_connection);
              connection^.wait_state := nac$inactive_wait;
              IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                    (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
                FREE connection^.receiver_request.application_buffer.allocated_description IN
                      nav$network_paged_heap^;
              IFEND;
              terminate_io (receiver, connection^.receive_file_identifier);
            IFEND;
            nlp$ta_report_undelivered_data (cl_connection, connection^.total_message_buffers_queued);
            osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          ELSE
            osp$set_status_from_condition (nac$status_id, condition, sa, condition_status, status);
          IFEND;

        = pmc$user_defined_condition =
          IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
            pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          IFEND;
          condition_status.normal := TRUE;

        ELSE
          condition_status.normal := TRUE;
        CASEND;
      PROCEND terminate_continue_receive_data;
?? OLDTITLE, EJECT ??

      VAR
        delivery_complete: boolean;

      ; {continue normal processing
      osp$establish_condition_handler (^terminate_continue_receive_data, FALSE);
      condition_cause := nac$application_data;
      #SPOIL (condition_cause);
      deliver_connection_events (connection, cl_connection, delivery_complete, condition_cause,
            ignore_status);
      IF delivery_complete THEN
        nlp$cl_deactivate_receiver (cl_connection);
        connection^.wait_state := nac$inactive_wait;
        IF (connection^.data_queue.count > 0) OR (connection^.supervisory_event_queue.beginning <> NIL) THEN
          nlp$select_timer (nac$inactive_receiver_timeout, 0, connection^.event_timer);
        ELSE
          nlp$cancel_timer (connection^.event_timer);
        IFEND;
        condition_cause := nac$activity_status;
        #SPOIL (condition_cause);
        complete_activity (receive, connection^.receive_file_identifier, NIL);
      IFEND;
    PROCEND continue_receive_data;
?? OLDTITLE, EJECT ??

    VAR
      accounting_info: ^array [1 .. * ] of cell,
      active_file: boolean,
      connection: ^nat$connection_descriptor,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      data_length: integer,
      event_element: ^nat$se_supervisory_element,
      ignore: integer,
      ignore_status: ost$status,
      layer_active: boolean,
      message_id: nlt$bm_message_id,
      processing_task: ost$global_task_id,
      se_event: nat$se_peer_operation;

    nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
    CASE event.kind OF
?? NEWTITLE := ' DATA_INDICATION', EJECT ??

    = nlc$sl_data_event =
      IF connection^.receive_synchronize_count > 0 THEN
        message_id := event.data.message_id;
        nlp$bm_release_message (message_id);
        inventory_report.changed := FALSE;
      ELSEIF connection^.discard_to_end_of_message THEN
        message_id := event.data.message_id;
        nlp$bm_release_message (message_id);
        IF event.data.end_of_message THEN
          dequeue_data_event (connection^);
          connection^.discard_to_end_of_message := FALSE;
        IFEND;
        inventory_report.changed := FALSE;
      ELSE
        IF (connection^.wait_state <> nac$waiting_to_receive_data) AND (connection^.data_queue.count = 0) AND
              (connection^.supervisory_event_queue.beginning = NIL) THEN
          nlp$select_timer (nac$inactive_receiver_timeout, 0, connection^.event_timer);
        IFEND;
        queue_data_event (event, connection^);
        IF (connection^.wait_state = nac$waiting_for_data_available) AND
              ((connection^.data_queue.beginning^.event_element [connection^.data_queue.beginning^.first].
              event.end_of_message) OR (connection^.total_data_queued >=
              4096 {nac$min_await_data_available} ) OR (connection^.total_message_buffers_queued >= 4)) THEN
          pmp$get_executing_task_gtid (processing_task);
          IF cl_connection^.message_receiver.task <> processing_task THEN
            pmp$ready_task (cl_connection^.message_receiver.task, ignore_status);
          IFEND;
          nlp$cl_deactivate_receiver (cl_connection);
          connection^.wait_state := nac$inactive_wait;
        ELSEIF connection^.wait_state = nac$waiting_to_receive_data THEN
          pmp$get_executing_task_gtid (processing_task);
          IF cl_connection^.message_receiver.task = processing_task THEN
            continue_receive_data (connection, cl_connection);
          ELSE
            activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
          IFEND;
        IFEND;
        inventory_report.changed := TRUE;
        inventory_report.accumulated_message_buffers := connection^.total_message_buffers_queued;
      IFEND;
    = nlc$sl_clear_to_send_event =
      IF cl_connection^.message_sender.active THEN
        pmp$get_executing_task_gtid (processing_task);
        IF cl_connection^.message_sender.task = processing_task THEN
          continue_send_data (connection, cl_connection);
        ELSE
          activate_sender_task (cl_connection, cl_connection^.message_sender.task);
        IFEND;
      IFEND;
      inventory_report.changed := FALSE;
    = nlc$sl_interrupt_event =
      IF connection^.nominal_connection THEN
        se_event.kind := nac$se_interrupt;
        data_fragments [1].address := ^se_event.interrupt_data;
        data_fragments [1].length := #SIZE (se_event.interrupt_data);
        message_id := event.interrupt.message_id;
        nlp$bm_flush_message (data_fragments, message_id, data_length, ignore_status);
        se_event.interrupt_data_length := data_length;

{send_timesharing signal

        send_timesharing_signal (jmc$timesharing_interrupt, connection^.nominal_connection_task_id,
              ^se_event);
      ELSE
        IF (connection^.wait_state <> nac$waiting_to_receive_data) AND (connection^.data_queue.count = 0) AND
              (connection^.supervisory_event_queue.beginning = NIL) THEN
          nlp$select_timer (nac$inactive_receiver_timeout, 0, connection^.event_timer);
        IFEND;
        REPEAT
          ALLOCATE event_element IN nav$network_paged_heap^;
          IF event_element = NIL THEN
            syp$cycle;
          IFEND;
        UNTIL event_element <> NIL;
        event_element^.next_element := NIL;
        IF connection^.supervisory_event_queue.beginning = NIL THEN
          connection^.supervisory_event_queue.beginning := event_element;
        ELSE
          connection^.supervisory_event_queue.ending^.next_element := event_element;
        IFEND;
        connection^.supervisory_event_queue.ending := event_element;
        event_element^.event.kind := nac$se_interrupt;
        data_fragments [1].address := ^event_element^.event.interrupt_data;
        data_fragments [1].length := #SIZE (event_element^.event.interrupt_data);
        message_id := event.interrupt.message_id;
        nlp$bm_flush_message (data_fragments, message_id, data_length, ignore_status);
        event_element^.event.interrupt_data_length := data_length;
        IF connection^.wait_state = nac$waiting_for_data_available THEN
          pmp$ready_task (cl_connection^.message_receiver.task, ignore_status);
          nlp$cl_deactivate_receiver (cl_connection);
          connection^.wait_state := nac$inactive_wait;
        ELSEIF connection^.wait_state = nac$waiting_to_receive_data THEN
          activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
        IFEND;
      IFEND;
      inventory_report.changed := FALSE;

{! statistics begin
      osp$increment_locked_variable (nav$global_statistics.session.interrupt_requests_received, 0, ignore);
{! statistics end

    = nlc$sl_synch_event =
      IF (connection^.nominal_connection) AND (NOT connection^.break_condition_active) AND
            (event.synch.discard_option = nlc$sl_discard_send_receive) THEN
        ; {setup event
        connection^.break_condition_active := TRUE;
        connection^.event.kind := nac$se_synchronize;
        connection^.event.direction := nac$se_synchronize_all_data;
        data_fragments [1].address := ^connection^.event.synchronize_data;
        data_fragments [1].length := #SIZE (connection^.event.synchronize_data);
        message_id := event.synch.message_id;
        nlp$bm_flush_message (data_fragments, message_id, data_length, ignore_status);
        connection^.event.synchronize_data_length := data_length;

{send_timesharing signal

        IF (connection^.wait_state <> nac$waiting_to_receive_data) AND
              (NOT cl_connection^.message_sender.active) THEN
          send_timesharing_signal (jmc$timesharing_synchronize, connection^.nominal_connection_task_id,
                ^connection^.event);
        IFEND;
      ELSE
        IF (connection^.wait_state <> nac$waiting_to_receive_data) AND (connection^.data_queue.count = 0) AND
              (connection^.supervisory_event_queue.beginning = NIL) THEN
          nlp$select_timer (nac$inactive_receiver_timeout, 0, connection^.event_timer);
        IFEND;

{queue_event

        REPEAT
          ALLOCATE event_element IN nav$network_paged_heap^;
          IF event_element = NIL THEN
            syp$cycle;
          IFEND;
        UNTIL event_element <> NIL;
        event_element^.next_element := NIL;
        IF connection^.supervisory_event_queue.beginning = NIL THEN
          connection^.supervisory_event_queue.beginning := event_element;
        ELSE
          connection^.supervisory_event_queue.ending^.next_element := event_element;
        IFEND;
        connection^.supervisory_event_queue.ending := event_element;
        event_element^.event.kind := nac$se_synchronize;
        IF event.synch.discard_option = nlc$sl_discard_send_receive THEN
          event_element^.event.direction := nac$se_synchronize_all_data;
        ELSEIF event.synch.discard_option = nlc$sl_discard_send THEN
          event_element^.event.direction := nac$se_synchronize_receive_data;
        ELSEIF event.synch.discard_option = nlc$sl_discard_receive THEN
          event_element^.event.direction := nac$se_synchronize_send_data;
        IFEND;
        data_fragments [1].address := ^event_element^.event.synchronize_data;
        data_fragments [1].length := #SIZE (event_element^.event.synchronize_data);
        message_id := event.synch.message_id;
        nlp$bm_flush_message (data_fragments, message_id, data_length, ignore_status);
        event_element^.event.synchronize_data_length := data_length;
        IF connection^.wait_state = nac$waiting_for_data_available THEN
          pmp$ready_task (cl_connection^.message_receiver.task, ignore_status);
          nlp$cl_deactivate_receiver (cl_connection);
          connection^.wait_state := nac$inactive_wait;
        IFEND;
      IFEND;
      IF (event.synch.discard_option = nlc$sl_discard_send_receive) OR
            (event.synch.discard_option = nlc$sl_discard_receive) THEN
        inventory_report.changed := FALSE;
        {OK} connection^.send_synchronize_count := connection^.send_synchronize_count + 1;
        connection^.intermediate_put_partial := FALSE;
        connection^.send_put_partial_termination := FALSE;
        IF cl_connection^.message_sender.active THEN
          nlp$cancel_timer (connection^.send_timer);
          IF (connection^.nominal_connection) AND (NOT connection^.break_connection_send) THEN
            connection^.break_connection_send := TRUE;
          ELSEIF (NOT connection^.nominal_connection) AND (NOT connection^.synchronize_send) THEN
            connection^.synchronize_send := TRUE;
          IFEND;
          activate_sender_task (cl_connection, cl_connection^.message_sender.task);
        IFEND;
      IFEND;
      IF (event.synch.discard_option = nlc$sl_discard_send_receive) OR
            (event.synch.discard_option = nlc$sl_discard_send) THEN
        release_data_queue (connection^);
        inventory_report.changed := TRUE;
        inventory_report.accumulated_message_buffers := connection^.total_message_buffers_queued;
        IF connection^.wait_state = nac$waiting_to_receive_data THEN
          IF (connection^.nominal_connection) AND (NOT connection^.break_connection_receive) THEN
            connection^.break_connection_receive := TRUE;
          ELSEIF (NOT connection^.nominal_connection) AND (NOT connection^.synchronize_receive) THEN
            connection^.synchronize_receive := TRUE;
          IFEND;
          activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
        IFEND;
      IFEND;
      ; {
      ; {Possibly update or terminate timers
      ; {

{! statistics begin
      osp$increment_locked_variable (nav$global_statistics.session.synchronize_requests_received, 0, ignore);
{! statistics end

    = nlc$sl_synch_confirm_event =
      IF connection^.receive_synchronize_count > 0 THEN
        IF (connection^.wait_state <> nac$waiting_to_receive_data) AND (connection^.data_queue.count = 0) AND
              (connection^.supervisory_event_queue.beginning = NIL) THEN
          nlp$select_timer (nac$inactive_receiver_timeout, 0, connection^.event_timer);
        IFEND;
        REPEAT
          ALLOCATE event_element IN nav$network_paged_heap^;
          IF event_element = NIL THEN
            syp$cycle;
          IFEND;
        UNTIL event_element <> NIL;
        event_element^.next_element := NIL;
        IF connection^.supervisory_event_queue.beginning = NIL THEN
          connection^.supervisory_event_queue.beginning := event_element;
        ELSE
          connection^.supervisory_event_queue.ending^.next_element := event_element;
        IFEND;
        connection^.supervisory_event_queue.ending := event_element;
        event_element^.event.kind := nac$se_synchronize_confirm;
        {OK} connection^.receive_synchronize_count := connection^.receive_synchronize_count - 1;

        IF connection^.wait_state = nac$waiting_to_receive_data THEN
          activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
        IFEND;
      ELSE { IF connection^.receive_synchronize_count = 0 THEN
        nap$namve_system_error (TRUE, 'Receive synchronize count = 0.', NIL);
      IFEND;
      IF connection^.wait_state = nac$waiting_for_data_available THEN
        pmp$ready_task (cl_connection^.message_receiver.task, ignore_status);
        nlp$cl_deactivate_receiver (cl_connection);
        connection^.wait_state := nac$inactive_wait;
      IFEND;
      inventory_report.changed := FALSE;
    = nlc$sl_clear_event =
      connection^.connection_state := nac$terminated;
      IF event.clear.reason = nlc$sl_user_clear THEN
        connection^.termination_reason := nac$peer_request;
        inventory_report.changed := FALSE;
      ELSE
        connection^.termination_reason := nac$connection_failed;
        release_data_queue (connection^);
        inventory_report.changed := TRUE;
        inventory_report.accumulated_message_buffers := 0;
        WHILE connection^.supervisory_event_queue.beginning <> NIL DO
          event_element := connection^.supervisory_event_queue.beginning;
          connection^.supervisory_event_queue.beginning := event_element^.next_element;
          FREE event_element IN nav$network_paged_heap^;
        WHILEND;
      IFEND;
      nlp$bm_get_message_length (event.clear.message_id, data_length);
      IF data_length > 0 THEN
        message_id := event.clear.message_id;
        REPEAT
          ALLOCATE connection^.peer_termination_data: [[REP data_length OF cell]] IN nav$network_paged_heap^;
          IF connection^.peer_termination_data = NIL THEN
            syp$cycle;
          IFEND;
        UNTIL connection^.peer_termination_data <> NIL;
        data_fragments [1].address := connection^.peer_termination_data;
        data_fragments [1].length := data_length;
        nlp$bm_flush_message (data_fragments, message_id, data_length, ignore_status);
      IFEND;
      IF connection^.await_server_response THEN
        pmp$ready_task (connection^.await_server_response_task_id, ignore_status);
        connection^.await_server_response := FALSE;
      IFEND;
      IF connection^.wait_state = nac$waiting_for_data_available THEN
        pmp$ready_task (cl_connection^.message_receiver.task, ignore_status);
        nlp$cl_deactivate_receiver (cl_connection);
        connection^.wait_state := nac$inactive_wait;
      IFEND;
      IF (connection^.nominal_connection) AND (NOT connection^.timesharing_disconnect_sent) AND
            (connection^.wait_state <> nac$waiting_to_receive_data) AND
            (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
        ; {send time_sharing_signal
        connection^.timesharing_disconnect_sent := TRUE;
        send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id, NIL);
      ELSE
        IF connection^.wait_state = nac$waiting_to_receive_data THEN
          activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
        IFEND;
        IF cl_connection^.message_sender.active THEN
          activate_sender_task (cl_connection, cl_connection^.message_sender.task);
        IFEND;
      IFEND;
      send_disconnect_signal (cl_connection, connection^.job_monitor_task_id);
    = nlc$sl_confirm_event =
      IF connection^.connection_state = nac$connection_request_sent THEN
        connection^.connection_state := nac$established;
        nlp$bm_get_message_length (event.confirm.message_id, data_length);
        IF data_length > 0 THEN
          message_id := event.confirm.message_id;
          REPEAT
            ALLOCATE connection^.peer_connect_data: [[REP data_length OF cell]] IN nav$network_paged_heap^;

            IF connection^.peer_connect_data = NIL THEN
              syp$cycle;
            IFEND;
          UNTIL connection^.peer_connect_data <> NIL;
          data_fragments [1].address := connection^.peer_connect_data;
          data_fragments [1].length := data_length;
          nlp$bm_flush_message (data_fragments, message_id, data_length, ignore_status);
        IFEND;
        IF event.confirm.accounting_length > 0 THEN
          REPEAT
            ALLOCATE connection^.peer_accounting_information:
                  [[REP event.confirm.accounting_length OF cell]] IN nav$network_paged_heap^;
            IF connection^.peer_accounting_information = NIL THEN
              syp$cycle;
            IFEND;
          UNTIL connection^.peer_accounting_information <> NIL;
          RESET connection^.peer_accounting_information;
          NEXT accounting_info: [1 .. event.confirm.accounting_length] IN
                connection^.peer_accounting_information;
          accounting_info^ := event.confirm.accounting_info^;
        IFEND;
        IF connection^.await_server_response THEN
          pmp$ready_task (connection^.await_server_response_task_id, ignore_status);
          connection^.await_server_response := FALSE;
        IFEND;
      IFEND;
      inventory_report.changed := FALSE;
    ELSE
      nap$namve_system_error (TRUE, 'Invalid internal session event received.', NIL);
    CASEND;
  PROCEND nap$se_process_connection_event;
?? OLDTITLE ??
?? TITLE := '  PROCESS_SAP_EVENT', EJECT ??

  PROCEDURE [XDCL] nap$se_process_sap_event
    (    cl_connection: ^nlt$cl_connection;
         event: nlt$sl_event;
     VAR inventory_report: nlt$sl_inventory_report);

    CONST
      us# = $CHAR (1f(16)); { unit separator character }

    VAR
      accounting_info: ^array [1 .. * ] of cell,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      data_length: integer,
      layer_active: boolean,
      connection: ^nat$connection_descriptor,
      data: array [1 .. 2] of nat$data_fragment,
      i: ost$status_message_line_count,
      in_message: ^ost$status_message,
      line: ^ost$status_message_line,
      line_count: ^ost$status_message_line_count,
      line_length: ^ost$status_message_line_size,
      message: ^ost$status_message,
      message_id: nlt$bm_message_id,
      message_size: integer,
      out_line: ^ost$status_message_line,
      out_message: ^ost$status_message,
      sap_identifier: nat$sap_identifier,
      status_message: ^ost$status_message,
      status: ost$status,
      vtp_output_data: nat$vtp_output_data;

    nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
    connection^ := nav$se_initialized_connection;
    nlp$cancel_timer (connection^.send_timer);
    connection^.receive_timer := connection^.send_timer;
    connection^.event_timer := connection^.send_timer;
    connection^.connection_state := nac$connection_request_received;
    ; {Setup local_address
    connection^.peer_address := event.call.source;
    connection^.local_address := event.call.sap;
    connection^.client := FALSE;
    REPEAT
      ALLOCATE connection^.data_queue.beginning IN nav$network_paged_heap^;
      IF connection^.data_queue.beginning = NIL THEN
        syp$cycle;
      IFEND;
    UNTIL connection^.data_queue.beginning <> NIL;
    connection^.data_queue.ending := connection^.data_queue.beginning;
    connection^.data_queue.beginning^.next_element := NIL;
    ; { Setup connection_attributes from event
    nlp$bm_get_message_length (event.call.message_id, data_length);
    IF data_length > 0 THEN
      message_id := event.call.message_id;
      REPEAT
        ALLOCATE connection^.peer_connect_data: [[REP data_length OF cell]] IN nav$network_paged_heap^;

        IF connection^.peer_connect_data = NIL THEN
          syp$cycle;
        IFEND;
      UNTIL connection^.peer_connect_data <> NIL;
      data_fragments [1].address := connection^.peer_connect_data;
      data_fragments [1].length := data_length;
      nlp$bm_flush_message (data_fragments, message_id, data_length, {ignore} status);
    IFEND;
    IF event.call.accounting_length > 0 THEN
      REPEAT
        ALLOCATE connection^.peer_accounting_information: [[REP event.call.accounting_length OF cell]] IN
              nav$network_paged_heap^;
        IF connection^.peer_accounting_information = NIL THEN
          syp$cycle;
        IFEND;
      UNTIL connection^.peer_accounting_information <> NIL;
      RESET connection^.peer_accounting_information;
      NEXT accounting_info: [1 .. event.call.accounting_length] IN connection^.peer_accounting_information;
      accounting_info^ := event.call.accounting_info^;
    IFEND;
    nlp$cl_activate_layer (cl_connection^.application_layer, cl_connection);
    sap_identifier := event.call.sap;
    nap$process_connect_indication (sap_identifier, cl_connection^.identifier, cl_connection,
          event.call.source, connection^.application_name, connection^.protocol, status);
    IF status.normal THEN
      connection^.client := FALSE;
    ELSE
      PUSH status_message;
      osp$format_message (status, osc$brief_message_level, osc$max_status_message_line, status_message^,
            {ignore} status);
      PUSH message;
      in_message := status_message;
      out_message := message;
      RESET in_message;
      RESET out_message;
      NEXT line_count IN in_message;
      message_size := 0;
      FOR i := 1 TO line_count^ DO
        NEXT line_length IN in_message;
        NEXT line: [line_length^] IN in_message;
        NEXT out_line: [line_length^] IN out_message;
        out_line^ := line^;
        message_size := message_size + line_length^;
        NEXT out_line: [1] IN out_message;
        out_line^ (1) := us#; { Lines must be separated with unit separator characters }
        message_size := message_size + 1;
      FOREND;

{ The Tip needs the vtp_output_data at the beginning of the message.  Without the
{ vtp_output_data the first three characters would be truncated.

      IF connection^.protocol = nac$cdna_virtual_terminal THEN
        data [1].length := #SIZE (vtp_output_data);
        data [1].address := ^vtp_output_data;
        vtp_output_data.message_type := 0;
        vtp_output_data.formatting_mode := 1; { virtual line mode encoding
        vtp_output_data.suppress_echoplex := FALSE; { secured input suppressed echoplex bit
        vtp_output_data.suppress_end_of_line_partition := FALSE; {secured input suppressed end of line
        vtp_output_data.partial_output := FALSE;
        NEXT out_line: [1] IN out_message;
        out_line^ (1) := ' '; { Terminate with blank line for carriage control}
        message_size := message_size + 1;
      ELSE
        data [1].length := 0;
        data [1].address := NIL;
      IFEND;
      IF message_size <= nlc$sl_max_clear_message - data [1].length THEN
        data [2].length := message_size;
      ELSE
        data [2].length := nlc$sl_max_clear_message - data [1].length;
      IFEND;
      data [2].address := out_message;
      nlp$sl_clear_request (cl_connection, data, status);
      IF NOT status.normal THEN
        nap$namve_system_error (TRUE, 'NLP$SL_CLEAR_REQUEST failed.', ^status);
      IFEND;
      connection^.connection_state := nac$terminated;
      connection^.termination_reason := nac$local_clear;
      terminate_connection (connection, cl_connection);
      nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
    IFEND;
  PROCEND nap$se_process_sap_event;
?? TITLE := '  DEQUEUE_DATA_EVENT', EJECT ??

  PROCEDURE [INLINE] dequeue_data_event
    (VAR connection: nat$connection_descriptor);

    VAR
      event_element_p: ^nat$se_event_element,
      event_element_q_p: ^nat$se_event_element_queue,
      only_element: boolean;

    IF (connection.data_queue.count > 0) THEN
      event_element_p := ^connection.data_queue.beginning^.
            event_element [connection.data_queue.beginning^.first];
      only_element := connection.data_queue.beginning^.first = connection.data_queue.beginning^.last;
      IF event_element_p^.queued_data_length > 0 THEN
        nlp$bm_release_message (event_element_p^.message_id);
        connection.total_data_queued := connection.total_data_queued - event_element_p^.queued_data_length;
        connection.total_message_buffers_queued := connection.total_message_buffers_queued -
              event_element_p^.queued_message_buffers;
      IFEND;

      IF only_element THEN
        IF connection.data_queue.beginning^.next_element <> NIL THEN
          event_element_q_p := connection.data_queue.beginning;
          connection.data_queue.beginning := event_element_q_p^.next_element;
          FREE event_element_q_p IN nav$network_paged_heap^;
          connection.data_queue.count := connection.data_queue.count - nac$se_max_element_count;
        ELSE
          connection.data_queue.count := connection.data_queue.count - 1;
        IFEND;
      ELSE
        connection.data_queue.beginning^.first := (connection.data_queue.beginning^.first + 1) MOD
              nac$se_max_element_count;
        IF connection.data_queue.beginning^.next_element = NIL THEN
          connection.data_queue.count := connection.data_queue.count - 1;
        IFEND;
      IFEND;
    ELSE
    IFEND;

  PROCEND dequeue_data_event;
?? TITLE := '  [INLINE] QUEUE_DATA_EVENT', EJECT ??

  PROCEDURE [INLINE] queue_data_event
    (    event: nlt$sl_event;
     VAR connection: nat$connection_descriptor);

    VAR
      data_length: integer,
      event_element_p: ^nat$se_event_element,
      event_element_q_p: ^nat$se_event_element_queue,
      index: integer,
      message_array: array [1 .. 2] of nlt$bm_message_id,
      number_of_buffers: integer;

    nlp$bm_get_message_resources (event.data.message_id, data_length, number_of_buffers);
    IF (connection.data_queue.count > 0) AND (NOT connection.data_queue.ending^.
          event_element [connection.data_queue.ending^.last].event.end_of_message) THEN
      ; {concatenate_message

      event_element_p := ^connection.data_queue.ending^.event_element [connection.data_queue.ending^.last];
      IF data_length > 0 THEN
        IF event_element_p^.queued_data_length > 0 THEN
          event_element_p^.queued_data_length := event_element_p^.queued_data_length + data_length;
          event_element_p^.queued_message_buffers := event_element_p^.queued_message_buffers +
                number_of_buffers;
          connection.total_data_queued := connection.total_data_queued + data_length;
          connection.total_message_buffers_queued := connection.total_message_buffers_queued +
                number_of_buffers;
          message_array [1] := event_element_p^.message_id;
          message_array [2] := event.data.message_id;
          nlp$bm_concatenate_messages (message_array, event_element_p^.message_id);
        ELSE
          event_element_p^.queued_data_length := data_length;
          event_element_p^.queued_message_buffers := number_of_buffers;
          connection.total_data_queued := connection.total_data_queued + data_length;
          connection.total_message_buffers_queued := connection.total_message_buffers_queued +
                number_of_buffers;
          event_element_p^.message_id := event.data.message_id;
        IFEND;
      IFEND;

      event_element_p^.event.end_of_message := event.data.end_of_message;
    ELSE
      IF connection.data_queue.count = 0 THEN
        connection.data_queue.beginning^.first := 0;
        connection.data_queue.beginning^.last := 0;
        index := 0;
      ELSEIF connection.data_queue.count < nac$se_max_element_count THEN
        connection.data_queue.beginning^.last := (connection.data_queue.beginning^.last + 1) MOD
              nac$se_max_element_count;
        index := connection.data_queue.beginning^.last;
      ELSEIF (connection.data_queue.count MOD nac$se_max_element_count = 0) AND
            (connection.data_queue.count > 0) THEN
        REPEAT
          ALLOCATE event_element_q_p IN nav$network_paged_heap^;
          IF event_element_q_p = NIL THEN
            syp$cycle;
          IFEND;
        UNTIL event_element_q_p <> NIL;
        event_element_q_p^.next_element := NIL;
        connection.data_queue.ending^.next_element := event_element_q_p;
        connection.data_queue.ending := event_element_q_p;
        event_element_q_p^.first := 0;
        event_element_q_p^.last := 0;
        index := 0;
      ELSE
        connection.data_queue.ending^.last := connection.data_queue.ending^.last + 1;
        index := connection.data_queue.ending^.last;
      IFEND;
      ; {setup event

      event_element_p := ^connection.data_queue.ending^.event_element [index];
      event_element_p^.event.kind := nac$se_send_data;
      event_element_p^.event.end_of_message := event.data.end_of_message;
      event_element_p^.event.qualified_data := event.data.qualified_data;
      event_element_p^.message_id := event.data.message_id;
      event_element_p^.start_of_data_sequence := TRUE;
      connection.discard_to_end_of_message := FALSE;
      event_element_p^.queued_data_length := data_length;
      connection.data_queue.ending^.event_element [connection.data_queue.ending^.last].
            queued_message_buffers := number_of_buffers;
      connection.total_data_queued := connection.total_data_queued + data_length;
      connection.total_message_buffers_queued := connection.total_message_buffers_queued + number_of_buffers;
      event_element_p^.total_bytes_moved := 0;
      connection.data_queue.count := connection.data_queue.count + 1;
    IFEND;

  PROCEND queue_data_event;
?? TITLE := '  RELEASE_DATA_QUEUE', EJECT ??

  PROCEDURE release_data_queue
    (VAR connection: nat$connection_descriptor);

    VAR
      event_element_q_p: ^nat$se_event_element_queue,
      i: integer;

    WHILE connection.data_queue.count > 0 DO
      IF connection.data_queue.beginning^.first <= connection.data_queue.beginning^.last THEN
        FOR i := connection.data_queue.beginning^.first TO connection.data_queue.beginning^.last DO
          IF connection.data_queue.beginning^.event_element [i].queued_data_length > 0 THEN
            nlp$bm_release_message (connection.data_queue.beginning^.event_element [i].message_id);
          IFEND;
        FOREND;
      ELSE
        FOR i := connection.data_queue.beginning^.first TO (nac$se_max_element_count - 1) DO
          IF connection.data_queue.beginning^.event_element [i].queued_data_length > 0 THEN
            nlp$bm_release_message (connection.data_queue.beginning^.event_element [i].message_id);
          IFEND;
        FOREND;
        FOR i := 0 TO connection.data_queue.beginning^.last DO
          IF connection.data_queue.beginning^.event_element [i].queued_data_length > 0 THEN
            nlp$bm_release_message (connection.data_queue.beginning^.event_element [i].message_id);
          IFEND;
        FOREND;
      IFEND;
      IF connection.data_queue.beginning <> connection.data_queue.ending THEN
        event_element_q_p := connection.data_queue.beginning;
        connection.data_queue.beginning := event_element_q_p^.next_element;
        FREE event_element_q_p IN nav$network_paged_heap^;
      ELSE
        connection.data_queue.count := 0;
      IFEND;
    WHILEND;
    connection.total_data_queued := 0;
    connection.total_message_buffers_queued := 0;

  PROCEND release_data_queue;
?? TITLE := ' F$EOI_MESSAGE', EJECT ??

  FUNCTION [INLINE, UNSAFE] f$eoi_message
    (    eoi: ^nat$eoi_message;
         message_id: nlt$bm_message_id): boolean;

    VAR
      data_length: integer,
      ignore_status: ost$status,
      scratch_eoi_message: nat$eoi_message;

    nlp$bm_get_message_length (message_id, data_length);
    IF eoi <> NIL THEN
      IF data_length = eoi^.size THEN
        nlp$bm_get_message_prefix (^scratch_eoi_message.value, data_length, message_id, ignore_status);
        f$eoi_message := eoi^.value (1, data_length) = scratch_eoi_message.value (1, data_length);
      ELSE
        f$eoi_message := FALSE;
      IFEND;
    ELSE
      IF data_length = nav$eoi_message.size THEN
        nlp$bm_get_message_prefix (^scratch_eoi_message.value, data_length, message_id, ignore_status);
        f$eoi_message := nav$eoi_message.value (1, data_length) = scratch_eoi_message.value (1, data_length);
      ELSE
        f$eoi_message := FALSE;
      IFEND;
    IFEND;
  FUNCEND f$eoi_message;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] nap$se_clear_request' ??
?? NEWTITLE := '  terminate_clear', EJECT ??

  PROCEDURE [XDCL] nap$se_clear_request
    (    file: fst$file_reference;
     VAR status: ost$status);


    PROCEDURE terminate_clear
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        IF cl_connection <> NIL THEN
          nlp$cl_clear_exclusive_access (cl_connection);
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nap$se_clear_request; {----->
        ELSE
          osp$pop_inhibit_job_recovery;
          osp$set_status_from_condition (nac$status_id, condition, sa, status, condition_status);
          EXIT nap$se_clear_request; {----->
        IFEND;
      = pmc$user_defined_condition =
        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;
      ELSE
        condition_status.normal := TRUE;
      CASEND;
    PROCEND terminate_clear;
?? OLDTITLE, EJECT ??

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      connection_id: nlt$cl_connection_id,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      event_element: ^nat$se_supervisory_element,
      layer_active: boolean,
      processing_task: ost$global_task_id,
      switch_offer_pending: boolean;

    fmp$get_connection_identifier (file, connection_id, switch_offer_pending, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, file, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A GET ATTRIBUTES ', status);
      IFEND;
      RETURN; {----->
    IFEND;

    IF switch_offer_pending THEN
      osp$set_status_condition (nae$switch_offer_pending, status);
      RETURN; {----->
    IFEND;

    cl_connection := NIL;
    #SPOIL (cl_connection);
    osp$push_inhibit_job_recovery;
    osp$establish_condition_handler (^terminate_clear, FALSE);
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.connection_state <> nac$terminated THEN
          IF connection^.termination_data <> NIL THEN
            data_fragments [1].address := connection^.termination_data;
            data_fragments [1].length := #SIZE (connection^.termination_data^);
          ELSE
            data_fragments [1] := nav$null_data [1];
          IFEND;
          nlp$sl_clear_request (cl_connection, data_fragments, {ignore} status);
          connection^.connection_state := nac$terminated;
          connection^.termination_reason := nac$local_clear;
          IF connection^.await_server_response THEN
            pmp$ready_task (connection^.await_server_response_task_id, {ignore} status);
            connection^.await_server_response := FALSE;
          IFEND;
          IF connection^.wait_state = nac$waiting_for_data_available THEN
            pmp$ready_task (cl_connection^.message_receiver.task, {ignore} status);
            nlp$cl_deactivate_receiver (cl_connection);
            connection^.wait_state := nac$inactive_wait;
          IFEND;
          IF connection^.data_queue.count > 0 THEN
            nlp$ta_report_undelivered_data (cl_connection, 0);
            release_data_queue (connection^);
          IFEND;
          WHILE connection^.supervisory_event_queue.beginning <> NIL DO
            event_element := connection^.supervisory_event_queue.beginning;
            connection^.supervisory_event_queue.beginning := event_element^.next_element;
            FREE event_element IN nav$network_paged_heap^;
          WHILEND;
          pmp$get_executing_task_gtid (processing_task);
          IF connection^.wait_state = nac$waiting_to_receive_data THEN
            IF cl_connection^.message_receiver.task = processing_task THEN
              IF NOT connection^.nominal_connection THEN
                osp$set_status_condition (nae$connection_terminated, status);
              ELSE
                osp$set_status_condition (nae$interactive_cond_interrupt, status);
              IFEND;
              terminate_receive_data (connection, cl_connection, ^status);
              status.normal := TRUE;
            ELSE
              activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
            IFEND;
          IFEND;
          IF cl_connection^.message_sender.active THEN
            IF cl_connection^.message_sender.task = processing_task THEN
              IF NOT connection^.nominal_connection THEN
                osp$set_status_condition (nae$connection_terminated, status);
              ELSE
                osp$set_status_condition (nae$interactive_cond_interrupt, status);
              IFEND;
              terminate_send_data (connection, cl_connection, ^status);
              status.normal := TRUE;
            ELSE
              activate_sender_task (cl_connection, cl_connection^.message_sender.task);
            IFEND;
          IFEND;
          IF (connection^.nominal_connection) AND (NOT connection^.timesharing_disconnect_sent) AND
                (connection^.wait_state <> nac$waiting_to_receive_data) AND
                (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
            connection^.timesharing_disconnect_sent := TRUE;
            send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id, NIL);
          IFEND;
        ELSE
          osp$set_status_condition (nae$connection_terminated, status);
        IFEND;
        nlp$cl_release_exclusive_access (cl_connection);
        IF status.normal THEN
          fmp$process_disconnect (file, connection_id);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
        nlp$cl_release_exclusive_access (cl_connection);
      IFEND;
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nap$se_clear_request;
?? OLDTITLE ??
?? NEWTITLE := 'NAP$SE_TERMINATE_CONNECTION', EJECT ??

  PROCEDURE [XDCL] nap$se_terminate_connection
    (    connection_id: nat$connection_id;
         reason: nat$termination_reason;
         active_file: boolean;
     VAR connection_released: boolean;
     VAR status: ost$status);

    VAR
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      event_element: ^nat$se_supervisory_element,
      layer_active: boolean,
      message_id: nlt$bm_message_id;

    status.normal := TRUE;
    connection_released := FALSE;

    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF connection^.connection_state <> nac$terminated THEN
          IF active_file THEN
            IF connection^.await_server_response THEN
              pmp$ready_task (connection^.await_server_response_task_id, {ignore} status);
              connection^.await_server_response := FALSE;
            IFEND;
            IF connection^.wait_state = nac$waiting_for_data_available THEN
              pmp$ready_task (cl_connection^.message_receiver.task, {ignore} status);
              nlp$cl_deactivate_receiver (cl_connection);
              connection^.wait_state := nac$inactive_wait;
            IFEND;
            IF (connection^.nominal_connection) AND (NOT connection^.timesharing_disconnect_sent) AND
                  (connection^.wait_state <> nac$waiting_to_receive_data) AND
                  (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
              connection^.timesharing_disconnect_sent := TRUE;
              send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id,
                    NIL);
            ELSE
              IF connection^.data_queue.count > 0 THEN
                nlp$ta_report_undelivered_data (cl_connection, 0);
                release_data_queue (connection^);
              IFEND;
              WHILE connection^.supervisory_event_queue.beginning <> NIL DO
                event_element := connection^.supervisory_event_queue.beginning;
                connection^.supervisory_event_queue.beginning := event_element^.next_element;
                FREE event_element IN nav$network_paged_heap^;
              WHILEND;
              IF connection^.wait_state = nac$waiting_to_receive_data THEN
                activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
              IFEND;
              IF cl_connection^.message_sender.active THEN
                activate_sender_task (cl_connection, cl_connection^.message_sender.task);
              IFEND;
            IFEND;
            IF connection^.termination_data <> NIL THEN
              data_fragments [1].address := connection^.termination_data;
              data_fragments [1].length := #SIZE (connection^.termination_data^);
            ELSE
              data_fragments [1] := nav$null_data [1];
            IFEND;
            nlp$sl_clear_request (cl_connection, data_fragments, {ignore} status);
            connection^.connection_state := nac$terminated;
            connection^.termination_reason := reason;
          ELSE
            terminate_connection (connection, cl_connection);
            nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
            connection_released := TRUE;
          IFEND;
        ELSE
          nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
          connection_released := TRUE;
        IFEND;
        status.normal := TRUE;
      ELSE
        connection_released := TRUE;
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      connection_released := TRUE;
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nap$se_terminate_connection;

?? OLDTITLE ??
?? NEWTITLE := 'NAP$SE_RETURN_FILE', EJECT ??

  PROCEDURE [XDCL] nap$se_return_file
    (    connection_id: nat$connection_id;
     VAR status: ost$status);

    VAR
      active_file: boolean,
      application_name: nat$application_name,
      cl_connection: ^nlt$cl_connection,
      client: boolean,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      ignore_status: ost$status,
      layer_active: boolean;

    status.normal := TRUE;

    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      client := (connection^.client = TRUE);
      application_name := connection^.application_name;
      IF layer_active THEN
        terminate_connection (connection, cl_connection);
        nlp$cl_deactivate_layer (cl_connection^.application_layer, cl_connection);
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
      nap$delete_connection (application_name, application_kind [client], connection_id, active_file,
            ignore_status);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nap$se_return_file;

?? OLDTITLE ??
?? NEWTITLE := 'TERMINATE_CONNECTION', EJECT ??

  PROCEDURE terminate_connection
    (    connection: ^nat$connection_descriptor;
         cl_connection: ^nlt$cl_connection);

    VAR
      connection_element: ^nat$se_supervisory_element,
      data_fragments: array [1 .. 1] of nat$data_fragment,
      ignore_status: ost$status,
      message_id: nlt$bm_message_id;

    IF connection^.data_queue.count > 0 THEN
      release_data_queue (connection^);
      nlp$ta_report_undelivered_data (cl_connection, 0);
    IFEND;
    IF connection^.connection_state <> nac$terminated THEN
      IF connection^.termination_data <> NIL THEN
        data_fragments [1].address := connection^.termination_data;
        data_fragments [1].length := #SIZE (connection^.termination_data^);
      ELSE
        data_fragments [1] := nav$null_data [1];
      IFEND;
      nlp$sl_clear_request (cl_connection, data_fragments, ignore_status);
    IFEND;
    IF connection^.data_queue.beginning <> NIL THEN
      FREE connection^.data_queue.beginning IN nav$network_paged_heap^;
    IFEND;
    WHILE connection^.supervisory_event_queue.beginning <> NIL DO
      connection_element := connection^.supervisory_event_queue.beginning;
      connection^.supervisory_event_queue.beginning := connection_element^.next_element;
      FREE connection_element IN nav$network_paged_heap^;
    WHILEND;
    IF connection^.connect_data <> NIL THEN
      FREE connection^.connect_data IN nav$network_paged_heap^;
    IFEND;

    IF connection^.termination_data <> NIL THEN
      FREE connection^.termination_data IN nav$network_paged_heap^;
    IFEND;

    IF connection^.peer_accounting_information <> NIL THEN
      FREE connection^.peer_accounting_information IN nav$network_paged_heap^;
    IFEND;

    IF connection^.peer_connect_data <> NIL THEN
      FREE connection^.peer_connect_data IN nav$network_paged_heap^;
    IFEND;

    IF connection^.peer_termination_data <> NIL THEN
      FREE connection^.peer_termination_data IN nav$network_paged_heap^;
    IFEND;
    IF connection^.eoi_message <> NIL THEN
      FREE connection^.eoi_message IN nav$network_paged_heap^;
    IFEND;
  PROCEND terminate_connection;
?? OLDTITLE ??
?? NEWTITLE := 'NAP$CLOSE_FILE', EJECT ??

  PROCEDURE [XDCL, #GATE] nap$close_file
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      file_instance: ^bat$task_file_entry,
      layer_active: boolean;

    #CALLER_ID (caller_id);
    status.normal := TRUE;

    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > file_instance^.instance_attributes.static_label.ring_attributes.r2 THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;

    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (file_instance^.global_file_information^.device_dependent_info.
          network_connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        IF file_instance^.eoi_message <> NIL THEN
          FREE file_instance^.eoi_message IN osv$task_private_heap^;
        IFEND;
        IF file_instance^.receiver_active THEN
          ; {
          ; { Do not deactivate I/O.
          ; {
          IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
                (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
            FREE connection^.receiver_request.application_buffer.allocated_description IN
                  nav$network_paged_heap^;
          IFEND;
          nlp$cl_deactivate_receiver (cl_connection);
          connection^.wait_state := nac$inactive_wait;
        IFEND;
        IF file_instance^.sender_active THEN
          ; {
          ; { Do not deactivate I/O.
          ; {
          IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
                (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
            FREE connection^.sender_request.application_buffer.allocated_description IN
                  nav$network_paged_heap^;
          IFEND;
          nlp$cl_deactivate_sender (cl_connection);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      osp$set_status_condition (nae$connection_terminated, status);
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nap$close_file;
?? OLDTITLE ??
?? NEWTITLE := 'NAP$OPEN_FILE', EJECT ??

  PROCEDURE [XDCL, #GATE] nap$open_file
    (    file_identifier: amt$file_identifier;
         layer: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR status: ost$status);

    IF (NOT osp$is_caller_system_privileged ()) AND (NOT jmv$executing_within_system_job) THEN
      osp$set_status_abnormal ('NA', nae$insufficient_privilege, 'nap$open_file', status);
      RETURN; {----->
    IFEND;

    fmp$open_network_file (call_block.open.local_file_name, file_identifier, status);
    IF NOT status.normal THEN
      IF status.condition = fme$no_cycle_description THEN
        osp$set_status_abnormal ('AM', ame$file_not_known, call_block.open.local_file_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'A OPEN FILE ', status);
      IFEND;
    IFEND;
  PROCEND nap$open_file;
?? TITLE := 'NLP$OPEN_FILE', EJECT ??

  PROCEDURE [XDCL] nlp$open_file
    (    connection_id: nat$connection_id;
         file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      cl_connection: ^nlt$cl_connection,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      file_instance: ^bat$task_file_entry,
      file_is_valid: boolean,
      layer_active: boolean;

    #CALLER_ID (caller_id);
    status.normal := TRUE;
    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance = NIL THEN
      osp$set_status_condition (ame$improper_file_id, status);
      RETURN; {----->
    IFEND;

    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (connection_id, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        file_instance^.sender_active := FALSE;
        file_instance^.receiver_active := FALSE;
        IF (connection^.data_queue.count > 0) OR (connection^.supervisory_event_queue.beginning <> NIL) OR
              (connection^.connection_state <> nac$terminated) OR
              ((connection^.nominal_connection) AND (connection^.connection_state = nac$terminated) AND
              (connection^.send_synchronize_count > 0)) THEN
          ; {
          ; {fillin attributes
          ; {
          file_instance^.data_transfer_timeout := connection^.data_transfer_timeout;
          file_instance^.eoi_message_enabled := connection^.eoi_message_enabled;
          IF connection^.eoi_message <> NIL THEN
            ALLOCATE file_instance^.eoi_message IN osv$task_private_heap^;
            file_instance^.eoi_message^ := connection^.eoi_message^;
          ELSE
            file_instance^.eoi_message := NIL;
          IFEND;
          file_instance^.eoi_peer_termination := connection^.eoi_peer_termination;
        ELSE
          file_instance^.eoi_message := NIL;
          osp$set_status_condition (nae$connection_terminated, status);
        IFEND;
      ELSE
        osp$set_status_condition (nae$connection_terminated, status);
      IFEND;
      nlp$cl_release_exclusive_access (cl_connection);
    ELSE
      IF jmv$connection_acquired THEN
        osp$set_status_condition (nae$connection_terminated, status);
      ELSE
        file_instance^.sender_active := FALSE;
        file_instance^.receiver_active := FALSE;
        file_instance^.eoi_message := NIL;
        file_instance^.eoi_message_enabled := FALSE;
        file_instance^.data_transfer_timeout := 60000;
        file_instance^.eoi_peer_termination := FALSE;
      IFEND;
    IFEND;
    osp$pop_inhibit_job_recovery;
  PROCEND nlp$open_file;
?? OLDTITLE ??
?? TITLE := '[XDCL] nap$se_disconnect_handler', EJECT ??

  PROCEDURE [XDCL] nap$se_disconnect_handler
    (    originator: ost$global_task_id;
         signal: pmt$signal);

    VAR
      cl_connection: ^nlt$cl_connection,
      cl_connection_id: ^nat$connection_id,
      connection: ^nat$connection_descriptor,
      connection_exists: boolean,
      layer_active: boolean,
      local_file_name: amt$local_file_name;

{Debug Code

    VAR
      actual_value: integer,
      ignore_error: boolean;

    osp$increment_locked_variable (nav$namve_tsk_hndl_active_count, 0, actual_value);
    IF actual_value > 1 THEN
      osp$increment_locked_variable (nav$multiple_namve_hndler_calls, 0, actual_value);
      IF nav$debug_mode > nac$no_debug THEN
        nap$namve_system_error (TRUE {=recoverable} ,
              'NAP$SE_DISCONNECT_HANDLER invoked while another handler active.', NIL);
      IFEND;
    IFEND;
{End Debug Code

    cl_connection_id := #LOC (signal.contents);
    osp$push_inhibit_job_recovery;
    nlp$cl_get_exclusive_via_cid (cl_connection_id^, connection_exists, cl_connection);
    IF connection_exists THEN
      nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
      IF layer_active THEN
        local_file_name := connection^.local_file_name;
        nlp$cl_release_exclusive_access (cl_connection);
        fmp$process_disconnect (local_file_name, cl_connection_id^);
      ELSE
        nlp$cl_release_exclusive_access (cl_connection);
      IFEND;
    IFEND;
    osp$pop_inhibit_job_recovery;

{Debug Code
    osp$decrement_locked_variable (nav$namve_tsk_hndl_active_count, 1, actual_value, ignore_error);
{End Debug Code

  PROCEND nap$se_disconnect_handler;
?? TITLE := '  EVALUATE_IO_TIMERS', EJECT ??

  PROCEDURE [XDCL] nap$se_evaluate_io_timers
    (    current_time: integer;
         cl_connection: ^nlt$cl_connection);

    VAR
      layer_active: boolean,
      connection: ^nat$connection_descriptor,
      ignore_status: ost$status;

    nlp$cl_get_layer_connection (cl_connection^.application_layer, cl_connection, layer_active, connection);
    IF layer_active THEN
      IF connection^.wait_state = nac$waiting_to_receive_data THEN
        IF nlp$timer_expired (current_time, connection^.receive_timer) THEN
          nlp$cancel_timer (connection^.receive_timer);
          connection^.receive_timeout := TRUE;
          activate_receiver_task (cl_connection, cl_connection^.message_receiver.task);
        IFEND;
      IFEND;
      IF cl_connection^.message_sender.active THEN
        IF nlp$timer_expired (current_time, connection^.send_timer) THEN
          nlp$cancel_timer (connection^.send_timer);
          connection^.send_timeout := TRUE;
          activate_sender_task (cl_connection, cl_connection^.message_sender.task);
        IFEND;
      IFEND;
      IF nlp$timer_expired (current_time, connection^.event_timer) THEN
        IF (connection^.data_queue.count > 0) OR (connection^.supervisory_event_queue.beginning <> NIL) THEN
          ; {
          ; { DELETE CONNECTION
          ; {
          nlp$cancel_timer (connection^.event_timer);
        IFEND;
      IFEND;
    IFEND;
  PROCEND nap$se_evaluate_io_timers;
?? TITLE := '  GET_OPTIMUM_TRANSFER_SIZE', EJECT ??

  PROCEDURE get_optimum_transfer_size
    (    cl_connection: ^nlt$cl_connection;
     VAR optimum_transfer_unit_size: nat$data_length);

    VAR
      cc_connection: ^nlt$cc_connection,
      layer_active: boolean;

    nlp$cl_get_layer_connection (nlc$channel_connection_layer, cl_connection, layer_active, cc_connection);
    optimum_transfer_unit_size := cc_connection^.device_specific_attributes.maximum_data_length -
          nlc$lower_layer_overhead;

  PROCEND get_optimum_transfer_size;

?? TITLE := '  PROCESS_NOMINAL_CONNECT_EVENTS', EJECT ??

  PROCEDURE [INLINE] process_nominal_connect_events
    (    connection: ^nat$connection_descriptor;
         cl_connection: ^nlt$cl_connection);

    VAR
      dequeued_event_element: ^nat$se_supervisory_element,
      event_element: ^^nat$se_supervisory_element;

    IF (connection^.supervisory_event_queue.beginning <> NIL) AND (connection^.nominal_connection) THEN
      event_element := ^connection^.supervisory_event_queue.beginning;
      WHILE event_element^ <> NIL DO
        IF event_element^^.event.kind = nac$se_interrupt THEN
          send_timesharing_signal (jmc$timesharing_interrupt, connection^.nominal_connection_task_id,
                ^event_element^^.event);
          ; {dequeue_event
          dequeued_event_element := event_element^;
          event_element^ := event_element^^.next_element;
          FREE dequeued_event_element IN nav$network_paged_heap^;
        ELSEIF (event_element^^.event.kind = nac$se_synchronize) AND
              (event_element^^.event.direction = nac$se_synchronize_all_data) THEN
          IF connection^.break_condition_active THEN
            event_element^ := event_element^^.next_element;
          ELSE
            send_timesharing_signal (jmc$timesharing_synchronize, connection^.nominal_connection_task_id,
                  ^event_element^^.event);
            ; {dequeue_event
            dequeued_event_element := event_element^;
            event_element^ := event_element^^.next_element;
            FREE dequeued_event_element IN nav$network_paged_heap^;
            connection^.break_condition_active := TRUE;
          IFEND;
        ELSE
          event_element^ := event_element^^.next_element;
        IFEND;
      WHILEND;
    IFEND;
    IF (connection^.connection_state = nac$terminated) AND (NOT connection^.timesharing_disconnect_sent) AND
          (connection^.data_queue.count = 0) AND (connection^.supervisory_event_queue.beginning = NIL) AND
          (connection^.wait_state <> nac$waiting_to_receive_data) AND
          (NOT cl_connection^.message_sender.active) AND (connection^.send_synchronize_count = 0) THEN
      ; {send_signal (clear)
      connection^.timesharing_disconnect_sent := TRUE;
      send_timesharing_signal (jmc$timesharing_disconnect, connection^.nominal_connection_task_id, NIL);
    IFEND;

  PROCEND process_nominal_connect_events;

?? TITLE := '  SEND_TIMESHARING_SIGNAL', EJECT ??

  PROCEDURE send_timesharing_signal
    (    signal: jmt$timesharing_signal_kind;
         task_id: ost$global_task_id;
         event: ^nat$se_peer_operation);

    VAR
      data_string: ^string ( * ),
      local_status: ost$status,
      seq_ptr: ^SEQ ( * ),
      timesharing_signal: jmt$timesharing_signal;

    timesharing_signal.signal_id := jmc$timesharing_signal_id;
    timesharing_signal.signal_contents.signal_kind := signal;

    IF signal = jmc$timesharing_interrupt THEN
      seq_ptr := ^event^.interrupt_data;
      RESET seq_ptr;
      NEXT data_string: [event^.interrupt_data_length] IN seq_ptr;
      timesharing_signal.signal_contents.interrupt := data_string^;
    ELSEIF signal = jmc$timesharing_synchronize THEN
      seq_ptr := ^event^.synchronize_data;
      RESET seq_ptr;
      NEXT data_string: [event^.synchronize_data_length] IN seq_ptr;
      timesharing_signal.signal_contents.synchronize := data_string^;
    ELSEIF signal = jmc$timesharing_disconnect THEN
      timesharing_signal.signal_contents.disconnect.disconnect_reason := jmc$ts_line_disconnect;
    IFEND;

    pmp$send_signal (task_id, timesharing_signal.signal, local_status);

  PROCEND send_timesharing_signal;

?? TITLE := '  COMPLETE_ACTIVITY', EJECT ??

  PROCEDURE [inline] complete_activity
    (    operation: (send, receive);
         file_identifier: amt$file_identifier;
         status: ^ost$status);

    VAR
      file_instance: ^bat$task_file_entry;

    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance <> NIL THEN
      IF operation = send THEN
        file_instance^.sender_activity_status^.complete := TRUE;
        file_instance^.sender_active := FALSE;
        IF (status <> NIL) AND (NOT status^.normal) THEN
          file_instance^.sender_activity_status^.status := status^;
        IFEND;
      ELSE
        file_instance^.receiver_activity_status^.complete := TRUE;
        file_instance^.receiver_active := FALSE;
        IF (status <> NIL) AND (NOT status^.normal) THEN
          file_instance^.receiver_activity_status^.status := status^;
        IFEND;
      IFEND;
    ELSE
      nap$namve_system_error (TRUE, invalid_file_identifier, NIL);
    IFEND;

  PROCEND complete_activity;

?? TITLE := '  TERMINATE_IO', EJECT ??

  PROCEDURE terminate_io
    (    operation: (sender, receiver);
         file_identifier: amt$file_identifier);

    VAR
      file_instance: ^bat$task_file_entry;

    file_instance := baf$task_file_entry_p (file_identifier);
    IF file_instance <> NIL THEN
      IF operation = sender THEN
        file_instance^.sender_active := FALSE;
      ELSE
        file_instance^.receiver_active := FALSE;
      IFEND;
    ELSE
      nap$namve_system_error (TRUE, invalid_file_identifier, NIL);
    IFEND;

  PROCEND terminate_io;

?? TITLE := '  NLP$RECOVER_TASK_ACTIVITY' ??
?? NEWTITLE := '    CONTINUE_RECOVERY -- CONDITION HANDLER', EJECT ??

  PROCEDURE [XDCL] nlp$recover_task_activity
    (VAR status: ost$status);

    PROCEDURE continue_recovery
      (    condition: pmt$condition;
           ignore_condition_descriptor: ^pmt$condition_information;
           sa: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      nap$condition_handler_trace (condition, sa);
      CASE condition.selector OF
      = pmc$system_conditions, mmc$segment_access_condition =
        nlp$recover_task_activity (condition_status);
        condition_status.normal := TRUE;
        EXIT nlp$recover_task_activity; {----->

      = pmc$user_defined_condition =

{ osp$recover_job checks for recursive job recovery. But if we are in here, I think, we would give up
{ and not properly go through this cleanup.

        IF condition.user_condition_name = 'OSC$JOB_RECOVERY' THEN
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND;
        condition_status.normal := TRUE;

      ELSE
        condition_status.normal := TRUE;
      CASEND;

    PROCEND continue_recovery;
?? OLDTITLE, EJECT ??

    VAR
      i: bat$tft_limit;

    status.normal := TRUE;
    nap$reset_received_message_list;
    nap$gt_close_job_connections (status);
    IF status.normal THEN
      nap$gt_delete_job_saps;
      nlp$sk_process_job_recovery;

      FOR i := 1 TO bav$last_tft_entry DO
        IF bav$tft_entry_assignment^ (i, 1) = fmc$entry_assigned THEN
          IF bav$task_file_table^ [i].device_class = rmc$network_device THEN
            osp$establish_condition_handler (^continue_recovery, FALSE);
            IF bav$task_file_table^ [i].sender_active THEN
              bav$task_file_table^ [i].sender_active := FALSE;
              osp$set_status_condition (nae$job_recovery, bav$task_file_table^ [i].sender_activity_status^.
                    status);
              bav$task_file_table^ [i].sender_activity_status^.complete := TRUE;
            IFEND;
            IF bav$task_file_table^ [i].receiver_active THEN
              bav$task_file_table^ [i].receiver_active := FALSE;
              osp$set_status_condition (nae$job_recovery, bav$task_file_table^ [i].receiver_activity_status^.
                    status);
              bav$task_file_table^ [i].receiver_activity_status^.complete := TRUE;
            IFEND;
            osp$disestablish_cond_handler;
          IFEND;
        IFEND;
      FOREND;
    IFEND;

  PROCEND nlp$recover_task_activity;
?? OLDTITLE ??
?? NEWTITLE := 'terminate_receive_data', EJECT ??

  PROCEDURE terminate_receive_data
    (    connection: ^nat$connection_descriptor;
         cl_connection: ^nlt$cl_connection;
         status: ^ost$status);

    IF ((connection^.receiver_request.application_buffer.description_kind = nac$allocated) AND
          (connection^.receiver_request.application_buffer.allocated_description <> NIL)) THEN
      FREE connection^.receiver_request.application_buffer.allocated_description IN nav$network_paged_heap^;
    IFEND;
    nlp$cl_deactivate_receiver (cl_connection);
    connection^.wait_state := nac$inactive_wait;
    complete_activity (receive, connection^.receive_file_identifier, status);

  PROCEND terminate_receive_data;
?? OLDTITLE ??
?? NEWTITLE := 'terminate_send_data', EJECT ??

  PROCEDURE terminate_send_data
    (    connection: ^nat$connection_descriptor;
         cl_connection: ^nlt$cl_connection;
         status: ^ost$status);

    IF ((connection^.sender_request.application_buffer.description_kind = nac$allocated) AND
          (connection^.sender_request.application_buffer.allocated_description <> NIL)) THEN
      FREE connection^.sender_request.application_buffer.allocated_description IN nav$network_paged_heap^;
    IFEND;
    nlp$cl_deactivate_sender (cl_connection);
    complete_activity (send, connection^.send_file_identifier, status);

  PROCEND terminate_send_data;
?? OLDTITLE ??
MODEND nam$se_external_interface;
