?? RIGHT := 110 ??
?? TITLE := ' NOS/VE Backup/Restore Utilities:  backup_cycle', EJECT ??
MODULE pum$backup_cycle;

{  PURPOSE:
{    This module contains procedures required to produce a backup copy of a
{    specified cycle.

?? NEWTITLE := '  Global Declarations' ??
?? PUSH (LISTEXT := ON) ??
*copyc cyd$run_time_error_condition
*copyc pud$hierarchy_list
*copyc pfe$external_archive_conditions
*copyc pue$error_condition_codes
*copyc ost$caller_identifier
*copyc pft$cycle_info_desc_version_1
*copyc pft$cycle_info_desc_version_2
*copyc pmt$program_parameters
*copyc put$file_display_info
*copyc put$log_keyed_file_parameters
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$log_keyed_file_backup
*copyc amp$return
*copyc avp$family_administrator
*copyc avp$system_administrator
*copyc clp$convert_string_to_file
*copyc clp$get_value
*copyc clp$scan_parameter_list
*copyc dmp$get_stored_fmd_header_info
*copyc dmp$get_stored_fmd_volume_list
*copyc fmp$get_files_volume_info
*copyc fsp$build_file_ref_from_elems
*copyc fsp$expand_file_label
*copyc mmp$create_scratch_segment
*copyc mmp$delete_scratch_segment
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$establish_condition_handler
*copyc osp$log_io_read_error
*copyc osp$set_status_abnormal
*copyc osp$set_status_from_condition
*copyc pfp$convert_device_class_to_pf
*copyc pfp$find_archive_info
*copyc pfp$find_cycle_array_extended
*copyc pfp$find_cycle_directory
*copyc pfp$find_cycle_entry
*copyc pfp$find_cycle_entry_version_2
*copyc pfp$find_cycle_label
*copyc pfp$find_cycle_media
*copyc pfp$find_direct_info_record
*copyc pfp$find_directory_array
*copyc pfp$find_next_archive_entry
*copyc pfp$find_next_info_record
*copyc pfp$get_family_set
*copyc pfp$get_item_info
*copyc pfp$get_ownership
*copyc pfp$release_data
*copyc pfp$retrieve_archived_file
*copyc pfp$utility_attach
*copyc pmp$continue_to_cause
*copyc pmp$date_time_compare
*copyc pmp$execute_with_less_privilege
*copyc pmp$get_unique_name
*copyc pup$abort_output
*copyc pup$all_volumes_included
*copyc pup$build_catalog_header
*copyc pup$build_entry
*copyc pup$build_hierarchy_list
*copyc pup$check_if_size_included
*copyc pup$check_if_volume_included
*copyc pup$check_site_backup_options
*copyc pup$convert_cycle_path_to_strng
*copyc pup$display_blank_lines
*copyc pup$display_integer
*copyc pup$display_line
*copyc pup$find_cycle_info_record
*copyc pup$get_cycle_array
*copyc pup$get_cycle_array_version_2
*copyc pup$initialize_backup_listing
*copyc pup$output_cycle
*copyc pup$set_unknown_cycle_status
*copyc pup$store_file_gfn
*copyc pup$verify_file_path
*copyc pup$write_cycle_display
*copyc pup$write_excluded_cycle
*copyc pup$write_file_display
*copyc pup$write_logical_partition
*copyc pup$write_os_status
*copyc pup$write_status_to_listing
*copyc puv$backup_information
*copyc puv$backup_share_modes
*copyc puv$bacpf_backup_file_version
*copyc puv$bacpf_cycle_data_total
*copyc puv$cycle_display_selections
*copyc puv$data_file_selected
*copyc puv$exclude_catalog_information
*copyc puv$include_archive_information
*copyc puv$include_data_options
*copyc puv$include_exceptions
*copyc puv$last_volume_number
*copyc puv$null_original_unique_name
*copyc puv$null_res_cycle_array_ent_sp
*copyc puv$null_reserved_cycle_info_sp
*copyc puv$read_data_on_null_bf
*copyc puv$trace_selected
?? TITLE := '    Global Variables', EJECT ??

  VAR
    puv$log_keyed_file_backup: boolean := TRUE;

  VAR
    number_of_cycles_backed_up: integer := 0,
    number_of_cycles_overflowed: integer := 0,
    total_cycle_data_backed_up: integer := 0;

  VAR
    default_program_attributes: [STATIC, READ] pmt$program_attributes :=
          [[pmc$starting_proc_specified, pmc$library_list_specified], 'PUP$R4_LOG_KEYED_FILE_BACKUP', 0, 0,
          1, osc$null_name, [pmc$no_load_map], pmc$error_load_errors, pmc$initialize_to_zero,
          osc$max_segment_length, osc$null_name, osc$null_name, osc$null_name, FALSE];

?? TITLE := '  [XDCL] pup$backup_cycle', EJECT ??

  PROCEDURE [XDCL] pup$backup_cycle
    (    cycle_entry: put$entry;
         password: pft$password;
         pf_utility_catalog_header: put$catalog_header;
         cycle_array_entry: pft$cycle_array_entry_version_2;
         pf_utility_hierarchy_list: put$hierarchy_list;
         check_cycle_included: boolean;
     VAR file_display_info: put$file_display_info;
     VAR p_cycle_info_record: { input } pft$p_info_record;
     VAR file_archive_info: { input/output } amt$segment_pointer;
     VAR p_cycle_array_extended_record: pft$p_info_record;
     VAR p_cycle_directory_array: pft$p_cycle_directory_array;
     VAR pf_backup_file_id: put$file_identifier;
     VAR status: ost$status);


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

      VAR
        display_status: ost$status,
        condition_status: ost$status,
        construction_status: ost$status,
        run_time_status: ^ost$status;

      CASE condition.selector OF

      = pmc$system_conditions, mmc$segment_access_condition =
        { Display the reason for the condition.
        pup$display_line (' Condition occurred in backing up file.', display_status);
        IF (condition.selector = mmc$segment_access_condition) AND
                (condition.segment_access_condition.identifier = mmc$sac_io_read_error) THEN
          PUSH p_path_string;
          pup$convert_cycle_path_to_strng (pf_utility_catalog_header.path, cycle_number, p_path_string^);
          osp$set_status_abnormal (puc$pf_utility_id, pue$unrecovered_ms_read_error,
                p_path_string^.value (1,p_path_string^.size), status);
          osp$append_status_integer (osc$status_parameter_delimiter, cycle_length, 10, false, status);
          osp$append_status_integer (osc$status_parameter_delimiter, puv$bacpf_cycle_data_total, 10, false,
                status);
          pup$write_os_status (status, display_status);
          osp$log_io_read_error (p_path_string^.value (1,p_path_string^.size), gfc$fk_job_permanent_file,
                condition.segment_access_condition.segment);
        ELSE
          osp$set_status_from_condition (puc$pf_utility_id, condition, save_area, condition_status,
                construction_status);
          IF construction_status.normal THEN
            pup$write_os_status (condition_status, display_status);
          ELSE
            pup$write_os_status (construction_status, display_status);
          IFEND;
        IFEND;
        pup$write_logical_partition (pf_backup_file_id, construction_status);

        osp$set_status_abnormal (puc$pf_utility_id, pue$backup_condition, '', status);
        current_pf_lfn_usable := FALSE;
        EXIT pup$backup_cycle;

      = pmc$user_defined_condition =
        IF condition.user_condition_name = cye$run_time_condition THEN
          run_time_status := condition_information;
          status := run_time_status^;
          EXIT pup$backup_cycle;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
          RETURN;
        IFEND;

      = pmc$block_exit_processing =
        IF (NOT cycle_array_entry.cycle_reservation.cycle_reserved) AND cycle_attached THEN
          amp$return (pf_lfn, local_status);
        IFEND;
        RETURN;

      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);

      CASEND;

    PROCEND backup_abort_handler;

?? EJECT ??

    VAR
      action_descriptor: put$action_descriptor,
      backup_with_write_access: boolean,
      call_log_keyed_file_backup: boolean,
      contains_data: boolean,
      current_pf_lfn_usable: [STATIC] boolean := FALSE,
      cycle_attached: boolean,
      cycle_damage_symptoms: fst$cycle_damage_symptoms,
      cycle_included: boolean,
      cycle_info: put$backup_item_info,
      cycle_length: amt$file_length,
      cycle_number: fst$cycle_number,
      existing_file: boolean,
      fmd_exists: boolean,
      fmd_header: pft$fmd_header,
      fmd_size: integer,
      gfn: ost$binary_unique_name,
      ignore_status: ost$status,
      info_size: integer,
      label_exists: boolean,
      local_file: boolean,
      local_status: ost$status,
      ownership: pft$ownership,
      path_string: ost$string,
      p_archive_list: pft$p_info_record,
      p_cycle_label: ^SEQ ( * ),
      p_cycle_media_description: pft$p_file_media_description,
      p_cycle_info_desc_version_1: ^pft$cycle_info_desc_version_1,
      p_cycle_info_desc_version_2: ^pft$cycle_info_desc_version_2,
      p_cycle_info_fmd: ^SEQ ( * ),
      p_cycle_media_description_fmd: ^SEQ ( * ),
      p_file_attributes: ^amt$get_attributes,
      p_fmd: ^SEQ ( * ),
      p_path_string: ^ost$string,
      p_volume_list: ^pft$volume_list,
      perform_utility_attach: boolean,
      pf_lfn: [STATIC] amt$local_file_name,
      retrieve_allowed: boolean,
      start_volume: amt$volume_number,
      usage_selections: pft$usage_selections,
      utility_attach_allowed: boolean,
      utility_attach_attempted: boolean,
      variant_path: pft$variant_path;

    display (' entering pup$backup_cycle');
    osp$establish_condition_handler (^backup_abort_handler, { Block_exit =} TRUE);
    cycle_attached := FALSE;
    #SPOIL (cycle_attached);

    IF NOT (avp$family_administrator() OR avp$system_administrator()) THEN
      puv$include_archive_information := FALSE;
    IFEND;

    pfp$find_cycle_media (p_cycle_info_record, p_cycle_media_description, status);
    IF status.normal THEN
       fmd_exists := TRUE;
    ELSEIF status.condition = pfe$unknown_cycle_media THEN
      fmd_exists := FALSE;
      status.normal := TRUE;
    ELSE
      RETURN;
    IFEND;

    action_descriptor := ' ';
    backup_with_write_access := FALSE;
    call_log_keyed_file_backup := FALSE;
    cycle_damage_symptoms := $fst$cycle_damage_symptoms [];
    cycle_number := cycle_array_entry.cycle_number;
    cycle_included := TRUE;
    local_status.normal := TRUE;
    p_volume_list := NIL;
    perform_utility_attach := (pf_backup_file_id.device_class <> rmc$null_device) OR
          ((pf_backup_file_id.device_class = rmc$null_device) AND
          (puv$read_data_on_null_bf OR puv$include_exceptions));
    retrieve_allowed := FALSE;
    start_volume := puv$last_volume_number;
    utility_attach_allowed := TRUE;
    utility_attach_attempted := FALSE;
    gfn := puv$unknown_global_file_name;

    pup$check_site_backup_options (cycle_array_entry, cycle_included);
    IF NOT cycle_included THEN
      action_descriptor := 'EXCLUDE SITE';
    ELSE
      IF cycle_array_entry.device_class = rmc$mass_storage_device THEN
        {
        { Get the volume list from the fmd if needed.
        { Determine if the cycle is excluded from this backup by a previous
        { INCLUDE_VOLUMES command.
        {
        IF ((NOT pup$all_volumes_included ()) OR (puc$cdo_recorded_vsn IN puv$cycle_display_selections))
              AND fmd_exists THEN
          dmp$get_stored_fmd_header_info (^p_cycle_media_description^.file_media_descriptor, fmd_header,
                status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          PUSH p_volume_list: [1 .. fmd_header.number_of_subfiles];
          dmp$get_stored_fmd_volume_list (^p_cycle_media_description^.file_media_descriptor, p_volume_list,
                status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          pup$check_if_volume_included (p_volume_list, cycle_included);
          IF NOT cycle_included THEN
            action_descriptor := 'EXCLUDE VOLUME';
          IFEND;

        IFEND;


        {
        {    Exclude the cycle if neither archive information nor data will be backed up.
        {
        IF (((NOT fmd_exists) AND NOT (puc$include_offline_data IN puv$include_data_options))
              OR ((NOT (puc$include_unreleasable_data IN puv$include_data_options))
              AND (NOT (puc$include_releasable_data IN puv$include_data_options)) AND fmd_exists))
              AND NOT puv$include_archive_information THEN
          cycle_included := FALSE;
          action_descriptor := 'EXCLUDE CYCLE';
        {
        {   If data that has not been released is to be included on the backup file (which is the default),
        { and the cycle data has not been released, then the cycle will be backed up.  Otherwise, the cycle's
        { archive information must be read to determine whether or not to back up the cycle.
        {
        ELSEIF NOT ((puc$include_releasable_data IN puv$include_data_options) AND fmd_exists
              AND (puc$include_unreleasable_data IN puv$include_data_options)) THEN
          IF (file_archive_info.sequence_pointer = NIL) AND NOT puv$include_archive_information THEN
            {
            {    Archive information was not read from the catalog, because archive information was not to be
            {  backed up.  Therefore, it is not contained in the cycle info record passed to this procedure.
            {  However, it has been determined that the cycle's archive information must be read from the
            {  catalog to decide if the cycle should be backed up.  Thus, the catalog must be read again to
            {  obtain this information.
            {
            get_archive_item_info (cycle_array_entry, pf_utility_catalog_header, file_archive_info,
                  p_cycle_array_extended_record, p_cycle_directory_array, p_cycle_info_record, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;
          pfp$find_archive_info (p_cycle_info_record, p_archive_list, status);
          display (' pfp$find_archive_info');
          IF NOT status.normal THEN
            IF status.condition = pfe$unknown_archive_info THEN
              display (' status is PFE$UNKNOWN_ARCHIVE_LIST: status.normal changed to TRUE');
              status.normal := TRUE;
              p_archive_list := NIL;
            ELSE
              display_status (status);
              RETURN;
            IFEND;
          IFEND;
          {
          {    Check if the cycle should be excluded based upon whether or not it is archived.
          {
          check_for_arc_related_exclusion (p_archive_list, cycle_array_entry, check_cycle_included,
                fmd_exists, cycle_included, action_descriptor, utility_attach_allowed, retrieve_allowed,
                cycle_length, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;
      ELSEIF cycle_array_entry.device_class = rmc$magnetic_tape_device THEN
        retrieve_allowed := FALSE;
        utility_attach_allowed := FALSE;
        cycle_length := puc$released_cycle_size;
      IFEND;
    IFEND;

    IF (cycle_array_entry.data_residence = pfc$offline_data) AND
          (NOT puv$exclude_catalog_information) THEN
      IF NOT puv$include_archive_information AND
           NOT (puc$include_offline_data IN puv$include_data_options) THEN
        osp$set_status_abnormal (puc$pf_utility_id, pue$archive_info_not_backed_up, '', status);
      ELSE
        IF avp$family_administrator() AND (NOT avp$system_administrator()) THEN
          variant_path.complete_path := FALSE;
          variant_path.p_path := ^pf_utility_catalog_header.path;
          pfp$get_ownership (variant_path, {system_privilege} TRUE, ownership, status);
          IF NOT status.normal OR (NOT (pfc$family_owner IN ownership)) THEN
            osp$set_status_abnormal (puc$pf_utility_id, pue$archive_info_not_backed_up, '', status);
          IFEND;
        IFEND;
      IFEND;
    IFEND;

    IF utility_attach_allowed AND cycle_included THEN
      IF NOT current_pf_lfn_usable THEN
        pmp$get_unique_name (pf_lfn, status);
      IFEND;
{
{ Data for an archived file that resides offline is retrieved prior to the
{ utility attach when OFFLINE_DATA is incuded in the set specified by the
{ INCLUDE_DATA SET_RESTORE_OPTIONS parameter and:
{
{    a) The backup file is not $NULL.
{
{    b) The backup file is $NULL and READ_DATA is specified for the
{       NULL_BACKUP_FILE_OPTION parameter of the SET_RESTORE_OPTIONS subcommand.
{
      IF retrieve_allowed THEN
        IF (pf_backup_file_id.device_class <> rmc$null_device) OR
              ((pf_backup_file_id.device_class = rmc$null_device) AND puv$read_data_on_null_bf) THEN
          pfp$retrieve_archived_file (pf_utility_catalog_header.path, cycle_array_entry.cycle_number,
            password, { wait } osc$wait, status);
        ELSE
          perform_utility_attach := FALSE;
        IFEND;
      IFEND;
      IF status.normal AND perform_utility_attach THEN
        utility_attach_attempted := TRUE;
        display (' pfp$utility_attach user''s permanent file');
        IF NOT cycle_array_entry.cycle_reservation.cycle_reserved THEN
          PUSH p_path_string;
          pup$convert_cycle_path_to_strng (pf_utility_catalog_header.path, cycle_number, p_path_string^);
          IF (p_path_string^.value(1,36) = ':$SYSTEM.$SYSTEM.AAM.AAF$44D_LIBRARY') THEN
            usage_selections := $pft$usage_selections [pfc$read, pfc$execute];
          ELSE
            usage_selections := $pft$usage_selections [pfc$read];
          IFEND;
          pfp$utility_attach (pf_lfn, pf_utility_catalog_header.path,
                cycle_entry.pf_selector.cycle_selector, password, usage_selections,
                $pft$share_selections [pfc$read, pfc$execute], pfc$no_wait,
                $fst$cycle_damage_symptoms [fsc$respf_modification_mismatch, fsc$parent_catalog_restored],
                cycle_damage_symptoms, cycle_number, status);
          IF ((($pft$usage_selections [pfc$append, pfc$modify, pfc$shorten] *
                puv$backup_share_modes) <> $pft$usage_selections []) AND
                (NOT status.normal) AND (status.condition = pfe$cycle_busy)) THEN
            pfp$utility_attach (pf_lfn, pf_utility_catalog_header.path,
                  cycle_entry.pf_selector.cycle_selector, password, usage_selections,
                  puv$backup_share_modes, pfc$no_wait,
                  $fst$cycle_damage_symptoms [fsc$respf_modification_mismatch, fsc$parent_catalog_restored],
                  cycle_damage_symptoms, cycle_number, status);
            backup_with_write_access := status.normal;
          IFEND;
          display_status (status);
          display (' pfp$utility_attach complete');
        IFEND;
        cycle_attached := (cycle_array_entry.cycle_reservation.cycle_reserved OR status.normal);
      IFEND;
    IFEND;

    IF status.normal AND utility_attach_allowed AND cycle_included THEN
      IF cycle_array_entry.device_class = rmc$mass_storage_device THEN
        pup$get_file_attributes (pf_lfn, cycle_array_entry, cycle_length, gfn, status);
      IFEND;
      IF status.normal AND (NOT cycle_array_entry.cycle_reservation.cycle_reserved) AND
              check_cycle_included THEN
        pup$check_if_size_included (cycle_length, cycle_included);
        IF NOT cycle_included THEN
          action_descriptor := 'EXCLUDE SIZE';
        IFEND;
      IFEND;
    IFEND;

    IF (NOT utility_attach_allowed) OR retrieve_allowed THEN
      PUSH p_volume_list: [1 .. 1];
      p_volume_list^ [1] := puc$nonexistent_recorded_vsn;
    IFEND;

    IF status.normal THEN
      IF cycle_included THEN
        IF (cycle_length = 0) AND (NOT perform_utility_attach) AND (NOT puv$include_exceptions) THEN
        { Obtain correct cycle length for busy file cycle since 0 is returned in the cycle array.
          pup$convert_cycle_path_to_strng (pf_utility_catalog_header.path, cycle_number, path_string);
          PUSH p_file_attributes: [1 .. 1];
          p_file_attributes^ [1].key := amc$file_length;
          amp$get_file_attributes (path_string.value(1, path_string.size), p_file_attributes^,
                local_file, existing_file, contains_data, status);
          IF status.normal AND existing_file AND contains_data THEN
            cycle_length := p_file_attributes^ [1].file_length;
          IFEND;
        IFEND;
        IF file_display_info.display THEN
          pup$write_file_display (file_display_info.pf_entry,
                 file_display_info.p_file_description^.charge_id.account,
                 file_display_info.p_file_description^.charge_id.project, ignore_status);
          file_display_info.display := FALSE;
        IFEND;
        pup$write_cycle_display (cycle_entry, cycle_array_entry, cycle_length, gfn, p_volume_list,
              p_cycle_array_extended_record, p_cycle_directory_array, status);
        IF puv$data_file_selected THEN
          pup$store_file_gfn (gfn, pf_utility_catalog_header.path, cycle_entry.pf_selector.cycle_selector,
                local_status);
        IFEND;
        IF cycle_damage_symptoms <> $fst$cycle_damage_symptoms [ ] THEN
          IF fsc$respf_modification_mismatch IN cycle_damage_symptoms THEN
            pup$display_line (' --  Warning Cycle damaged: respf_modification_mismatch --', local_status);
          IFEND;
          IF fsc$parent_catalog_restored IN cycle_damage_symptoms THEN
            pup$display_line (' --  Warning Cycle damaged: parent_catalog_restored --', local_status);
          IFEND;
        IFEND;
        display (' pfp$find_cycle_label');
        pfp$find_cycle_label (p_cycle_info_record, p_cycle_label, local_status);
        display_status (local_status);
        label_exists := local_status.normal;
        IF NOT label_exists THEN
          local_status.normal := TRUE;
          RESET p_cycle_label;
          PUSH p_cycle_label: [[REP 1 OF CELL]];
        IFEND;
        cycle_info.item_type := puc$backup_item_cycle_info;
        IF puv$bacpf_backup_file_version = puc$backup_file_version_1 THEN
          PUSH p_cycle_info_desc_version_1;
          p_cycle_info_desc_version_1^.cycle_number := cycle_array_entry.cycle_number;
          p_cycle_info_desc_version_1^.cycle_statistics := cycle_array_entry.cycle_statistics;
          p_cycle_info_desc_version_1^.expiration_date_time := cycle_array_entry.expiration_date_time;
          cycle_info.cycle_item_info.body_size := #SIZE(p_cycle_info_desc_version_1^);
          cycle_info.cycle_item_info.body := p_cycle_info_desc_version_1;
        ELSEIF puv$bacpf_backup_file_version = puc$backup_file_version_2 THEN
          IF fmd_exists THEN
            fmd_size := #SIZE(p_cycle_media_description^.file_media_descriptor);
          ELSE
            fmd_size := 1;
          IFEND;
          PUSH p_cycle_info_desc_version_2: [[REP fmd_size OF cell]];
          p_cycle_info_desc_version_2^.cycle_damage_symptoms := cycle_array_entry.cycle_damage_symptoms;
          p_cycle_info_desc_version_2^.cycle_number := cycle_array_entry.cycle_number;
          p_cycle_info_desc_version_2^.cycle_statistics := cycle_array_entry.cycle_statistics;
          IF cycle_array_entry.data_modification_date_time.year > 0 THEN
            p_cycle_info_desc_version_2^.data_modification_date_time :=
                  cycle_array_entry.data_modification_date_time;
          ELSE
            p_cycle_info_desc_version_2^.data_modification_date_time :=
                  cycle_array_entry.cycle_statistics.modification_date_time;
          IFEND;
          pfp$convert_device_class_to_pf (cycle_array_entry.device_class,
                p_cycle_info_desc_version_2^.device_class);
          p_cycle_info_desc_version_2^.expiration_date_time := cycle_array_entry.expiration_date_time;
          p_cycle_info_desc_version_2^.original_unique_name := cycle_array_entry.original_unique_name;
          p_cycle_info_desc_version_2^.sparse_backup_file_format := FALSE;
          p_cycle_info_desc_version_2^.shared_queue_info := cycle_array_entry.shared_queue_info;
          p_cycle_info_desc_version_2^.retrieve_option := cycle_array_entry.retrieve_option;;
          p_cycle_info_desc_version_2^.site_backup_option := cycle_array_entry.site_backup_option;;
          p_cycle_info_desc_version_2^.site_archive_option := cycle_array_entry.site_archive_option;;
          p_cycle_info_desc_version_2^.site_release_option := cycle_array_entry.site_release_option;;
          p_cycle_info_desc_version_2^.reserved_cycle_info_space := puv$null_reserved_cycle_info_sp;
          IF fmd_exists THEN
            p_cycle_info_desc_version_2^.fmd_checksum := p_cycle_media_description^.checksum;
            p_fmd := ^p_cycle_media_description^.file_media_descriptor;
            RESET p_fmd;
            NEXT p_cycle_media_description_fmd: [[REP fmd_size OF cell]] IN p_fmd;
            p_fmd := ^p_cycle_info_desc_version_2^.file_media_descriptor;
            RESET p_fmd;
            NEXT p_cycle_info_fmd: [[REP fmd_size OF cell]] IN p_fmd;
            p_cycle_info_fmd^ := p_cycle_media_description_fmd^;
            cycle_info.cycle_item_info.body_size := #SIZE(p_cycle_info_desc_version_2^);
          ELSE
            p_cycle_info_desc_version_2^.fmd_checksum := 0;
            cycle_info.cycle_item_info.body_size := #SIZE(p_cycle_info_desc_version_2^) - 1;
          IFEND;
          cycle_info.cycle_item_info.body := p_cycle_info_desc_version_2;
        IFEND;
        pup$output_cycle (pf_lfn, cycle_entry, pf_utility_catalog_header, cycle_info, cycle_array_entry,
              label_exists,
              p_cycle_label^, pf_utility_hierarchy_list, cycle_length, utility_attach_allowed,
              pf_backup_file_id, status);
        display (' pup$output_cycle');
        display_status (status);
        IF status.normal THEN
          IF backup_with_write_access THEN
            PUSH p_path_string;
            pup$convert_cycle_path_to_strng (pf_utility_catalog_header.path, cycle_number, p_path_string^);
            osp$set_status_abnormal (puc$pf_utility_id, pue$backed_up_with_write_access,
                  p_path_string^.value (1, p_path_string^.size), status);
            pup$write_os_status (status, local_status);
            status.normal := TRUE;
          IFEND;
          number_of_cycles_backed_up := number_of_cycles_backed_up + 1;
          IF cycle_length <> puc$released_cycle_size THEN
            total_cycle_data_backed_up := total_cycle_data_backed_up + cycle_length;
          IFEND;
          IF (p_volume_list <> NIL) AND (UPPERBOUND (p_volume_list^) > 1) THEN
            number_of_cycles_overflowed := number_of_cycles_overflowed + 1;
          IFEND;
          IF label_exists THEN
            check_aam_file_attributes (p_cycle_label, call_log_keyed_file_backup, local_status);
          IFEND
        ELSE
          pup$abort_output (cycle_entry, pf_backup_file_id, status, local_status);
        IFEND;
      ELSE
        pup$write_excluded_cycle (cycle_entry, cycle_array_entry, cycle_length, gfn, p_volume_list,
              p_cycle_array_extended_record, p_cycle_directory_array, action_descriptor, status);
      IFEND;
    IFEND;

    IF cycle_attached THEN
      IF NOT cycle_array_entry.cycle_reservation.cycle_reserved THEN
        display (' amp$return cycle');
        amp$return (pf_lfn, local_status);
        cycle_attached := FALSE;
      IFEND;
      IF call_log_keyed_file_backup THEN
        log_keyed_file_backup (pf_utility_catalog_header.path, cycle_number, password, start_volume,
              puv$last_volume_number, pf_backup_file_id, puv$backup_information);
      IFEND;
      display_status (local_status);
    IFEND;

    IF retrieve_allowed AND ((pf_backup_file_id.device_class <> rmc$null_device) OR
           ((pf_backup_file_id.device_class = rmc$null_device) AND puv$read_data_on_null_bf)) THEN
      pfp$release_data (pf_utility_catalog_header.path, cycle_entry.pf_selector.cycle_selector, password,
            local_status);
    IFEND;

 {  If the data for a file in another user's catalog is offline and the user is permitted to read
 {  the file, backup is allowed but the data will not be released after the backup.

    IF (NOT local_status.normal) AND (local_status.condition = pfe$usage_not_permitted) THEN
      local_status.normal := TRUE;
    IFEND;

    IF utility_attach_attempted THEN
      current_pf_lfn_usable := status.normal;
    IFEND;

    display_status (local_status);
    IF (NOT local_status.normal) AND status.normal THEN
      status := local_status;
    IFEND;
  PROCEND pup$backup_cycle;

?? TITLE := '    [XDCL] pup$backup_cycle_request', EJECT ??

  PROCEDURE [XDCL] pup$backup_cycle_request (file_path: pft$path;
        cycle_selector: pft$cycle_selector;
        password: pft$password;
    VAR pf_backup_file_id: put$file_identifier;
    VAR status: ost$status);

    VAR
      cycle_array_entry: pft$cycle_array_entry_version_2,
      cycle_entry: put$entry,
      cycle_index: pft$array_index,
      file_display_info: put$file_display_info,
      file_info_selections: pft$file_info_selections,
      file_item_info: pft$p_info_record,
      group: pft$group,
      local_status: ost$status,
      p_cycle_array_version_1: pft$p_cycle_array,
      p_cycle_array_version_2: ^pft$cycle_array_version_2,
      p_cycle_array_extended_record: pft$p_info_record,
      p_cycle_directory_array: pft$p_cycle_directory_array,
      p_cycle_info_record: pft$p_info_record,
      p_hierarchy_list: ^put$hierarchy_list,
      segment_pointer: amt$segment_pointer,
      set_name: stt$set_name;

    display (' entering pup$backup_cycle_request');
    local_status.normal := TRUE;
    status.normal := TRUE;
    file_display_info.display := FALSE;

    pfp$get_family_set (file_path [pfc$family_name_index], set_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pup$build_entry (file_path [UPPERBOUND (file_path)], cycle_selector, puc$valid_cycle_entry, cycle_entry);
    PUSH p_hierarchy_list: [1 .. UPPERBOUND (file_path)];
    pup$build_catalog_header (set_name, ^file_path, p_hierarchy_list^.catalog_header);
    pup$build_hierarchy_list (cycle_entry, p_hierarchy_list^.catalog_header, p_hierarchy_list^, status);
    IF status.normal THEN
      pup$verify_file_path (file_path, status);
      IF status.normal THEN
        mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, segment_pointer, status);
        IF status.normal THEN
          group.group_type := pfc$public;
          IF puv$bacpf_backup_file_version = puc$backup_file_version_1 THEN
            file_info_selections := $pft$file_info_selections [pfc$file_directory,
                pfc$file_cycles, pfc$cycle_media_descriptor, pfc$cycle_label_descriptor,
                pfc$archive_descriptors];
          ELSEIF puv$bacpf_backup_file_version = puc$backup_file_version_2 THEN
            file_info_selections := $pft$file_info_selections [pfc$file_directory,
                pfc$file_cycles_version_2, pfc$cycle_media_descriptor, pfc$cycle_label_descriptor,
                pfc$archive_descriptors];
          IFEND;
          pfp$get_item_info (file_path, group, $pft$catalog_info_selections [], file_info_selections,
                segment_pointer.sequence_pointer, status);
          IF status.normal THEN
            IF puv$bacpf_backup_file_version = puc$backup_file_version_1 THEN
              pup$get_cycle_array (segment_pointer.sequence_pointer, p_cycle_array_version_1, file_item_info,
                    status);
              IF status.normal THEN
                pfp$find_cycle_entry (p_cycle_array_version_1, cycle_selector, cycle_index, status);
                IF status.normal THEN
                  cycle_array_entry.bytes_allocated := 0;
                  cycle_array_entry.cycle_damage_symptoms := $fst$cycle_damage_symptoms [];
                  cycle_array_entry.cycle_number := p_cycle_array_version_1^ [cycle_index].cycle_number;
                  cycle_array_entry.cycle_statistics :=
                        p_cycle_array_version_1^ [cycle_index].cycle_statistics;
                  cycle_array_entry.data_modification_date_time :=
                        p_cycle_array_version_1^ [cycle_index].cycle_statistics.modification_date_time;
                  cycle_array_entry.data_residence := pfc$unreleasable_data;
                  cycle_array_entry.device_class := rmc$mass_storage_device;
                  cycle_array_entry.eoi := 0;
                  cycle_array_entry.expiration_date_time :=
                        p_cycle_array_version_1^ [cycle_index].expiration_date_time;
                  cycle_array_entry.original_unique_name := puv$null_original_unique_name;
                  cycle_array_entry.sparse_allocation := FALSE;
                  cycle_array_entry.cycle_reservation.cycle_reserved := FALSE;
                  cycle_array_entry.reserved_cycle_array_entry_sp := puv$null_res_cycle_array_ent_sp;
                ELSE
                  pup$set_unknown_cycle_status (file_path [UPPERBOUND (file_path)], cycle_selector, status);
                IFEND;
              IFEND;
            ELSEIF puv$bacpf_backup_file_version = puc$backup_file_version_2 THEN
              pup$get_cycle_array_version_2 (segment_pointer.sequence_pointer, p_cycle_array_version_2,
                    file_item_info, status);
              IF status.normal THEN
                pfp$find_cycle_entry_version_2 (p_cycle_array_version_2, cycle_selector, cycle_index, status);
                IF status.normal THEN
                  cycle_array_entry := p_cycle_array_version_2^ [cycle_index];
                ELSE
                  pup$set_unknown_cycle_status (file_path [UPPERBOUND (file_path)], cycle_selector, status);
                IFEND;
              IFEND;
            IFEND;
            IF status.normal THEN
              pfp$find_cycle_array_extended (file_item_info, p_cycle_array_extended_record, status);
              IF status.normal THEN
                pfp$find_cycle_directory (p_cycle_array_extended_record, p_cycle_directory_array, status);
                IF status.normal THEN
                  pup$initialize_backup_listing (p_hierarchy_list^, pf_backup_file_id,
                        puv$backup_information, status);
                  IF status.normal THEN
                    pup$find_cycle_info_record (p_cycle_array_extended_record, p_cycle_directory_array,
                          cycle_array_entry.cycle_number, ^p_hierarchy_list^.catalog_header.path,
                          p_cycle_info_record, status);
                    IF status.normal THEN
                      { reset cycle_number in case of $HIGH or $LOW}
                      cycle_entry.pf_selector.cycle_selector.cycle_option := pfc$specific_cycle;
                      cycle_entry.pf_selector.cycle_selector.cycle_number := cycle_array_entry.cycle_number;
                      pup$backup_cycle (cycle_entry, password, p_hierarchy_list^.catalog_header,
                            cycle_array_entry, p_hierarchy_list^, { check_cycle_included  } FALSE,
                            file_display_info, p_cycle_info_record, segment_pointer,
                            p_cycle_array_extended_record, p_cycle_directory_array, pf_backup_file_id,
                            status);
                      pup$display_backup_output_total;
                    IFEND;
                  IFEND;
                IFEND;
              IFEND;
            IFEND;
          IFEND;
          mmp$delete_scratch_segment (segment_pointer, local_status);
        IFEND;
      IFEND;
    IFEND;
    pup$write_status_to_listing (cycle_entry, status, local_status);
  PROCEND pup$backup_cycle_request;

?? TITLE := '    [XDCL] pup$display_backup_output_total', EJECT ??

  PROCEDURE [XDCL] pup$display_backup_output_total;

    VAR
      local_status: ost$status;

    pup$display_blank_lines (3, local_status);
    pup$display_line (' BACKUP SUMMARY: ', local_status);
    pup$display_integer ('   NUMBER OF CYCLES BACKED UP: ', number_of_cycles_backed_up, local_status);
    number_of_cycles_backed_up := 0;
    IF puc$cdo_recorded_vsn IN puv$cycle_display_selections THEN
      pup$display_integer ('   NUMBER OF CYCLES ON MULTIPLE VOLUMES: ', number_of_cycles_overflowed,
            local_status);
      number_of_cycles_overflowed := 0;
    IFEND;
    pup$display_integer ('   TOTAL CYCLE DATA BACKED UP: ', total_cycle_data_backed_up, local_status);
    total_cycle_data_backed_up := 0;
  PROCEND pup$display_backup_output_total;

?? TITLE := '  pup$get_file_attributes', EJECT ??

  PROCEDURE [XDCL] pup$get_file_attributes
    (    lfn: fst$file_reference;
         cycle_array_entry: pft$cycle_array_entry_version_2;
     VAR file_length: amt$file_length;
     VAR gfn: ost$binary_unique_name;
     VAR status: ost$status);

    VAR
      contains_data: boolean,
      existing_file: boolean,
      local_file: boolean,
      p_file_attributes: ^amt$get_attributes;


    IF (puv$bacpf_backup_file_version = puc$backup_file_version_2) AND (cycle_array_entry.eoi > 0) THEN
      file_length := cycle_array_entry.eoi;
      gfn := cycle_array_entry.original_unique_name;
    ELSE
      PUSH p_file_attributes: [1 .. 2];
      p_file_attributes^ [1].key := amc$file_length;
      p_file_attributes^ [2].key := amc$global_file_name;
      amp$get_file_attributes (lfn, p_file_attributes^, local_file, existing_file, contains_data, status);
      IF status.normal THEN
        IF existing_file AND contains_data THEN
          file_length := p_file_attributes^ [1].file_length;
        ELSE
          file_length := 0;
        IFEND;
        display_integer (' user file length: ', file_length);
        gfn := p_file_attributes^ [2].global_file_name;
      IFEND;
    IFEND;
  PROCEND pup$get_file_attributes;

?? TITLE := '    [XDCL] pup$log_keyed_file_backup', EJECT ??

  PROCEDURE [XDCL] pup$log_keyed_file_backup
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ pdt logkfb_pdt (selected, s: boolean = true
{  status)

?? PUSH (LISTEXT := ON) ??

  VAR
    logkfb_pdt: [STATIC, READ, cls$pdt] clt$parameter_descriptor_table := [^logkfb_pdt_names,
      ^logkfb_pdt_params];

  VAR
    logkfb_pdt_names: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 3] of
      clt$parameter_name_descriptor := [['SELECTED', 1], ['S', 1], ['STATUS', 2]];

  VAR
    logkfb_pdt_params: [STATIC, READ, cls$pdt_parameters] array [1 .. 2] of clt$parameter_descriptor := [

{ SELECTED S }
    [[clc$optional_with_default, ^logkfb_pdt_dv1], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL,
      clc$boolean_value]],

{ STATUS }
    [[clc$optional], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$variable_reference,
      clc$array_not_allowed, clc$status_value]]];

  VAR
    logkfb_pdt_dv1: [STATIC, READ, cls$pdt_names_and_defaults] string (4) := 'true';


?? POP ??

    VAR
      value: clt$value;

    clp$scan_parameter_list (parameter_list, logkfb_pdt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$get_value ('SELECTED', 1, 1, clc$Low, value, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    puv$log_keyed_file_backup := value.bool.value;
    IF puv$log_keyed_file_backup THEN
      pup$display_line (' LOGGING KEYED FILE BACKUPS', status);
    ELSE
      pup$display_line (' NOT LOGGING KEYED FILE BACKUPS', status);
    IFEND;
  PROCEND pup$log_keyed_file_backup;

?? TITLE := '    [XDCL, #GATE] pup$r4_log_keyed_file_backup', EJECT ??

  PROCEDURE [XDCL, #GATE] pup$r4_log_keyed_file_backup
    (    program_parameters: pmt$program_parameters;
     VAR status: ost$status);

    VAR
      p_log_keyed_file_parameters: ^put$log_keyed_file_parameters,
      p_parameters: ^SEQ( *),
      p_volume_list: ^rmt$volume_list;

    p_parameters := ^program_parameters;
    RESET p_parameters;
    NEXT p_log_keyed_file_parameters IN p_parameters;
    NEXT p_volume_list: [1 .. p_log_keyed_file_parameters^.volume_list_size] IN p_parameters;

    amp$log_keyed_file_backup (p_log_keyed_file_parameters^.path, p_log_keyed_file_parameters^.password,
          p_log_keyed_file_parameters^.global_file_name, p_log_keyed_file_parameters^.backup_information,
          p_volume_list^, status);
  PROCEND pup$r4_log_keyed_file_backup;

?? TITLE := '    check_aam_file_attributes ', EJECT ??

  PROCEDURE check_aam_file_attributes
    (    p_cycle_label: ^SEQ ( * );
     VAR call_log_keyed_file_backup: boolean;
     VAR status: ost$status);

    TYPE
      file_organization_set = set of amt$file_organization;

    VAR
      file_previously_opened: boolean,
      label_size: integer,
      p_local_cycle_label: ^SEQ (*),
      p_physical_file_label: ^pft$physical_file_label,
      p_static_label_attributes: ^bat$static_label_attributes;

    IF NOT puv$log_keyed_file_backup THEN
      RETURN;
    IFEND;

    p_local_cycle_label := p_cycle_label;
    label_size := #SIZE(p_local_cycle_label^) - #SIZE(pft$checksum);
    RESET p_local_cycle_label;
    NEXT p_physical_file_label: [[REP label_size OF CELL]] IN p_local_cycle_label;

    PUSH p_static_label_attributes;
    fsp$expand_file_label (^p_physical_file_label^.file_label, p_static_label_attributes^,
          file_previously_opened, status);
    IF status.normal AND file_previously_opened THEN
      call_log_keyed_file_backup := ((p_static_label_attributes^.file_organization_source <>
            amc$undefined_attribute) AND (p_static_label_attributes^.file_organization IN
            $file_organization_set [amc$indexed_sequential, amc$direct_access, amc$system_key])) AND
            ((p_static_label_attributes^.logging_options_source <> amc$undefined_attribute) AND
            (amc$enable_media_recovery IN p_static_label_attributes^.logging_options));
    IFEND;

  PROCEND check_aam_file_attributes;

?? TITLE := '    check_for_arc_related_exclusion', EJECT ??

  PROCEDURE check_for_arc_related_exclusion (
        p_archive_list: { input } pft$p_info_record;
        cycle_array_entry: pft$cycle_array_entry_version_2;
        check_cycle_included: boolean;
        fmd_exists: boolean;
    VAR cycle_included: {i/o} boolean;
    VAR action_descriptor: {i/o} put$action_descriptor;
    VAR utility_attach_allowed: {i/o} boolean;
    VAR retrieve_allowed: {i/o} boolean;
    VAR cycle_length: amt$file_length;
    VAR status: ost$status);

    VAR
      cycle_archived: boolean,
      data_modification_date_time: ost$date_time;

    cycle_length := puc$released_cycle_size;
    cycle_archived := FALSE;

    IF p_archive_list = NIL THEN
      status.normal := TRUE;
    ELSE
      IF cycle_array_entry.data_modification_date_time.year > 0 THEN
        data_modification_date_time := cycle_array_entry.data_modification_date_time;
      ELSE
        data_modification_date_time := cycle_array_entry.cycle_statistics.modification_date_time;
      IFEND;
      check_if_cycle_archived (data_modification_date_time, p_archive_list, cycle_archived,
            status);
      display (' check_if_cycle_archived');
      display_status (status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF cycle_archived THEN
        IF check_cycle_included THEN
          pup$check_if_size_included (cycle_array_entry.eoi, cycle_included);
          IF NOT cycle_included THEN
            action_descriptor := 'EXCLUDE SIZE';
          ELSEIF (NOT pup$all_volumes_included ()) AND NOT fmd_exists THEN
            cycle_included := NOT puv$exclude_catalog_information;
            action_descriptor := 'EXCLUDE VOLUME';
          IFEND;
        ELSEIF (NOT fmd_exists) AND (NOT (puc$include_offline_data IN puv$include_data_options)) THEN
          osp$set_status_abnormal (puc$pf_utility_id, pue$empty_cycle_partition, '', status);
          RETURN;
        IFEND;

        IF cycle_included THEN
          IF (NOT (puc$include_releasable_data IN puv$include_data_options)) AND fmd_exists
                AND NOT puv$include_archive_information THEN
            cycle_included := FALSE;
            action_descriptor := 'EXCLUDE CYCLE';
          ELSEIF ((NOT fmd_exists) AND NOT (puc$include_offline_data IN puv$include_data_options)) OR
                ((NOT (puc$include_releasable_data IN puv$include_data_options)) AND fmd_exists) THEN
            IF NOT (avp$family_administrator() OR avp$system_administrator()) THEN
              cycle_included := FALSE;
              action_descriptor := 'EXCLUDE ADMINISTRATOR';
            ELSE
              utility_attach_allowed := FALSE;
            IFEND;
          ELSEIF (puc$include_offline_data IN puv$include_data_options) AND NOT fmd_exists AND
                (cycle_array_entry.data_residence <> pfc$unreleasable_data) THEN
            retrieve_allowed := TRUE;
          IFEND;
        IFEND;
      IFEND;
    IFEND;

    IF ((NOT (puc$include_unreleasable_data IN puv$include_data_options)) AND
          ((p_archive_list = NIL) OR NOT cycle_archived) AND fmd_exists) OR
       ((NOT (puc$include_releasable_data IN puv$include_data_options)) AND
       cycle_archived AND fmd_exists) THEN
      cycle_included := FALSE;
      action_descriptor := 'EXCLUDE CYCLE';
    IFEND;

  PROCEND check_for_arc_related_exclusion;

?? TITLE := '    check_if_cycle_archived ', EJECT ??

  PROCEDURE check_if_cycle_archived
   (    data_modification_date_time: ost$date_time;
        p_archive_list: {i^/o^} pft$p_info_record;
    VAR cycle_archived: boolean;
    VAR status: ost$status);

    VAR
      archive_identification: pft$archive_identification,
      comparison_result: pmt$comparison_result,
      p_archive_entry: pft$p_archive_array_entry,
      p_archive_group: pft$p_info_record,
      p_archive_list_body: pft$p_info,
      p_archive_media: pft$p_amd;

    status.normal := TRUE;
    cycle_archived := FALSE;
    p_archive_list_body := ^p_archive_list^.body;
    IF p_archive_list_body = NIL THEN
      RETURN;
    IFEND;
    archive_identification.application_identifier := osc$null_name;
    archive_identification.media_identifier.media_device_class := osc$null_name;
    archive_identification.media_identifier.media_volume_identifier := '';
    RESET p_archive_list_body;
  /search_archive_list/
    REPEAT
      pfp$find_next_archive_entry (archive_identification, p_archive_list_body, p_archive_group,
            p_archive_entry, p_archive_media, status);
      IF status.normal AND (p_archive_entry <> NIL) THEN
        pmp$date_time_compare (p_archive_entry^.archive_date_time, data_modification_date_time,
              comparison_result, status);
        IF status.normal AND (comparison_result = pmc$left_is_greater) THEN
          cycle_archived := TRUE;
          EXIT /search_archive_list/;
        IFEND;
      IFEND;
    UNTIL (NOT status.normal) OR (p_archive_entry = NIL);

    IF status.condition = pfe$unknown_info_record THEN
      status.normal := TRUE;  { cycle not duplicated }
    IFEND;
  PROCEND check_if_cycle_archived;

?? TITLE := '    get_archive_item_info', EJECT ??

  PROCEDURE get_archive_item_info (
        cycle_array_entry: pft$cycle_array_entry_version_2;
        pf_utility_catalog_header: put$catalog_header;
    VAR file_archive_info: amt$segment_pointer;
    VAR p_cycle_array_extended_record: pft$p_info_record;
    VAR p_cycle_directory_array: pft$p_cycle_directory_array;
    VAR p_cycle_info_record: pft$p_info_record;
    VAR status: ost$status);

    VAR
      group: pft$group,
      p_directory_array: pft$p_directory_array,
      p_info_record: pft$p_info_record,
      p_item_record: pft$p_info_record;

    mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, file_archive_info, status);
    IF status.normal THEN
      group.group_type := pfc$public;
      RESET file_archive_info.sequence_pointer;
      pfp$get_item_info (pf_utility_catalog_header.path, group, $pft$catalog_info_selections [],
            $pft$file_info_selections [pfc$cycle_media_descriptor, pfc$cycle_label_descriptor,
            pfc$archive_descriptors], file_archive_info.sequence_pointer, status);
      display (' pfp$get_item_info');
      display_status (status);
      IF status.normal THEN
        RESET file_archive_info.sequence_pointer;
        pfp$find_next_info_record (file_archive_info.sequence_pointer, p_info_record, status);
        display (' pfp$find_next_info_record');
        display_status (status);
        IF status.normal THEN
          pfp$find_directory_array (p_info_record, p_directory_array, status);
          display (' pfp$find_directory_array');
          display_status (status);
          IF status.normal THEN
            pfp$find_direct_info_record (^p_info_record^.body,
                  p_directory_array^ [LOWERBOUND (p_directory_array^)].info_offset, p_item_record,
                  status);
            display (' pfp$find_direct_info_record');
            display_status (status);
            IF status.normal THEN
              pfp$find_cycle_array_extended (p_item_record, p_cycle_array_extended_record, status);
              display (' pfp$find_cycle_array_extended');
              display_status (status);
              IF status.normal THEN
                pfp$find_cycle_directory (p_cycle_array_extended_record, p_cycle_directory_array, status);
                display (' pfp$find_cycle_directory');
                display_status (status);
                IF status.normal THEN
                  pup$find_cycle_info_record (p_cycle_array_extended_record, p_cycle_directory_array,
                        cycle_array_entry.cycle_number, ^pf_utility_catalog_header.path,
                        p_cycle_info_record, status);
                  display (' pup$find_cycle_info_record');
                  display_status (status);
                IFEND;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND get_archive_item_info;

?? TITLE := '    log_keyed_file_backup', EJECT ??

  PROCEDURE log_keyed_file_backup
    (    path: pft$path;
         cycle_number: fst$cycle_number;
         password: pft$password;
         starting_tape_volume_number: amt$volume_number;
         ending_tape_volume_number: amt$volume_number;
         backup_file_id: put$file_identifier,
         backup_information: amt$backup_information);

    CONST
      library_path = ':$SYSTEM.$SYSTEM.OSF$BUILTIN_LIBRARY';

    VAR
      caller_id: ost$caller_identifier,
      cycle_path_string: ost$string,
      cl_file: clt$file,
      null_global_file_name: [READ, pus$literals] ost$binary_unique_name :=
            [0, osc$cyber_180_model_unknown, 1980, 1, 1, 0, 0, 0, 0, 0],
      p_libraries: ^pmt$object_library_list,
      p_log_keyed_file_parameters: ^put$log_keyed_file_parameters,
      p_parameters: ^SEQ ( * ),
      p_program_attributes: ^pmt$program_attributes,
      p_program_description: ^pmt$program_description,
      p_temp_volume_list: ^rmt$volume_list,
      p_volume_info: ^array [ * ] of fmt$volume_info,
      p_volume_list: ^rmt$volume_list,
      saved_file_path: fst$path,
      status: ost$status,
      task_id: pmt$task_id,
      task_status: pmt$task_status,
      volume: amt$volume_number;

    CASE backup_file_id.device_class OF
    = rmc$mass_storage_device =
      IF backup_information.file_path (1, 7) = ':$LOCAL' THEN
        RETURN;
      IFEND;
      PUSH p_volume_list: [1 .. 1];

    = rmc$magnetic_tape_device =
      { Fetch the volume list.
      PUSH p_volume_list: [starting_tape_volume_number .. ending_tape_volume_number];
      PUSH p_volume_info: [starting_tape_volume_number .. ending_tape_volume_number];
      FOR volume := starting_tape_volume_number TO ending_tape_volume_number DO
        p_volume_info^ [volume].key := fmc$volume;
        p_volume_info^ [volume].requested_volume_number := volume;
      FOREND;
      fmp$get_files_volume_info (backup_file_id.lfn, p_volume_info^, status);
      IF NOT status.normal THEN
        pup$write_os_status (status, status);
        pup$display_line (' UNABLE TO GET TAPE INFO TO LOG KEYED FILE BACKUP', status);
        RETURN;
      IFEND;
      FOR volume := starting_tape_volume_number TO ending_tape_volume_number DO
        IF p_volume_info^ [volume].item_returned THEN
          p_volume_list^ [volume] := p_volume_info^ [volume].volume;
        ELSE
          pup$display_line (' UNABLE TO LOG KEYED FILE BACKUP', status);
          pup$display_integer (' TAPE VOLUME INFO NOT RETURNED FOR VOLUME NUMBER: ', volume, status);
          RETURN;
        IFEND;
      FOREND;

    ELSE {null device}
      RETURN;
    CASEND;

    #CALLER_ID (caller_id);
    pup$convert_cycle_path_to_strng (path, cycle_number, cycle_path_string);
    saved_file_path := cycle_path_string.value (1, cycle_path_string.size);
    IF caller_id.ring >= 4 THEN
      display (' amp$log_keyed_file_backup');
      amp$log_keyed_file_backup (saved_file_path, password, null_global_file_name, backup_information,
            p_volume_list^, status);
    ELSE
      clp$convert_string_to_file (library_path, cl_file, status);
      IF status.normal THEN
        PUSH p_program_description: [[REP (#SIZE (pmt$program_attributes) + #SIZE (amt$local_file_name)) OF
              cell]];
        RESET p_program_description;
        NEXT p_program_attributes IN p_program_description;
        p_program_attributes^ := default_program_attributes;
        NEXT p_libraries: [1 .. 1] IN p_program_description;
        p_libraries^ [1] := cl_file.local_file_name;

        PUSH p_parameters: [[REP #SIZE (put$log_keyed_file_parameters) + #SIZE (p_volume_list^) OF cell]];
        RESET p_parameters;
        NEXT p_log_keyed_file_parameters IN p_parameters;
        p_log_keyed_file_parameters^.path := saved_file_path;
        p_log_keyed_file_parameters^.path_size := cycle_path_string.size;
        p_log_keyed_file_parameters^.password := password;
        p_log_keyed_file_parameters^.global_file_name := null_global_file_name;
        p_log_keyed_file_parameters^.backup_information := backup_information;
        p_log_keyed_file_parameters^.volume_list_size := UPPERBOUND (p_volume_list^) -
              LOWERBOUND(p_volume_list^) + 1;
        NEXT p_temp_volume_list: [LOWERBOUND(p_volume_list^) .. UPPERBOUND (p_volume_list^)] IN p_parameters;
        p_temp_volume_list^ := p_volume_list^;

        display (' Call pmp$execute_with_less_privilege');
        pmp$execute_with_less_privilege ({execution_ring} 4, p_program_description^, p_parameters^,
              osc$wait, {cl_task} FALSE, task_id, task_status, status);
      IFEND;
    IFEND;

    IF NOT status.normal THEN
      pup$write_os_status (status, status);
      pup$display_line (' UNABLE TO LOG KEYED FILE BACKUP', status);
      RETURN;
    IFEND;
  PROCEND log_keyed_file_backup;

?? SKIP := 2 ??
MODEND pum$backup_cycle;
