?? LEFT := 1, RIGHT := 110 ??
?? FMT (FORMAT := ON, INDENT := 2) ??
?? SET (LIST := ON, LISTCTS := OFF) ??
MODULE nfm$ptf_client;
{
{     PURPOSE:
{            This module contains procedures to perform Permanent file
{            Transfer Facility (PTF) client functions.
{
{     DESCRIPTION:
{            Requests for
{            PTF client access come either through the Manage Remote Files
{            (MANRF) command or implicit command access.  The MANRF command
{            gains access to the starting procedure nfp$manage_remote_files
{            via a program descriptor known to SCL.  Implicit command access
{            allows a number of SCL commands (e.g. Copy_File, Display_Catalog,
{            etc.) to execute a PTF client task with the starting procedure
{            nfp$perform_implicit_transfer.
{
*copyc amp$get_file_attributes
*copyc amp$open
*copyc amp$put_next
*copyc avp$get_capability
*copyc clp$convert_integer_to_rjstring
*copyc clp$convert_integer_to_string
*copyc clp$convert_string_to_integer
*copyc clp$convert_str_to_path_handle
*copyc clp$evaluate_parameters
*copyc clp$get_command_origin
*copyc clp$get_fs_path_string
*copyc clp$get_line_from_command_file
*copyc clp$get_parameter_list
*copyc clp$convert_value_to_string
*copyc clp$pop_input
*copyc clp$push_input
*copyc clp$read_variable
*copyc clp$substitute_delimited_text
*copyc jme$queued_file_conditions
*copyc fmt$path_handle
*copyc fse$copy_validation_errors
*copyc fst$evaluated_file_reference
*copyc fst$path_handle_name
*copyc jmp$system_job
*copyc mmp$create_scratch_segment
*copyc nap$get_attributes
*copyc nap$request_connection
*copyc nap$se_send_data
*copyc nap$se_receive_data
*copyc nap$store_attributes
*copyc nfp$count_directives_text
*copyc nfp$find_remote_validation
*copyc nfp$format_message_to_job_log
*copyc nfp$generate_ptf_statistic
*copyc nfp$verify_family
*copyc nfp$get_remote_validation
*copyc nfp$set_abnormal_if_normal
*copyc nfp$string_length
*copyc nfp$convert_p31_to_ordinal
*copyc nfp$dispose_user_msg_to_log
*copyc nfp$find_delimitd_string_length
*copyc nfp$send_command
*copyc nfp$send_connect_request
*copyc nfp$receive_command
*copyc nfp$initialize_control_block
*copyc nfp$transfer_file
*copyc nfp$ptf_format_message_to_out
*copyc nfp$terminate_path
*copyc osp$append_status_parameter
*copyc osp$await_activity_completion
*copyc osp$format_message
*copyc osp$set_status_abnormal
*copyc osp$set_status_from_condition
*copyc pmp$continue_to_cause
*copyc pmp$disestablish_cond_handler
*copyc pmp$establish_condition_handler
*copyc pmp$get_170_os_type
*copyc pmp$get_compact_date_time
*copyc pmp$get_job_names
*copyc pmp$get_user_identification
*copyc pmp$generate_unique_name
*copyc pmp$log
*copyc pmp$exit
*copyc rfp$get_local_host_physical_id
*copyc rfp$store
?? PUSH (LISTEXT := ON) ??
*copyc clt$parameter_list
*copyc cle$ecc_command_processing
*copyc cle$ecc_expression_result
*copyc jme$queued_file_conditions
*copyc nae$application_interfaces
*copyc nfe$ptf_condition_codes
*copyc nfe$sou_condition_codes
*copyc nft$directive_entry
*copyc nft$file_access_mode
*copyc nft$ve_to_ve_access
*copyc oss$job_paged_literal
*copyc clc$standard_file_names
*copyc clt$parameter_list
*copyc nfs$ptf_static_data
*copyc nft$implicit_command
*copyc nft$number_implicit_commands
*copyc ost$caller_identifier
*copyc ost$name
*copyc ost$status
*copyc nfc$abnormal_conditions
*copyc NFC$COMMAND_DEFINITIONS
*copyc NFC$PARAMETER_DEFINITIONS
*copyc NFC$PARAMETER_00_DEFINITIONS
*copyc NFC$PARAMETER_01_DEFINITIONS
*copyc NFC$PARAMETER_02_DEFINITIONS
*copyc NFC$PARAMETER_03_DEFINITIONS
*copyc NFC$PARAMETER_04_DEFINITIONS
*copyc NFC$PARAMETER_05_DEFINITIONS
*copyc NFC$PARAMETER_06_DEFINITIONS
*copyc NFC$PARAMETER_07_DEFINITIONS
*copyc NFC$PARAMETER_08_DEFINITIONS
*copyc NFC$PARAMETER_09_DEFINITIONS
*copyc NFC$PARAMETER_10_DEFINITIONS
*copyc NFC$PARAMETER_11_DEFINITIONS
*copyc NFC$PARAMETER_12_DEFINITIONS
*copyc NFC$PARAMETER_13_DEFINITIONS
*copyc NFC$PARAMETER_16_DEFINITIONS
*copyc NFC$PARAMETER_20_DEFINITIONS
*copyc NFC$PARAMETER_21_DEFINITIONS
*copyc NFC$PARAMETER_22_DEFINITIONS
*copyc NFC$PARAMETER_24_DEFINITIONS
*copyc NFC$PARAMETER_25_DEFINITIONS
*copyc NFC$PARAMETER_26_DEFINITIONS
*copyc NFC$PARAMETER_27_DEFINITIONS
*copyc NFC$PARAMETER_28_DEFINITIONS
*copyc NFC$PARAMETER_29_DEFINITIONS
*copyc NFC$PARAMETER_30_DEFINITIONS
*copyc NFC$PARAMETER_31_DEFINITIONS
*copyc NFC$PARAMETER_32_DEFINITIONS
*copyc NFC$PARAMETER_33_DEFINITIONS
*copyc NFC$PARAMETER_90_DEFINITIONS
*copyc NFC$PARAMETER_91_DEFINITIONS
*copyc NFC$PARAMETER_92_DEFINITIONS
*copyc NFC$PARAMETER_93_DEFINITIONS
*copyc NFC$PARAMETER_94_DEFINITIONS
*copyc NFC$PARAMETER_95_DEFINITIONS
*copyc NFC$PARAMETER_96_DEFINITIONS
*copyc NFC$PARAMETER_97_DEFINITIONS
*copyc NFC$PARAMETER_98_DEFINITIONS
*copyc NFC$PARAMETER_99_DEFINITIONS
*copyc nfe$batch_transfer_services
*copyc nfe$ptf_condition_codes
*copyc nft$transfer_declarations
*copyc nft$transfer_status
*copyc NFT$FILE_ACCESS_MODE
*copyc NFT$MODE_OF_ACCESS
*copyc nft$parameter_values
*copyc nft$parameter_qualifiers
*copyc nft$parameter_qualifier_values
*copyc nft$application_values
*copyc NFT$PARAMETER_00_VALUES
*copyc NFT$PARAMETER_01_VALUES
*copyc nft$parameter_03_values
*copyc nft$parameter_03_value_set
*copyc nft$parameter_03_netvalues
*copyc nft$parameter_03_elements
*copyc nft$parameter_04_values
*copyc nft$parameter_06_values
*copyc nft$parameter_12_range
*copyc nft$parameter_20_range
*copyc NFT$PARAMETER_21_values
*copyc NFT$PARAMETER_21_OPTIONS
*copyc NFT$PARAMETER_21_specifications
*copyc nft$parameter_22_values
*copyc nft$parameter_22_strings
*copyc nft$parameter_24_definition
*copyc nft$parameter_25_definition
*copyc nft$parameter_26_definition
*copyc nft$parameter_26_all_chars
*copyc nft$parameter_27_definition
*copyc NFT$PROTOCOL_COMMANDS
*copyc NFT$PROTOCOL_PARAMETERS
*copyc nft$parameter_set
*copyc nft$command_set
*COPYC NFT$P00_VALUES
*copyc nft$last_command_sent
*copyc nft$last_command_received
*copyc nft$control_block
*copyc nft$network_type
*copyc nft$directive_entry
*copyc nft$parameter_rules
*copyc nft$command_values
*copyc nft$crack_parameter_action
*copyc nft$buffer_control_block
*copyc nft$ptf_protocol_states
*copyc nft$required_param_on_command
*copyc nft$ve_to_ve_access
*copyc nfv$p04_values
*copyc osv$lower_to_upper
*copyc rfe$condition_codes

  TYPE
    nft$ptf_transfer_state = (nfc$xfer_complete_normal, nfc$xfer_retryable_term_connect,
          nfc$xfer_retryable_neg_protocol, nfc$xfer_retryable_path_discon, nfc$xfer_noretry_term_connect,
          nfc$xfer_noretry_path_discon);

  TYPE
    nft$ptf_transfer_state_set = set of nft$ptf_transfer_state;

?? NEWTITLE := 'ptf static definitions', EJECT ??

{ nfm$ptf_static_definitions }


  VAR
    nfv$ptf_required_params: [READ, STATIC, XDCL, nfs$ptf_static_data] nft$required_param_on_command := [[],
    { Null Command }
    [nfc$protocol_id, { RFT }
          nfc$user_text_directive, nfc$host_type, nfc$transfer_lid, nfc$job_name, nfc$physical_id],
          [nfc$protocol_id, { RPOS }
          nfc$mode_of_access, nfc$host_type, nfc$job_name, nfc$physical_id], [nfc$state_of_transfer], { RNEG }
          [], { GO }
          [nfc$state_of_transfer], { STOP }
          [nfc$state_of_transfer], { STOPR }
          [], { ETP }
          [], { ETPR }
          []]; { FINI }

  VAR
    ptf_parameter_00_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p00_min_size, nfc$p00_size_a101, [nfc$rft, nfc$rpos], [], [nfc$stop], [nfc$go, nfc$stopr],
          TRUE], [{ A102 }
          TRUE, nfc$p00_min_size, nfc$p00_size_a102, [nfc$rft, nfc$rpos], [], [nfc$stop], [nfc$go, nfc$stopr],
          TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_01_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p01_min_size, nfc$p01_max_size, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p01_min_size, nfc$p01_max_size, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_02_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p02_min_size, nfc$p02_max_size, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p02_min_size, nfc$p02_max_size, [], [], [], [], FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_03_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p03_min_size, nfc$p03_max_size, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p03_min_size, nfc$p03_max_size, [], [], [], [], FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_04_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p04_min_param_len, nfc$p04_max_param_len, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p04_min_param_len, nfc$p04_max_param_len, [], [], [], [], FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_05_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p05_min_param_len, nfc$ptfs_job_line_width, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p05_min_param_len, nfc$ptfs_job_line_width, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_06_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p06_min_param_len, nfc$p06_max_param_len, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p06_min_param_len, nfc$p06_max_param_len, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_07_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p07_min_param_len, nfc$p07_max_param_len_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p07_min_param_len, nfc$p07_max_param_len_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_08_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p08_min_param_len, nfc$p08_max_param_len_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p08_min_param_len, nfc$p08_max_param_len_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_09_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p09_min_param_len, nfc$p09_max_param_len_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p09_min_param_len, nfc$p09_max_param_len_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_10_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p10_min_param_len, nfc$p10_max_param_len_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p10_min_param_len, nfc$p10_max_param_len_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_11_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p11_min_param_len, nfc$p11_max_param_len, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p11_min_param_len, nfc$p11_max_param_len, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_12_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p12_min_size_a101, nfc$p12_max_size_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p12_min_size_a102, nfc$p12_max_size_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_13_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p13_min_param_size, nfc$p13_max_param_size, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p13_min_param_size, nfc$p13_max_param_size, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_16_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p16_min_param_length, nfc$p16_max_param_length_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p16_min_param_length, nfc$p16_max_param_length_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_17_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A102 }
          FALSE], [{ A101 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_18_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A102 }
          FALSE], [{ A101 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_19_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A102 }
          FALSE], [{ A101 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_20_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p20_min_size, nfc$p20_max_size, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p20_min_size, nfc$p20_max_size, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_21_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p21_min_param_len, nfc$p21_max_param_len, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p21_min_param_len, nfc$p21_max_param_len, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_22_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p22_min_size, nfc$p22_max_size, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p22_min_size, nfc$p22_max_size, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_23_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A102 }
          FALSE], [{ A101 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_24_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A102 }
          FALSE], [{ A101 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_25_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p25_min_param_size_a101, nfc$p25_max_param_size_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p25_min_param_size_a102, nfc$p25_max_param_size_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_26_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p26_min_param_length, nfc$p26_max_param_length_a101, [], [], [], [], TRUE], [{ A102 }
          TRUE, nfc$p26_min_param_length, nfc$p26_max_param_length_a102, [], [], [], [], TRUE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_27_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p27_min_param_size_a101, nfc$p27_max_param_size_a101, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p27_min_param_size_a102, nfc$p27_max_param_size_a102, [], [], [], [], FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_28_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p28_min_size, nfc$p28_max_size, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p28_min_size, nfc$p28_max_size, [], [], [], [], FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_29_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p29_min_param_size_a101, nfc$p29_max_param_size_a101, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p29_min_param_size_a102, nfc$p29_max_param_size_a102, [], [], [], [], FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_30_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p30_min_param_size, nfc$p30_max_param_size, [], [], [], [], FALSE], [{ A102 }
          TRUE, nfc$p30_min_param_size, nfc$p30_max_param_size, [], [], [], [], FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_31_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p31_min_param_length_a101, nfc$p31_max_param_length_a101, [], [], [], [], FALSE],
          [{ A102 }
          TRUE, nfc$p31_min_param_length_a102, nfc$p31_max_param_length_a102, [], [], [], [], FALSE],
          [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_32_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p32_min_param_length_a101, nfc$p32_max_param_length_a101, [], [], [], [], FALSE],
          [{ A102 }
          TRUE, nfc$p32_min_param_length_a102, nfc$p32_max_param_length_a102, [], [], [], [], FALSE],
          [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_33_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          TRUE, nfc$p33_min_param_length_a101, nfc$p33_max_param_length_a101, [], [], [], [], FALSE],
          [{ A102 }
          TRUE, nfc$p33_min_param_length_a102, nfc$p33_max_param_length_a102, [], [], [], [], FALSE],
          [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_51_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_52_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_53_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_54_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_55_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_56_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_57_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_58_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_59_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_60_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_90_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_91_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_92_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_93_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_94_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_95_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_96_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_97_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_98_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    ptf_parameter_99_rules: [READ, STATIC, nfs$ptf_static_data] nft$parameter_rules := [[{ A101 }
          FALSE], [{ A102 }
          FALSE], [{ B101 }
          FALSE]];

  VAR
    nfv$ptf_parameter_rules: [STATIC, READ, XDCL, nfs$ptf_static_data] nft$parameter_rules_array :=
          [^ptf_parameter_00_rules, ^ptf_parameter_01_rules, ^ptf_parameter_02_rules, ^ptf_parameter_03_rules,
          ^ptf_parameter_04_rules, ^ptf_parameter_05_rules, ^ptf_parameter_06_rules, ^ptf_parameter_07_rules,
          ^ptf_parameter_08_rules, ^ptf_parameter_09_rules, ^ptf_parameter_10_rules, ^ptf_parameter_11_rules,
          ^ptf_parameter_12_rules, ^ptf_parameter_13_rules, ^ptf_parameter_16_rules, ^ptf_parameter_17_rules,
          ^ptf_parameter_18_rules, ^ptf_parameter_19_rules, ^ptf_parameter_20_rules, ^ptf_parameter_21_rules,
          ^ptf_parameter_22_rules, ^ptf_parameter_23_rules, ^ptf_parameter_24_rules, ^ptf_parameter_25_rules,
          ^ptf_parameter_26_rules, ^ptf_parameter_27_rules, ^ptf_parameter_28_rules, ^ptf_parameter_29_rules,
          ^ptf_parameter_30_rules, ^ptf_parameter_31_rules, ^ptf_parameter_32_rules, ^ptf_parameter_33_rules,
          ^ptf_parameter_51_rules, ^ptf_parameter_52_rules, ^ptf_parameter_53_rules, ^ptf_parameter_54_rules,
          ^ptf_parameter_55_rules, ^ptf_parameter_56_rules, ^ptf_parameter_57_rules, ^ptf_parameter_58_rules,
          ^ptf_parameter_59_rules, ^ptf_parameter_60_rules,
          ^ptf_parameter_90_rules, ^ptf_parameter_91_rules, ^ptf_parameter_92_rules, ^ptf_parameter_93_rules,
          ^ptf_parameter_94_rules, ^ptf_parameter_95_rules, ^ptf_parameter_96_rules, ^ptf_parameter_97_rules,
          ^ptf_parameter_98_rules, ^ptf_parameter_99_rules];

?? POP ??
?? OLDTITLE ??
?? NEWTITLE := 'access_remote_file', EJECT ??

  PROCEDURE access_remote_file
    (    location: ost$name;
         file_name: amt$local_file_name;
         data_declaration: nft$parameter_31_type;
         directives: ^nft$directive_entry;
         known_host: nft$ve_to_ve_access;
         ptf_command: ost$string;
     VAR status: ost$status);

{
{ Procedure access_remote_file
{
{ Purpose   Handle connect phase, protocol phase,
{           and retry conditions.
{
{ Description This module initiates connect to remote host.  Then protocol
{             exchange up to data transfer is performed.  The data transfer
{             module is called for file transfer.  If any errors occur,
{             the possibility for retry is considered.
{
{ Input parameters
{            Location             : Name of remote family/host
{            File_name            : File to be transferred (if any)
{            Data_declaration     : Data format of transfer (if any)
{            Directives           : List of remote host directives
{            File_access_mode     : Flag if mode of access is known
{            Known_host           : Flag if remote host is NOS/VE (for sure)
{            Ptf_command          : Command which initiated PTF
{
{ Output parameters
{            Status               : Returned status
{
?? EJECT ??

    VAR
      arf_conditions: pmt$condition,
      arf_condition_descriptor: pmt$established_handler,
      caller_id: ost$caller_identifier,
      control_block: nft$control_block,
      ignore_status: ost$status,
      nam_attributes: ^nat$change_attributes,
      nam_optimum_attributes: ^nat$get_attributes,
      network_file_name: ost$unique_name,
      path_name: ost$unique_name,
      physical_id: rft$physical_identifier,
      rhfam_attributes: ^rft$change_attributes,
      terminate_now: boolean,
      transfer_state: nft$ptf_transfer_state,
      user_id: ost$user_identification;

    VAR
      nfv$ptf_parameter_rules: [XREF] nft$parameter_rules_array;

    VAR
      nfv$ptf_send_p03_values: [STATIC, READ, XDCL, nfs$ptf_static_data] nft$parameter_03_netvalues :=
            [[], [nfc$collective_text_string, nfc$ss_ack_required], [nfc$collective_text_string]];

    VAR
      nfv$retry_states: [XDCL, STATIC, READ, nfs$ptf_static_data] nft$ptf_transfer_state_set :=
            [nfc$xfer_retryable_term_connect, nfc$xfer_retryable_neg_protocol,
            nfc$xfer_retryable_path_discon];

?? NEWTITLE := 'arf_condition_handler', EJECT ??

    PROCEDURE arf_condition_handler
      (    condition: pmt$condition;
           condition_desc: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR trap_status: ost$status);

{
{ Procedure  arf_condition_handler
{
{ Purpose    To handle any condition which occurs while a path is connected.
{            This handler is responsible for "cleaning up" any resources
{            (including connections) held by the application at the time
{            of the condition.
{
{ Description
{            This routine's only purpose is to terminate any outstanding
{            connection to a remote host.  This must be done so that the
{            servicer may terminate.  Note: the interactive conditions
{            pause and reconnect are treated somewhat differently.  We do
{            not allow transfers to be paused.  This would result in network
{            resources (DI/NAD buffers) being locked until path timeout
{            or the connection is resumed.  Therefore, we assume the user
{            wanted to continue, so a 'we ignored your interrupt' is
{            delivered.  The exception is for NOS/BE dual state systems.
{            NOS/BE allows only one asynch interrupt, and that is mapped
{            to NOS/VE pause.  If the pause were not serviced as a break,
{            the user could never terminate.  Therefore, on NOS/BE, a
{            pause terminates the transfer.
{
{ Input parameters
{            See info on condition handlers.  Also note, because defined
{            in access remote file, we have access to all of arf's
{            variables.
{
{ Output parameters
{            trap_status          : returned status
{

      VAR
        ignored_params: nft$parameter_set,
        local_status: ost$status,
        modified_params: nft$parameter_set,
        os_type: ost$170_os_type,
        output_status: ost$status,
        received_params: nft$parameter_set;

      VAR
        nfv$ptf_required_params: [XREF] nft$required_param_on_command;

      CASE condition.selector OF
      = ifc$interactive_condition =
        CASE condition.interactive_condition OF
        = ifc$pause_break, ifc$job_reconnect =
          pmp$get_170_os_type (os_type, local_status);
          IF (NOT local_status.normal) OR (os_type = osc$ot7_dual_state_nos_be) THEN
            IF control_block.path.path_connected THEN
              nfp$terminate_path (control_block.application, TRUE, control_block.path, local_status);
              osp$set_status_from_condition (nfc$status_id, condition, save_area, status, local_status);
              EXIT access_remote_file;
            IFEND;
          ELSE
            { spit out a message saying pause ignored }
            osp$set_status_abnormal (nfc$status_id, nfe$user_interrupt_ignored, '', output_status);
            nfp$ptf_format_message_to_out( output_status );
            RETURN;
          IFEND;
        = ifc$terminate_break =
          IF control_block.path.path_connected THEN
            nfp$terminate_path (control_block.application, TRUE, control_block.path, local_status);
          IFEND;
          pmp$continue_to_cause (pmc$execute_standard_procedure, trap_status);
          osp$set_status_from_condition (nfc$status_id, condition, save_area, status, local_status);
          EXIT access_remote_file;
        = ifc$terminal_connection_broken =
          pmp$continue_to_cause (pmc$execute_standard_procedure, trap_status);
          RETURN;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, trap_status);
          RETURN;
        CASEND;
      = pmc$block_exit_processing =
        IF control_block.path.path_connected THEN
          IF (control_block.last_command_sent <> nfc$unknown_command) AND
            (control_block.last_command_received <> nfc$unknown_command) THEN
            IF (control_block.last_command_sent = nfc$rft) AND (control_block.last_command_received =
                  nfc$rpos) THEN
              control_block.last_command_received := nfc$rneg;
            IFEND;
            ptf_process_protocol (control_block, local_status);
            IF local_status.normal THEN
              ptf_terminate_connection (control_block);
            IFEND;
            pmp$continue_to_cause (pmc$execute_standard_procedure, trap_status);
          IFEND;
          nfp$terminate_path (control_block.application, TRUE, control_block.path, local_status);
        IFEND;
        RETURN;
      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, trap_status);
      CASEND;

    PROCEND arf_condition_handler;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    nfp$initialize_control_block (nfc$application_ptf, data_declaration,
          nfv$ptf_send_p03_values [nfc$network_lcn], nfv$ptf_send_p03_values [nfc$network_lcn],
          nfv$ptf_send_p03_values [nfc$network_nam], nfc$p00_a102, nfc$null, ^nfv$ptf_parameter_rules,
          control_block);
    control_block.retry_limit := 3;
    control_block.retry_milliseconds := 1000;
    control_block.send_directives := directives;
    control_block.ptf_scl_directive := ptf_command;
    control_block.transfer_lid_length := nfp$string_length (location);
    control_block.transfer_lid := location (1, control_block.transfer_lid_length);
    control_block.file_name := file_name;

    PUSH control_block.path.network_file: [STRLENGTH (path_name.value)];
    IF known_host.ve_server THEN
      control_block.remote_ring.value := known_host.execution_ring;
    ELSE
      #CALLER_ID (caller_id);
      control_block.remote_ring.value := caller_id.ring;
    IFEND;
    pmp$get_job_names (control_block.user_job_name, control_block.system_job_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    pmp$get_user_identification (user_id, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    arf_conditions.selector := pmc$condition_combination;
    arf_conditions.combination := $pmt$condition_combination
          [pmc$block_exit_processing, ifc$interactive_condition];
    pmp$establish_condition_handler (arf_conditions, ^arf_condition_handler, ^arf_condition_descriptor,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    REPEAT

{     Initialize

      status.normal := TRUE;
      control_block.negotiate_protocol := FALSE;
      control_block.last_command_sent := nfc$unknown_command;
      control_block.last_command_received := nfc$unknown_command;
      control_block.data_xfer_complete := FALSE;
      control_block.state_of_transfer.normal := TRUE;
      control_block.local_status.normal := TRUE;
      control_block.remote_status.normal := TRUE;
      control_block.send_operator_messages := NIL;
      control_block.send_user_messages := NIL;
      control_block.send_account_messages := NIL;
      control_block.send_errorlog_messages := NIL;

{     Check if necessary to connect path

      IF NOT control_block.path.path_connected THEN
        pmp$generate_unique_name (network_file_name, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        control_block.path.network_file^ := network_file_name.value;
        nfp$send_connect_request (location, control_block.application_server, control_block.application,
              control_block.path, status);
      IFEND;

      IF status.normal THEN
        CASE control_block.path.network_type OF
        = nfc$network_nam =
          IF control_block.protocol_in_use = nfc$p00_a101 THEN { MAKE fit }
            control_block.data_block_size := nfc$p12_lcn_default;
          ELSE
            PUSH nam_optimum_attributes: [1..2];
            nam_optimum_attributes^ [1].kind := nac$optimum_transfer_unit_incr;
            nam_optimum_attributes^ [2].kind := nac$optimum_transfer_unit_size;
            nap$get_attributes(network_file_name.value, nam_optimum_attributes^, status);
            IF status.normal THEN
              control_block.data_block_size := nam_optimum_attributes^ [2].optimum_transfer_unit_size;
              IF nam_optimum_attributes^ [1].optimum_transfer_unit_incr > 0 THEN
                WHILE control_block.data_block_size < 10240 DO
                  control_block.data_block_size := control_block.data_block_size +
                      nam_optimum_attributes^ [1].optimum_transfer_unit_incr;
                WHILEND;
              IFEND;
              control_block.data_block_size := control_block.data_block_size - data_header_length;
            IFEND;
            IF (NOT status.normal) OR (control_block.data_block_size < 512) THEN
              control_block.data_block_size := nfc$p12_nam_default;
            IFEND;
          IFEND;
          control_block.transfer_pid_length := nfp$string_length (user_id.family);
          control_block.transfer_pid := user_id.family (1, control_block.transfer_pid_length);
          control_block.send_facilities := nfv$ptf_send_p03_values [nfc$network_nam];
          PUSH nam_attributes: [1 .. 1];
          nam_attributes^ [1].kind := nac$data_transfer_timeout;
          nam_attributes^ [1].data_transfer_timeout := control_block.time_out * nfc$milliseconds;
          nap$store_attributes (control_block.path.network_file_id, nam_attributes^, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        = nfc$network_lcn =
          control_block.data_block_size := nfc$p12_lcn_default;
          rfp$get_local_host_physical_id (physical_id, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          control_block.transfer_pid_length := #SIZE (physical_id);
          control_block.transfer_pid := physical_id;
          PUSH rhfam_attributes: [1 .. 1];
          rhfam_attributes^ [1].key := rfc$data_transfer_timeout;
          rhfam_attributes^ [1].data_transfer_timeout := control_block.time_out * nfc$milliseconds;
          rfp$store (control_block.path.network_file_id, rhfam_attributes^, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        ELSE
          osp$set_status_abnormal (nfc$status_id, nfe$bts_internal_error, 'access_remote_file case error',
                status);
          RETURN;
        CASEND;
        ptf_process_protocol (control_block, status);
        nfp$set_abnormal_if_normal (status, control_block.local_status);
      ELSE
        nfp$set_abnormal_if_normal (status, control_block.local_status);
      IFEND;

{     Decide if retry is necessary }

      ptf_retry (control_block, transfer_state, status);
      CASE transfer_state OF
      = nfc$xfer_retryable_term_connect, nfc$xfer_noretry_term_connect, nfc$xfer_complete_normal =
        ptf_terminate_connection (control_block);
        nfp$terminate_path (control_block.application, TRUE, control_block.path, ignore_status);
      = nfc$xfer_retryable_neg_protocol =
        { No action, around again }
      = nfc$xfer_retryable_path_discon, nfc$xfer_noretry_path_discon =
        nfp$terminate_path (control_block.application, TRUE, control_block.path, ignore_status);
      CASEND;

    UNTIL NOT (transfer_state IN nfv$retry_states);

    nfp$terminate_path (control_block.application, TRUE, control_block.path, ignore_status);
    pmp$disestablish_cond_handler (arf_conditions, ignore_status);

  PROCEND access_remote_file;
?? OLDTITLE ??
?? NEWTITLE := 'ptf_process_protocol', EJECT ??

{ PURPOSE:
{   This procedure processes the sequence of A-A protocol necessary to
{   transfer a file, which is defined by the stat table.  The state table
{   takes into account three things: last command sent, last command
{   received, and if data transfer has occured.  There are three actions
{   possible, send command, receive command, and transfer file.

  PROCEDURE ptf_process_protocol
    (VAR control_block: nft$control_block;
     VAR status: ost$status);

    VAR
      begin_connection_time: ost$date_time,
      end_connection_time: ost$date_time,
      ignored_params: nft$parameter_set,
      index: 1 .. nfc$ptf_number_pstates,
      secured_scl_directive_line: ost$string,
      modified_params: nft$parameter_set,
      new_state: nft$protocol_actions,
      received_params: nft$parameter_set,
      remote_family: nat$network_address,
      send_parameters: nft$parameter_set,
      state_known: boolean,
      terminate_status: ost$status;

    VAR
      ptfi_protocol: [READ, STATIC, nfs$ptf_static_data] nft$ptf_protocol_states := [
            [nfc$unknown_command,    { Sent command
            nfc$unknown_command,     { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_send_command,    { Send command to remote
            nfc$rft,                 { Make it RFT
            [nfc$protocol_id, nfc$facilities, nfc$user_text_directive, nfc$file_length, nfc$max_block_size,
            nfc$minimum_timeout_interval, nfc$host_type, nfc$transfer_lid, nfc$job_name, nfc$physical_id]],

            [nfc$rft,                { Sent command
            nfc$unknown_command,     { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_receive_command, { Get one
            [nfc$rpos, nfc$rneg]],

            [nfc$rft,                { Sent command
            nfc$rpos,                { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_start_transfer,  { Send command to remote
            nfc$go,                  { Make it Go
            []],

            [nfc$rft,                { Sent command
            nfc$rneg,                { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_send_command,    { Send command to remote
            nfc$stop,                { Make it Rft
            [nfc$state_of_transfer]],

            [nfc$go,                 { Sent command
            nfc$rpos,                { Received command
            TRUE,                    { Data xfer complete
            nfc$ptf_send_command,    { Send command to remote
            nfc$stop,                { Make it Rft
            [nfc$state_of_transfer]],

            [nfc$go,                 { Sent command
            nfc$rpos,                { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_send_command,    { Send command to remote
            nfc$stop,                { Make it Rft
            [nfc$state_of_transfer]],

            [nfc$stop,               { Sent command
            nfc$rneg,                { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_receive_command, { Receive STOPR
            [nfc$stopr]],

            [nfc$stop,               { Sent command
            nfc$rpos,                { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_receive_command, { Send command to remote
            [nfc$stopr]],

           [nfc$stop,                { Sent command
            nfc$rpos,                { Received command
            TRUE,                    { Data xfer complete
            nfc$ptf_receive_command, { Send command to remote
            [nfc$stopr]],

            [nfc$stop,               { Sent command
            nfc$stopr,               { Received command
            TRUE,                    { Data xfer complete
            nfc$ptf_terminate],      { All done

            [nfc$stop,               { Sent command
            nfc$stopr,               { Received command
            FALSE,                   { Data xfer complete
            nfc$ptf_terminate]];     { All done

    VAR
      nfv$ptf_required_params: [XREF] nft$required_param_on_command;
?? NEWTITLE := 'truncate_scl_directive_string', EJECT ??

    PROCEDURE truncate_scl_directive_string
      (VAR scl_directive_string: ost$string);

  {  PURPOSE:
  {      Given an SCL directive string to be used in file transfer logs, truncate
  {    the directive string at a position before a secure parameter could occur,
  {    thereby preventing the recording of secure parameters in the log entry.
  {
  {  ASSUMPTIONS:
  {    (1) When PTF obtains the SCL directive string, a pre-processor has formatted the
  {        command to conform to one of the following formats:
  {          a) "<scl_command_name> file=<file_name> ...etc..."
  {          b) "<scl_command_name> file=(<file_name>, <file_name>, ..., <file_name>) ...etc..."
  {        The use of this format allows the use of the character "=" as a landmark character;
  {        it represents the boundry between trivial and non-trivial information in the SCL
  {        directive string.
  {
  {    (2) Any string not in the previously mentioned formats can be secured by truncating
  {        at the first separator found.

      TYPE
        scan_char_flags = packed array [0 .. 255] of 0 .. 1,
        character_set = set of char;

      VAR
        scan_bit_set: scan_char_flags,
        search_char_found: boolean,
        search_index: integer,
        separator_list: character_set,
        working_string: ost$string;

      search_char_found := FALSE;
      FOR search_index := 0 TO 255 DO
        scan_bit_set [search_index] := 0;
      FOREND;
      scan_bit_set [$INTEGER ('=')] := 1;
      search_index := 0;
      working_string := scl_directive_string;

      #SCAN (scan_bit_set, working_string.value, search_index, search_char_found);

      IF search_char_found THEN
        search_index := search_index + 1;
        IF (working_string.value (search_index) = '(') THEN
          separator_list := $character_set [')'];
        ELSE { only one file name was specified in the SCL directive string.
          separator_list := $character_set [' ', ','];
        IFEND;
      ELSE { the SCL directive string isn't in the format expected, reset the search index & make best attempt
        search_index := 0;
        separator_list := $character_set [' ', '"', ')', ','];
      IFEND;

      search_char_found := FALSE;
      REPEAT
        search_index := search_index + 1;
        IF working_string.value (search_index) IN separator_list THEN
          search_char_found := TRUE;
        IFEND;
      UNTIL (search_char_found) OR (search_index >= STRLENGTH (scl_directive_string.value));

      IF (search_char_found) THEN
        scl_directive_string.value := working_string.value (1, search_index);
        scl_directive_string.size := search_index;
      IFEND;

    PROCEND truncate_scl_directive_string;

?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    pmp$get_compact_date_time( begin_connection_time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    control_block.transfer_directives_length := nfp$count_directives_text(control_block.
      send_directives);

    WHILE TRUE DO { Do protocol until receive STOPR or connection is terminated
      state_known := FALSE;

    /state_loop/
      FOR index := LOWERVALUE (index) TO UPPERVALUE (index) DO
        IF ((ptfi_protocol [index].last_command_sent = control_block.last_command_sent) AND
              (ptfi_protocol [index].last_command_received = control_block.last_command_received) AND
              (ptfi_protocol [index].data_xfer_complete = control_block.data_xfer_complete)) THEN
          state_known := TRUE;
          EXIT /state_loop/
        IFEND;
      FOREND /state_loop/;
      IF NOT state_known THEN
        osp$set_status_abnormal (nfc$status_id, nfe$invalid_command_code, ' ', status);
        RETURN;
      ELSE
        new_state := ptfi_protocol [index].action;
        CASE new_state OF
        = nfc$ptf_send_command =
          send_parameters := ptfi_protocol [index].send_parameters;
          IF ptfi_protocol [index].send_command = nfc$rft THEN
            IF control_block.protocol_in_use = nfc$p00_a102 THEN
              build_ptfi_ring_parameter (control_block.remote_ring.value,
                    control_block.send_special_options, status);
              IF NOT status.normal THEN
                RETURN;
              ELSE
                send_parameters := send_parameters + $nft$parameter_set [nfc$special_options];
              IFEND;
            IFEND;
            IF control_block.data_declaration <> nfc$p31_unspecified THEN
              send_parameters := send_parameters + $nft$parameter_set [nfc$data_declaration];
            IFEND;
          IFEND;
          nfp$send_command (ptfi_protocol [index].send_command, send_parameters,
             $nft$parameter_set[ ], $nft$parameter_set[ ], control_block, status);
        = nfc$ptf_receive_command =
          nfp$receive_command (ptfi_protocol [index].legal_receive_commands, nfv$ptf_required_params,
                control_block, received_params, ignored_params, modified_params, status);
          nfp$set_abnormal_if_normal (status, control_block.local_status);
          IF (status.normal) AND (control_block.received_user_messages.head <> NIL) THEN
            control_block.transfer_directives_length := nfp$count_directives_text(control_block.
               received_user_messages.head) + control_block.transfer_directives_length;
            nfp$dispose_user_msg_to_log (control_block.received_user_messages);
          IFEND;
          IF (nfc$special_options IN received_params) AND (control_block.remote_host_type =
                nfc$p22_nos_ve) AND control_block.remote_status.normal THEN
            receive_remote_status (control_block.receive_special_options.
                  value (1, control_block.receive_special_options.size), control_block.remote_status, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;

{ *** NOTE here is a trick to make the state table work for two odd conditions.
{ If RPOS was received, but an error occured, the application should treat the error as
{ if an RNEG was received.  If RPOS was received, but protocol negotiation was requested
{ by the server, the initiator should treat the condition as an RNEG.

          IF (control_block.last_command_received = nfc$rpos) THEN
            IF (NOT status.normal) THEN
              control_block.last_command_received := nfc$rneg;
              osp$set_status_abnormal (nfc$status_id, nfe$terminate_transfer_message, ' ',
                    control_block.state_of_transfer);
              status := control_block.state_of_transfer;
            ELSE
              IF (control_block.negotiate_protocol) THEN
                control_block.last_command_received := nfc$rneg;
              IFEND;
            IFEND;
          IFEND;
        = nfc$ptf_terminate =
          IF control_block.path.path_connected AND control_block.remote_status.normal AND
                control_block.local_status.normal AND control_block.state_of_transfer.
                normal AND control_block.data_xfer_complete THEN

            pmp$get_compact_date_time( end_connection_time, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;

            secured_scl_directive_line.value := control_block.ptf_scl_directive.value;
            secured_scl_directive_line.size  := STRLENGTH(control_block.ptf_scl_directive.value);

{ The SCL directive string is only trucated if the access mode is NFC$NULL, commands with an access mode
{ of NFC$GIVE or NFC$TAKE do not have secure parameters, and truncation is not needed.

            IF (control_block.mode_of_access = nfc$null) THEN
              truncate_scl_directive_string(secured_scl_directive_line);
            IFEND;

            nfp$generate_ptf_statistic( begin_connection_time,
                    end_connection_time, control_block.transfer_file_size,
                    control_block.transfer_directives_length,
                    control_block.transfer_pid(1,
                           control_block.transfer_pid_length),
                    control_block.transfer_lid(1,
                           control_block.transfer_lid_length),
                    control_block.application,
                    secured_scl_directive_line );
          IFEND;
          status.normal := TRUE;
          RETURN;
        = nfc$ptf_start_transfer =
          IF control_block.mode_of_access = nfc$null THEN
            control_block.data_xfer_complete := TRUE;
            control_block.last_command_sent := nfc$go;
          ELSE
            nfp$send_command (ptfi_protocol [index].xfer_send_command,
                  ptfi_protocol [index].xfer_send_parameters,
                  $nft$parameter_set[ ], $nft$parameter_set[ ],
                  control_block, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
            nfp$transfer_file (control_block, status);
            control_block.data_xfer_complete := TRUE;
          IFEND;
        ELSE
          osp$set_status_abnormal (nfc$status_id, nfe$bts_internal_error, 'ptf_process_protocol', status);
          RETURN;
        CASEND;

{ Check result of previous action

        IF NOT status.normal THEN
          nfp$set_abnormal_if_normal (status, control_block.local_status);
        IFEND;
        IF NOT control_block.path.path_connected THEN
          RETURN;
        IFEND;
      IFEND;
    WHILEND;

  PROCEND ptf_process_protocol;
?? OLDTITLE ??
?? NEWTITLE := 'ptf_retry', EJECT ??

  PROCEDURE ptf_retry
    (VAR control_block: nft$control_block;
     VAR transfer_state: nft$ptf_transfer_state;
     VAR status: ost$status);

{
{ Procedure  ptf_retry
{
{ Purpose    This routine takes the results of an attempted transfer and
{            decides if it completed successfully.  If it did not, a
{            decision is made on whether or not to retry.
{
{ Description
{            The algorthim here is fairly simple, check all transfer status
{            values for an error.  If there is an error, it is checked
{            against the retryable error table.  Any NON-RETRYABLE error
{            should case PTFI to terminate without retry. Note: design
{                   direction states transfers may not be retried if an SCL (or
{            remote host command for that matter) has been executed, so if we
{            have received RPOS or RNEG already, no retry is possible.
{
{ Input parameters
{            None
{
{ Input/Output parameters
{            Control_block        input/output transfer control structure
{
{ Output parameters
{            Transfer_state       Ordinal returned indicating status of xfer,
{                                 and possible retry action.  NOTE: this value
{                                 is ALWAYS valid, even if STATUS is not!
{            Status               Return status
{
?? EJECT ??
{}

    CONST
      nfc$number_local_retry_cond = 3,
      nfc$number_remote_retry_cond = 1;

{}

    VAR
      index: 1 .. nfc$p04_max_transfer_states,
      local_status: ost$status,
      message_status: ost$status,
      ready_index: integer,
      remote_status_index: 1 .. nfc$number_remote_retry_cond,
      retry_index: 1 .. nfc$number_local_retry_cond,
      wait_list: ^ost$wait_list;

    VAR
      no_retry_states: [STATIC, READ, nfs$ptf_static_data] nft$ptf_transfer_state_set :=
            [nfc$xfer_noretry_term_connect, nfc$xfer_noretry_path_discon];

    VAR
      retryable_conditions: [READ, STATIC, nfs$ptf_static_data] array [1 .. nfc$number_local_retry_cond] of
            ost$status_condition_code := [nfe$recoverable_connect, nae$connection_terminated,
            rfe$connection_terminated];

    VAR
      remote_retryable_conditions: [READ, STATIC, nfs$ptf_static_data] array
            [1 .. nfc$number_remote_retry_cond] of ost$status_condition_code := [jme$maximum_jobs];

    VAR
      nfv$retry_states: [XREF] nft$ptf_transfer_state_set;

{}
    status.normal := TRUE;
    transfer_state := nfc$xfer_complete_normal;
{}
{     If A102/A101 protocol negotiation in progress }
{}
    IF control_block.negotiate_protocol THEN
      IF control_block.path.path_connected THEN { Expected case }
        transfer_state := nfc$xfer_retryable_neg_protocol;
        RETURN;
      ELSE { Unlikely condition, handle it as retryable }
        transfer_state := nfc$xfer_retryable_path_discon;
        osp$set_status_abnormal (nfc$status_id, nfe$protocol_anomaly, '', status);
      IFEND;
    IFEND;
{}
{     Now a hierarchy, any retryable condition here is overriden by
{     a non-retryable condition
{}
{     *** CASE # 1
{     Deviate from design direction, no retry necessary after STOP instead of
{     If RPOS or RNEG has been received, no retry is possible.  At this point,
{     no irrecoverable conditions exist.
{}
    IF (control_block.last_command_sent > nfc$unknown_command) AND
          (control_block.last_command_received < nfc$stopr) THEN
      IF NOT (control_block.path.path_connected) THEN
        transfer_state := nfc$xfer_retryable_path_discon; { Expected case }
      ELSE
        transfer_state := nfc$xfer_noretry_term_connect; { Protocol problem? }
        osp$set_status_abnormal (nfc$status_id, nfe$protocol_anomaly, '', status);
      IFEND;
    IFEND;
{}
{     *** CASE # 2
{     Here we check the state of transfer.  The state of transfer should
{     represent the "worst" case, i.e. if the servicer thinks things are
{     o.k. and the initiator thinks things are bad, we have the initiators
{     attitude contained in the SOT.
{}
    IF NOT control_block.state_of_transfer.normal THEN
      status := control_block.state_of_transfer;
      IF NOT (transfer_state IN no_retry_states) THEN

      /sot_for_loop/
        FOR index := LOWERVALUE (index) TO UPPERVALUE (index) DO
          IF nfv$p04_values [index].condition = control_block.state_of_transfer.condition THEN
            IF nfv$p04_values [index].retryable THEN
              IF control_block.path.path_connected THEN
                transfer_state := nfc$xfer_retryable_term_connect;
              ELSE
                transfer_state := nfc$xfer_retryable_path_discon;
              IFEND;
            ELSE
              IF control_block.path.path_connected THEN
                transfer_state := nfc$xfer_noretry_term_connect;
              ELSE
                transfer_state := nfc$xfer_noretry_path_discon;
              IFEND;
            IFEND;
            EXIT /sot_for_loop/;
          IFEND;
        FOREND /sot_for_loop/;
      IFEND;
    IFEND;
{}
{     *** CASE # 3
{     Check the remote status ( in NOS/VE <-> NOS/VE transfers this is
{     set by parameter 11, special options ) to see if it is retryable
{
    IF NOT control_block.remote_status.normal THEN
      status := control_block.remote_status;
      IF NOT (transfer_state IN no_retry_states) THEN
        IF control_block.path.path_connected THEN { Initialize for worst case}
          transfer_state := nfc$xfer_noretry_term_connect;
        ELSE
          transfer_state := nfc$xfer_noretry_path_discon;
        IFEND;

      /remote_status_loop/
        FOR remote_status_index := LOWERBOUND (remote_retryable_conditions)
              TO UPPERBOUND (remote_retryable_conditions) DO
          IF status.condition = remote_retryable_conditions [remote_status_index] THEN
            IF control_block.path.path_connected THEN { Initialize for worst case}
              transfer_state := nfc$xfer_retryable_term_connect;
            ELSE
              transfer_state := nfc$xfer_retryable_path_discon;
            IFEND;
            EXIT /remote_status_loop/;
          IFEND;
        FOREND /remote_status_loop/;
      IFEND;
{}
{     Change here for NV0K444.  The problem with remote status not being }
{     valid on client mainframe.  Problem has to do with path handles (file }
{     names to be translated) not having value to client.  Use a generic }
{     message instead or non-NF messages, with a couple exceptions. }
{}
      IF (status.condition<nfc$min_ecc) OR
         (status.condition>nfc$max_ecc) THEN
        IF (status.condition=ave$bad_user_validation_info) OR
           (status.condition=cle$bad_or_missing_login_in_job) THEN
          osp$set_status_abnormal(nfc$status_id,nfe$bad_or_missing_login_in_job,
                    '',status);
        ELSEIF (status.condition<>jme$maximum_jobs) THEN
          osp$set_status_abnormal(nfc$status_id,nfe$remote_system_error_see_jl,
                    '',status);
        IFEND;
      IFEND;
    IFEND;
{}
{     *** CASE # 4
{     Check the local status to see if it is retryable
{
    IF NOT control_block.local_status.normal THEN
      status := control_block.local_status;

      IF NOT (transfer_state IN no_retry_states) THEN { Assume not retryable }
        IF NOT control_block.path.path_connected THEN
          transfer_state := nfc$xfer_noretry_path_discon;
        ELSE
          transfer_state := nfc$xfer_noretry_term_connect;
        IFEND;

      /local_status_retry_loop/
        FOR retry_index := LOWERBOUND (retryable_conditions) TO UPPERBOUND (retryable_conditions) DO
          IF control_block.local_status.condition = retryable_conditions [retry_index] THEN
            IF NOT control_block.path.path_connected THEN
              transfer_state := nfc$xfer_retryable_path_discon;
            ELSE
              transfer_state := nfc$xfer_retryable_term_connect;
            IFEND;
            EXIT /local_status_retry_loop/;
          IFEND;
        FOREND /local_status_retry_loop/;
      IFEND;
    IFEND;
{}
{     See if connect retry limit is reached }
{}
    IF transfer_state IN nfv$retry_states THEN
      control_block.retry_count := control_block.retry_count + 1;
      IF control_block.retry_count > control_block.retry_limit THEN
        IF NOT control_block.path.path_connected THEN
          transfer_state := nfc$xfer_noretry_path_discon;
        ELSE
          transfer_state := nfc$xfer_noretry_term_connect;
        IFEND;
      ELSE
        nfp$ptf_format_message_to_out (status);
        osp$set_status_abnormal (nfc$status_id, nfe$transfer_failed_recovering, '', local_status);
        nfp$ptf_format_message_to_out (local_status);
        PUSH wait_list: [1 .. 1];
        wait_list^ [1].activity := osc$await_time;
        wait_list^ [1].milliseconds := control_block.retry_milliseconds;
        osp$await_activity_completion (wait_list^, ready_index, local_status);
      IFEND;
    IFEND;
{}
  PROCEND ptf_retry;
?? OLDTITLE ??
?? NEWTITLE := 'ptf_terminate_connection', EJECT ??

  PROCEDURE ptf_terminate_connection
    (VAR control_block: nft$control_block);

{
{ Procedure  ptf_terminate_connection
{
{ Purpose    To complete A-A protocol (ETP,ETPR,FINI,disconnect) on
{            a connection.
{
{ Description
{            This routine completes protocol for PTFI in this order:
{                   Send ETP
{                   Receive ETPR
{                   Send FINI
{                   Disconnect path
{
{ Input parameters
{                   None
{
{ Input/Output parameters
{            Control_block        input/output transfer control structure
{
{ Output parameters
{                   None
{
{ Algorithm
{                   Nfp$send_command( ETP )
{                   Nfp$receive_command( ETPR )
{                   Nfp$send_command( FINI )
{
?? EJECT ??

    VAR
      ignored_params: nft$parameter_set,
      legal_commands: nft$command_set,
      local_status: ost$status,
      modified_params: nft$parameter_set,
      received_params: nft$parameter_set;

    VAR
      nfv$ptf_required_params: [XREF] nft$required_param_on_command;

{}
{     Send ETP }
{}
    nfp$send_command (nfc$etp, $nft$parameter_set[ ],
      $nft$parameter_set[ ], $nft$parameter_set[ ],
      control_block, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;
{}
{     Receive ETPR }
{}
    legal_commands := $nft$command_set [nfc$etpr];
    nfp$receive_command (legal_commands, nfv$ptf_required_params, control_block, received_params,
          ignored_params, modified_params, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;
{}
{     Send FINI }
{}
    nfp$send_command (nfc$fini, $nft$parameter_set[ ],
      $nft$parameter_set[ ], $nft$parameter_set[ ],
      control_block, local_status);
{}
  PROCEND ptf_terminate_connection;
?? OLDTITLE ??
?? TITLE := 'build_ptfi_ring_parameter', EJECT ??

  PROCEDURE build_ptfi_ring_parameter
    (    ring: ost$ring;
     VAR special_options: nft$parameter_11_value;
     VAR status: ost$status);

{
{ Procedure  build_ptfi_ring_parameter
{
{ Purpose    To build a string containing the ring of the
{            initiating application.
{
{ Description
{            The current ring is encoded as a string.
{
{ Input parameters
{            ring   : Current execution ring
{
{ Output parameters
{            special_options      : returned ring representation
{            status               : return status
{
{ Algorithm
{            Encode ring
{
?? EJECT ??
{}

    VAR
      ring_string: ost$string;

{}
    status.normal := TRUE;
    clp$convert_integer_to_string (ring, 10, FALSE, ring_string, status);
    IF status.normal THEN
      special_options.size := ring_string.size;
      IF special_options.size > 0 THEN
        special_options.value := ring_string.value;
      ELSE
        osp$set_status_abnormal (nfc$status_id, nfe$bts_internal_error,
              'build_ptfi_ring_parameter length < 0', status);
      IFEND;
    IFEND;
{}
  PROCEND build_ptfi_ring_parameter;
?? TITLE := 'receive_remote_status', EJECT ??

  PROCEDURE receive_remote_status
    (    received_parameter: string ( * <= nfc$max_param_size);
     VAR remote_status: ost$status;
     VAR status: ost$status);

{
{ Procedure  receive_remote_status
{
{ Purpose    This routing cracks the special options parameter
{            as a NOS/VE status.
{
{ Description
{            The remote status parameter is of the form
{            code condition # status parameter(s).
{
{ Input parameters
{            receive_parameter    : Text value of status parameter
{
{ Output parameters
{            remote_status        : Cracked status value
{            status               : Return status
{
{ Algorithm
{            Crack condition name
{            Crack condition integer value
{            Crack status parameter(s)
{            Build status record
{
?? EJECT ??
{}

    VAR
      integer_record: clt$integer,
      length_condition: integer,
      length_status_id: integer,
      parameter_position: nft$parameter_size,
      status_id: ost$status_identifier;

{}
    status.normal := TRUE;
    remote_status.normal := TRUE;
    nfp$find_delimitd_string_length (received_parameter, length_status_id, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    parameter_position := length_status_id + 2;
    nfp$find_delimitd_string_length (received_parameter (parameter_position, * ), length_condition, status);
    IF NOT status.normal THEN
      length_condition := STRLENGTH (received_parameter) - parameter_position + 1;
      IF length_condition <= 0 THEN { Incorrect parameter }
        RETURN;
      ELSE { Assume no message field }
        status.normal := TRUE;
      IFEND;
    IFEND;
    clp$convert_string_to_integer (received_parameter (parameter_position, length_condition), integer_record,
          status);
    IF status.normal THEN
      parameter_position := length_condition + 2 + parameter_position;
      status_id := received_parameter (1, length_status_id);
      IF parameter_position >= STRLENGTH (received_parameter) THEN
        osp$set_status_abnormal (status_id, integer_record.value, '', remote_status);
      ELSE
        osp$set_status_abnormal (status_id, integer_record.value, received_parameter (parameter_position, * ),
              remote_status);
      IFEND;
    IFEND;
{}
  PROCEND receive_remote_status;
?? TITLE := '  [#GATE,XDCL] nfp$perform_implicit_transfer', EJECT ??

  PROCEDURE [#GATE, XDCL] nfp$perform_implicit_transfer
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{
{ Procedure  nfp$perform_implicit_transfer
{
{ Purpose    To server as the starting point for an implicit PTF transfer.
{            Implicit PTF transfers (i.e. COPY_FILE) execute a task to
{            perform the PTF function.  This is done because the implicit
{            command processors exist as subroutines of the job monitor task
{            (for performance reasons).  However, it is desirable not to
{            have PTF in the job template, so a task is executed.
{
{ Description
{            The procedure uses a sequence, passed by execute_task, to
{            build the parameters for a PTF transfer.  The sequence is cracked
{            and a call is made to begin the transfer.
{
{ Input parameters
{            parameter_list              : Pointer to sequence
{
{ Output parameters
{            status                      : Return status
{
{ Algorithm
{            Crack sequence for transfer parameters
{            Ensure remote validation is available
{            Call access_remote_file
{
?? EJECT ??
?? TITLE := '  [INLINE] link_directive', EJECT ??

{
{   Code to link a string onto a link list of server directives.
{

    PROCEDURE [INLINE] link_directive;

      IF directive_ptr = NIL THEN
        PUSH directive_ptr: [size];
        directive_list_ptr := directive_ptr;
      ELSE
        PUSH directive_ptr^.link: [size];
        directive_ptr := directive_ptr^.link;
      IFEND;
      directive_ptr^.link := NIL;
      directive_ptr^.line := line (1, size);

    PROCEND link_directive;

?? TITLE := '  [INLINE] append_string', EJECT ??

{  Procedure to append a string to an existing string.

    PROCEDURE [INLINE] append_string
      (    add_string: string ( * );
           length: 0 .. osc$max_string_size);

      IF size + length > line_limit THEN
        line (size + 1, 2) := ellipsis;
        size := size + 2;
        PUSH directive_ptr^.link: [size];
        directive_ptr := directive_ptr^.link;
        directive_ptr^.link := NIL;
        directive_ptr^.line := line (1, size);
        size := 0;
      IFEND;

      line (size + 1, length) := add_string (1, length);
      size := size + length;
    PROCEND append_string;

?? OLDTITLE, EJECT ??

    VAR
      access_mode: nft$mode_of_access,
      access_mode_ptr: ^nft$mode_of_access,
      caller_id: ost$caller_identifier,
      command_name: ost$name,
      command_name_ptr: ^ost$name,
      contains_data: boolean,
      data_declaration: nft$parameter_31_type,
      directive_list_ptr: ^nft$directive_entry,
      directive_ptr: ^nft$directive_entry,
      file_attributes: ^amt$get_attributes,
      file_exists: boolean,
      file_length: amt$file_length,
      file_previously_opened: boolean,
      i: 0 .. clc$max_parameters,
      j: 1 .. nfc$max_validation_lines,
      implicit_command: ost$string,
      implicit_command_ptr: ^ost$string,
      index: nft$number_implicit_commands,
      line: string (osc$max_string_size),
      line_count: 0 .. nfc$max_validation_lines,
      local_file: amt$local_file_name,
      local_file_path: fst$path,
      local_file_path_size: fst$path_size,
      local_file_phn: fmt$path_handle,
      local_file_ptr: ^amt$local_file_name,
      local_status: ost$status,
      location: ost$name,
      location_ptr: ^ost$name,
      name_count: 1 .. clc$max_parameters,
      name_index: 1 .. clc$max_parameters,
      number_implicit_cmds: nft$number_implicit_commands,
      number_implicit_ptr: ^nft$number_implicit_commands,
      param_name: ^nft$number_implicit_commands,
      param_name_size: 1 .. osc$max_name_size,
      param_number: 0 .. clc$max_parameters,
      parameter_sequence: ^clt$parameter_list,
      ptf_scl_directive: ost$string,
      remote_file_path: ost$string,
      remote_file_ptr: ^ost$string,
      size: ost$string_size,
      str: ost$string,
      validation_ptr: ^array [1 .. * ] of string (osc$max_string_size),
      value: clt$value,
      ve_server: nft$ve_to_ve_access;

    CONST
      space = ' ',
      equal = '=',
      apostrophe = '''',
      ellipsis = '..',
      open_p = '(',
      close_p = ')',
      line_limit = osc$max_string_size - 2;


    status.normal := TRUE;

  /perform_remote_access/
    BEGIN

      directive_ptr := NIL;
      directive_list_ptr := NIL;
{}
{     Get input parameters }
{}
      parameter_sequence := ^parameter_list;
      RESET parameter_sequence;
      NEXT location_ptr IN parameter_sequence;
      location := location_ptr^;
      NEXT local_file_ptr IN parameter_sequence;
      local_file := local_file_ptr^;
      NEXT remote_file_ptr IN parameter_sequence;
      remote_file_path := remote_file_ptr^;
      NEXT access_mode_ptr IN parameter_sequence;
      access_mode := access_mode_ptr^;
      NEXT command_name_ptr IN parameter_sequence;
      command_name := command_name_ptr^;
      NEXT number_implicit_ptr IN parameter_sequence;
      number_implicit_cmds := number_implicit_ptr^;

{}
{     Ensure remote host is accessable }
{}
      nfp$find_remote_validation (location, line_count, status);
      IF NOT status.normal THEN
        EXIT /perform_remote_access/;
      ELSEIF line_count = 0 THEN
        osp$set_status_abnormal (nfc$status_id, nfe$remote_val_undefined, location, status);
        EXIT /perform_remote_access/;
      IFEND;

      PUSH validation_ptr: [1 .. line_count];
      nfp$get_remote_validation (location, validation_ptr, status);
      IF NOT status.normal THEN
        EXIT /perform_remote_access/;
      IFEND;
{}
{     Put validation commands on list }
{}
      FOR j := 1 TO line_count DO
        line := validation_ptr^ [j];
        size := nfp$string_length (line);
        link_directive;
      FOREND;

{ Put implicit commands (e.g. DISFA) on list
{ Note that for COPY_FILE the command_name is null

      IF number_implicit_cmds > 0 THEN
        FOR index := 1 TO number_implicit_cmds DO
          NEXT implicit_command_ptr IN parameter_sequence;
          line := implicit_command_ptr^.value;
          size := implicit_command_ptr^.size;

{ The first directive is assumed to contain the implicit command (or at
{ least the first 256 characters) that we want to save for accounting

          IF index = 1 THEN
            ptf_scl_directive.value := line (1, size);
            ptf_scl_directive.size := size;
          IFEND;
          link_directive;
        FOREND;
      IFEND;

{ Reconstruct COPY_FILE command for accounting

      IF command_name = osc$null_name THEN
        clp$get_fs_path_string (local_file, local_file_path,
              local_file_path_size, local_file_phn, status);
        IF NOT status.normal THEN
          EXIT /perform_remote_access/;
        IFEND;
        IF access_mode = nfc$give THEN
          line := 'COPY_FILE INPUT=';
          size := 16;
          line (size+1, remote_file_path.size) := remote_file_path.value
                (1, remote_file_path.size);
          size := size + remote_file_path.size;
          line (size+1, 8) := ' OUTPUT=';
          size := size + 8;
          line (size+1, local_file_path_size) := local_file_path
                (1, local_file_path_size);
          size := size + local_file_path_size;
        ELSE

{ Check if the non-remote file actually exists before initiating the transfer.

          PUSH file_attributes: [1..1];
          file_attributes^ [1].key := amc$file_length;
          file_attributes^ [1].file_length := 0;
          amp$get_file_attributes (local_file_path, file_attributes^, file_exists,
             file_previously_opened, contains_data, status);

          IF NOT status.normal THEN
            RETURN;
          IFEND;
          IF NOT file_exists THEN
            osp$set_status_abnormal ('AM', ame$file_not_known, local_file, status);
            osp$append_status_parameter(osc$status_parameter_delimiter,'FSP$OPEN_FILE', status);
            RETURN;
          ELSEIF file_attributes^ [1].file_length <= 0 THEN
            osp$set_status_abnormal ('FS', fse$empty_input_file, local_file, status);
            RETURN;
          IFEND;

          line := 'COPY_FILE INPUT=';
          size := 16;
          line (size+1, local_file_path_size) := local_file_path
                (1, local_file_path_size);
          size := size + local_file_path_size;
          line (size+1, 8) := ' OUTPUT=';
          size := size + 8;
          line (size+1, remote_file_path.size) := remote_file_path.value
                (1, remote_file_path.size);
          size := size + remote_file_path.size;
        IFEND;
        ptf_scl_directive.value := line (1, size);
        ptf_scl_directive.size := size;
      IFEND;
{}
{     Put file transfer commands on list }
{}
      IF access_mode <> nfc$null THEN
        IF access_mode = nfc$take THEN
          line := 'RECEIVE_FILE ';
          size := remote_file_path.size + 13;
          line (14, remote_file_path.size) := remote_file_path.value (1, remote_file_path.size);
        ELSE
          line := 'SEND_FILE ';
          size := remote_file_path.size + 10;
          line (11, remote_file_path.size) := remote_file_path.value (1, remote_file_path.size);
        IFEND;
        link_directive;
      IFEND;

      #CALLER_ID (caller_id);
      ve_server.ve_server := TRUE;
      ve_server.execution_ring := caller_id.ring;
      data_declaration := nfc$p31_host_dependent_uh;

      access_remote_file (location, local_file, data_declaration, directive_list_ptr,
            ve_server, ptf_scl_directive, status);

    END /perform_remote_access/;

  PROCEND nfp$perform_implicit_transfer;

?? RIGHT := 110 ??
?? NEWTITLE := 'nfm$manage_remote_files', EJECT ??

?? TITLE := '  [#GATE,XDCL] nfp$manage_remote_files', EJECT ??

  PROCEDURE [#GATE, XDCL] nfp$manage_remote_files
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{
{ Procedure  nfp$manage_remote_files
{
{ Purpose    This procedure contains the processor for the
{            manage_remote_files command.
{
{ Description
{            This routine gets the transfer parameters, via SCL calls,
{            and initiates the PTF transfer.  Note that PTF is installed
{            as a product so there is a program descriptor pointing to the
{            library in which this module resides.
{
{ Input parameters
{            parameter_list       : parameter list passed by SCL
{
{ Output parameters
{            status               : return status
{
{ Algorithm
{            Check user allowed to do explicit file transfer
{            Check SCL command valid
{            Get SCL command parameters
{            Read remote directives
{            Call access_remote_file
{
?? EJECT ??
{ PROCEDURE manage_remote_files_pdt (
{   location, l: any of
{       string 1..31
{       name
{     anyend = $required
{   file, f: file = $required
{   data_declaration, dd: key
{       c8, c6, us, uu
{     keyend = $optional
{   until, u: string = '**'
{   substitution_mark, sm: any of
{       string 1
{       key
{         none
{       keyend
{     anyend = none
{   ignore_remote_validation, irv: boolean = false
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 13] of clt$pdt_parameter_name,
      parameters: array [1 .. 7] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$string_type_qualifier,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
      recend,
      type2: record
        header: clt$type_specification_header,
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 4] of clt$keyword_specification,
      recend,
      type4: record
        header: clt$type_specification_header,
        qualifier: clt$string_type_qualifier,
        default_value: string (4),
      recend,
      type5: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$string_type_qualifier,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 1] of clt$keyword_specification,
        recend,
        default_value: string (4),
      recend,
      type6: record
        header: clt$type_specification_header,
        default_value: string (5),
      recend,
      type7: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [91, 7, 23, 13, 42, 28, 605],
    clc$command, 13, 7, 2, 0, 0, 0, 7, ''], [
    ['DATA_DECLARATION               ',clc$nominal_entry, 3],
    ['DD                             ',clc$abbreviation_entry, 3],
    ['F                              ',clc$abbreviation_entry, 2],
    ['FILE                           ',clc$nominal_entry, 2],
    ['IGNORE_REMOTE_VALIDATION       ',clc$nominal_entry, 6],
    ['IRV                            ',clc$abbreviation_entry, 6],
    ['L                              ',clc$abbreviation_entry, 1],
    ['LOCATION                       ',clc$nominal_entry, 1],
    ['SM                             ',clc$abbreviation_entry, 5],
    ['STATUS                         ',clc$nominal_entry, 7],
    ['SUBSTITUTION_MARK              ',clc$nominal_entry, 5],
    ['U                              ',clc$abbreviation_entry, 4],
    ['UNTIL                          ',clc$nominal_entry, 4]],
    [
{ PARAMETER 1
    [8, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 33,
  clc$required_parameter, 0, 0],
{ PARAMETER 2
    [4, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter,
  0, 0],
{ PARAMETER 3
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 155,
  clc$optional_parameter, 0, 0],
{ PARAMETER 4
    [13, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 8,
  clc$optional_default_parameter, 0, 4],
{ PARAMETER 5
    [11, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 72,
  clc$optional_default_parameter, 0, 4],
{ PARAMETER 6
    [5, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 5],
{ PARAMETER 7
    [10, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$union_type], [[clc$name_type, clc$string_type],
    TRUE, 2],
    8, [[1, 0, clc$string_type], [1, 31, FALSE]],
    5, [[1, 0, clc$name_type], [1, osc$max_name_size]]
    ],
{ PARAMETER 2
    [[1, 0, clc$file_type]],
{ PARAMETER 3
    [[1, 0, clc$keyword_type], [4], [
    ['C6                             ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['C8                             ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['US                             ', clc$nominal_entry, clc$normal_usage_entry, 3],
    ['UU                             ', clc$nominal_entry, clc$normal_usage_entry, 4]]
    ],
{ PARAMETER 4
    [[1, 0, clc$string_type], [0, clc$max_string_size, FALSE],
    '''**'''],
{ PARAMETER 5
    [[1, 0, clc$union_type], [[clc$keyword_type, clc$string_type],
    FALSE, 2],
    8, [[1, 0, clc$string_type], [1, 1, FALSE]],
    44, [[1, 0, clc$keyword_type], [1], [
      ['NONE                           ', clc$nominal_entry, clc$normal_usage_entry, 1]]
      ]
    ,
    'none'],
{ PARAMETER 6
    [[1, 0, clc$boolean_type],
    'false'],
{ PARAMETER 7
    [[1, 0, clc$status_type]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$location = 1,
      p$file = 2,
      p$data_declaration = 3,
      p$until = 4,
      p$substitution_mark = 5,
      p$ignore_remote_validation = 6,
      p$status = 7;

    VAR
      pvt: array [1 .. 7] of clt$parameter_value;

?? NEWTITLE := '    abort_handler', EJECT ??
*copyc cyd$run_time_error_condition
?? POP ??
?? TITLE := '  link_directive', EJECT ??

{
{   Inline code to link a string onto a link list of server directives.
{

    PROCEDURE [INLINE] link_directive;

      IF directive_ptr = NIL THEN
        PUSH directive_ptr: [line.size];
        directive_list_ptr := directive_ptr;
      ELSE
        PUSH directive_ptr^.link: [line.size];
        directive_ptr := directive_ptr^.link;
      IFEND;
      directive_ptr^.link := NIL;
      directive_ptr^.line := line.value (1, line.size);

    PROCEND link_directive;

?? OLDTITLE, EJECT ??

    CONST
      delete_allowed = FALSE,
      include_open_pos_in_handle = TRUE,
      resolve_path = FALSE;

    VAR
      caller_in_current_task: boolean,
      data_declaration: nft$parameter_31_type,
      directive_list_ptr: ^nft$directive_entry,
      directive_ptr: ^nft$directive_entry,
      explicit_remote_file: boolean,
      file_exists: boolean,
      get_attributes: array [1 .. 1] of amt$get_item,
      i: 1 .. nfc$max_validation_lines,
      ignore_file_contains_data: boolean,
      ignore_file_is_local: boolean,
      ignore_file_reference: fst$evaluated_file_reference,
      input_block_handle: clt$block_handle,
      input_executable: boolean,
      input_file_id: amt$file_identifier,
      interactive: boolean,
      line: ost$string,
      line_count: 0 .. nfc$max_validation_lines,
      local_status: ost$status,
      location_name: ost$name,
      new_line: ost$string,
      new_line_size: clt$command_line_size,
      path_handle_name: fst$path_handle_name,
      ptf_scl_directive: ost$string,
      scl_line: ^clt$command_line,
      string_value: ^ost$string,
      validation_ptr: ^array [1 .. * ] of string (osc$max_string_size),
      variable_value: clt$variable_reference,
      ve_server: nft$ve_to_ve_access;

    VAR
      mrf_prompt: [STATIC, READ, oss$job_paged_literal] string (5) := 'mrf? ';


    status.normal := TRUE;
    IF NOT jmp$system_job () THEN

      avp$get_capability (avc$explicit_remote_file, avc$user, explicit_remote_file, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF NOT explicit_remote_file THEN
        osp$set_status_abnormal (nfc$status_id, nfe$sou_invalid_user, 'MANAGE_REMOTE_FILES', status);
        RETURN;
      IFEND;
    IFEND;

    clp$evaluate_parameters (parameter_list, #SEQ(pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    CASE pvt [p$location].value^.kind OF
      =clc$name=
        location_name := pvt [p$location].value^.name_value;
      =clc$string=
        #TRANSLATE(osv$lower_to_upper, pvt [p$location].value^.string_value^, location_name);
    CASEND;

  /set_up_transfer/
    BEGIN
      IF pvt [p$data_declaration].specified THEN
        nfp$convert_p31_to_ordinal (pvt [p$data_declaration].value^.name_value, data_declaration, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      ELSE
        data_declaration := nfc$p31_unspecified;
      IFEND;

      directive_ptr := NIL;
      get_attributes [1].key := amc$file_contents;

      clp$convert_str_to_path_handle (pvt [p$file].value^.file_value^, delete_allowed,
        resolve_path, include_open_pos_in_handle, path_handle_name, ignore_file_reference,
        status);

      amp$get_file_attributes (path_handle_name, get_attributes, ignore_file_is_local,
            file_exists, ignore_file_contains_data, status);

      IF NOT (pvt [p$ignore_remote_validation].value^.boolean_value.value) THEN
        nfp$find_remote_validation (location_name, line_count, status);
        IF NOT status.normal THEN
          EXIT /set_up_transfer/;
        ELSEIF line_count = 0 THEN
          EXIT /set_up_transfer/;
        IFEND;

        PUSH validation_ptr: [1 .. line_count];
        nfp$get_remote_validation (location_name, validation_ptr, status);
        IF NOT status.normal THEN
          EXIT /set_up_transfer/;
        IFEND;

        FOR i := 1 TO line_count DO
          line.value := validation_ptr^ [i];
          line.size := nfp$string_length (line.value);
          link_directive;
          IF directive_ptr = NIL THEN
            RETURN;
          IFEND;
        FOREND;
      IFEND; { if prev. declared remote validations should be used.
    END /set_up_transfer/;

    local_status.normal := TRUE;

    IF NOT status.normal THEN
      clp$get_command_origin (interactive, local_status);
      IF interactive THEN
        RETURN;
      IFEND;
    IFEND;

    clp$push_input (clc$current_command_input, osc$null_name, '', FALSE, FALSE, input_block_handle,
          input_file_id, input_executable, local_status);
    IF NOT (local_status.normal) THEN
      IF status.normal THEN
        status := local_status;
      IFEND;
      RETURN;
    IFEND;

  /collect_directives/
    WHILE TRUE DO
      clp$get_line_from_command_file (mrf_prompt, scl_line, local_status);
      IF status.normal AND (NOT local_status.normal) THEN
        status := local_status;
      IFEND;
      IF NOT local_status.normal THEN
        EXIT /collect_directives/;
      ELSEIF scl_line = NIL THEN
        IF status.normal THEN
          osp$set_status_abnormal (nfc$status_id, nfe$encountered_eoi, 'MANAGE_REMOTE_FILES', status);
        IFEND;
        EXIT /collect_directives/;
      ELSEIF (STRLENGTH (scl_line^) = STRLENGTH (pvt [p$until].value^.string_value^ )) AND
               (scl_line^ = pvt [p$until].value^.string_value^) THEN
        EXIT /collect_directives/;
      ELSEIF STRLENGTH (scl_line^) = 0 THEN
        CYCLE /collect_directives/;
      ELSE
        IF STRLENGTH (scl_line^) <= osc$max_string_size THEN
          line.value := scl_line^;
          line.size := STRLENGTH (scl_line^);
          IF pvt [p$substitution_mark].value^.kind = clc$string THEN
            clp$substitute_delimited_text (line.value (1, line.size),
              pvt [p$substitution_mark].value^.string_value^(1), new_line.value, new_line_size, local_status);
            IF local_status.normal THEN
              IF new_line_size > osc$max_string_size THEN
                osp$set_status_abnormal (nfc$status_id, cle$string_too_long, 'FOR SUBSTITUTION', local_status);
              ELSE
                new_line.size := new_line_size;
                line := new_line;
              IFEND;
            IFEND;
          IFEND;
        ELSE
          osp$set_status_abnormal (nfc$status_id, cle$string_too_long, 'FOR MANAGE_REMOTE_FILES',
                local_status);
        IFEND;
        IF local_status.normal THEN
          link_directive;
        ELSE
          IF status.normal THEN
            status := local_status;
          IFEND;
          RETURN;
        IFEND;
      IFEND;
    WHILEND /collect_directives/;

    clp$pop_input (TRUE, input_block_handle, input_file_id, input_executable, NIL, local_status);

    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF directive_ptr = NIL THEN
      osp$set_status_abnormal (nfc$status_id, nfe$directives_missing, 'MANAGE_REMOTE_FILES', status);
      RETURN
    IFEND;

{ Get parameter }

    build_ptfi_scl_command('manage_remote_files', ptf_scl_directive, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    ve_server.ve_server := FALSE;
    access_remote_file (location_name, path_handle_name, data_declaration,
          directive_list_ptr, ve_server, ptf_scl_directive, status);

  PROCEND nfp$manage_remote_files;

?? OLDTITLE ??
?? NEWTITLE := 'build_ptfi_scl_command', EJECT ??
{
{     The purpose of this procedure is to create an OST$STRING which
{  contains the command and parameter list used to start this task.
{
{       NFP$BUILD_PTFI_SCL_COMMAND( COMMAND, SCL_COMMAND, STATUS);
{
{ COMMAND : (input) Initiating command name.
{
{ SCL_COMMAND : (output) Output string containing command and parameters
{     used to start this PTF task.
{
{ STATUS: (output) This parameter specifies the request status.
{     CONDITIONS:
{       Any from clp$get_parameter_list.
{
  PROCEDURE build_ptfi_scl_command
      (      command: string(*<=osc$max_string_size);
        VAR  scl_command: ost$string;
        VAR  status: ost$status);

VAR
      input_command_length: ost$string_size,
      parameter_list: ost$string;

status.normal := TRUE;
clp$get_parameter_list( parameter_list, status);
IF NOT status.normal THEN
  RETURN;
IFEND;
input_command_length := STRLENGTH(command);
scl_command.value := command;
scl_command.size := input_command_length + 2;
input_command_length := scl_command.size;
IF parameter_list.size > 0 THEN
  scl_command.value(scl_command.size,*) := parameter_list.value(1,parameter_list.size);
  IF (parameter_list.size + scl_command.size > osc$max_string_size) THEN
    scl_command.size := osc$max_string_size;
  ELSE
    scl_command.size := scl_command.size + parameter_list.size;
  IFEND;
IFEND;

  PROCEND build_ptfi_scl_command;
?? OLDTITLE ??
MODEND nfm$ptf_client;
