?? TITLE := 'NOS/VE :  BASIC ACCESS METHOD, RING BRACKETS 23D' ??
MODULE amm$validate_caller_privilege;
?? RIGHT := 110 ??

*copy amh$validate_caller_privilege

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc amc$condition_code_limits
*copyc osd$virtual_address
*copyc ame$access_validation_errors
*copyc ame$fap_validation_errors
*copyc ame$improper_file_id
*copyc ame$ring_validation_errors
*copyc amt$call_block
*copyc amt$fap_layer_number
*copyc amt$fap_pointer
*copyc amt$file_identifier
*copyc ost$caller_identifier
*copyc pft$usage_options
*copyc pft$usage_selections
?? POP ??
*copyc baf$task_file_entry_p
*copyc amp$set_file_instance_abnormal
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] AMP$VALIDATE_CALLER_PRIVILEGE', EJECT ??

  PROCEDURE [XDCL, #GATE] amp$validate_caller_privilege ALIAS 'amxvcp'
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
         required_write_privilege: pft$usage_selections;
         caller_ring_number: ost$ring;
     VAR structure_pointer: ^cell;
     VAR status: ost$status);

    CONST
      interface_name = 'AMP$VALIDATE_CALLER_PRIVILEGE';

    VAR
      caller_id: ost$caller_identifier,
      delimiter: char,
      file_instance_p: ^bat$task_file_entry,
      i: pft$usage_options,
      layer_p: ^bat$fap_descriptor,
      previous_append: boolean,
      validation_ring: ost$ring,
      write_permission: array [pfc$shorten .. pfc$modify] of string (7);

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

    file_instance_p := baf$task_file_entry_p (file_identifier);
    IF file_instance_p = NIL THEN
      osp$set_status_abnormal (amc$access_method_id, ame$improper_file_id, interface_name, status);
      RETURN; {----->
    IFEND;

    IF caller_id.ring > caller_ring_number THEN
      amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
            status);
      RETURN; {----->
    IFEND;

    validation_ring := caller_ring_number;

    CASE call_block.operation OF
    = amc$close_req, amc$close_volume_req, amc$open_req =
      IF validation_ring > file_instance_p^.open_ring THEN
        amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
              status);
        RETURN; {----->
      IFEND;

    = amc$delete_req, amc$delete_direct_req, amc$delete_key_req, amc$flush_req, amc$pack_block_req,
          amc$pack_record_req, amc$put_direct_req, amc$put_key_req, amc$put_label_req, amc$put_next_req,
          amc$put_partial_req, amc$putrep_req, amc$replace_req, amc$replace_direct_req, amc$replace_key_req,
          amc$set_segment_eoi_req, amc$write_req, amc$write_direct_req, amc$write_end_partition_req,
          amc$write_tape_mark_req, amc$abandon_key_definitions, amc$apply_key_definitions,
          amc$create_key_definition, amc$create_nested_file, amc$delete_key_definition,
          amc$delete_nested_file, amc$find_record_space, amc$separate_key_groups, nac$se_send_data_req =

      IF required_write_privilege = $pft$usage_selections [] THEN
        amp$set_file_instance_abnormal (file_identifier, ame$null_set_specified, call_block.operation,
              'REQUIRED_WRITE_PRIVILEGE', status);
        RETURN; {----->
      IFEND;

      IF validation_ring > file_instance_p^.instance_attributes.static_label.ring_attributes.r1 THEN
        amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
              status);
        RETURN; {----->
      IFEND;

      IF NOT (required_write_privilege <= file_instance_p^.instance_attributes.dynamic_label.access_mode) THEN
        amp$set_file_instance_abnormal (file_identifier, ame$improper_access_attempt, call_block.operation,
              '', status);
        previous_append := FALSE;
        write_permission [pfc$shorten] := 'SHORTEN';
        write_permission [pfc$append] := 'APPEND';
        write_permission [pfc$modify] := 'MODIFY';
        FOR i := LOWERBOUND (write_permission) TO UPPERBOUND (write_permission) DO
          IF i IN required_write_privilege THEN
            IF previous_append THEN
              delimiter := ',';
            ELSE
              delimiter := ' ';
            IFEND;
            osp$append_status_parameter (delimiter, write_permission [i], status);
            previous_append := TRUE;
          IFEND;
        FOREND;
        RETURN; {----->
      IFEND;

    = amc$check_buffer_req, amc$check_record_req, amc$get_direct_req, amc$get_key_req, amc$get_label_req,
          amc$get_next_req, amc$get_next_key_req, amc$get_partial_req, amc$get_segment_pointer_req,
          amc$read_req, amc$read_direct_req, amc$read_direct_skip_req, amc$read_skip_req,
          amc$set_segment_position_req, amc$start_req, amc$unpack_block_req, amc$unpack_record_req,
          amc$get_lock_keyed_record, amc$get_lock_next_keyed_record, amc$get_next_primary_key_list,
          amc$get_primary_key_count, amc$get_space_used_for_key, nac$se_receive_data_req =

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

      IF NOT (pfc$read IN file_instance_p^.instance_attributes.dynamic_label.access_mode) THEN
        amp$set_file_instance_abnormal (file_identifier, ame$improper_access_attempt, call_block.operation,
              ' READ', status);
        RETURN; {----->
      IFEND;

    = ifc$fetch_terminal_req =
      IF validation_ring > file_instance_p^.instance_attributes.static_label.ring_attributes.r2 THEN
        amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
              status);
        RETURN; {----->
      IFEND;

    = amc$fetch_access_information_rq, amc$fetch_req, nac$fetch_attributes =
      IF validation_ring > file_instance_p^.instance_attributes.static_label.ring_attributes.r3 THEN
        amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
              status);
        RETURN; {----->
      IFEND;

    = amc$rewind_req, amc$rewind_volume_req, amc$skip_req, amc$seek_direct_req, amc$abort_file_parcel,
          amc$begin_file_parcel, amc$check_nowait_request, amc$commit_file_parcel, amc$get_key_definitions,
          amc$get_nested_file_definitions, amc$lock_file, amc$lock_key, amc$select_key,
          amc$select_nested_file, amc$unlock_file, amc$unlock_key =

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

      IF ($pft$usage_selections [pfc$read, pfc$append, pfc$modify, pfc$shorten] *
            file_instance_p^.instance_attributes.dynamic_label.access_mode) = $pft$usage_selections [] THEN
        amp$set_file_instance_abnormal (file_identifier, ame$improper_access_attempt, call_block.operation,
              ' READ or WRITE', status);
        RETURN; {----->
      IFEND;

    = amc$store_req, ifc$store_terminal_req, nac$store_attributes =
      IF validation_ring > file_instance_p^.instance_attributes.static_label.ring_attributes.r1 THEN
        amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error, call_block.operation, '',
              status);
        RETURN; {----->
      IFEND;
    ELSE
      amp$set_file_instance_abnormal (file_identifier, ame$improper_fap_operation,
            amc$validate_caller_privilege, '', status);
      RETURN; {----->
    CASEND;

    IF (file_instance_p^.fap_control_information.fap_array = NIL) AND (layer_number = 0) THEN
      layer_p := ^file_instance_p^.fap_control_information.first_fap;
    ELSEIF (file_instance_p^.fap_control_information.fap_array <> NIL)
{ } AND (layer_number <= UPPERBOUND (file_instance_p^.fap_control_information.fap_array^)) THEN
      layer_p := ^file_instance_p^.fap_control_information.fap_array^ [layer_number];
    ELSE
      osp$set_status_abnormal (amc$access_method_id, ame$improper_layer_number, interface_name, status);
      RETURN; {----->
    IFEND;

    IF layer_p^.structure_pointer <> NIL THEN
      IF caller_id.ring <= layer_p^.loaded_ring THEN
        structure_pointer := layer_p^.structure_pointer;
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$ring_validation_error,
              amc$validate_caller_privilege, '', status);
      IFEND;
    IFEND;

  PROCEND amp$validate_caller_privilege;
?? OLDTITLE ??
MODEND amm$validate_caller_privilege;
