?? RIGHT := 110 ??
?? NEWTITLE := ' NOS/VE Backup/Restore Utilities:  display_backup_file ', EJECT ??
MODULE pum$display_backup_file;
{
{  This contains processing for the the DISPLAY_BACKUP_FILE subcommand
{  and $BACKUP_FILE function.
{  This may read tapes produced by BACKUP_FILE_VERSION_001 or BACKUP_FILE_VERSION_002
{
?? NEWTITLE := '   Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc pus$literals
*copyc pud$backup_file
*copyc pud$hierarchy_list
*copyc pue$error_condition_codes
*copyc amt$local_file_name
*copyc ost$name
?? POP ??
*copyc clf#make_string_value

*copyc clp$evaluate_parameters
*copyc clp$get_fs_path_string
*copyc clp$get_path_name
*copyc clp$get_value
*copyc clp$scan_parameter_list
*copyc clp$trimmed_string_size
*copyc mmp$create_scratch_segment
*copyc mmp$delete_scratch_segment
*copyc osp$append_status_integer
*copyc osp$set_status_abnormal
*copyc pup$advised_get_part
*copyc pup$close_backup_file
*copyc pup$convert_cycle_path_to_strng
*copyc pup$convert_path_to_string
*copyc pup$crack_boolean
*copyc pup$crack_file
*copyc pup$display_blank_lines
*copyc pup$display_catalog_info
*copyc pup$display_cycle_info_desc_v1
*copyc pup$display_cycle_info_desc_v2
*copyc pup$display_file_info
*copyc pup$display_file_label
*copyc pup$display_integer
*copyc pup$display_item_descriptor
*copyc pup$display_line
*copyc pup$format_date_time
*copyc pup$get_item_descriptor
*copyc pup$get_next_hierarchy_list
*copyc pup$get_next_record_header
*copyc pup$get_part
*copyc pup$get_summary_status
*copyc pup$initialize_summary_status
*copyc pup$locate_valid_version
*copyc pup$open_backup_file
*copyc pup$skip_logical_partition
*copyc pup$write_os_status
*copyc bav$task_file_table
*copyc puv$prev_open_by_$backup_file
*copyc puv$respf_backup_file_version
?? TITLE := '    Global Variables', EJECT ??

  VAR
    number_of_cycles_displayed: integer := 0,
    total_bytes_displayed: integer := 0;


  CONST
    puc$maximum_partitions = 1000000000;

  VAR
    puv$record_header_name_table: [READ, pus$literals] array [put$backup_record_type] of
          ost$name := ['puc$backup_item_identifier', 'puc$backup_hierarchy_list', 'puc$backup_set_info',
          'puc$backup_family_info', 'puc$backup_family_content_info', 'puc$backup_catalog_info',
          'puc$backup_catalog_content_info', 'puc$backup_file_info', 'puc$backup_cycle_info',
          'puc$backup_cycle_data', 'puc$backup_system_label'];

  TYPE
    put$display_bf_options = (puc$dbf_identifier, puc$dbf_descriptor, puc$dbf_read_cycle_data,
          puc$dbf_catalog_info);

  VAR
    display_backup_file_table: [STATIC, pus$literals, READ] array [1 .. 8] of record
      name: ost$name,
      display_option: put$display_bf_options,
    recend := [
          {} ['IDENTIFIER                     ', puc$dbf_identifier],
          {} ['I                              ', puc$dbf_identifier],
          {} ['DESCRIPTOR                     ', puc$dbf_descriptor],
          {} ['D                              ', puc$dbf_descriptor],
          {} ['READ_DATA                      ', puc$dbf_read_cycle_data],
          {} ['RD                             ', puc$dbf_read_cycle_data],
          {} ['CATALOG_INFO                   ', puc$dbf_catalog_info],
          {} ['CI                             ', puc$dbf_catalog_info]];


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

  PROCEDURE [XDCL] pup$$backup_file
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);

{ FUNCTION $backup_file (
{   backup_file: file = $required
{   result: key
{       (identifier, i)
{       (identifier_type, it)
{     keyend = identifier
{   )

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

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 2] of clt$pdt_parameter_name,
      parameters: array [1 .. 2] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 4] of clt$keyword_specification,
        default_value: string (10),
      recend,
    recend := [
    [1,
    [104, 5, 14, 15, 6, 53, 192],
    clc$function, 2, 2, 1, 0, 0, 0, 0, ''], [
    ['BACKUP_FILE                    ',clc$nominal_entry, 1],
    ['RESULT                         ',clc$nominal_entry, 2]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$required_parameter, 0
  , 0],
{ PARAMETER 2
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 155,
  clc$optional_default_parameter, 0, 10]],
{ PARAMETER 1
    [[1, 0, clc$file_type]],
{ PARAMETER 2
    [[1, 0, clc$keyword_type], [4], [
    ['I                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['IDENTIFIER                     ', clc$nominal_entry, clc$normal_usage_entry, 1],
    ['IDENTIFIER_TYPE                ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['IT                             ', clc$abbreviation_entry, clc$normal_usage_entry, 2]]
    ,
    'identifier']];

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

    CONST
      p$backup_file = 1,
      p$result = 2;

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

    VAR
      backup_file_id: put$file_identifier,
      backup_file_position: put$file_position,
      entry_type_string: ost$string,
      local_status: ost$status,
      p_item_descriptor: ^put$backup_item_descriptor,
      path_string: ost$string,
      record_header: put$backup_file_record_header,
      stored_backup_file_version: put$backup_file_version_name;

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

    puv$prev_open_by_$backup_file := false;
    pup$open_backup_file (pvt [p$backup_file].value^.file_value^, puc$display_backup_file, amc$open_at_boi,
          backup_file_id, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    backup_file_id.operation := puc$$backup_file;

    pup$locate_valid_version (backup_file_id, stored_backup_file_version, backup_file_position, status);
    IF status.normal THEN
      pup$get_next_record_header (backup_file_id, record_header, backup_file_position, status);
      IF status.normal THEN
        PUSH p_item_descriptor: [1 .. record_header.size];
        pup$get_item_descriptor (backup_file_id, p_item_descriptor^, backup_file_position, status);
        IF status.normal THEN
          IF pvt [p$result].value^.name_value = 'IDENTIFIER_TYPE' THEN
            convert_entry_type_to_string (p_item_descriptor^.pf_utility_entry.entry_type, entry_type_string);
            result := clf#make_string_value (entry_type_string.value (1, entry_type_string.size), work_area);
          ELSE { IDENTIFIER OR I}
            convert_item_descriptor_to_strn (p_item_descriptor^, path_string);
            result := clf#make_string_value (path_string.value (1, path_string.size), work_area);
          IFEND;
        IFEND;
      IFEND;
    IFEND;

    pup$close_backup_file (backup_file_id, local_status);

  PROCEND pup$$backup_file;
?? TITLE := '    pup$display_backup_file ', EJECT ??

  PROCEDURE pup$display_backup_file
    (VAR backup_file_id: put$file_identifier;
         display_option: put$display_bf_options;
         number_to_display: integer;
     VAR status: ost$status);

    VAR
      file_position: put$file_position,
      local_status: ost$status,
      number_displayed: integer,
      p_item_description: ^put$backup_item_descriptor,
      record_header: put$backup_file_record_header,
      stored_backup_file_version: put$backup_file_version_name;

    status.normal := TRUE;
    number_displayed := 0;

  /loop_through_partitions/
    REPEAT
      pup$locate_valid_version (backup_file_id, stored_backup_file_version, file_position, status);
      IF status.normal AND (file_position <> puc$eoi) THEN
        pup$display_line ('------------------------------', status);
        IF display_option <> puc$dbf_identifier THEN
          pup$display_line (stored_backup_file_version, status);
        IFEND;
        pup$get_next_record_header (backup_file_id, record_header, file_position, status);
        IF status.normal THEN
          IF display_option <> puc$dbf_identifier THEN
            pup$display_record_header (record_header);
          IFEND;
          IF (record_header.kind = puc$backup_item_identifier) AND (record_header.size >= 1) THEN
            ALLOCATE p_item_description: [1 .. record_header.size];
            pup$get_item_descriptor (backup_file_id, p_item_description^, file_position, status);
            IF status.normal THEN
              pup$display_line (p_item_description^.catalog_header.set_name, status);
              pup$display_item_descriptor ('', p_item_description^.catalog_header,
                    p_item_description^.pf_utility_entry, status);
              number_displayed := number_displayed + 1;
              IF display_option <> puc$dbf_identifier THEN
                display_full_entry (display_option, backup_file_id, file_position,
                      p_item_description^.pf_utility_entry.entry_type, status);
              IFEND;
            IFEND;
            FREE p_item_description;
          ELSE
            pup$display_line (' expecting backup_item_identifier, entry skipped', status);
          IFEND;
        IFEND;
        pup$write_os_status (status, local_status);
        status.normal := TRUE;
        IF file_position = puc$mid_partition THEN
          pup$skip_logical_partition (backup_file_id, file_position, status);
        IFEND;
      IFEND;
    UNTIL NOT status.normal OR (file_position = puc$eoi) OR (number_displayed >= number_to_display);
    IF (status.normal) AND (number_to_display > number_displayed) AND
          (number_to_display <> puc$maximum_partitions) THEN
      osp$set_status_abnormal (puc$pf_utility_id, pue$number_of_items, '', status);
      osp$append_status_integer (osc$status_parameter_delimiter, number_displayed, 10, FALSE, status);
    IFEND;
    pup$write_os_status (status, status);
  PROCEND pup$display_backup_file;

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

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

    VAR
      backup_file: amt$local_file_name,
      display_option: put$display_bf_options,
      local_status: ost$status,
      number_to_display: 1 .. puc$maximum_partitions;

    crack_disbf (parameter_list, backup_file, display_option, number_to_display, status);
    IF status.normal THEN
      pup$display_backup_file_request (backup_file, display_option, number_to_display, status);
      pup$write_os_status (status, local_status);
    IFEND;
  PROCEND pup$display_backup_file_command;

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

  PROCEDURE pup$display_backup_file_request
    (    backup_file: amt$local_file_name;
         display_option: put$display_bf_options;
         number_to_display: 1 .. puc$maximum_partitions;
     VAR status: ost$status);

    TYPE
      character_set = set of char;

    VAR
      backup_file_id: put$file_identifier,
      fs_path: fst$path,
      fs_path_size: fst$path_size,
      local_status: ost$status,
      path_handle: fmt$path_handle;

    pup$display_line (' DISPLAY BACKUP FILE:', status);
    pup$initialize_summary_status;

    pup$open_backup_file (backup_file, puc$display_backup_file, amc$open_at_boi, backup_file_id, status);
    IF status.normal THEN
      clp$get_fs_path_string (bav$task_file_table^ [backup_file_id.file_id.ordinal].local_file_name,
            fs_path, fs_path_size, path_handle, local_status);
      IF fs_path_size > osc$max_string_size THEN
        fs_path_size := osc$max_string_size;
      IFEND;
      pup$display_line (fs_path (1, fs_path_size), status);
      number_of_cycles_displayed := 0;
      total_bytes_displayed := 0;
      pup$display_backup_file (backup_file_id, display_option, number_to_display, status);
      pup$close_backup_file (backup_file_id, local_status);
      IF display_option <> puc$dbf_identifier THEN
        display_display_totals;
      IFEND;
      pup$get_summary_status (status);
    IFEND;
  PROCEND pup$display_backup_file_request;

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

  PROCEDURE pup$display_record_header
    (    record_header: put$backup_file_record_header);

    VAR
      number_length: integer,
      record_header_descriptor: string (78),
      status: ost$status;

    CASE record_header.kind OF
    = puc$backup_item_identifier, puc$backup_hierarchy_list, puc$backup_set_info, puc$backup_family_info,
          puc$backup_family_content_info, puc$backup_catalog_info, puc$backup_catalog_content_info,
          puc$backup_file_info, puc$backup_cycle_info, puc$backup_cycle_data, puc$backup_system_label =
      record_header_descriptor := ' ';
      STRINGREP (record_header_descriptor, number_length, ' Record header type: ',
            puv$record_header_name_table [record_header.kind], '  Size: ', record_header.size);
      pup$display_line (record_header_descriptor, status);
    ELSE
      pup$display_line (' INVALID RECORD HEADER ENCOUNTERED', status);
    CASEND;
  PROCEND pup$display_record_header;


?? TITLE := '    convert_entry_type_to_string ', EJECT ??

  PROCEDURE convert_entry_type_to_string
    (    entry_type: put$entry_type;
     VAR entry_string: ost$string);

    CASE entry_type OF
    = puc$valid_set_entry =
      entry_string.size := 3;
      entry_string.value := 'SET';
    = puc$valid_family_entry, puc$valid_catalog_entry =
      entry_string.size := 7;
      entry_string.value := 'CATALOG';
    = puc$valid_pf_entry =
      entry_string.size := 4;
      entry_string.value := 'FILE';
    = puc$valid_cycle_entry =
      entry_string.size := 5;
      entry_string.value := 'CYCLE';
    ELSE
      entry_string.size := 7;
      entry_string.value := 'UNKNOWN';
    CASEND;
  PROCEND convert_entry_type_to_string;

?? TITLE := '    convert_item_descriptor_to_strn ', EJECT ??

  PROCEDURE convert_item_descriptor_to_strn
    (    item_descriptor: put$backup_item_descriptor;
     VAR item_string: ost$string);

    IF item_descriptor.catalog_header.logical_path_length = 0 THEN
      item_string.value := item_descriptor.catalog_header.set_name;
      item_string.size := clp$trimmed_string_size (item_descriptor.catalog_header.set_name);
    ELSE
      CASE item_descriptor.pf_utility_entry.entry_type OF
      = puc$valid_cycle_entry =
        pup$convert_cycle_path_to_strng (item_descriptor.catalog_header.path,
              item_descriptor.pf_utility_entry.pf_selector.cycle_selector.cycle_number, item_string);
      ELSE
        pup$convert_path_to_string (item_descriptor.catalog_header.path, item_string);
      CASEND;
    IFEND;
  PROCEND convert_item_descriptor_to_strn;

?? TITLE := '    convert_name_to_option ', EJECT ??

  PROCEDURE convert_name_to_option
    (    name: ost$name;
     VAR display_bf_option: put$display_bf_options;
     VAR status: ost$status);

    VAR
      i: integer;

    status.normal := TRUE;
    FOR i := 1 TO UPPERBOUND (display_backup_file_table) DO
      IF display_backup_file_table [i].name = name THEN
        display_bf_option := display_backup_file_table [i].display_option;
        RETURN;
      IFEND;
    FOREND;
    osp$set_status_abnormal (puc$pf_utility_id, cle$name_not_a_keyword_value, name, status);
  PROCEND convert_name_to_option;

?? TITLE := '    crack_disbf ', EJECT ??

  PROCEDURE crack_disbf
    (    parameter_list: clt$parameter_list;
     VAR backup_file: amt$local_file_name;
     VAR display_option: put$display_bf_options;
     VAR number_to_display: 1 .. puc$maximum_partitions;
     VAR status: ost$status);

?? RIGHT := 110 ??

{ pdt display_backup_file_pdt (
{ backup_file,bf:file=$required
{  display_option, do: key identifier, i, descriptor, d, read_data, ..
{    rd, catalog_info, ci = identifier
{ number, n: integer 1 .. puc$maximum_partitions or key all = all
{ status)

?? PUSH (LISTEXT := ON) ??

    VAR
      display_backup_file_pdt: [STATIC, READ, cls$pdt] clt$parameter_descriptor_table :=
            [^display_backup_file_pdt_names, ^display_backup_file_pdt_params];

    VAR
      display_backup_file_pdt_names: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 7] of
            clt$parameter_name_descriptor := [['BACKUP_FILE', 1], ['BF', 1], ['DISPLAY_OPTION', 2], ['DO', 2],
            ['NUMBER', 3], ['N', 3], ['STATUS', 4]];

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

{ BACKUP_FILE BF }
      [[clc$required], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$file_value]],

{ DISPLAY_OPTION DO }
      [[clc$optional_with_default, ^display_backup_file_pdt_dv2], 1, 1, 1, 1, clc$value_range_not_allowed,
            [^display_backup_file_pdt_kv2, clc$keyword_value]],

{ NUMBER N }
      [[clc$optional_with_default, ^display_backup_file_pdt_dv3], 1, 1, 1, 1, clc$value_range_not_allowed,
            [^display_backup_file_pdt_kv3, clc$integer_value, 1, puc$maximum_partitions]],

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

    VAR
      display_backup_file_pdt_kv2: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 8] of
            ost$name := ['IDENTIFIER', 'I', 'DESCRIPTOR', 'D', 'READ_DATA', 'RD', 'CATALOG_INFO', 'CI'];

    VAR
      display_backup_file_pdt_kv3: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 1] of
            ost$name := ['ALL'];

    VAR
      display_backup_file_pdt_dv2: [STATIC, READ, cls$pdt_names_and_defaults] string (10) := 'identifier';

    VAR
      display_backup_file_pdt_dv3: [STATIC, READ, cls$pdt_names_and_defaults] string (3) := 'all';

?? POP ??

    VAR
      value: clt$value;


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

    pup$crack_file ('BACKUP_FILE', backup_file, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$get_value ('DISPLAY_OPTION', 1, 1, clc$low, value, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    convert_name_to_option (value.name.value, display_option, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$get_value ('NUMBER', 1, 1, clc$low, value, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF value.kind = clc$name_value THEN
      { ALL selected
      number_to_display := puc$maximum_partitions;
    ELSE
      number_to_display := value.int.value;
    IFEND;
  PROCEND crack_disbf;


?? TITLE := '    display_backup_cycle_info ', EJECT ??

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

{  This routine extracts the cycle array entry from the backup file.

    VAR
      fmd_size: integer,
      local_status: ost$status,
      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_file_media_descriptor: ^SEQ ( * ),
      record_header: put$backup_file_record_header,
      transfer_count: amt$file_length;

    pup$get_next_record_header (backup_file_id, record_header, file_position, status);
    IF status.normal THEN
      pup$display_record_header (record_header);
      IF (file_position = puc$mid_partition) AND (record_header.kind = puc$backup_cycle_info) THEN
        IF puv$respf_backup_file_version = puc$backup_file_version_1 THEN
          PUSH p_cycle_info_desc_version_1;
          pup$get_part (backup_file_id, p_cycle_info_desc_version_1, #SIZE (p_cycle_info_desc_version_1^),
                file_position, transfer_count, status);
          IF status.normal THEN
            pup$display_cycle_info_desc_v1 (p_cycle_info_desc_version_1, 4);
          IFEND;
        ELSEIF puv$respf_backup_file_version = puc$backup_file_version_2 THEN
          IF record_header.size > (#SIZE(pft$cycle_info_desc_version_2: [[REP 1 OF cell]]) - 1) THEN
            fmd_size := record_header.size - (#SIZE(pft$cycle_info_desc_version_2: [[REP 1 OF cell]]) - 1);
          ELSE
            fmd_size := 1;
          IFEND;
          PUSH p_cycle_info_desc_version_2: [[REP fmd_size OF cell]];
          pup$get_part (backup_file_id, p_cycle_info_desc_version_2, record_header.size, file_position,
                transfer_count, status);
          IF status.normal THEN
            IF fmd_size > 1 THEN
              p_file_media_descriptor := ^p_cycle_info_desc_version_2^.file_media_descriptor;
            ELSE
              p_file_media_descriptor := NIL;
            IFEND;
            pup$display_cycle_info_desc_v2 (p_cycle_info_desc_version_2, p_file_media_descriptor, 4);
          IFEND;
        IFEND;
      ELSE
        pup$display_line (' Unexpected item encountered, expecting: puc$backup_cycle_info', status);
        osp$set_status_abnormal (puc$pf_utility_id, pue$unusable_restore_file, '', status);
      IFEND;
    IFEND;
  PROCEND display_backup_cycle_info;

?? TITLE := '    display_catalog_entry ', EJECT ??

  PROCEDURE display_catalog_entry
    (    display_option: put$display_bf_options;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      p_info_record: pft$p_info_record,
      record_header: put$backup_file_record_header,
      transfer_count: amt$file_length;

    IF display_option = puc$dbf_catalog_info THEN
      display_catalog_info (backup_file_id, file_position, status);
    ELSE
      display_item_record (puc$backup_catalog_info, backup_file_id, file_position, status);
    IFEND;

    IF status.normal THEN
      { determine what version of the backup_file we are displaying.
      { BACKUP_FILE_VERSION_001 has a puc$backup_catalog_content_info while 002 does not.
      pup$get_next_record_header (backup_file_id, record_header, file_position, status);
      IF status.normal THEN
        pup$display_record_header (record_header);
        CASE record_header.kind OF
        = puc$backup_catalog_content_info =
          { skip over the item info.
          IF record_header.size > 0 THEN
            PUSH p_info_record: [[REP record_header.size OF cell]];
            pup$get_part (backup_file_id, p_info_record, #SIZE (p_info_record^), file_position,
                  transfer_count, status);
            pup$write_os_status (status, local_status);
            IF status.normal THEN
              display_hierarchy_list (backup_file_id, file_position, status);
            IFEND;
          ELSE
            pup$display_integer (' unexpected record header size: ', record_header.size, local_status);
          IFEND;

        = puc$backup_hierarchy_list =
          display_hierarchy_list_info (record_header.size, backup_file_id, file_position, status);
        ELSE
          pup$display_line (' Unexpected item encountered, expecting: puc$backup_hierachy_list, or puc$backup'
                CAT '_catalog_content_info', status);
          osp$set_status_abnormal (puc$pf_utility_id, pue$unusable_restore_file, '', status);
        CASEND;
      IFEND;
    IFEND;
  PROCEND display_catalog_entry;
?? TITLE := '    display_catalog_info', EJECT ??

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

    VAR
      local_status: ost$status,
      outputline: string (200),
      outputline_index: integer,
      p_info_record: pft$p_info_record,
      record_header: put$backup_file_record_header,
      transfer_count: amt$file_length;

    pup$get_next_record_header (backup_file_id, record_header, file_position, status);
    IF status.normal THEN
      pup$display_record_header (record_header);
      IF (record_header.kind = puc$backup_family_info) OR (record_header.kind = puc$backup_catalog_info) THEN
        IF record_header.size > 0 THEN
          PUSH p_info_record: [[REP record_header.size OF cell]];
          pup$get_part (backup_file_id, p_info_record, #SIZE (p_info_record^), file_position,
                transfer_count, status);
          IF status.normal THEN
            pup$display_catalog_info (osc$null_name, p_info_record, 2, status);
          IFEND;
          pup$write_os_status (status, local_status);
        ELSE
          pup$display_integer (' unexpected record header size: ', record_header.size, local_status);
        IFEND;
      ELSE
        STRINGREP (outputline, outputline_index, ' Unexpected record header kind.  Expecting: ',
              ' Catalog or Family info ');
        pup$display_line (outputline (1, outputline_index), status);
        osp$set_status_abnormal (puc$pf_utility_id, pue$unexpected_item_requested, '', status);
      IFEND;
    IFEND;
  PROCEND display_catalog_info;

?? TITLE := '    display_cycle_entry ', EJECT ??

  PROCEDURE display_cycle_entry
    (    display_option: put$display_bf_options;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      record_header: put$backup_file_record_header;

    display_backup_cycle_info (backup_file_id, file_position, status);
    IF status.normal THEN
      number_of_cycles_displayed := number_of_cycles_displayed + 1;
      display_label_record (backup_file_id, file_position, status);
      IF status.normal THEN
        display_hierarchy_list (backup_file_id, file_position, status);
        IF status.normal THEN
          pup$get_next_record_header (backup_file_id, record_header, file_position, status);
          IF status.normal THEN
            pup$display_record_header (record_header);
            IF record_header.kind = puc$backup_cycle_data THEN
              IF display_option = puc$dbf_read_cycle_data THEN
                read_cycle_data (record_header.size, backup_file_id, file_position, status);
              IFEND;
              IF status.normal THEN
                total_bytes_displayed := total_bytes_displayed + record_header.size;
              IFEND;
            ELSE
              pup$display_line (' invalid record header type expecting: cycle_data ', status);
            IFEND;
          ELSEIF status.condition = pue$unusable_restore_file THEN
            pup$display_line (' Cycle data not present', status);
          IFEND;
        IFEND;
      IFEND;
    IFEND;
  PROCEND display_cycle_entry;

?? TITLE := '    display_date_time ', EJECT ??

  PROCEDURE display_date_time
    (    descriptor: string ( * <= 90);
         date_time: ost$date_time);

    VAR
      status: ost$status,
      working_string: string (120),
      date_time_string: string (30);

    working_string := descriptor;
    pup$format_date_time (date_time, date_time_string);
    working_string ((STRLENGTH (descriptor) + 1), * ) := date_time_string;
    pup$display_line (working_string (1, (STRLENGTH (descriptor) + 30)), status);
  PROCEND display_date_time;

?? TITLE := '    display_display_totals ', EJECT ??

  PROCEDURE display_display_totals;

    VAR
      local_status: ost$status;

    pup$display_blank_lines (3, local_status);
    pup$display_line (' DISPLAY SUMMARY: ', local_status);
    pup$display_integer ('   NUMBER OF CYCLES DISPLAYED: ', number_of_cycles_displayed, local_status);
    number_of_cycles_displayed := 0;
    pup$display_integer ('   TOTAL CYCLE DATA DISPLAYED: ', total_bytes_displayed, local_status);
    total_bytes_displayed := 0;
  PROCEND display_display_totals;

?? TITLE := '    display_family_entry ', EJECT ??

  PROCEDURE display_family_entry
    (    display_option: put$display_bf_options;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      p_info_record: pft$p_info_record,
      record_header: put$backup_file_record_header,
      transfer_count: amt$file_length;

    IF display_option = puc$dbf_catalog_info THEN
      display_catalog_info (backup_file_id, file_position, status);
    ELSE
      display_item_record (puc$backup_family_info, backup_file_id, file_position, status);
    IFEND;
    IF status.normal THEN
      { determine what version of the backup_file we are displaying.
      pup$get_next_record_header (backup_file_id, record_header, file_position, status);
      IF status.normal THEN
        pup$display_record_header (record_header);
        CASE record_header.kind OF
        = puc$backup_family_content_info =
          {version 001
          { skip over the item info.
          IF record_header.size > 0 THEN
            PUSH p_info_record: [[REP record_header.size OF cell]];
            pup$get_part (backup_file_id, p_info_record, #SIZE (p_info_record^), file_position,
                  transfer_count, status);
            pup$write_os_status (status, local_status);
            IF status.normal THEN
              display_hierarchy_list (backup_file_id, file_position, status);
            IFEND;
          ELSE
            pup$display_integer (' unexpected record header size: ', record_header.size, local_status);
          IFEND;
        = puc$backup_hierarchy_list =
          {version 002
          display_hierarchy_list_info (record_header.size, backup_file_id, file_position, status);
        ELSE
          pup$display_line (' Unexpected item encountered, expecting: puc$backup_hierachy_list, or puc$backup'
                CAT '_catalog_content_info', status);
          osp$set_status_abnormal (puc$pf_utility_id, pue$unusable_restore_file, '', status);
        CASEND;
      IFEND;
    IFEND;

  PROCEND display_family_entry;

?? TITLE := '    display_file_info', EJECT ??

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

    VAR
      local_status: ost$status,
      outputline: string (200),
      outputline_index: integer,
      p_info_record: pft$p_info_record,
      record_header: put$backup_file_record_header,
      transfer_count: amt$file_length;

    pup$get_next_record_header (backup_file_id, record_header, file_position, status);
    IF status.normal THEN
      pup$display_record_header (record_header);
      IF (record_header.kind = puc$backup_file_info) THEN
        IF record_header.size > 0 THEN
          PUSH p_info_record: [[REP record_header.size OF cell]];
          pup$get_part (backup_file_id, p_info_record, #SIZE (p_info_record^), file_position,
                transfer_count, status);
          IF status.normal THEN
            pup$display_file_info (osc$null_name, p_info_record, 2, status);
          IFEND;
          pup$write_os_status (status, local_status);
        ELSE
          pup$display_integer (' unexpected record header size: ', record_header.size, local_status);
        IFEND;
      ELSE
        STRINGREP (outputline, outputline_index, ' Unexpected record header kind.  Expecting: ',
              ' File info ');
        pup$display_line (outputline (1, outputline_index), status);
        osp$set_status_abnormal (puc$pf_utility_id, pue$unexpected_item_requested, '', status);
      IFEND;
    IFEND;
  PROCEND display_file_info;
?? TITLE := '    display_full_entry ', EJECT ??

  PROCEDURE display_full_entry
    (    display_option: put$display_bf_options;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
         entry_type: put$entry_type;
     VAR status: ost$status);

    CASE entry_type OF
    = puc$valid_set_entry =
      display_set_entry (display_option, backup_file_id, file_position, status);
    = puc$valid_family_entry =
      display_family_entry (display_option, backup_file_id, file_position, status);
    = puc$valid_catalog_entry =
      display_catalog_entry (display_option, backup_file_id, file_position, status);
    = puc$valid_pf_entry =
      display_pf_entry (display_option, backup_file_id, file_position, status);
    = puc$valid_cycle_entry =
      display_cycle_entry (display_option, backup_file_id, file_position, status);
    = puc$invalid_entry =
      pup$display_line (' PUC$INVALID_ENTRY ', status);
    ELSE
      pup$display_line (' UNSELECTED CASE ON ENTRY TYPE', status);
    CASEND;
  PROCEND display_full_entry;

?? TITLE := '    display_hierarchy_list ', EJECT ??

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

    VAR
      record_header: put$backup_file_record_header;

    pup$get_next_record_header (backup_file_id, record_header, file_position, status);
    IF status.normal THEN
      pup$display_record_header (record_header);
      IF record_header.kind = puc$backup_hierarchy_list THEN
        display_hierarchy_list_info (record_header.size, backup_file_id, file_position, status);
      ELSE
        pup$display_line ('Unexpected record header: expecting puc$backup_hierarchy_list', status);
      IFEND;
    IFEND;
  PROCEND display_hierarchy_list;
?? TITLE := '    display_hierarchy_list_info ', EJECT ??

  PROCEDURE display_hierarchy_list_info
    (    size: integer;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      date_time_string: string (30),
      local_status: ost$status,
      p_hierarchy_list: ^put$hierarchy_list;

    IF size > 0 THEN
      PUSH p_hierarchy_list: [1 .. size];
      pup$get_next_hierarchy_list (backup_file_id, p_hierarchy_list^, file_position, status);
      IF status.normal THEN
        display_date_time (' Item backed up on: ', p_hierarchy_list^.date_time);
        pup$display_item_descriptor (' Produced by backup of: ', p_hierarchy_list^.catalog_header,
              p_hierarchy_list^.pf_entry, status);
        IF (p_hierarchy_list^.catalog_header.logical_path_length = 0) THEN
          pup$display_line ('   backup_all_files ', status);
        IFEND;
      IFEND;
    ELSE
      pup$display_integer (' unexpected size for hierarchy list: ', size, status);
    IFEND;
  PROCEND display_hierarchy_list_info;

?? TITLE := '    display_item_record ', EJECT ??

  PROCEDURE display_item_record
    (    expected_item_type: put$backup_record_type;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      outputline: string (200),
      outputline_index: integer,
      p_info_record: pft$p_info_record,
      record_header: put$backup_file_record_header,
      transfer_count: amt$file_length;

    pup$get_next_record_header (backup_file_id, record_header, file_position, status);
    IF status.normal THEN
      pup$display_record_header (record_header);
      IF record_header.kind = expected_item_type THEN
        IF record_header.size > 0 THEN
          PUSH p_info_record: [[REP record_header.size OF cell]];
          pup$get_part (backup_file_id, p_info_record, #SIZE (p_info_record^), file_position,
                transfer_count, status);
          pup$write_os_status (status, local_status);
        ELSE
          pup$display_integer (' unexpected record header size: ', record_header.size, local_status);
        IFEND;
      ELSE
        STRINGREP (outputline, outputline_index, ' Unexpected record header kind.  Expecting: ',
              puv$record_header_name_table [expected_item_type]);
        pup$display_line (outputline (1, outputline_index), status);
        osp$set_status_abnormal (puc$pf_utility_id, pue$unexpected_item_requested, '', status);
      IFEND;
    IFEND;
  PROCEND display_item_record;

?? TITLE := '    display_label_record ', EJECT ??

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

    VAR
      local_status: ost$status,
      p_label: ^SEQ ( * ),
      record_header: put$backup_file_record_header,
      transfer_count: amt$file_length;

    pup$get_next_record_header (backup_file_id, record_header, file_position, status);
    IF status.normal THEN
      pup$display_record_header (record_header);
      IF record_header.kind = puc$backup_system_label THEN
        IF record_header.size > 0 THEN
          PUSH p_label: [[REP record_header.size OF cell]];
          pup$get_part (backup_file_id, p_label, #SIZE (p_label^), file_position, transfer_count,
                status);
          IF status.normal THEN
            pup$display_file_label (p_label^, 2, status);
          IFEND;
          pup$write_os_status (status, local_status);
        IFEND;
      ELSE
        pup$display_line (' Unexpected record header kind expecting: puc$backup_system_label', status);
        osp$set_status_abnormal (puc$pf_utility_id, pue$unexpected_item_requested, '', status);
      IFEND;
    IFEND;
  PROCEND display_label_record;


?? TITLE := '    display_pf_entry ', EJECT ??

  PROCEDURE display_pf_entry
    (    display_option: put$display_bf_options;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    IF display_option = puc$dbf_catalog_info THEN
      display_file_info (backup_file_id, file_position, status);
    ELSE
      display_item_record (puc$backup_file_info, backup_file_id, file_position, status);
    IFEND;

    IF status.normal THEN
      display_hierarchy_list (backup_file_id, file_position, status);
    IFEND;


  PROCEND display_pf_entry;

?? TITLE := '    display_set_entry ', EJECT ??

  PROCEDURE display_set_entry
    (    display_option: put$display_bf_options;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);


    display_item_record (puc$backup_set_info, backup_file_id, file_position, status);

    IF status.normal THEN
      display_hierarchy_list (backup_file_id, file_position, status);
    IFEND;


  PROCEND display_set_entry;

?? TITLE := '    read_cycle_data ', EJECT ??

  PROCEDURE read_cycle_data
    (    cycle_data_size: integer;
     VAR backup_file_id: put$file_identifier;
     VAR file_position: put$file_position;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      segment: amt$segment_pointer,
      transfer_count: amt$file_length;

    IF cycle_data_size <= 0 THEN
      pup$display_line (' No cycle data. ', status);
    ELSE
      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, segment, status);
      IF NOT status.normal THEN
        pup$display_line ('unable to create transient segment', local_status);
        RETURN;
      IFEND;
      pup$display_line (' Reading cycle data. ', status);
      pup$advised_get_part (backup_file_id, segment.sequence_pointer, cycle_data_size, file_position,
            transfer_count, status);
      IF status.normal THEN
        pup$display_line (' Able to read cycle data. ', status);
      ELSE
        pup$write_os_status (status, local_status);
        pup$display_line (' Unable to read cycle data. ', local_status);
      IFEND;
      mmp$delete_scratch_segment (segment, status);
    IFEND;
  PROCEND read_cycle_data;

MODEND pum$display_backup_file;
