?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE SCL Interpreter : Access Command File' ??
MODULE clm$access_command_file;

{
{ PURPOSE:
{   This module contains a procedure to test command file attributes and
{ open the command file.
{

?? NEWTITLE := 'Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*IF NOT $true(osv$unix)
*copyc ame$lfn_program_actions
*copyc ame$open_validation_errors
*IFEND
*copyc clc$standard_file_names
*copyc cle$ecc_command_processing
*copyc cle$ecc_miscellaneous
*copyc clt$command_file_kind
*copyc clt$file_contents
*IF $true(osv$unix)
*copyc cyt$mips_signal_handler
*ELSE
*copyc ost$caller_identifier
*IFEND
?? POP ??
*IF NOT $true(osv$unix)
*copyc amp$get_file_attributes
*copyc amp$set_local_name_abnormal
*IFEND
*copyc amv$nil_file_identifier
*IF NOT $true(osv$unix)
*copyc bap$get_phn_via_file_id
*IFEND
*copyc clp$close_command_file
*copyc clp$determine_line_layout
*copyc clp$open_command_file
*copyc clp$open_executable_cmnd_file
*copyc clp$trimmed_string_size
*IF NOT $true(osv$unix)
*copyc clv$standard_files
*copyc fsp$convert_to_new_contents
*copyc fsp$set_file_reference_abnormal
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*IFEND
*copyc fsp$get_open_information
*copyc osp$set_status_abnormal
*IF NOT $true(osv$unix)
*copyc pmf$job_mode
*copyc rmp$get_device_class
*ELSE
*copyc ame$condition_codes
*IFEND

?? TITLE := 'clp$access_command_file', EJECT ??
*IF NOT $true(osv$unix)
{
{   The purpose of this request is to open the command file if necessary and execute
{ file attribute tests other than those performed during open validation or if an open
{ request was never issued.  The command file will be closed if a test fails and the
{ file was opened.
{
{   The access modes for opening a command file are as follows:
{ 1. the command file may be opened as a readable file,
{ 2. the command file may be opened as an executable file in ring 3 or lower,
{ 3. an attempt is made to open the command file as a readable file if the
{    caller ring is higher than 3.  If that attempt fails, another attempt
{    is made to open the file in ring 3 as an executable file.
{ All command files are opened except for the command file kind of
{ clc$command_catalog that is found to be an object file or an object library.
{
{   A description of available tests is listed below:
{ COMMAND_FILE_TEST -
{   include_file:               file contents = legible_scl_include, legible_data, legible, data or unknown
{                            OR
{                               file contents = legible_scl_job, legible_data, legible, data or unknown
{
{   object_library:             file contents = object_library
{
{   proc_or_object_file_or_lib: file contents = legible_scl_procedure, legible_data, legible, data or unknown
{                            OR
{                               file contents = object_library or object_data
{
{ FILE_ORGANIZATION_TEST (boolean) -
{   TRUE:                       file_organization = sequential,
{                               (record type <> undefined OR block type = user specified).
{
{ CALLABLE_FILE_TEST -
{   (This test is not performed if the command file is opened as a readable_file.)
{   call_bracket:               caller_ring <= r3,
{
{   execute_bracket:            caller_ring >= r1,
{                               caller ring <= r2.
{
{ EXECUTE_ACCESS_TEST (boolean) -
{   TRUE:                       access mode includes execute.
{
{ FAP_NOT_ALLOWED_TEST (boolean) -
{   TRUE:                       file access procedure = none.
{
{   NOTE: A test has not been created for an allowable fap associated with a command file.
{         The attribute requirements for this instance are automatically validated during the
{         opening of the command file with one exception.  The exception is the caller ring is
{         ring 3 and the command file access mode does not include read.  The actual requirements
{         for an allowable fap associated with a command file are the caller ring <= r2 and the
{         access mode includes read.
{
{
{   Listed below for each kind of command file is the access mode option and the test settings
{   before the open is performed.
{ CLC$INCLUDE_FILE -
{   access mode option:     readable or executable, executable
{   command_file_test:      include_file, none
{   file_organization_test: TRUE
{   callable_file_test:     execute_bracket, none
{   execute_access_test:    FALSE
{   fap_not_allowed_test:   FALSE
{
{   IF the command file name is 'COMMAND' the access mode option will be executable.  The
{   command_file_test and the callable_file_test are set to none.  Otherwise the access
{   mode option will be readable or executable, the command_file_test is set to include_file,
{   and the callable_file_test is set to execute_bracket.
{   Access level is assumed record.
{
{ CLC$INCF_SEGMENT_CALLER_FILE -                                CLC$INCF_RECORD_CALLER_FILE -
{   access mode option:     readable or executable, executable    readable or executable, executable
{   command_file_test:      none                                   none
{   file_organization_test: FALSE                                 TRUE
{   callable_file_test:     execute_bracket, none                 execute_bracket, none
{   execute_access_test:    FALSE                                 FALSE
{   fap_not_allowed_test:   FALSE                                 FALSE
{
{   Access level is assumed segment.                              Access level is assumed record.
{
{   These two kinds of command files reference a file by $COMMAND or $COMMAND_OF_CALLER.
{   IF the command file name is 'COMMAND' the access mode option will be executable.  And the
{   callable_file_test is set to none.  Otherwise the access mode option will be readable or
{   executable.  AND the callable_file_test is set to execute_bracket.
{
{ CLC$GET_FILE -
{   access mode option:     readable
{   command_file_test:      none
{   file_organization_test: TRUE
{   callable_file_test:     none
{   execute_access_test:    FALSE
{   fap_not_allowed_test:   FALSE
{
{   Access level is assumed record.
{
{ CLC$GET_SEGMENT_CALLER_FILE -                                 CLC$GET_RECORD_CALLER_FILE -
{   access mode option:     readable                              readable
{   command_file_test:      none                                  none
{   file_organization_test: FALSE                                 TRUE
{   callable_file_test:     none                                  none
{   execute_access_test:    FALSE                                 FALSE
{   fap_not_allowed_test:   FALSE                                 FALSE
{
{   Access level is assumed segment.                              Access level is assumed record.
{
{   These two kinds of command files reference a file by $COMMAND or $COMMAND_OF_CALLER.
{
{ CLC$CATALOG_COMMAND -
{   access mode option:     executable, none
{   command_file_test:      proc_or_object_file_or_lib
{   file_organization_test: TRUE,FALSE
{   callable_file_test:     call_bracket, execute_bracket
{   execute_access_test:    TRUE,FALSE
{   fap_not_allowed_test:   TRUE
{
{   If the command_file_test has determined that the command file is an SCL proc the
{   access mode option will be executable, the access level is assumed record, the
{   file_organization_test is set to TRUE, the execute_access_test is set to FALSE, and the
{   callable_file_test is set to execute_bracket because, currently, there is no "ring switch"
{   for procs.  Otherwise the file is not opened, the access level is assumed segment, the
{   file_organization_test is set to FALSE, the execute_access_test is set to TRUE, and the
{   callable_file_test is set to call_bracket.
{
{ CLC$COMMAND_LIBRARY -
{   access mode option:     executable
{   command_file_test:      object_library
{   file_organization_test: FALSE
{   callable_file_test:     none
{   execute_access_test:    FALSE
{   fap_not_allowed_test:   TRUE
{
{   Access level is assumed segment.
{
{ CLC$SUBMIT_JOB -
{   access mode option:     executable
{   command_file_test:      include_file
{   file_organization_test: TRUE
{   callable_file_test:     call_bracket
{   execute_access_test:    FALSE
{   fap_not_allowed_test:   TRUE
{
{   Access level is assumed record.
{
{
{
{   Listed below are the output parameters that are set for each kind of command file:
{ CLC$INCLUDE_FILE, CLC$GET_FILE -
{   file_id, segment, opened_executable_file, can_be_echoed, line_layout, ring_attributes, file_has_fap,
{         open_path_handle_name.
{
{ CLC$INCF_SEGMENT_CALLER_FILE, CLC$INCF_RECORD_CALLER_FILE,
{ CLC$GET_SEGMENT_CALLER_FILE, CLC$GET_RECORD_CALLER_FILE -
{   file_id, segment, opened_executable_file, ring_attributes, file_has_fap, open_path_handle_name.
{
{ CLC$CATALOG_COMMAND -
{   file_contents, ring_attributes, file_has_fap,
{   IF the command file is an SCL PROC (file_contents.is_object = FALSE)
{     file_id, segment, opened_executable_file, can_be_echoed, line_layout, open_path_handle_name.
{
{ CLC$COMMAND_LIBRARY -
{   file_id, segment, opened_executable_file, can_be_echoed, ring_attributes, file_has_fap,
{         open_path_handle_name.
{
{ CLC$SUBMIT_JOB -
{   file_id, segment, opened_executable_file, can_be_echoed, line_layout, ring_attributes, file_has_fap,
{         open_path_handle_name.
{
{
{       CLP$ACCESS_COMMAND_FILE (COMMAND_FILE, SUBMITTER_RING, FILE_REFERENCE, FILE_ID,
{         SEGMENT, OPENED_EXECUTABLE_FILE, CAN_BE_ECHOED, LINE_LAYOUT, FILE_CONTENTS_IS_OBJECT,
{         RING_ATTRIBUTES, FILE_HAS_FAP, OPEN_PATH_HANDLE_NAME, DEVICE_CLASS, STATUS);
{
{ COMMAND_FILE: (input) This parameter specifies the command file kind.
{
{ SUBMITTER_RING: (input) This parameter specifies the submitted ring for validation.
{
{ FILE_REFERENCE: (input) This parameter specifies the file reference of the command file.  The file
{       reference must not be a relative path because this routine calls procedures (ie. fsp$open_file,
{       amp$get_file_attributes) which assume $LOCAL as the working catalog rather than using the actual
{       catalog.
{       If the file is the standard command file, then its path_handle_name must be passed instead.
{
{ FILE_ID: (output) This parameter specifies the file id after opening the command file.
{
{ SEGMENT: (output) This parameter specifies the segment address after opening the command file.
{
{ OPENED_EXECUTABLE_FILE: (output) This parameter specifies if the commmand file was opened as
{         an executable file (opened in ring 3) or the file was opened at the caller ring level.
{
{ CAN_BE_ECHOED: (output) This parameter specifies if the command file can be echoed.
{
{ LINE_LAYOUT: (output) This parameter specifes the line layout of the command file.
{
{ FILE_CONTENTS: (output) This parameter specifies if the file contents attribute is object
{         and if the path exists.
{
{ RING_ATTRIBUTES: (output) This parameter specifies the ring attributes of the command file.
{
{ FILE_HAS_FAP: (output) This parameter specifies whether the file has a FAP associated with it.
{
{ DEVICE_CLASS: (output) This parameter specifies the device class of the command file.
{
{ OPEN_PATH_HANDLE_NAME: (output) This parameter specifies the path handle name of the opened file.
{
{ STATUS: (output) This parameter specifes the request status.
{
*IFEND

  PROCEDURE [XDCL] clp$access_command_file
    (    command_file: clt$command_file_kind;
*IF NOT $true(osv$unix)
         submitter_ring: ost$ring;
*IFEND
         file_reference: fst$file_reference;
     VAR file_id: amt$file_identifier;
     VAR segment: ^SEQ ( * );
     VAR opened_executable_file: boolean;
     VAR can_be_echoed: boolean;
     VAR line_layout: clt$line_layout;
*IF NOT $true(osv$unix)
     VAR file_contents: clt$file_contents;
     VAR ring_attributes: amt$ring_attributes;
     VAR file_has_fap: boolean;
*IFEND
     VAR device_class: rmt$device_class;
*IF NOT $true(osv$unix)
     VAR open_path_handle_name: fst$path_handle_name;
*ELSE
     VAR open_path_handle_name: fst$path;
*IFEND
     VAR status: ost$status);

?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
*IF $true(osv$unix)
      (    signal_no: integer;
           code: integer;
           p_sigcontext: ^cyt$mips_sigcontext);
*ELSE
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);
*IFEND

*IF NOT $true(osv$unix)
      clp$close_command_file (file_id, opened_executable_file, handler_status);
      handler_status.normal := TRUE;
*IFEND

    PROCEND abort_handler;
*IF NOT $true(osv$unix)
?? TITLE := 'establish_incf_caller_tests', EJECT ??

    PROCEDURE [INLINE] establish_incf_caller_tests;


      IF (job_mode = jmc$batch) AND (file_reference = clv$standard_files [clc$sf_command_file].
            path_handle_name) THEN
        open_executable_cmnd_file := TRUE;
        exec_cmnd_file_access_options := all_options;
        callable_file_test := no_callable_file_test;
      ELSE
        open_command_file := TRUE;
        cmnd_file_access_options := one_option_read;
        open_executable_cmnd_file := TRUE;
        exec_cmnd_file_access_options := one_option_execute;
        callable_file_test := execute_bracket;
      IFEND;

      command_file_test := no_command_file_test;
      execute_access_test := FALSE;
      fap_not_allowed_test := FALSE;
      fetch_attributes := TRUE;
      caller_file := TRUE;

    PROCEND establish_incf_caller_tests;
?? TITLE := 'establish_get_file_tests', EJECT ??

    PROCEDURE [INLINE] establish_get_file_tests;


      IF (command_file <> clc$get_file) AND (caller_id.ring > osc$tsrv_ring) AND (job_mode = jmc$batch) AND
            (file_reference = clv$standard_files [clc$sf_command_file].path_handle_name) THEN
        open_executable_cmnd_file := TRUE;
        exec_cmnd_file_access_options := one_option_read;
      ELSE
        open_command_file := TRUE;
        cmnd_file_access_options := one_option_read;
      IFEND;

      command_file_test := no_command_file_test;
      callable_file_test := no_callable_file_test;
      execute_access_test := FALSE;
      fap_not_allowed_test := FALSE;
      fetch_attributes := TRUE;

    PROCEND establish_get_file_tests;
*IFEND
?? TITLE := 'determine_open_choices', EJECT ??

    PROCEDURE [INLINE] determine_open_choices;


*IF NOT $true(osv$unix)
      IF caller_id.ring > osc$tsrv_ring THEN
        open_executable_cmnd_file := TRUE;
        exec_cmnd_file_access_options := two_options_read_exec_or_exec;
      ELSE
*IFEND
        open_command_file := TRUE;
        cmnd_file_access_options := two_options_read_exec_or_exec;
*IF NOT $true(osv$unix)
      IFEND;
*IFEND

    PROCEND determine_open_choices;
?? TITLE := 'establish_file_access_modes', EJECT ??

    PROCEDURE [INLINE] establish_file_access_modes
      (    file_access_options: access_options);


      CASE file_access_options OF
      = one_option_read =
        file_access_modes [1] := $fst$file_access_options [fsc$read];
        file_access_modes [2] := $fst$file_access_options [];
        file_access_modes [3] := $fst$file_access_options [];

      = one_option_execute =
        file_access_modes [1] := $fst$file_access_options [fsc$execute];
        file_access_modes [2] := $fst$file_access_options [];
        file_access_modes [3] := $fst$file_access_options [];

      = two_options_read_exec_or_exec =
        file_access_modes [1] := $fst$file_access_options [fsc$read, fsc$execute];
        file_access_modes [2] := $fst$file_access_options [fsc$execute];
        file_access_modes [3] := $fst$file_access_options [];

      ELSE
        file_access_modes [1] := $fst$file_access_options [fsc$read, fsc$execute];
        file_access_modes [2] := $fst$file_access_options [fsc$execute];
        file_access_modes [3] := $fst$file_access_options [fsc$read];

      CASEND;

    PROCEND establish_file_access_modes;
?? OLDTITLE, EJECT ??

    CONST

{ The constants defined below represent the number of attribute validation
{ selections needed for a particular test as listed:
{ command_file_test/include_file = 5,
{ command_file_test/object_library = 1,
{ file_organization_test = 1,
{ fap_not_allowed_test = 1.

      include_file_selections = 5,
      object_library_selections = 1,
      file_organization_selections = 1,
      fap_selections = 1,

{ The following constants represent the number of attribute validation
{ selections needed for open validation for each kind of command file.
{ The number of validation selections for a file is determined by the
{ required testing for that file.

      select_incf_file_org_fap = include_file_selections + file_organization_selections + fap_selections,
      select_incf_file_org = include_file_selections + file_organization_selections,
      select_object_lib_fap = object_library_selections + fap_selections,
      select_file_org_fap = file_organization_selections + fap_selections,
      select_file_org = file_organization_selections,
      no_selections = 0;

    TYPE
      access_options = (one_option_read, one_option_execute, two_options_read_exec_or_exec, all_options);

    VAR
      access_level: amc$record .. amc$segment,
      allowed_device_classes: fst$device_classes,
*IF NOT $true(osv$unix)
      attachment_information: fst$attachment_information,
*IFEND
      attribute_count: 1 .. 2,
      attribute_index: no_selections .. select_incf_file_org_fap,
      attribute_validation: ^fst$file_cycle_attributes,
      callable_file_test: (no_callable_file_test, execute_bracket, call_bracket),
      caller_file: boolean,
*IF NOT $true(osv$unix)
      caller_id: ost$caller_identifier,
      catalog_information: fst$catalog_information,
*IFEND
      cmnd_file_access_options: access_options,
      command_file_test: (no_command_file_test, include_file, object_library, proc_or_object_file_or_lib),
*IF NOT $true(osv$unix)
      cycle_attribute_sources: fst$cycle_attribute_sources,
      cycle_attribute_values: fst$cycle_attribute_values,
*IFEND
      device_assigned: boolean,
      exec_cmnd_file_access_options: access_options,
      execute_access_test: boolean,
      existing_file: boolean,
      fap_not_allowed_test: boolean,
*IF NOT $true(osv$unix)
      fap_null_name: pmt$entry_point_reference,
*IFEND
      fetch_attributes: boolean,
      file_access_modes: clt$command_file_access_modes,
      file_organization_test: boolean,
*IF NOT $true(osv$unix)
      fs_file_contents: amt$file_contents,
      get_attributes: array [1 .. 11] of amt$get_item,
*ELSE
      handler_established: boolean,
*IFEND
*IF NOT $true(osv$unix)
      ignore_contains_data: boolean,
      ignore_file_contents_truncated: boolean,
*IFEND
      ignore_local_file: boolean,
      ignore_status: ost$status,
*IF NOT $true(osv$unix)
      instance_information: fst$open_instance_information,
      job_mode: jmt$job_mode,
*IFEND
      open_command_file: boolean,
      open_executable_cmnd_file: boolean,
*IF NOT $true(osv$unix)
      open_validation_selections: no_selections .. select_incf_file_org_fap,
      user_defined_attribute_size: fst$user_defined_attribute_size;
*ELSE
      open_validation_selections: no_selections .. select_incf_file_org_fap;
*IFEND


    status.normal := TRUE;
    open_command_file := FALSE;
    open_executable_cmnd_file := FALSE;
    file_id := amv$nil_file_identifier;
*IF NOT $true(osv$unix)
    #SPOIL (file_id);
    file_contents.path_exists := TRUE;
    file_contents.is_object := FALSE;
*ELSE
    can_be_echoed := FALSE;
*IFEND
    open_path_handle_name := osc$null_name;
    allowed_device_classes := -$fst$device_classes [];

*IF NOT $true(osv$unix)
    #CALLER_ID (caller_id);

    job_mode := pmf$job_mode ();
*IFEND

    CASE command_file OF
    = clc$include_file =
*IF NOT $true(osv$unix)
      IF (job_mode = jmc$batch) AND (file_reference = clv$standard_files [clc$sf_command_file].
            path_handle_name) THEN
        open_executable_cmnd_file := TRUE;
        exec_cmnd_file_access_options := all_options;
        command_file_test := no_command_file_test;
        callable_file_test := no_callable_file_test;
        open_validation_selections := select_file_org;
      ELSE
*IFEND
        open_command_file := TRUE;
        cmnd_file_access_options := one_option_read;
        open_executable_cmnd_file := TRUE;
        exec_cmnd_file_access_options := one_option_execute;
        command_file_test := include_file;
        callable_file_test := execute_bracket;
*IF NOT $true(osv$unix)
        open_validation_selections := select_incf_file_org;
      IFEND;
*IFEND

      file_organization_test := TRUE;
      execute_access_test := FALSE;
      fap_not_allowed_test := FALSE;
      access_level := amc$record;
      fetch_attributes := TRUE;
      caller_file := FALSE;

*IF NOT $true(osv$unix)
    = clc$incf_segment_caller_file =
      establish_incf_caller_tests;
      file_organization_test := FALSE;
      access_level := amc$segment;
      open_validation_selections := no_selections;

    = clc$incf_record_caller_file =
      establish_incf_caller_tests;
      file_organization_test := TRUE;
      access_level := amc$record;
      open_validation_selections := select_file_org;

    = clc$get_file =
      establish_get_file_tests;
      file_organization_test := TRUE;
      access_level := amc$record;
      open_validation_selections := select_file_org;
      caller_file := FALSE;

    = clc$get_segment_caller_file =
      establish_get_file_tests;
      file_organization_test := FALSE;
      access_level := amc$segment;
      open_validation_selections := no_selections;
      caller_file := TRUE;

    = clc$get_record_caller_file =
      establish_get_file_tests;
      file_organization_test := TRUE;
      access_level := amc$record;
      open_validation_selections := select_file_org;
      caller_file := TRUE;

    = clc$catalog_command =
      get_attributes [1].key := amc$ring_attributes;
      get_attributes [2].key := amc$record_type;
      get_attributes [3].key := amc$block_type;
      get_attributes [4].key := amc$access_mode;
      get_attributes [5].key := amc$global_access_mode;
      get_attributes [6].key := amc$max_record_length;
      get_attributes [7].key := amc$line_number;
      get_attributes [8].key := amc$statement_identifier;
      get_attributes [9].key := amc$file_access_procedure;
      get_attributes [10].key := amc$file_contents;
      get_attributes [11].key := amc$file_structure;

      amp$get_file_attributes (file_reference, get_attributes, ignore_local_file, existing_file,
            ignore_contains_data, status);

      IF NOT status.normal THEN
        file_contents.path_exists := FALSE;
        RETURN;
      IFEND;

      IF NOT existing_file THEN
        file_contents.path_exists := FALSE;
        osp$set_status_abnormal ('CL', cle$not_a_command_file, '', status);
        osp$append_status_file (osc$status_parameter_delimiter, file_reference, status);
        RETURN;
      IFEND;

{ The decision to open the file, the file_organization_test, and the execute_access_test
{ are determined in the command_file_test.

      command_file_test := proc_or_object_file_or_lib;
      callable_file_test := call_bracket;
      fap_not_allowed_test := TRUE;
      open_validation_selections := select_file_org_fap;
      fetch_attributes := FALSE;
      caller_file := FALSE;
      file_contents.is_object := get_attributes [10].file_contents = amc$object;

    = clc$command_library =
      determine_open_choices;
      command_file_test := object_library;
      file_organization_test := FALSE;
      callable_file_test := no_callable_file_test;
      execute_access_test := FALSE;
      fap_not_allowed_test := TRUE;
      access_level := amc$segment;
      open_validation_selections := select_object_lib_fap;
      fetch_attributes := TRUE;
      caller_file := FALSE;

    = clc$submit_job =

{ It is known that the caller ring is ring 3.

      open_command_file := TRUE;
      allowed_device_classes := $fst$device_classes [fsc$mass_storage_device];
      cmnd_file_access_options := all_options;
      command_file_test := include_file;
      file_organization_test := TRUE;
      callable_file_test := call_bracket;
      execute_access_test := FALSE;
      fap_not_allowed_test := TRUE;
      access_level := amc$record;
      open_validation_selections := select_incf_file_org_fap;
      fetch_attributes := TRUE;
      caller_file := FALSE;
*IFEND

    ELSE
      osp$set_status_abnormal ('CL', cle$unexpected_call_to, 'clp$access_command_file', status);
      RETURN;
    CASEND;

*IF NOT $true(osv$unix)
    IF open_validation_selections = no_selections THEN
      attribute_validation := NIL;
    ELSE
      PUSH attribute_validation: [1 .. open_validation_selections];
      attribute_index := 0;
    IFEND;

    CASE command_file_test OF
    = include_file =
      FOR attribute_index := 1 TO 5 DO
        attribute_validation^ [attribute_index].selector := fsc$file_contents_and_processor;
        attribute_validation^ [attribute_index].file_processor := osc$null_name;
      FOREND;
      IF command_file = clc$submit_job THEN
        attribute_validation^ [1].file_contents := fsc$legible_scl_job;
      ELSE
        attribute_validation^ [1].file_contents := fsc$legible_scl_include;
      IFEND;
      attribute_validation^ [2].file_contents := fsc$legible_data;
      attribute_validation^ [3].file_contents := amc$legible;
      attribute_validation^ [4].file_contents := fsc$data;
      attribute_validation^ [5].file_contents := fsc$unknown_contents;
      attribute_index := 5;

    = object_library =
      attribute_validation^ [1].selector := fsc$file_contents_and_processor;
      attribute_validation^ [1].file_contents := fsc$object_library;
      attribute_validation^ [1].file_processor := osc$null_name;
      attribute_index := 1;

    = proc_or_object_file_or_lib =
      fsp$convert_to_new_contents (get_attributes [10].file_contents, get_attributes [11].file_structure,
            fs_file_contents, ignore_file_contents_truncated);
      IF (fs_file_contents = fsc$object_library) OR (fs_file_contents = fsc$object_data) THEN
        file_organization_test := FALSE;
        execute_access_test := TRUE;
        access_level := amc$segment;
      ELSEIF (fs_file_contents = fsc$legible_scl_procedure) OR (fs_file_contents = fsc$legible_data) OR
            (fs_file_contents = amc$legible) OR (fs_file_contents = fsc$data) OR (fs_file_contents =
            fsc$unknown_contents) THEN
        determine_open_choices;
        file_organization_test := TRUE;
        callable_file_test := execute_bracket; { Currently no "ring switch" for procs.
        execute_access_test := FALSE;
        access_level := amc$record;
      ELSE
        osp$set_status_abnormal ('CL', cle$not_a_command_file, '', status);
        osp$append_status_file (osc$status_parameter_delimiter, file_reference, status);
        RETURN;
      IFEND;

    ELSE
      ;
    CASEND;

    IF file_organization_test THEN
      attribute_index := attribute_index + 1;
      attribute_validation^ [attribute_index].selector := fsc$file_organization;
      attribute_validation^ [attribute_index].file_organization := amc$sequential;
    IFEND;

    IF fap_not_allowed_test THEN
      fap_null_name.entry_point := osc$null_name;
      fap_null_name.object_library := ' ';
      attribute_index := attribute_index + 1;
      attribute_validation^ [attribute_index].selector := fsc$file_access_procedure_name;
      attribute_validation^ [attribute_index].file_access_procedure_name := ^fap_null_name;
    IFEND;

    osp$establish_block_exit_hndlr (^abort_handler);
*IFEND
*IF $true(osv$unix)
    handler_established := #establish_condition_handler (-1, ^abort_handler);
*IFEND

    IF open_command_file THEN
      establish_file_access_modes (cmnd_file_access_options);
*IF NOT $true(osv$unix)
      clp$open_command_file (file_reference, job_mode, access_level, file_access_modes, attribute_validation,
            allowed_device_classes, file_id, segment, status);
*ELSE
      clp$open_command_file (file_reference, access_level, file_access_modes, attribute_validation,
            file_id, segment, status);
*IFEND
      opened_executable_file := FALSE;
*IF NOT $true(osv$unix)
      #SPOIL (opened_executable_file);
*IFEND
    IFEND;

*IF NOT $true(osv$unix)
    IF open_executable_cmnd_file THEN
      IF (NOT open_command_file) OR ((NOT status.normal) AND
            (status.condition = cle$command_file_not_executable)) THEN
        establish_file_access_modes (exec_cmnd_file_access_options);
        clp$open_executable_cmnd_file (file_reference, job_mode, access_level, file_access_modes,
              attribute_validation, file_id, segment, status);
        opened_executable_file := TRUE;
        #SPOIL (opened_executable_file);
      ELSE
        callable_file_test := no_callable_file_test;
      IFEND;
    IFEND;
*IFEND

    IF NOT status.normal THEN
*IF NOT $true(osv$unix)
      IF status.condition = ame$attribute_validation_error THEN
        status.condition := cle$improper_command_file_attr;
      ELSEIF status.condition = cle$command_file_not_executable THEN
*ELSE
      IF status.condition = cle$command_file_not_executable THEN
*IFEND

        CASE command_file OF
        = clc$get_file, clc$get_segment_caller_file, clc$get_record_caller_file =
*IF NOT $true(osv$unix)
          fsp$set_file_reference_abnormal (file_reference, ame$no_permission_for_access,
                amc$open_req, 'READ', status);
*IFEND
        ELSE
          ;
        CASEND;

      IFEND;
*IF $true(osv$unix)
      IF handler_established THEN
        handler_established := NOT #disestablish_condition_handler (-1);
      IFEND;
*ELSE
      osp$disestablish_cond_handler;
*IFEND
      RETURN;
    IFEND;

  /file_tests/
    BEGIN
      IF open_command_file OR open_executable_cmnd_file THEN
*IF NOT $true(osv$unix)
        bap$get_phn_via_file_id (file_id, open_path_handle_name, status);
        IF NOT status.normal THEN
          EXIT /file_tests/;
        IFEND;
*ELSE
        open_path_handle_name := file_reference;
*IFEND
      IFEND;

*IF NOT $true(osv$unix)
      IF fetch_attributes THEN
        fsp$get_open_information (file_id, ^attachment_information,
              ^catalog_information, ^cycle_attribute_sources,
              ^cycle_attribute_values, ^instance_information,
              NIL, NIL, user_defined_attribute_size, status);
        IF NOT status.normal THEN
          EXIT /file_tests/;
        IFEND;
        device_class := catalog_information.cycle_registration.residence.device_class;
      ELSE
        rmp$get_device_class (file_reference, device_assigned, device_class, status);
        IF NOT status.normal THEN
          EXIT /file_tests/;
        IFEND;
*ELSE
        fsp$get_open_information (file_id, device_class);
*IFEND
*IF NOT $true(osv$unix)
        catalog_information.cycle_registration.ring_attributes := get_attributes [1].ring_attributes;
        cycle_attribute_values.record_type := get_attributes [2].record_type;
        cycle_attribute_values.block_type := get_attributes [3].block_type;
        #unchecked_conversion (get_attributes [4].access_mode,
              instance_information.attachment_information.access_modes);
        #unchecked_conversion (get_attributes [5].global_access_mode,
              attachment_information.administration_information.attached_access_modes);
        cycle_attribute_values.max_record_length := get_attributes [6].max_record_length;
        cycle_attribute_sources.line_number := get_attributes [7].source;
        cycle_attribute_values.line_number := get_attributes [7].line_number;
        cycle_attribute_sources.statement_identifier := get_attributes [8].source;
        cycle_attribute_values.statement_identifier := get_attributes [8].statement_identifier;
        cycle_attribute_values.file_access_procedure_name.entry_point :=
              get_attributes [9].file_access_procedure;
      IFEND;

      ring_attributes := catalog_information.cycle_registration.ring_attributes;
      file_has_fap := cycle_attribute_values.file_access_procedure_name.entry_point <> osc$null_name;
      IF submitter_ring > caller_id.ring THEN
        caller_id.ring := submitter_ring;
      IFEND;

      IF file_organization_test AND (cycle_attribute_values.record_type = amc$undefined) AND
            (cycle_attribute_values.block_type = amc$system_specified) THEN
        fsp$set_file_reference_abnormal (file_reference, cle$improper_command_file_attr,
              amc$open_req, 'record_type = undefined', status);
        EXIT /file_tests/;
      IFEND;

      CASE callable_file_test OF
      = call_bracket =
        IF caller_id.ring > catalog_information.cycle_registration.ring_attributes.r3 THEN
          osp$set_status_abnormal ('CL', cle$command_file_not_callable, '', status);
          osp$append_status_file (osc$status_parameter_delimiter, file_reference, status);
          EXIT /file_tests/;
        IFEND;

      = execute_bracket =
        IF (caller_id.ring < catalog_information.cycle_registration.ring_attributes.r1) OR
              (caller_id.ring > catalog_information.cycle_registration.ring_attributes.r2) THEN
          osp$set_status_abnormal ('CL', cle$command_file_not_callable, '', status);
          osp$append_status_file (osc$status_parameter_delimiter, file_reference, status);
          EXIT /file_tests/;
        IFEND;

      ELSE
        ;
      CASEND;

      IF execute_access_test AND (NOT (fsc$execute IN instance_information.
        attachment_information.access_modes)) THEN
        osp$set_status_abnormal ('CL', cle$command_file_not_executable, '', status);
        osp$append_status_file (osc$status_parameter_delimiter, file_reference, status);
        EXIT /file_tests/;
      IFEND;
*IFEND

    END /file_tests/;

    IF file_id <> amv$nil_file_identifier THEN
      IF status.normal AND (NOT caller_file) THEN
*IF NOT $true(osv$unix)
        can_be_echoed := (file_reference = clv$standard_files [clc$sf_command_file].path_handle_name) OR
              ((fsc$read IN attachment_information.administration_information.attached_access_modes) AND
              (caller_id.ring <= catalog_information.cycle_registration.ring_attributes.r3));

*IFEND
        IF access_level = amc$record THEN
*IF NOT $true(osv$unix)
          clp$determine_line_layout (file_reference, cycle_attribute_values.record_type,
                cycle_attribute_values.max_record_length, cycle_attribute_sources.line_number
                <> amc$undefined_attribute, cycle_attribute_values.line_number,
                cycle_attribute_sources.statement_identifier <> amc$undefined_attribute,
                cycle_attribute_values.statement_identifier, line_layout, status);
*ELSE
          clp$determine_line_layout (file_reference, line_layout, status);
*IFEND
        IFEND;
      IFEND;

      IF NOT status.normal THEN
        clp$close_command_file (file_id, opened_executable_file, ignore_status);
      IFEND;
    IFEND;

*IF $true(osv$unix)
    IF handler_established THEN
      handler_established := NOT #disestablish_condition_handler (-1);
    IFEND;
*ELSE
    osp$disestablish_cond_handler;
*IFEND

  PROCEND clp$access_command_file;

MODEND clm$access_command_file;
