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

{  PURPOSE:
{    This module manages interfaces to the access method to read or write the backup file.

?? NEWTITLE := '    Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc pus$literals
*copyc osd$integer_limits
*copyc pud$backup_file
*copyc pud$hierarchy_list
*copyc dme$tape_errors
*copyc pue$error_condition_codes
*copyc amt$backup_information
*copyc fst$goi_object_information
*copyc fst$tape_attachment_information
*copyc ost$name
*copyc put$file_identifier
*copyc put$file_position
*copyc put$global_backup_file_id
*copyc put$operation
*copyc rmt$device_class
?? POP ??
*copyc amp$close_volume
*copyc amp$fetch_access_information
*copyc amp$get_file_attributes
*copyc amp$get_partial
*copyc amp$put_next
*copyc amp$put_partial
*copyc amp$skip
*copyc amp$skip_tape_marks
*copyc amp$write_end_partition
*copyc amp$write_tape_mark
*copyc clp$convert_file_ref_to_string
*copyc clp$convert_str_to_path_handle
*copyc clp$convert_string_to_file
*copyc clp$evaluate_parameters
*copyc clp$get_fs_path_string
*copyc fmp$get_files_volume_info
*copyc fsp$close_file
*copyc fsp$get_tape_label_attributes
*copyc fsp$open_file
*copyc osp$append_status_file
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc pfp$get_object_information
*copyc pup$allow_job_termination
*copyc pup$display_blank_lines
*copyc pup$display_line
*copyc pup$write_os_status
*copyc puv$backup_file_id
*copyc puv$backup_information
*copyc puv$prev_open_by_$backup_file
*copyc puv$trace_selected
?? TITLE := '    Global Variables', EJECT ??

  VAR
    puv$global_backup_file_id: [XDCL] put$global_backup_file_id := [FALSE],
    puv$last_volume_number: [XDCL] amt$volume_number := 1,
    puv$volumes_switched_forward: [XDCL] boolean := FALSE;

  VAR
    backup_file_info_request: [pus$literals, READ] fst$goi_information_request :=
          [[fsc$specific_depth, 1], [fsc$goi_job_environment_info]],
    skipped_tape_mark: boolean := FALSE,
    volume_position_table: [pus$literals, READ] array [amt$volume_position] of string (25) :=
          ['AMC$AFTER_DATA_BLOCK', 'AMC$AFTER_TAPE_MARK', 'AMC$BEFORE_TAPEMARK', 'AMC$BOV', 'AMC$EOV',
          'AMC$MID_BOV_LABEL_GROUP', 'AMC$MID_EOF_LABEL_GROUP', 'AMC$MID_EOV_LABEL_GROUP',
          'AMC$MID_HDR_LABEL_GROUP', 'AMC$POSITION_UNCERTAIN'];

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

  PROCEDURE [XDCL] pup$close_backup_file
    (VAR file_id: put$file_identifier;
     VAR status: ost$status);

    status.normal := TRUE;
    display (' Enter pup$close backup file');
    IF puv$global_backup_file_id.backup_file_open THEN
      fsp$close_file (file_id.file_id, status);
      display_status (status);
    IFEND;

    IF file_id.operation = puc$$backup_file THEN
      puv$prev_open_by_$backup_file := TRUE;
    ELSE
      puv$prev_open_by_$backup_file := FALSE;
    IFEND;

    puv$global_backup_file_id.backup_file_open := FALSE;

  PROCEND pup$close_backup_file;
?? TITLE := '    [XDCL] pup$close_volume', EJECT ??

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

{ PROCEDURE close_volume (
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [104, 5, 17, 13, 22, 32, 229],
    clc$command, 1, 1, 0, 0, 0, 0, 1, ''], [
    ['STATUS                         ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$status_type]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$status = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    display (' Enter pup$close_volume');
    amp$close_volume (puv$backup_file_id.file_id, status);

  PROCEND pup$close_volume;
?? TITLE := '    determine_backup_file_attr', EJECT ??

  PROCEDURE determine_backup_file_attr
    (VAR file_id: {input, output} put$file_identifier;
     VAR mandated_creation_attributes: ^fst$file_cycle_attributes;
     VAR file_attachment: ^fst$attachment_options;
     VAR attribute_validation: ^fst$file_cycle_attributes;
     VAR backup_file_phn: fst$path_handle_name;
     VAR status: ost$status);

{ This routine determines the device class of a file and file attributes of the backup file.

    CONST
      file_connections = 15, {generous limit for estimating size of sequence}

      {target file attribute array indices:
      tf_bt = 1,
      tf_dc = 2,
      tf_fc = 3,
      tf_flt = 4,
      tf_rt = 5,

      {file attachment array indices:
      amsm = 1 {access and share modes} ,
      osm = 2 {open share modes} ,
      pr = 3 {private read} ,
      cf = 4 {create file} ,
      op = 5 {open position} ,
      fsp = 6 {file set position} ,
      rl = 7 {rewrite labels} ,

      {file cycle attribute array indices:
      bt = 1 {block type} ,
      rt = 2 {record type} ,
      flt = 3 {file label type} ,
      fcfp = 4 {file contents and processor} ;

    VAR
      backup_file_path: fst$path,
      backup_file_path_size: fst$path_size,
      connected_files_list: ^fst$target_file_list,
      contains_data: boolean,
      evaluated_file_reference: fst$evaluated_file_reference,
      file_attributes: array [1 .. 5] of amt$get_item,
      file_previously_opened: boolean,
      ignore_path_handle: fmt$path_handle,
      ignore_returned_attributes: fst$tla_returned_attributes,
      index: ost$positive_integers,
      information_request: fst$goi_information_request,
      local_file: boolean,
      local_status: ost$status,
      p_object_info_seq: ^SEQ ( * ),
      p_object_information: ^fst$goi_object_information,
      true_device_class: rmt$device_class;

    display (' amp$get_file_attributes');
    file_attributes [1].key := amc$label_type;
    file_attributes [2].key := amc$open_position;
    file_attributes [3].key := amc$device_class;
    file_attributes [4].key := amc$null_attribute;
    file_attributes [5].key := amc$null_attribute;
    amp$get_file_attributes (file_id.lfn, file_attributes, local_file, file_previously_opened, contains_data,
          status);
    IF status.normal THEN
      file_id.label_type := file_attributes [1].label_type;
      file_id.open_position := file_attributes [2].open_position;
      file_id.device_class := file_attributes [3].device_class;

      true_device_class := file_attributes [3].device_class;
      backup_file_phn := file_id.lfn;

      CASE file_id.device_class OF
      = rmc$mass_storage_device =
        display ('   MASS_STORAGE');
        file_id.record_type := amc$variable;
      = rmc$magnetic_tape_device =
        display ('   TAPE');
        IF file_id.label_type = amc$unlabelled THEN
          file_id.record_type := amc$undefined;
        ELSE
          file_id.record_type := amc$variable;
        IFEND;
      = rmc$null_device =
        display ('   NULL');
        file_id.record_type := amc$variable;
      = rmc$connected_file_device =
        display ('   CONNECTED_FILE_DEVICE');
        PUSH p_object_info_seq: [[REP #SIZE (fst$goi_object_information) OF cell,
              REP fsc$max_path_size OF cell, REP #SIZE (fst$goi_object) OF
              cell, REP #SIZE (fst$job_environment_information) OF cell, REP
              (file_connections * #SIZE (fst$path)) OF cell]];
        information_request := backup_file_info_request;
        pfp$get_object_information (file_id.lfn, information_request, NIL, p_object_info_seq, status);
        IF NOT status.normal THEN
          display_status (status);
          RETURN; {----->
        IFEND;
        RESET p_object_info_seq;
        NEXT p_object_information IN p_object_info_seq;
        IF (p_object_information <> NIL) AND (p_object_information^.object <> NIL) AND
              (p_object_information^.object^.job_environment_information <> NIL) AND
              (p_object_information^.object^.job_environment_information^.connected_files <> NIL) THEN
          connected_files_list := p_object_information^.object^.job_environment_information^.connected_files;
          file_attributes [tf_bt].key := amc$block_type;
          file_attributes [tf_dc].key := amc$device_class;
          file_attributes [tf_fc].key := amc$file_contents;
          file_attributes [tf_flt].key := amc$label_type;
          file_attributes [tf_rt].key := amc$record_type;
          FOR index := 1 TO UPPERBOUND (connected_files_list^) DO
            amp$get_file_attributes (connected_files_list^ [index], file_attributes, local_file,
                  file_previously_opened, contains_data, status);
            IF status.normal THEN
              IF index = 1 THEN
                file_id.device_class := file_attributes [tf_dc].device_class;
                file_id.label_type := file_attributes [tf_flt].label_type;
                CASE file_id.device_class OF
                = rmc$magnetic_tape_device =
                  IF file_id.label_type = amc$unlabeled THEN
                    file_id.record_type := amc$undefined;
                  ELSE
                    file_id.record_type := amc$variable;
                  IFEND;
                = rmc$mass_storage_device, rmc$null_device =
                  file_id.record_type := amc$variable;
                ELSE
                  osp$set_status_condition (pue$invalid_device_type, status);
                  osp$append_status_file (osc$status_parameter_delimiter, connected_files_list^ [index],
                        status);
                CASEND;
              ELSE
                IF file_attributes [tf_dc].device_class = file_id.device_class THEN
                  IF (file_attributes [tf_dc].device_class = rmc$magnetic_tape_device) AND
                        (file_attributes [tf_flt].label_type <> file_id.label_type) THEN
                    osp$set_status_condition (pue$invalid_file_connection, status);
                    clp$get_fs_path_string (file_id.lfn, backup_file_path, backup_file_path_size,
                          ignore_path_handle, local_status);
                    osp$append_status_file (osc$status_parameter_delimiter,
                          backup_file_path (1, backup_file_path_size), status);
                  IFEND;
                ELSE
                  osp$set_status_condition (pue$invalid_file_connection, status);
                  clp$get_fs_path_string (file_id.lfn, backup_file_path, backup_file_path_size,
                        ignore_path_handle, local_status);
                  osp$append_status_file (osc$status_parameter_delimiter,
                        backup_file_path (1, backup_file_path_size), status);
                IFEND;
              IFEND;
            IFEND;
            IF ((file_id.device_class = rmc$mass_storage_device) OR
                  ((file_id.device_class = rmc$magnetic_tape_device) AND
                  (file_id.label_type = amc$unlabeled) AND (file_id.record_type = amc$undefined))) AND
                  (file_attributes [tf_bt].block_type <> amc$system_specified) THEN
              osp$set_status_condition (pue$invalid_file_connection, status);
              clp$get_fs_path_string (file_id.lfn, backup_file_path, backup_file_path_size,
                    ignore_path_handle, local_status);
              osp$append_status_file (osc$status_parameter_delimiter,
                    backup_file_path (1, backup_file_path_size), status);
            IFEND;
            IF NOT status.normal THEN
              display_status (status);
              RETURN; {----->
            IFEND;
          FOREND;

{ Convert the oldest target file path to a path handle name for input to pup$fetch_backup_information

          clp$convert_str_to_path_handle (connected_files_list^ [UPPERBOUND (connected_files_list^)],
                {delete_allowed} FALSE, {resolve_path} TRUE, {include_open_pos_in_handle} FALSE,
                backup_file_phn, evaluated_file_reference, status);
          IF NOT status.normal THEN
            display_status (status);
            RETURN; {----->
          IFEND;
        IFEND;
      ELSE
        osp$set_status_condition (pue$invalid_device_type, status);
        clp$get_fs_path_string (file_id.lfn, backup_file_path, backup_file_path_size, ignore_path_handle,
              local_status);
        osp$append_status_file (osc$status_parameter_delimiter, backup_file_path (1, backup_file_path_size),
              status);
        display_status (status);
      CASEND;

      IF file_id.device_class = rmc$magnetic_tape_device THEN
        IF file_id.record_type = amc$undefined THEN
          mandated_creation_attributes^ [bt].selector := fsc$block_type;
          mandated_creation_attributes^ [bt].block_type := amc$system_specified;
        ELSEIF file_id.record_type = amc$variable THEN
          mandated_creation_attributes^ [bt].selector := fsc$null_attribute;
        IFEND;
        mandated_creation_attributes^ [flt].selector := fsc$file_label_type;
        mandated_creation_attributes^ [flt].file_label_type := file_id.label_type;
      ELSE
        mandated_creation_attributes^ [bt].selector := fsc$block_type;
        mandated_creation_attributes^ [bt].block_type := amc$system_specified;
        mandated_creation_attributes^ [flt].selector := fsc$null_attribute;
      IFEND;
      mandated_creation_attributes^ [rt].selector := fsc$record_type;
      mandated_creation_attributes^ [rt].record_type := file_id.record_type;
      mandated_creation_attributes^ [fcfp].selector := fsc$file_contents_and_processor;
      mandated_creation_attributes^ [fcfp].file_contents := 'FILE_BACKUP';
      mandated_creation_attributes^ [fcfp].file_processor := osc$null_name;

      IF file_id.device_class = rmc$magnetic_tape_device THEN
        IF file_id.record_type = amc$undefined THEN
          attribute_validation^ [bt].selector := fsc$block_type;
          attribute_validation^ [bt].block_type := amc$system_specified;
        ELSEIF file_id.record_type = amc$variable THEN
          attribute_validation^ [bt].selector := fsc$null_attribute;
        IFEND;
      ELSE
        attribute_validation^ [bt].selector := fsc$block_type;
        attribute_validation^ [bt].block_type := amc$system_specified;
      IFEND;
      attribute_validation^ [rt].selector := fsc$record_type;
      attribute_validation^ [rt].record_type := file_id.record_type;
      attribute_validation^ [flt].selector := fsc$null_attribute;

      file_attachment^ [amsm].selector := fsc$access_and_share_modes;
      file_attachment^ [amsm].access_modes.selector := fsc$specific_access_modes;
      file_attachment^ [amsm].share_modes.selector := fsc$specific_share_modes;
      file_attachment^ [osm].selector := fsc$open_share_modes;
      file_attachment^ [pr].selector := fsc$private_read;
      file_attachment^ [cf].selector := fsc$create_file;
      file_attachment^ [op].selector := fsc$open_position;
      file_attachment^ [fsp].selector := fsc$null_attachment_option;
      file_attachment^ [rl].selector := fsc$null_attachment_option;

      IF file_id.operation = puc$backup_permanent_files THEN

        file_attachment^ [pr].selector := fsc$null_attachment_option;
        file_attachment^ [cf].create_file := TRUE;
        file_attachment^ [op].open_position := file_id.open_position;
        CASE true_device_class OF
        = rmc$null_device =
          file_attachment^ [amsm].access_modes.value := $fst$file_access_options
                [fsc$read, fsc$append, fsc$shorten];
          file_attachment^ [amsm].share_modes.value := $fst$file_access_options [];
          file_attachment^ [osm].open_share_modes := -$fst$file_access_options [];

        = rmc$connected_file_device, rmc$mass_storage_device =
          file_attachment^ [amsm].access_modes.value := $fst$file_access_options [fsc$append, fsc$shorten];
          file_attachment^ [amsm].share_modes.value := $fst$file_access_options [];
          file_attachment^ [osm].open_share_modes := $fst$file_access_options [];

        = rmc$magnetic_tape_device =
          file_attachment^ [amsm].access_modes.value := $fst$file_access_options [fsc$append, fsc$shorten];
          file_attachment^ [amsm].share_modes.value := $fst$file_access_options [];
          file_attachment^ [osm].open_share_modes := $fst$file_access_options [fsc$read];
          file_attachment^ [fsp].selector := fsc$tape_attachment;
          file_attachment^ [fsp].tape_attachment.selector := fsc$tape_file_set_position;
          file_attachment^ [fsp].tape_attachment.tape_file_set_position.position := fsc$tape_beginning_of_set;
          file_attachment^ [rl].selector := fsc$tape_attachment;
          file_attachment^ [rl].tape_attachment.selector := fsc$tape_rewrite_labels;
          file_attachment^ [rl].tape_attachment.tape_rewrite_labels :=
                (file_id.open_position = amc$open_at_boi);

          {A CHATLA command overrides the above defaults}

          fsp$get_tape_label_attributes (file_id.lfn, fsc$tla_explicit_specification, file_attachment^,
                ignore_returned_attributes, local_status);
        ELSE
        CASEND;
      ELSE

        file_attachment^ [cf].create_file := FALSE;
        file_attachment^ [op].open_position := file_id.open_position;
        CASE true_device_class OF
        = rmc$null_device =
          file_attachment^ [amsm].access_modes.value := $fst$file_access_options [fsc$read];
          file_attachment^ [amsm].share_modes.value := $fst$file_access_options [fsc$read];
          file_attachment^ [osm].open_share_modes := -$fst$file_access_options [];
          file_attachment^ [pr].private_read := FALSE;

        = rmc$mass_storage_device =
          file_attachment^ [amsm].access_modes.value := $fst$file_access_options [fsc$read];
          file_attachment^ [amsm].share_modes.value := $fst$file_access_options [fsc$read, fsc$execute];
          file_attachment^ [osm].open_share_modes := $fst$file_access_options
                [fsc$read, fsc$append, fsc$shorten];
          file_attachment^ [pr].private_read := FALSE;

        = rmc$magnetic_tape_device =
          file_attachment^ [amsm].access_modes.value := $fst$file_access_options [fsc$read];
          file_attachment^ [amsm].share_modes.value := $fst$file_access_options [];
          file_attachment^ [osm].open_share_modes := $fst$file_access_options
                [fsc$read, fsc$append, fsc$shorten];
          file_attachment^ [pr].private_read := TRUE;
          file_attachment^ [fsp].selector := fsc$tape_attachment;
          file_attachment^ [fsp].tape_attachment.selector := fsc$tape_file_set_position;
          file_attachment^ [fsp].tape_attachment.tape_file_set_position.position := fsc$tape_beginning_of_set;
          file_attachment^ [rl].selector := fsc$tape_attachment;
          file_attachment^ [rl].tape_attachment.selector := fsc$tape_rewrite_labels;
          file_attachment^ [rl].tape_attachment.tape_rewrite_labels := FALSE;

          {A CHATLA command overrides the above defaults}

          fsp$get_tape_label_attributes (file_id.lfn, fsc$tla_explicit_specification, file_attachment^,
                ignore_returned_attributes, local_status);

          IF puv$prev_open_by_$backup_file THEN
            file_attachment^ [fsp].tape_attachment.tape_file_set_position.position := fsc$tape_current_file;
          IFEND;
        ELSE
        CASEND;
      IFEND;

    ELSE
      display_status (status);
      file_id.device_class := rmc$mass_storage_device;
      file_id.label_type := amc$labelled;
      file_id.open_position := amc$open_at_boi;
    IFEND;

  PROCEND determine_backup_file_attr;

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

  PROCEDURE [XDCL] pup$display_volume_switch
    (    backup_file_id: put$file_identifier);

{ This procedure displays the external and recorded vsn of the current volume if
{ a volume switch has occurred.

    VAR
      current_volume: rmt$recorded_vsn,
      current_volume_number: amt$volume_number,
      local_status: ost$status,
      outputline: string (80),
      outputline_index: integer,
      status: ost$status,
      volume_description: rmt$volume_descriptor;

    fetch_volume_number (backup_file_id, current_volume_number);
    puv$volumes_switched_forward := (current_volume_number > puv$last_volume_number);
    IF current_volume_number <> puv$last_volume_number THEN
      puv$last_volume_number := current_volume_number;
      pup$display_blank_lines (6, local_status);
      STRINGREP (outputline, outputline_index, ' NOW ON TAPE NUMBER: ', puv$last_volume_number);
      get_volume_description (backup_file_id.file_id, current_volume_number, volume_description, status);
      IF status.normal THEN
        STRINGREP (outputline, outputline_index, outputline (1, outputline_index), '      EXTERNAL VSN: ',
              volume_description.external_vsn);
      ELSE
        display_status (status);
      IFEND;

      IF backup_file_id.label_type <> amc$unlabelled THEN
        STRINGREP (outputline, outputline_index, outputline (1, outputline_index), '      RECORDED VSN: ',
              volume_description.recorded_vsn);
        pup$display_line ('******************************************************************************',
              local_status);
        pup$display_line (outputline (1, outputline_index), local_status);
        pup$display_line ('******************************************************************************',
              local_status);
      ELSE
        pup$display_line ('****************************************************', local_status);
        pup$display_line (outputline (1, outputline_index), local_status);
        pup$display_line ('****************************************************', local_status);
      IFEND;
      pup$display_blank_lines (6, local_status);
    IFEND;
  PROCEND pup$display_volume_switch;

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

  PROCEDURE [XDCL] pup$fetch_backup_information
    (    device_class: rmt$device_class;
         backup_file_phn: fst$path_handle_name;
     VAR backup_information: amt$backup_information;
     VAR status: ost$status);

    CONST
      command_file_reference_allowed = TRUE,
      include_open_position = TRUE,
      record_path = TRUE,
      resolve_to_catalog = TRUE;

    VAR
      evaluated_file_reference: fst$evaluated_file_reference,
      file_registered: boolean,
      fs_path: fst$path,
      fs_path_size: fst$path_size,
      ignore_status: ost$status,
      p_path: ^pft$path,
      path_handle_name: fst$path_handle_name,
      path_resolution: fst$path_resolution,
      tape_volume_info: array [1 .. 2] of fmt$volume_info,
      temporary_file: boolean;

    backup_information.media := device_class;

    CASE device_class OF
    = rmc$mass_storage_device =
      clp$convert_str_to_path_handle (backup_file_phn, {delete_allowed =} TRUE, {resolve_path =} TRUE,
            NOT include_open_position, path_handle_name, evaluated_file_reference, status);
      IF status.normal THEN
        clp$convert_file_ref_to_string (evaluated_file_reference, NOT include_open_position, fs_path,
              fs_path_size, ignore_status);
        backup_information.file_path := fs_path (1, fs_path_size);
      IFEND;

    = rmc$magnetic_tape_device =
      tape_volume_info [1].key := fmc$tape_class;
      tape_volume_info [2].key := fmc$tape_density;
      fmp$get_files_volume_info (backup_file_phn, tape_volume_info, status);
      IF NOT status.normal THEN
        RETURN {----->
      IFEND;
      backup_information.class := tape_volume_info [1].tape_class;
      backup_information.density := tape_volume_info [2].tape_density;
    ELSE
    CASEND;
  PROCEND pup$fetch_backup_information;

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

  PROCEDURE [XDCL] pup$fetch_current_volume
    (    backup_file_id: put$file_identifier;
     VAR volume_number: amt$volume_number;
     VAR volume_description: rmt$volume_descriptor;
     VAR status: ost$status);

    fetch_volume_number (backup_file_id, volume_number);
    get_volume_description (backup_file_id.file_id, volume_number, volume_description, status);

  PROCEND pup$fetch_current_volume;
?? TITLE := '    [XDCL] pup$get_part', EJECT ??
*copyc puh$get_part

  PROCEDURE [XDCL] pup$get_part
    (VAR backup_file_id: put$file_identifier {source} ;
         wsa: ^cell {destination} ;
         working_storage_length: amt$working_storage_length;
     VAR file_position: put$file_position;
     VAR transfer_count: amt$file_length;
     VAR status: ost$status);

    VAR
      bam_file_position: amt$file_position,
      partial_transfer_count: amt$transfer_count,
      previous_status: ost$status;

    transfer_count := 0;

    get_partial (backup_file_id, wsa, working_storage_length, partial_transfer_count, bam_file_position,
          file_position, status);
    IF status.normal THEN
      transfer_count := partial_transfer_count;
      IF partial_transfer_count <> working_storage_length THEN
        display (' **** mismatch on transfer count ****');
        osp$set_status_abnormal (puc$pf_utility_id, pue$unusable_restore_file,
              ' data lost, requested (bytes):', status);
        osp$append_status_integer (osc$status_parameter_delimiter, working_storage_length, 10, FALSE, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, '  actually received:', status);
        osp$append_status_integer (osc$status_parameter_delimiter, partial_transfer_count, 10, FALSE, status);
        IF (partial_transfer_count <= 0) AND (bam_file_position = amc$eoi) AND (file_position <> puc$eoi) THEN
          { Tape file: Attempt to force end_of_volume.
          previous_status := status;
          get_partial (backup_file_id, wsa, working_storage_length, partial_transfer_count, bam_file_position,
                file_position, status);
          IF status.normal AND (file_position <> puc$eoi) AND
                ((NOT puv$volumes_switched_forward) OR (working_storage_length <>
                #SIZE (put$backup_file_version_name))) THEN
            pup$write_os_status (previous_status, status);
            pup$display_line (' Unexpected volume position after 0 transfer count.', status);
            IF partial_transfer_count <> working_storage_length THEN
              display (' **** mismatch on transfer count ****');
              osp$set_status_abnormal (puc$pf_utility_id, pue$unusable_restore_file,
                    ' data lost, requested (bytes):', status);
              osp$append_status_integer (osc$status_parameter_delimiter, working_storage_length, 10, FALSE,
                    status);
              osp$append_status_parameter (osc$status_parameter_delimiter, '  actually received:', status);
              osp$append_status_integer (osc$status_parameter_delimiter, partial_transfer_count, 10, FALSE,
                    status);
            IFEND;
          IFEND;
        IFEND
      IFEND;
    IFEND;
  PROCEND pup$get_part;

?? TITLE := '    [XDCL] pup$open_backup_file', EJECT ??
*copy puh$open_backup_file

  PROCEDURE [XDCL] pup$open_backup_file
    (    backup_file: fst$file_reference;
         operation: put$operation;
         open_position: amt$open_position;
     VAR file_id: put$file_identifier;
     VAR status: ost$status);


    CONST
      av_max = 3,
      fa_max = 7,
      mca_max = 4;

    VAR
      attribute_validation: ^fst$file_cycle_attributes,
      backup_file_lfn: clt$file,
      backup_file_phn: fst$path_handle_name,
      byte_address: amt$file_byte_address,
      default_creation_attributes: ^fst$file_cycle_attributes,
      file_attachment: ^fst$attachment_options,
      file_position: amt$file_position,
      mandated_creation_attributes: ^fst$file_cycle_attributes,
      transfer_count: amt$transfer_count,
      volume_description: rmt$volume_descriptor;

    display (' pup$open_backup_file');
    clp$convert_string_to_file (backup_file, backup_file_lfn, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    file_id.lfn := backup_file_lfn.local_file_name;
    file_id.operation := operation;

    PUSH mandated_creation_attributes: [1 .. mca_max];
    PUSH file_attachment: [1 .. fa_max];
    PUSH attribute_validation: [1 .. av_max];

    determine_backup_file_attr (file_id, mandated_creation_attributes, file_attachment, attribute_validation,
          backup_file_phn, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    default_creation_attributes := NIL;

    IF puv$global_backup_file_id.backup_file_open THEN
      display (' Close backup file prior to open.');
      pup$close_backup_file (puv$global_backup_file_id.backup_file_id, status);
    IFEND;

    display_open_position (file_id.open_position);
    display (' fsp$open_file backup_file');
    fsp$open_file (backup_file_lfn.local_file_name, {access_level} amc$record, file_attachment,
          default_creation_attributes, mandated_creation_attributes, attribute_validation,
          {override_attributes} NIL, file_id.file_id, status);
    display_status (status);
    puv$global_backup_file_id.backup_file_open := status.normal;
    IF puv$global_backup_file_id.backup_file_open THEN
      puv$global_backup_file_id.backup_file_id := file_id;
      pup$fetch_backup_information (file_id.device_class, backup_file_phn, puv$backup_information, status);
    IFEND;

    IF status.normal THEN
      display_integer (' backup_file_id.ordinal:', file_id.file_id.ordinal);
    IFEND;

  PROCEND pup$open_backup_file;

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

  PROCEDURE [XDCL] pup$put_next
    (VAR file_id: put$file_identifier;
         wsa: ^cell;
         wsl: amt$working_storage_length;
     VAR status: ost$status);

    VAR
      byte_address: amt$file_byte_address,
      local_status: ost$status;

    display_integer (' *** amp$put_next wsl: ', wsl);

    amp$put_next (file_id.file_id, wsa, wsl, byte_address, local_status);
    IF local_status.normal THEN
      display_integer ('     STATUS NORMAL byte address: ', byte_address);
    ELSE
      display_status (local_status);
    IFEND;
    process_write_status (local_status, file_id, status);
  PROCEND pup$put_next;

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

  PROCEDURE [XDCL] pup$put_partial
    (VAR file_id: put$file_identifier;
         wsa: ^cell;
         wsl: amt$working_storage_length;
         term_option: amt$term_option;
     VAR status: ost$status);

    VAR
      byte_address: amt$file_byte_address,
      local_status: ost$status;

    display_integer (' *** amp$put_partial wsl: ', wsl);
    display_term_option (term_option);
    amp$put_partial (file_id.file_id, wsa, wsl, byte_address, term_option, local_status);
    IF local_status.normal THEN
      display_integer ('     STATUS NORMAL byte address: ', byte_address);
    ELSE
      display_status (local_status);
    IFEND;
    process_write_status (local_status, file_id, status);
  PROCEND pup$put_partial;

?? TITLE := '    [XDCL] pup$skip_logical_partition', EJECT ??
*copy puh$skip_logical_partition

  PROCEDURE [XDCL] pup$skip_logical_partition
    (VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      bam_file_position: amt$file_position,
      local_status: ost$status,
      tape_failure_isolation: amt$tape_failure_isolation,
      volume_position: amt$volume_position;

    display (' *** pup$skip_logical_partition');
    pup$allow_job_termination;

    CASE backup_file_id.device_class OF
    = rmc$mass_storage_device, rmc$null_device =
      display ('     amp$skip amc$forward amc$skip_partition');
      amp$skip (backup_file_id.file_id, amc$forward, amc$skip_partition, {skip_count =} 0, bam_file_position,
            status);
      display_status (status);
      IF status.normal THEN
        convert_to_logical_position (backup_file_id, bam_file_position, file_position, status);
      ELSEIF status.condition = ame$skip_encountered_eoi THEN
        file_position := puc$eoi;
        status.normal := TRUE;
      IFEND;

    = rmc$magnetic_tape_device =
      IF backup_file_id.label_type = amc$unlabelled THEN
        display ('     amp$skip amc$forward amc$skip_tape_mark 1');
        amp$skip (backup_file_id.file_id, amc$forward, amc$skip_tape_mark, {skip_count =} 1,
              bam_file_position, status);
        display_status (status);
        skipped_tape_mark := TRUE;
        IF status.normal THEN
          { Check if we've skipped into EOV.
          verify_vol_position_after_skip (backup_file_id, file_position, status);
        ELSEIF status.condition = ame$skip_encountered_eoi THEN
          file_position := puc$eoi;
          status.normal := TRUE;
        ELSE { An unexpected error occurred. Close out the tape file and try again.
          pup$write_os_status (status, status);
          pup$display_line (' ----- SKIPPING PAST ERROR', local_status);
          pup$skip_physical_partition (backup_file_id, file_position, status);
          IF status.normal THEN
            pup$display_line (' ----- SKIP SUCCESSFULL', local_status);
          IFEND;
        IFEND;
        IF status.normal THEN
          pup$display_volume_switch (backup_file_id);
        IFEND;
        IF status.normal AND puv$volumes_switched_forward THEN
          { Tapes may have positioned one tape mark too far. Reposition to start
          { of reel.
          display ('     amp$skip amc$backward 3');
          amp$skip (backup_file_id.file_id, amc$backward, amc$skip_tape_mark, {skip_count =} 3,
                bam_file_position, status);
          display_status (status);
          verify_vol_position_after_skip (backup_file_id, file_position, status);
        IFEND;
      ELSE

      /skip_loop/
        WHILE TRUE DO
          display ('     amp$skip amc$forward amc$skip_partition');
          amp$skip (backup_file_id.file_id, amc$forward, amc$skip_partition, {skip_count =} 0,
                bam_file_position, status);
          display_status (status);
          IF status.normal THEN
            pup$display_volume_switch (backup_file_id);
          IFEND;
          IF status.normal THEN
            convert_to_logical_position (backup_file_id, bam_file_position, file_position, status);
            EXIT /skip_loop/; {----->
          ELSEIF status.condition = ame$skip_encountered_eoi THEN
            file_position := puc$eoi;
            status.normal := TRUE;
            EXIT /skip_loop/; {----->
          ELSEIF status.condition = ame$improper_record_header THEN
            pup$display_line (' Record header error - file or catalog information has been lost.',
                  local_status);
            pup$write_os_status (status, local_status);
            CYCLE /skip_loop/; {----->
          ELSEIF status.condition = ame$unrecovered_read_error THEN
            fetch_tape_failure_isolation (backup_file_id, tape_failure_isolation);
            IF (tape_failure_isolation.failed_at_current_position) AND
                  (amc$tfm_data_parity_error IN tape_failure_isolation.failure_modes) THEN
              pup$display_line (' Unrecovered read error - file or catalog information has been lost.',
                    local_status);
              pup$write_os_status (status, local_status);
              CYCLE /skip_loop/; {----->
            ELSE
              EXIT /skip_loop/; {----->
            IFEND;
          ELSE
            EXIT /skip_loop/; {----->
          IFEND;
        WHILEND /skip_loop/;
      IFEND;
    ELSE
    CASEND;
    display (' end pup$skip_logical_partition');
  PROCEND pup$skip_logical_partition;

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

  PROCEDURE [XDCL] pup$skip_physical_partition
    (VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      bam_file_position: amt$file_position,
      local_status: ost$status;

    display (' *** pup$skip_physical_partition');
    CASE backup_file_id.device_class OF
    = rmc$mass_storage_device, rmc$null_device =
      pup$skip_logical_partition (backup_file_id, file_position, status);

    = rmc$magnetic_tape_device =
      IF backup_file_id.label_type = amc$unlabelled THEN
        { Use the close, skip, open sequence in this routine so that any error
        { conditions will be reset by the close.
        pup$close_backup_file (backup_file_id, status);
        IF status.normal THEN
          display ('     amp$skip_tape_mark amc$forward 1');
          amp$skip_tape_marks (backup_file_id.lfn, amc$forward, 1, status);
          display_status (status);
          file_position := puc$partition_boundary;
          pup$open_backup_file (backup_file_id.lfn, puc$restore_permanent_files, amc$open_no_positioning,
                backup_file_id, local_status);
          IF status.normal THEN
            status := local_status;
          IFEND;
          IF status.normal THEN
            verify_vol_position_after_skip (backup_file_id, file_position, status);
          IFEND;
        IFEND;
      ELSE
        pup$skip_logical_partition (backup_file_id, file_position, status);
      IFEND;
    ELSE
    CASEND;
    display (' end pup$skip_physical_partition');
  PROCEND pup$skip_physical_partition;

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

  PROCEDURE [XDCL] pup$write_logical_partition
    (VAR backup_file_id: put$file_identifier;
     VAR status: ost$status);

    VAR
      local_status: ost$status;

    CASE backup_file_id.device_class OF
    = rmc$mass_storage_device, rmc$null_device =
      display (' *** amp$write_end_partition');
      amp$write_end_partition (backup_file_id.file_id, local_status);

    = rmc$magnetic_tape_device =
      IF backup_file_id.label_type = amc$unlabelled THEN
        display (' *** amp$write_tape_mark ***');
        amp$write_tape_mark (backup_file_id.file_id, local_status);
        IF local_status.normal THEN
          pup$display_volume_switch (backup_file_id);
        IFEND;
      ELSE
        display (' *** amp$write_end_partition');
        amp$write_end_partition (backup_file_id.file_id, local_status);
        IF local_status.normal THEN
          pup$display_volume_switch (backup_file_id);
        IFEND;
      IFEND;
    ELSE
    CASEND;
    display_status (local_status);
    process_write_status (local_status, backup_file_id, status);
    pup$allow_job_termination;
  PROCEND pup$write_logical_partition;


?? TITLE := '    [INLINE] convert_to_logical_position', EJECT ??

  PROCEDURE [INLINE] convert_to_logical_position
    (    file_id: put$file_identifier;
         bam_file_position: amt$file_position;
     VAR utility_file_position: put$file_position;
     VAR status: ost$status);

{ This routine converts a bam file position into a pf utility file position.
{ The pf utility does not use/recognize end-of-record, and for magnetic tape
{ uses a single tapemark as a partition boundary.

    VAR
      ignored_status: ost$status,
      volume_position: amt$volume_position;

    status.normal := TRUE;
    display_file_position (bam_file_position);

    CASE bam_file_position OF
    = amc$boi =
      utility_file_position := puc$boi;

    = amc$bop, amc$eop =
      { Or do these need to be seperated?
      utility_file_position := puc$partition_boundary;

    = amc$mid_record, amc$eor =
      utility_file_position := puc$mid_partition;

    = amc$eoi =
      utility_file_position := puc$eoi;
      IF (file_id.device_class = rmc$magnetic_tape_device) AND (file_id.label_type = amc$unlabelled) THEN
        fetch_volume_position (file_id, volume_position, status);
        IF status.normal THEN
          IF volume_position = amc$after_tapemark THEN
            utility_file_position := puc$partition_boundary;
          ELSEIF volume_position = amc$eov THEN
            utility_file_position := puc$eoi;
          ELSE
            utility_file_position := puc$partition_boundary;
            pup$display_line (' ** ERROR ** CONFUSED VOLUME POSITION **', ignored_status);
            pup$display_line (volume_position_table [volume_position], ignored_status);
          IFEND;
        IFEND;
      IFEND;
    ELSE
    CASEND;
  PROCEND convert_to_logical_position;

?? TITLE := '    [INLINE] display_file_position', EJECT ??

  PROCEDURE [INLINE] display_file_position
    (    file_position: amt$file_position);

    CASE file_position OF
    = amc$boi =
      display ('    amc$boi');
    = amc$bop =
      display ('    amc$bop');
    = amc$eop =
      display ('    amc$eop');
    = amc$mid_record =
      display ('    amc$mid_record');
    = amc$eor =
      display ('    amc$eor');
    = amc$eoi =
      display ('    amc$eoi');
    ELSE
      display ('    unknown file position');
    CASEND;
  PROCEND display_file_position;

?? TITLE := '    [INLINE] display_open_position', EJECT ??

  PROCEDURE [INLINE] display_open_position
    (    open_position: amt$open_position);

    CASE open_position OF
    = amc$open_no_positioning =
      display ('    amc$open_no_positioning');
    = amc$open_at_boi =
      display ('    amc$open_at_boi');
    = amc$open_at_eoi =
      display ('    amc$open_at_eoi');
    ELSE
      display ('    unknown open position');
    CASEND;
  PROCEND display_open_position;

?? TITLE := '    [INLINE] display_term_option', EJECT ??

  PROCEDURE [INLINE] display_term_option
    (    term_option: amt$term_option);

    CASE term_option OF
    = amc$start =
      display ('    amc$start');
    = amc$continue =
      display ('    amc$continue');
    = amc$terminate =
      display ('    amc$terminate');
    ELSE
      display ('    unknown term option');
    CASEND;
  PROCEND display_term_option;

?? TITLE := '    [INLINE] display_volume_position', EJECT ??

  PROCEDURE [INLINE] display_volume_position
    (    volume_position: amt$volume_position);

    CASE volume_position OF
    = amc$after_data_block =
      display ('    amc$after_data_block');
    = amc$after_tapemark =
      display ('    amc$after_tapemark');
    = amc$before_tapemark =
      display ('    amc$before_tapemark');
    = amc$bov =
      display ('    amc$bov');
    = amc$eov =
      display ('    amc$eov');
    = amc$mid_bov_label_group =
      display ('    amc$mid_bov_label_group');
    = amc$mid_eof_label_group =
      display ('    amc$mid_eof_label_group');
    = amc$mid_eov_label_group =
      display ('    amc$mid_eov_label_group');
    = amc$mid_hdr_label_group =
      display ('    amc$mid_hdr_label_group');
    = amc$position_uncertain =
      display ('    amc$position_uncertain');
    ELSE
      display ('    unknown volume position');
    CASEND;

  PROCEND display_volume_position;
?? TITLE := '    fetch_volume_number', EJECT ??

  PROCEDURE fetch_volume_number
    (    backup_file_id: put$file_identifier;
     VAR volume_number: amt$volume_number);

    VAR
      access_info: array [1 .. 1] of amt$access_info,
      local_status: ost$status;

    access_info [1].key := amc$volume_number;
    display (' amp$fetch volume_number');
    amp$fetch_access_information (backup_file_id.file_id, access_info, local_status);
    IF local_status.normal THEN
      IF access_info [1].item_returned THEN
        volume_number := access_info [1].volume_number;
      ELSE
        pup$display_line (' VOLUME NUMBER NOT RETURNED FROM FETCH', local_status);
        volume_number := 1;
      IFEND;
    ELSE
      pup$write_os_status (local_status, local_status);
      volume_number := 1;
    IFEND;
    display_integer (' current volume number:', volume_number);

  PROCEND fetch_volume_number;
?? TITLE := '    fetch_volume_position', EJECT ??

  PROCEDURE fetch_volume_position
    (    file_id: put$file_identifier;
     VAR volume_position: amt$volume_position;
     VAR status: ost$status);

    VAR
      p_access_information: ^amt$access_information;

    PUSH p_access_information: [1 .. 1];
    p_access_information^ [1].key := amc$volume_position;
    display (' amp$fetch_access_information amc$volume_position');
    amp$fetch_access_information (file_id.file_id, p_access_information^, status);
    display_status (status);
    IF status.normal THEN
      volume_position := p_access_information^ [1].volume_position;
      display_volume_position (volume_position);
    IFEND;

  PROCEND fetch_volume_position;
?? TITLE := '    fetch_tape_failure_isolation', EJECT ??

  PROCEDURE fetch_tape_failure_isolation
    (    backup_file_id: put$file_identifier;
     VAR tape_failure_isolation: amt$tape_failure_isolation);

    VAR
      access_info: array [1 .. 1] of amt$access_info,
      local_status: ost$status;

    access_info [1].key := amc$tape_failure_isolation;
    display (' amp$fetch tape_failure_isolation');
    amp$fetch_access_information (backup_file_id.file_id, access_info, local_status);
    IF local_status.normal THEN
      IF access_info [1].item_returned THEN
        tape_failure_isolation := access_info [1].tape_failure_isolation;
      ELSE
        pup$display_line (' TAPE FAILURE ISOLATION NOT RETURNED FROM FETCH', local_status);
        tape_failure_isolation.failed_at_current_position := FALSE;
        tape_failure_isolation.failure_modes := $amt$tape_failure_modes [];
      IFEND;
    ELSE
      pup$write_os_status (local_status, local_status);
      tape_failure_isolation.failed_at_current_position := FALSE;
      tape_failure_isolation.failure_modes := $amt$tape_failure_modes [];
    IFEND;

  PROCEND fetch_tape_failure_isolation;
?? TITLE := '    [INLINE] get_partial', EJECT ??

  PROCEDURE [INLINE] get_partial
    (VAR backup_file_id: put$file_identifier;
         wsa: ^cell;
         working_storage_length: amt$working_storage_length;
     VAR transfer_count: amt$transfer_count;
     VAR bam_file_position: amt$file_position;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      byte_address: amt$file_byte_address,
      local_status: ost$status,
      record_length: amt$max_record_length;

    display_integer (' *** amp$get_partial wsl: ', working_storage_length);
    bam_file_position := amc$mid_record;
    amp$get_partial (backup_file_id.file_id, wsa, working_storage_length, record_length, transfer_count,
          byte_address, bam_file_position, amc$no_skip, status);
    IF status.normal THEN
      display_integer ('     STATUS NORMAL transfer_count: ', transfer_count);
      display_integer ('     byte_address: ', byte_address);
      display_integer ('     record_length: ', record_length);
    ELSE
      display_status (status);
    IFEND;
    convert_to_logical_position (backup_file_id, bam_file_position, file_position, local_status);

  PROCEND get_partial;
?? TITLE := '    get_volume_description', EJECT ??

  PROCEDURE get_volume_description
    (    file_id: amt$file_identifier;
         volume_number: amt$volume_number;
     VAR volume_description: rmt$volume_descriptor;
     VAR status: ost$status);

    VAR
      access_info: array [1 .. 1] of amt$access_info;

    access_info [1].key := amc$volume_description;
    access_info [1].volume_index := volume_number;
    amp$fetch_access_information (file_id, access_info, status);
    IF status.normal THEN
      volume_description := access_info [1].volume_description;
    IFEND;
  PROCEND get_volume_description;

?? TITLE := '    [INLINE] process_write_status', EJECT ??

  PROCEDURE [INLINE] process_write_status
    (    amp_status: ost$status;
     VAR backup_file_id: put$file_identifier;
     VAR pu_status: ost$status);

    VAR
      file_position: amt$file_position,
      ignore_status: ost$status,
      recovery_status: ost$status;

    IF amp_status.normal THEN
      pu_status.normal := TRUE;
    ELSE
      pu_status := amp_status;
      IF pu_status.condition = ame$no_write_ring THEN
        RETURN; {----->
      IFEND;

      IF pu_status.condition = dme$operator_stop THEN
        pup$close_backup_file (backup_file_id, ignore_status);
        RETURN; {----->
      IFEND;

      CASE backup_file_id.device_class OF
      = rmc$magnetic_tape_device =
        pup$close_backup_file (backup_file_id, recovery_status);
        IF NOT recovery_status.normal THEN
          pup$display_line (' Unable to close backup file.', ignore_status);
        IFEND;
      ELSE {null or mass_storage}
        display (' amp$skip amc$backward amc$skip_partition 0');
        amp$skip (backup_file_id.file_id, amc$backward, amc$skip_partition, 0, file_position,
              recovery_status);
      CASEND;

      IF recovery_status.normal THEN
        pup$display_line (' BACKUP GOOD TO PREVIOUS FILE WRITTEN', ignore_status);
      ELSE
        pup$display_line (' Error recovery failed:', ignore_status);
        pup$write_os_status (recovery_status, ignore_status);
        pup$display_line (' CURRENT VOLUME UNUSABLE; PREVIOUS VOLUMES READABLE', ignore_status);
      IFEND;
    IFEND;
  PROCEND process_write_status;

?? TITLE := '    verify_vol_position_after_skip', EJECT ??

  PROCEDURE verify_vol_position_after_skip
    (    backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      volume_position: amt$volume_position;

    fetch_volume_position (backup_file_id, volume_position, status);
    IF status.normal THEN
      CASE volume_position OF
      = amc$eov =
        file_position := puc$eoi;
      = amc$after_tapemark =
        file_position := puc$partition_boundary;
      ELSE
        file_position := puc$partition_boundary; {tape bug}
      CASEND;
    IFEND;
  PROCEND verify_vol_position_after_skip;
MODEND pum$manage_backup_file_io;
