?? RIGHT := 110 ??
?? NEWTITLE := 'NFM$NTF_FILE_TRANSFER_PROCS' ??
MODULE nfm$ntf_file_transfer_procs;

{ PURPOSE:
{   This module contains procedures used by the Network Transfer Facility
{   (NTF) to receive and transmit files on a connection as well as
{   miscellaneous procedures and functions.
{
{ DESIGN:
{   The protocol routines provide the processing to support EBCDIC file
{   transfers to/from  either HASP or NJE remote systems.
{   The routines in this module are listed in alphabetical order.

?? NEWTITLE := 'Global Declarations References by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc nft$control_block
*copyc nft$parameter_17_definition
*copyc nft$parameter_32_b101_text
*copyc nft$parameter_58_b101_text
*copyc nft$parameter_set
?? POP ??
*copyc amp$get_next
*copyc amp$put_next
*copyc amp$return
*copyc clp$convert_string_to_file
*copyc clp$include_line
*copyc clp$read_variable
*copyc clp$trimmed_string_size
*copyc fsp$close_file
*copyc fsp$open_file
*copyc pmp$continue_to_cause
*copyc pmp$establish_condition_handler
*copyc pmp$get_unique_name
?? TITLE := 'Global Declarations Declared by This Module', EJECT ??

  CONST
    nfc$ntf_debug_library_variable = 'NFV$NTF_DEBUG_LIBRARY',
    nfc$receive_ntf_file_command_1 = 'EXECUTE_TASK L=(',
    nfc$receive_ntf_file_command_2 = ',$SYSTEM.BATCH_DEVICE_SUPPORT.OSF$BATCH_DEVICE_SUPPORT) ' CAT
          'SP=NFP$RECEIVE_NTF_FILE P=''',
    nfc$receive_ntf_file_command_3 = '''',
    nfc$system_library_path = '$SYSTEM.NETWORK_TRANSFER_FACILITY.BOUND_PRODUCT';

?? TITLE := 'get_library_path', EJECT ??

{ PURPOSE:
{   This procedure determines which library should be used for NTF receive file
{   processing.  If the SCL variable NFV$NTF_DEBUG_LIBRARY is defined with a
{   file name, that file name is used for the library.  Otherwise, the file
{   name $SYSTEM.NETWORK_TRANSFER_FACILITY.BOUND_PRODUCT is used for the
{   library.

  PROCEDURE get_library_path
    (VAR library_path: ost$string;
     VAR status: ost$status);

    VAR
      convert_status: ost$status,
      convert_string: ost$string,
      file: clt$file,
      read_status: ost$status,
      variable: clt$variable_reference;

    status.normal := TRUE;
    library_path.value := nfc$system_library_path;
    library_path.size := clp$trimmed_string_size (library_path.value);
    clp$read_variable (nfc$ntf_debug_library_variable, variable, read_status);
    IF read_status.normal AND (variable.value.kind = clc$string_value) AND (variable.lower_bound = 1) AND
          (variable.upper_bound = 1) AND (variable.value.max_string_size = osc$max_string_size) AND (#SIZE
          (variable.value.string_value^) = #SIZE (library_path)) THEN
      #UNCHECKED_CONVERSION (variable.value.string_value^, convert_string);
      clp$convert_string_to_file (convert_string.value (1, convert_string.size), file, convert_status);
      IF convert_status.normal THEN
        library_path := convert_string;
      IFEND;
    IFEND;
  PROCEND get_library_path;
?? TITLE := '[XDCL] NFP$NTF_RECEIVE_FILE', EJECT ??
*copy nfh$ntf_receive_file

  PROCEDURE [XDCL] nfp$ntf_receive_file
    (VAR control_block: nft$control_block;
     VAR p17_param: nft$parameter_17_definition;
     VAR p32_params: nft$p32_b101_ntf_params;
     VAR p58_params: nft$p58_b101_ntf_params;
     VAR stopr_params: nft$parameter_set;
     VAR queue_status: ost$status;
     VAR status: ost$status);

    VAR
      byte_address: amt$file_byte_address,
      command: string (osc$max_string_size),
      establish_descriptor: pmt$established_handler,
      file_identifier: amt$file_identifier,
      file_position: amt$file_position,
      input: amt$local_file_name,
      library_path: ost$string,
      output: amt$local_file_name,
      transfer_count: amt$transfer_count;

    VAR
      conditions: [READ] pmt$condition := [pmc$all_conditions];

?? NEWTITLE := 'handle_conditions', EJECT ??

    PROCEDURE handle_conditions
      (    condition: pmt$condition;
           condition_descriptor: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      fsp$close_file (file_identifier, ignore_status);
      amp$return (input, ignore_status);
      amp$return (output, ignore_status);
      IF (NOT status.normal) AND queue_status.normal THEN
        queue_status := status;
      IFEND;

      status.normal := TRUE;
      pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
    PROCEND handle_conditions;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    pmp$get_unique_name (input, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    pmp$get_unique_name (output, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    command := nfc$receive_ntf_file_command_1;
    get_library_path (library_path, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    command (clp$trimmed_string_size (command) + 1, * ) := library_path.value (1, library_path.size);
    command (clp$trimmed_string_size (command) + 1, * ) := nfc$receive_ntf_file_command_2;
    command (clp$trimmed_string_size (command) + 1, * ) := input;
    command (clp$trimmed_string_size (command) + 2, * ) := output;
    command (clp$trimmed_string_size (command) + 1, * ) := nfc$receive_ntf_file_command_3;
    pmp$establish_condition_handler (conditions, ^handle_conditions, ^establish_descriptor, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    fsp$open_file (input, amc$record, NIL, NIL, NIL, NIL, NIL, file_identifier, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$put_next (file_identifier, ^control_block, #SIZE (control_block), byte_address, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$put_next (file_identifier, ^p17_param, #SIZE (p17_param), byte_address, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$put_next (file_identifier, ^p32_params, #SIZE (p32_params), byte_address, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$put_next (file_identifier, ^p58_params, #SIZE (p58_params), byte_address, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$put_next (file_identifier, ^stopr_params, #SIZE (stopr_params), byte_address, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$put_next (file_identifier, ^queue_status, #SIZE (queue_status), byte_address, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    fsp$close_file (file_identifier, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    clp$include_line (command, FALSE, osc$null_name, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$return (input, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    fsp$open_file (output, amc$record, NIL, NIL, NIL, NIL, NIL, file_identifier, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$get_next (file_identifier, ^control_block, #SIZE (control_block), transfer_count, byte_address,
          file_position, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$get_next (file_identifier, ^p17_param, #SIZE (p17_param), transfer_count, byte_address, file_position,
          status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$get_next (file_identifier, ^p32_params, #SIZE (p32_params), transfer_count, byte_address,
          file_position, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$get_next (file_identifier, ^p58_params, #SIZE (p58_params), transfer_count, byte_address,
          file_position, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$get_next (file_identifier, ^stopr_params, #SIZE (stopr_params), transfer_count, byte_address,
          file_position, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$get_next (file_identifier, ^queue_status, #SIZE (queue_status), transfer_count, byte_address,
          file_position, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    fsp$close_file (file_identifier, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    amp$return (output, status);
  PROCEND nfp$ntf_receive_file;
MODEND nfm$ntf_file_transfer_procs;
