?? RIGHT := 110 ??
MODULE ifm$get_terminal_attributes;
?? TITLE := 'MODULE ifm$get_terminal_attributes' ??

?? PUSH (LISTEXT := ON) ??
*copyc AMT$LOCAL_FILE_NAME
*copyc fst$file_reference
*copyc ife$error_codes
*copyc IFK$KEYPOINTS
*copyc ift$terminal_attributes
*copyc OST$STATUS
?? POP ??

*copyc clp$validate_name
*copyc clp$get_ultimate_connection
*copyc clv$standard_files
*copyc IIP$GET_TERMINAL_ATTRIBUTES
*copyc iip$st_get_terminal_attributes
*copyc iiv$connection_desc_ptr
*copyc iiv$interactive_terminated
*copyc iip$xlate_local_file_to_session
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
*copyc pmp$get_job_mode
*copyc rmp$get_device_class

?? NEWTITLE := 'PROCEDURE ifp$get_terminal_attributes', EJECT ??
*copyc ifh$get_terminal_attributes
  PROCEDURE [XDCL, #GATE {TS_gate} ] ifp$get_terminal_attributes
    (terminal_file_name: fst$file_reference;
    VAR terminal_attributes: ift$terminal_attributes;
    VAR status: ost$status);

   VAR
      attributes_mapped: integer,
      converted_name: ost$name,
      device_assigned: boolean,
      device_class: rmt$device_class,
      device_is_network: boolean,
      i: integer,
      internal_file_name: amt$local_file_name,
      j: integer,
      job_mode: jmt$job_mode,
      local_status: ost$status,
      map: ^array [1 .. * {ifc$max_terminal_attribute_key}] OF integer,
      mapped_attributes: ^ift$terminal_attributes,
      temp_file_name: ost$name,
      ultimate_name: amt$local_file_name,
      valid_name: boolean,
      validated_terminal_file_name: ost$name;

    status.normal := TRUE;
    #KEYPOINT (osk$entry, 0, ifk$get_terminal_attributes);

  /get_terminal_attributes/
    BEGIN
      IF STRLENGTH (terminal_file_name) <= osc$max_name_size THEN
        internal_file_name := terminal_file_name;
      ELSE
        osp$set_status_abnormal (ifc$interactive_facility_id,
              ife$file_name_ill_formed, terminal_file_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter,
          'IFP$GET_TERMINAL_ATTRIBUTES', status);
        EXIT /get_terminal_attributes/;
      IFEND;

    { Convert and validate the file name.

      clp$get_ultimate_connection (internal_file_name, ultimate_name, status);
      IF NOT status.normal THEN
        EXIT /get_terminal_attributes/;
      IFEND;
      clp$validate_name (ultimate_name, converted_name, valid_name);
      IF NOT valid_name THEN
        osp$set_status_abnormal (ifc$interactive_facility_id,
              ife$file_name_ill_formed, internal_file_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter,
          'IFP$GET_TERMINAL_ATTRIBUTES', status);
        EXIT /get_terminal_attributes/;
      IFEND;

      CASE iiv$network_identifier OF
      = iic$cdcnet_network =

      { STANDALONE }
      { Verify that the terminal file exists and that it is a network file.

        validated_terminal_file_name := converted_name;
        rmp$get_device_class (validated_terminal_file_name, device_assigned, device_class,
              status);
        IF NOT status.normal THEN
          EXIT /get_terminal_attributes/;
        IFEND;
        device_is_network := (device_class = rmc$network_device) OR (device_class = rmc$terminal_device);

        IF NOT device_is_network THEN
          pmp$get_job_mode (job_mode, local_status);
          IF NOT local_status.normal THEN
            status := local_status;
            EXIT /get_terminal_attributes/;
          ELSEIF (NOT (job_mode IN $iit$job_modes [jmc$interactive_connected,
                 jmc$interactive_cmnd_disconnect, jmc$interactive_line_disconnect,
                 jmc$interactive_sys_disconnect]) AND
                 (((ultimate_name = clv$standard_files [clc$sf_job_input_file].path_handle_name) OR
                 (ultimate_name = clv$standard_files [clc$sf_job_output_file].path_handle_name)) OR
                 (ultimate_name = clv$standard_files [clc$sf_command_file].path_handle_name))) THEN
            osp$set_status_abnormal (ifc$interactive_facility_id,
                 ife$current_job_not_interactive, 'IFP$GET_TERMINAL_ATTRIBUTES',
                 status);
            EXIT /get_terminal_attributes/;
          ELSE
            osp$set_status_abnormal (ifc$interactive_facility_id,
                ife$file_name_not_terminal, converted_name, status);
            EXIT /get_terminal_attributes/;
          IFEND;
        IFEND;

        attributes_mapped := 0;
        FOR i:=1 to UPPERBOUND(terminal_attributes) DO
          CASE terminal_attributes [i].key OF
          = ifc$pause_break_character, ifc$terminal_class, ifc$terminate_break_character =

          ELSE
            attributes_mapped := attributes_mapped + 1;
          CASEND;
        FOREND;

        IF attributes_mapped <> 0 THEN
          PUSH map :[1 .. attributes_mapped];
          PUSH mapped_attributes :[1 .. attributes_mapped];
        IFEND;

        j := 0;
        FOR i:=1 to UPPERBOUND (terminal_attributes) DO
          CASE terminal_attributes [i].key OF
          = ifc$pause_break_character, ifc$terminal_class,
            ifc$terminate_break_character =
            terminal_attributes [i].key := ifc$null_terminal_attribute;

          ELSE
          j := j + 1;
          map^ [j] := i;
          mapped_attributes^ [j] := terminal_attributes [i];
          CASEND;
        FOREND;

        IF attributes_mapped > 0 THEN

          iip$st_get_terminal_attributes (ultimate_name, mapped_attributes^, status);

          FOR j:=1 to attributes_mapped DO
            terminal_attributes [map^ [j]] := mapped_attributes^ [j];
          FOREND;

        IFEND;

      = iic$dsiaf_network =

      { DUAL STATE }

      { Verify that the file is assigned to a terminal device.

        rmp$get_device_class (converted_name, device_assigned, device_class,
              local_status);
        IF NOT local_status.normal THEN
          status := local_status;
          EXIT /get_terminal_attributes/;
        ELSE
          IF device_class <> rmc$terminal_device THEN
            pmp$get_job_mode (job_mode, local_status);
            IF NOT local_status.normal THEN
              status := local_status;
              EXIT /get_terminal_attributes/;
            ELSEIF (NOT (job_mode IN $iit$job_modes [jmc$interactive_connected,
                   jmc$interactive_cmnd_disconnect, jmc$interactive_line_disconnect,
                   jmc$interactive_sys_disconnect]) AND
                   (((ultimate_name = clv$standard_files [clc$sf_job_input_file].path_handle_name) OR
                   (ultimate_name = clv$standard_files [clc$sf_job_output_file].path_handle_name)) OR
                   (ultimate_name = clv$standard_files [clc$sf_command_file].path_handle_name))) THEN
              osp$set_status_abnormal (ifc$interactive_facility_id,
                   ife$current_job_not_interactive, 'IFP$GET_TERMINAL_ATTRIBUTES',
                   status);
              EXIT /get_terminal_attributes/;
            ELSE
              osp$set_status_abnormal (ifc$interactive_facility_id,
                    ife$file_name_not_terminal, converted_name, status);
              osp$append_status_parameter (osc$status_parameter_delimiter,
                'IFP$GET_TERMINAL_ATTRIBUTES', status);
              EXIT /get_terminal_attributes/;
            IFEND;
          IFEND;
        IFEND;

        IF NOT iiv$cdcnet_connection THEN

        { For those attributes which are ignored in dual state 255x connections,
        { replace their keys in terminal_attributes with ifc$null_terminal_attribute.

          FOR i := 1 TO UPPERBOUND (terminal_attributes) DO
            CASE terminal_attributes [i].key OF
            = ifc$attention_character, ifc$begin_line_character, ifc$carriage_return_sequence,
              ifc$code_set, ifc$end_page_action, ifc$form_feed_delay, ifc$form_feed_sequence,
              ifc$hold_page_over, ifc$line_feed_sequence,
              ifc$control_code_replacement, ifc$function_key_class =

              terminal_attributes [i].key := ifc$null_terminal_attribute;
            ELSE
            { All other attributes will have their values returned.
            CASEND;

          FOREND;

        ELSE

          FOR i := 1 TO UPPERBOUND (terminal_attributes) DO
            CASE terminal_attributes [i].key OF
            = ifc$control_code_replacement, ifc$line_feed_sequence =

              terminal_attributes [i].key := ifc$null_terminal_attribute;
            ELSE
            { All other attributes will have their values returned.
            CASEND;
          FOREND;
        IFEND;

        iip$get_terminal_attributes (terminal_attributes, status);

      ELSE

      CASEND;

    END /get_terminal_attributes/;

    #KEYPOINT (osk$exit, 0, ifk$get_terminal_attributes);

  PROCEND ifp$get_terminal_attributes;

MODEND ifm$get_terminal_attributes;
