?? RIGHT := 110 ??
*copyc osd$default_pragmats
?? NEWTITLE := ' NOS/VE Backup/Restore Utilities:  restore_existing_file ', EJECT ??
MODULE pum$restore_existing_file;

?? NEWTITLE := '   Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc osc$nosve_system_set
*copyc pud$backup_file
*copyc pud$hierarchy_list
*copyc pue$error_condition_codes
*copyc amt$local_file_name
?? POP ??
*copyc avp$family_administrator
*copyc avp$system_administrator
*copyc clp$evaluate_file_reference
*copyc clp$evaluate_parameters
*copyc pup$build_catalog_header
*copyc pup$build_entry
*copyc pup$close_backup_file
*copyc pup$compare_paths
*copyc pup$crack_backup_file
*copyc pup$crack_pf_file_reference
*copyc pup$display_restore_totals
*copyc pup$get_summary_status
*copyc pup$initialize_restore_listing
*copyc pup$open_backup_file
*copyc pup$restore_sub_levels
*copyc pup$set_restore_subcmd_defaults
*copyc pup$verify_file_path
*copyc pup$write_os_status
*copyc puv$restore_archive_information
?? TITLE := '    [XDCL] pup$restore_existing_file_cm ', EJECT ??

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

    VAR
      backup_file: amt$local_file_name,
      backup_file_id: put$file_identifier,
      cycle_entry: put$entry,
      cycle_selector: pft$cycle_selector,
      cycle_specified: boolean,
      entry_type: put$entry_type,
      file_entry: put$entry,
      file_path_container: clt$path_container,
      local_status: ost$status,
      new_cycle_selector: pft$cycle_selector,
      new_cycle_specified: boolean,
      new_file_path_container: clt$path_container,
      p_catalog_header: ^put$catalog_header,
      p_file_path: ^pft$path,
      p_new_catalog_header: ^put$catalog_header,
      p_new_file_path: ^pft$path,
      p_selected_cycles: ^array [1 .. *] of put$selected_cycle_info,
      password: pft$password,
      path_1_above_path_2: boolean,
      paths_equal: boolean;

    crack_restore_existing_file (parameter_list, file_path_container, p_file_path, cycle_specified,
          cycle_selector, password, new_file_path_container, p_new_file_path, new_cycle_specified,
          new_cycle_selector, backup_file, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    PUSH p_selected_cycles: [1 .. 1];
    IF cycle_specified THEN
      p_selected_cycles ^[1].selected_cycle.cycle_specified := TRUE;
      p_selected_cycles ^[1].selected_cycle.cycle_selector := cycle_selector;
    ELSE
      p_selected_cycles ^[1].selected_cycle.cycle_specified := FALSE;
    IFEND;

    IF new_cycle_specified THEN
      p_selected_cycles ^[1].new_selected_cycle.cycle_specified := TRUE;
      p_selected_cycles ^[1].new_selected_cycle.cycle_selector := new_cycle_selector;
      IF NOT cycle_specified THEN
        cycle_specified := TRUE;
        cycle_selector.cycle_option := pfc$highest_cycle;
        p_selected_cycles ^[1].selected_cycle.cycle_specified := TRUE;
        p_selected_cycles ^[1].selected_cycle.cycle_selector.cycle_option := pfc$highest_cycle;
      IFEND;
    ELSE
      p_selected_cycles ^[1].new_selected_cycle.cycle_specified := FALSE;
    IFEND;

    pup$build_entry (p_file_path^ [UPPERBOUND (p_file_path^)], cycle_selector, puc$valid_pf_entry,
          file_entry);
    PUSH p_catalog_header: [1 .. UPPERBOUND (p_file_path^)];
    pup$build_catalog_header (osc$nosve_system_set, p_file_path, p_catalog_header^);
    PUSH p_new_catalog_header: [1 .. UPPERBOUND (p_new_file_path^)];
    pup$build_catalog_header (osc$nosve_system_set, p_new_file_path, p_new_catalog_header^);
    pup$verify_file_path (p_new_file_path^, status);
    IF status.normal THEN
      pup$open_backup_file (backup_file, puc$restore_permanent_files, amc$open_at_boi, backup_file_id,
            status);
      IF status.normal THEN
        IF cycle_specified THEN
          pup$build_entry (p_file_path^ [UPPERBOUND (p_file_path^)], cycle_selector,
                puc$valid_cycle_entry, cycle_entry);
          IF new_cycle_specified THEN
            pup$initialize_restore_listing ('RESTORE CYCLE OF EXISTING FILE:', p_catalog_header^,
                  cycle_entry, p_new_file_path^, new_cycle_selector, status);
          ELSE
            pup$initialize_restore_listing (' RESTORE EXISTING FILE: ', p_catalog_header^, cycle_entry,
                  p_new_file_path^, cycle_selector, status);
          IFEND;
        ELSE
          IF new_cycle_specified THEN
            pup$build_entry (p_file_path^ [UPPERBOUND (p_file_path^)], cycle_selector,
                  puc$valid_cycle_entry, cycle_entry);
            pup$initialize_restore_listing ('RESTORE CYCLE OF EXISTING FILE:', p_catalog_header^,
                  cycle_entry, p_new_file_path^, new_cycle_selector, status);
          ELSE
            pup$initialize_restore_listing (' RESTORE EXISTING FILE: ', p_catalog_header^, file_entry,
                  p_new_file_path^, cycle_selector, status);
          IFEND;
        IFEND;
        IF status.normal THEN
          pup$set_restore_subcmd_defaults (NOT (avp$system_administrator() OR avp$family_administrator()));
          pup$restore_sub_levels (file_entry, p_catalog_header^, {password_specified} TRUE, password,
                p_new_catalog_header^, {restore_n_levels} TRUE, p_selected_cycles, backup_file_id, status);
        IFEND;
        pup$close_backup_file (backup_file_id, local_status);
        IF status.normal THEN
          status := local_status;
        IFEND;
        pup$display_restore_totals;
        pup$get_summary_status (status);
      IFEND;
    IFEND;
    pup$write_os_status (status, local_status);

  PROCEND pup$restore_existing_file_cm;

?? TITLE := '    crack_restore_existing_file ', EJECT ??

  PROCEDURE crack_restore_existing_file
    (    parameter_list: clt$parameter_list;
     VAR file_path_container: clt$path_container;
     VAR p_file_path: ^pft$path;
     VAR cycle_specified: boolean;
     VAR cycle_selector: pft$cycle_selector;
     VAR password: pft$password;
     VAR new_file_path_container: clt$path_container;
     VAR p_new_file_path: ^pft$path;
     VAR new_cycle_specified: boolean;
     VAR new_cycle_selector: pft$cycle_selector;
     VAR backup_file: amt$local_file_name;
     VAR status: ost$status);

{ PROCEDURE (osm$resef) restore_existing_file, resef (
{   file, f: file = $required
{   backup_file, bf: file = $required
{   password, pw: (SECURE) any of
{       key
{         none
{       keyend
{       name
{     anyend = none
{   new_file_name, nfn: file = $optional
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 9] of clt$pdt_parameter_name,
        parameters: array [1 .. 5] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
        recend,
        type2: record
          header: clt$type_specification_header,
        recend,
        type3: record
          header: clt$type_specification_header,
          qualifier: clt$union_type_qualifier,
          type_size_1: clt$type_specification_size,
          element_type_spec_1: record
            header: clt$type_specification_header,
            qualifier: clt$keyword_type_qualifier,
            keyword_specs: array [1 .. 1] of clt$keyword_specification,
          recend,
          type_size_2: clt$type_specification_size,
          element_type_spec_2: record
            header: clt$type_specification_header,
            qualifier: clt$name_type_qualifier,
          recend,
          default_value: string (4),
        recend,
        type4: record
          header: clt$type_specification_header,
        recend,
        type5: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [87, 10, 20, 12, 59, 14, 296], clc$command, 9, 5, 2, 0, 0, 0, 5, 'OSM$RESEF'],
            [['BACKUP_FILE                    ', clc$nominal_entry, 2],
            ['BF                             ', clc$abbreviation_entry, 2],
            ['F                              ', clc$abbreviation_entry, 1],
            ['FILE                           ', clc$nominal_entry, 1],
            ['NEW_FILE_NAME                  ', clc$nominal_entry, 4],
            ['NFN                            ', clc$abbreviation_entry, 4],
            ['PASSWORD                       ', clc$nominal_entry, 3],
            ['PW                             ', clc$abbreviation_entry, 3],
            ['STATUS                         ', clc$nominal_entry, 5]], [
{ PARAMETER 1
      [4, clc$normal_usage_entry, clc$non_secure_parameter, $clt$parameter_spec_methods
            [clc$specify_by_name, clc$specify_positionally], clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$required_parameter, 0, 0],
{ PARAMETER 2
      [1, clc$normal_usage_entry, clc$non_secure_parameter, $clt$parameter_spec_methods
            [clc$specify_by_name, clc$specify_positionally], clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$required_parameter, 0, 0],
{ PARAMETER 3
      [7, clc$normal_usage_entry, clc$secure_parameter, $clt$parameter_spec_methods
            [clc$specify_by_name, clc$specify_positionally], clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 69, clc$optional_default_parameter, 0, 4],
{ PARAMETER 4
      [5, clc$normal_usage_entry, clc$non_secure_parameter, $clt$parameter_spec_methods
            [clc$specify_by_name, clc$specify_positionally], clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$optional_parameter, 0, 0],
{ PARAMETER 5
      [9, 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$file_type]],
{ PARAMETER 2
      [[1, 0, clc$file_type]],
{ PARAMETER 3
      [[1, 0, clc$union_type], [[clc$keyword_type, clc$name_type], FALSE, 2], 44,
            [[1, 0, clc$keyword_type], [1], [['NONE                           ', clc$nominal_entry,
            clc$normal_usage_entry, 1]]], 5, [[1, 0, clc$name_type], [1, osc$max_name_size]], 'none'],
{ PARAMETER 4
      [[1, 0, clc$file_type]],
{ PARAMETER 5
      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$file = 1,
      p$backup_file = 2,
      p$password = 3,
      p$new_file_name = 4,
      p$status = 5;

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

    VAR
      evaluated_file_reference: fst$evaluated_file_reference;

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

    pup$crack_pf_file_reference (pvt [p$file].value^.file_value^,
          $put$cycle_reference_selections [puc$cycle_omitted, puc$lowest_cycle, puc$highest_cycle,
          puc$specific_cycle], 'FILE', file_path_container, p_file_path, cycle_specified, cycle_selector,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pup$crack_backup_file (pvt [p$backup_file].value^.file_value^, backup_file, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt [p$password].value^.kind = clc$name THEN
      password := pvt [p$password].value^.name_value;
    ELSE {keyword = NONE}
      password := osc$null_name;
    IFEND;

    IF pvt [p$new_file_name].specified THEN
      pup$crack_pf_file_reference (pvt [p$new_file_name].value^.file_value^,
            $put$cycle_reference_selections [puc$cycle_omitted, puc$specific_cycle, puc$next_highest_cycle],
            'NEW_FILE_NAME', new_file_path_container, p_new_file_path,
            new_cycle_specified, new_cycle_selector, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF new_cycle_specified THEN
        clp$evaluate_file_reference (pvt [p$new_file_name].value^.file_value^,
              $clt$file_ref_parsing_options [], {resolve_cycle_number} TRUE, evaluated_file_reference,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        new_cycle_selector.cycle_option := pfc$specific_cycle;
        new_cycle_selector.cycle_number := evaluated_file_reference.cycle_reference.cycle_number;
      IFEND;
    ELSE
      new_cycle_specified := FALSE;
      p_new_file_path := p_file_path;
    IFEND;

  PROCEND crack_restore_existing_file;
MODEND pum$restore_existing_file;
