?? RIGHT := 110 ??
?? NEWTITLE := 'PACKAGE_SOFTWARE Utility: Module RAM$GET_FILE_INFORMATION.' ??
MODULE ram$get_file_information;

{ PURPOSE:
{   This module validates a file and determines
{   its size and checksum.
{
{ DESIGN:
{   Each file is checked for correct permits, cycles, and ring attributes
{   Then the files size and checksum are determined.
{
{ NOTES:
{
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rae$package_software_cc
*copyc ost$status
*copyc pft$path
*copyc pmt$condition
*copyc rat$subproduct_info_p
*copyc rat$subproduct_info_pointers
*copyc rat$subproduct_info_types
*copyc rat$validation_selections
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$get_segment_pointer
*copyc fsp$close_file
*copyc ocp$checksum
*copyc osp$append_status_file
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$generate_error_message
*copyc osp$set_status_abnormal
*copyc pfp$find_direct_info_record
*copyc pfp$find_file_description
*copyc rap$open_file
*copyc rap$test_cycles
*copyc rap$test_permits
?? TITLE := 'Global Declarations Declared by This Module', EJECT ??

?? TITLE := 'get_file_information', EJECT ??

{ PURPOSE:
{   This procedure validates a file and determines
{   its size and checksum.
{
{ DESIGN:
{   Each file is checked for correct permits, cycles, and ring attributes
{   Then the files size and checksum are determined.
{
{ NOTES:
{
{

  PROCEDURE [XDCL] rap$get_file_information
    (    file_ref_p: ^fst$file_reference;
         file_path: pft$path;
         pf_info_record_p: pft$p_info_record;
         info_offset: pft$info_offset;
         validation_selections: rat$validation_selections;
         checksum_contents: boolean;
     VAR validation_errors: {output} boolean;
     VAR element: {output} rat$element;
     VAR status: ost$status);


    VAR
      attributes_checksum: integer,
      attribute_override: array [1 .. 1] of fst$file_cycle_attribute,
      checksum_info_p: pft$p_info,
      cycles_p: pft$p_cycle_array,
      file_attributes: array [1 .. 4] of amt$get_item,
      file_id: amt$file_identifier,
      file_opened: boolean,
      file_seg_p: amt$segment_pointer,
      ignore_contains_data: boolean,
      ignore_existing_file: boolean,
      ignore_local_file: boolean,
      ignore_status: ost$status,
      info_record_p: pft$p_info_record,
      message_status: ost$status;

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

{ PURPOSE:
{   This procedure cleans up when an abort situation occurs
{   within the block structure.
{
{ DESIGN:
{   If the file has been opened, it will be closed before the
{   the procedure returns.
{
{ NOTES:
{
{

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

      VAR
        ignore_status: ost$status;

      IF file_opened THEN
        fsp$close_file (file_id, ignore_status);
      IFEND;

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??


    status.normal := TRUE;
    file_opened := FALSE;

    element.name := file_path [UPPERBOUND (file_path)];
    element.permit.defined := FALSE;
    element.permit.permit_selections := $pft$permit_selections [];
    element.permit.share_requirements := $pft$share_requirements [];
    element.permit.application_info := '';
    element.active_element := TRUE;
    element.next_element_across_p := NIL;
    element.element_type := rac$file;
    element.attributes_checksum := 0;
    element.contents_checksum := 0;
    element.correction_base_contents_cksum := 0;
    element.pre_genc_contents_checksum := 0;
    element.correction_directives := $rat$correction_directives[];
    element.correction_format := rac$replacement;
    element.file_contents_and_structure := rac$replacement;
    element.library_merge.path_container_index := 0;
    element.library_merge.path_length := 0;
    element.ring_attributes.r1 := osc$invalid_ring;
    element.ring_attributes.r2 := osc$invalid_ring;
    element.ring_attributes.r3 := osc$invalid_ring;
    element.storage_class := rmc$msc_product_files;
    element.size := 0;

    rap$test_permits (validation_selections, file_ref_p, pf_info_record_p, info_offset, validation_errors,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    rap$test_cycles (validation_selections, file_ref_p, pf_info_record_p, info_offset, cycles_p,
          validation_errors, attributes_checksum, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    element.modification_date_time := cycles_p^ [1].cycle_statistics.modification_date_time;
    element.attributes_checksum := attributes_checksum;

    test_logging (file_ref_p, pf_info_record_p, info_offset, validation_errors, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    file_attributes [1].key := amc$file_length;
    file_attributes [2].key := amc$ring_attributes;
    file_attributes [3].key := amc$file_contents;
    file_attributes [4].key := amc$file_structure;

    amp$get_file_attributes (file_ref_p^, file_attributes, ignore_local_file, ignore_existing_file,
          ignore_contains_data, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    element.size := file_attributes [1].file_length;

    IF rac$no_rings_below_11 IN validation_selections THEN
      IF (file_attributes [2].ring_attributes.r1 < 11) OR (file_attributes [2].ring_attributes.r2 < 11) OR
            (file_attributes [2].ring_attributes.r3 < 11) THEN
        osp$set_status_abnormal ('RA', rae$ring_value_too_low, '(11, 11, 11)', message_status);
        osp$append_status_file (osc$status_parameter_delimiter, file_ref_p^, message_status);
        osp$generate_error_message (message_status, ignore_status);
        validation_errors := TRUE;
      IFEND;
    IFEND;

    IF file_attributes [4].file_structure = amc$library THEN
      IF file_attributes [3].file_contents = amc$object THEN
        element.file_contents_and_structure := rac$object_library;
        element.correction_format := rac$object_library;
      ELSEIF file_attributes [3].file_contents = amc$legible THEN
        element.file_contents_and_structure := rac$source_library;
        element.correction_format := rac$source_library;
      IFEND;
    IFEND;

    IF (checksum_contents = TRUE) AND (element.size <> 0) THEN

      attribute_override [1].selector := fsc$file_organization;
      attribute_override [1].file_organization := amc$sequential;

      rap$open_file (file_ref_p, amc$segment, fsc$read, FALSE, ^attribute_override, file_id, file_opened,
            status);
      IF NOT status.normal THEN
        validation_errors := TRUE;
        RETURN;
      IFEND;

      osp$establish_block_exit_hndlr (^abort_handler);

    /main/
      BEGIN

        amp$get_segment_pointer (file_id, amc$sequence_pointer, file_seg_p, status);
        IF NOT status.normal THEN
          EXIT /main/;
        IFEND;

        RESET file_seg_p.sequence_pointer;
        checksum_info_p := file_seg_p.sequence_pointer;
        element.contents_checksum := ocp$checksum (checksum_info_p);

      END /main/;

      fsp$close_file (file_id, ignore_status);
      osp$disestablish_cond_handler;

    IFEND;

  PROCEND rap$get_file_information;

?? TITLE := 'test_logging', EJECT ??

{ PURPOSE:
{   This procedure validates that a file does not have
{   logging turned on.
{
{ DESIGN:
{   The PF utilities are used to see if logging has been
{   turned on for cycle 1 of a specific file.
{
{ NOTES:
{
{
  PROCEDURE test_logging
    (    element_ref_p: ^fst$file_reference;
         info_record_p: pft$p_info_record;
         info_offset: pft$info_offset;
     VAR validation_errors: boolean;
     VAR status: ost$status);


    VAR
      file_description_p: pft$p_file_description,
      file_info_record_p: pft$p_info_record,
      ignore_status: ost$status,
      message_status: ost$status;

    pfp$find_direct_info_record (^info_record_p^.body, info_offset, file_info_record_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pfp$find_file_description (file_info_record_p, file_description_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF file_description_p^.logging_selection = pfc$log THEN
     osp$set_status_abnormal ('RA', rae$logging_not_allowed, '', message_status);
     osp$append_status_file (osc$status_parameter_delimiter, element_ref_p^, message_status);
     osp$generate_error_message (message_status, ignore_status);
     validation_errors := TRUE;
   IFEND;

  PROCEND test_logging;

MODEND ram$get_file_information;
