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

?? 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$scan_parameter_list
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
*copyc pup$build_catalog_header
*copyc pup$build_entry
*copyc pup$close_backup_file
*copyc pup$compare_paths
*copyc pup$crack_catalog
*copyc pup$crack_file
*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_catalog_path
*copyc pup$verify_family_administrator
*copyc pup$write_os_status
*copyc puv$restore_archive_information
?? TITLE := '    Global Variables', EJECT ??
?? TITLE := '    [XDCL] pup$restore_existing_catalog_cm ', EJECT ??

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

    VAR
      backup_file: amt$local_file_name,
      catalog_path_container: clt$path_container,
      local_status: ost$status,
      new_catalog_path_container: clt$path_container,
      path_1_above_path_2: boolean,
      paths_equal: boolean,
      p_catalog_path: ^pft$path,
      p_new_catalog_path: ^pft$path;

    crack_resec (parameter_list, catalog_path_container, p_catalog_path, new_catalog_path_container,
          p_new_catalog_path, backup_file, status);
    IF status.normal THEN
      IF UPPERBOUND (p_new_catalog_path^) = pfc$family_name_index THEN
        pup$verify_family_administrator ('RESTORE_EXISTING_CATALOG',
              p_new_catalog_path^[pfc$family_name_index], status);
        IF NOT status.normal THEN
          osp$append_status_parameter (osc$status_parameter_delimiter, ' to restore to a family', status);
        IFEND;
      IFEND;
      IF status.normal THEN
        pup$restore_existing_cat_req (p_catalog_path^, p_new_catalog_path^, backup_file, status);
        pup$write_os_status (status, local_status);
      IFEND;
    IFEND;
  PROCEND pup$restore_existing_catalog_cm;

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

  PROCEDURE pup$restore_existing_cat_req (catalog_path: pft$path;
        new_catalog_path: pft$path;
        backup_file: amt$local_file_name;
    VAR status: ost$status);

    VAR
      backup_file_id: put$file_identifier,
      catalog_entry: put$entry,
      catalog_entry_type: put$entry_type,
      dummy_cycle_selector: pft$cycle_selector,
      dummy_password: pft$password,
      local_status: ost$status,
      p_catalog_header: ^put$catalog_header,
      p_new_catalog_header: ^put$catalog_header;

    IF UPPERBOUND(catalog_path) = pfc$family_name_index THEN
      catalog_entry_type := puc$valid_family_entry;
    ELSE
      catalog_entry_type := puc$valid_catalog_entry;
    IFEND;
    pup$build_entry (catalog_path [UPPERBOUND (catalog_path)], dummy_cycle_selector, catalog_entry_type,
          catalog_entry);
    PUSH p_catalog_header: [1 .. UPPERBOUND (catalog_path)];
    pup$build_catalog_header (osc$nosve_system_set, ^catalog_path, p_catalog_header^);
    PUSH p_new_catalog_header: [1 .. UPPERBOUND (new_catalog_path)];
    pup$build_catalog_header (osc$nosve_system_set, ^new_catalog_path, p_new_catalog_header^);
    pup$verify_catalog_path (new_catalog_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
        pup$initialize_restore_listing (' RESTORE EXISTING CATALOG:', p_catalog_header^, catalog_entry,
              new_catalog_path, dummy_cycle_selector, status);
        IF status.normal THEN
          pup$set_restore_subcmd_defaults (NOT (avp$system_administrator() OR avp$family_administrator()));
          pup$restore_sub_levels (catalog_entry, p_catalog_header^, {password_specified} FALSE,
                {password} osc$null_name, p_new_catalog_header^, {restore_n_levels} FALSE,
                {p_selected_cycles} NIL, 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;
  PROCEND pup$restore_existing_cat_req;

?? TITLE := '    crack_resec ', EJECT ??

  PROCEDURE crack_resec (parameter_list: clt$parameter_list;
    VAR catalog_path_container: clt$path_container;
    VAR p_catalog_path: ^pft$path;
    VAR new_catalog_path_container: clt$path_container;
    VAR p_new_catalog_path: ^pft$path;
    VAR backup_file: amt$local_file_name;
    VAR status: ost$status);

{ pdt restore_existing_cat_pdt (
{ catalog,c:file=$required
{ backup_file,bf:file=$required
{ new_catalog_name,ncn:file
{ status)

?? PUSH (LISTEXT := ON) ??

    VAR
      restore_existing_cat_pdt: [STATIC, READ, cls$pdt] clt$parameter_descriptor_table :=
        [^restore_existing_cat_pdt_names, ^restore_existing_cat_pdt_params];

    VAR
      restore_existing_cat_pdt_names: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 7] of
        clt$parameter_name_descriptor := [['CATALOG', 1], ['C', 1], ['BACKUP_FILE', 2], ['BF', 2], [
        'NEW_CATALOG_NAME', 3], ['NCN', 3], ['STATUS', 4]];

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

{ CATALOG C }
      [[clc$required], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$file_value]],

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

{ NEW_CATALOG_NAME NCN }
      [[clc$optional], 1, 1, 1, 1, clc$value_range_not_allowed, [NIL, clc$file_value]],

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

?? POP ??


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

    pup$crack_catalog ('CATALOG', catalog_path_container, p_catalog_path, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

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

    pup$crack_catalog ('NEW_CATALOG_NAME', new_catalog_path_container, p_new_catalog_path, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF p_new_catalog_path = NIL THEN
      p_new_catalog_path := p_catalog_path;
    ELSE
      CASE UPPERBOUND (p_catalog_path^) OF
      = pfc$family_name_index =
        IF UPPERBOUND (p_new_catalog_path^) > pfc$family_name_index THEN
          osp$set_status_abnormal (puc$pf_utility_id, pue$must_restore_as_family,
                '  RESTORE_EXISTING_CATALOG', status);
        IFEND;
      = pfc$master_catalog_name_index =
        IF UPPERBOUND (p_new_catalog_path^) = pfc$family_name_index THEN
          osp$set_status_abnormal (puc$pf_utility_id, pue$cant_restore_as_family,
                '  RESTORE_EXISTING_CATALOG', status);
        IFEND;
      ELSE {subcatalog
        IF UPPERBOUND (p_new_catalog_path^) <= pfc$family_name_index THEN
          osp$set_status_abnormal (puc$pf_utility_id, pue$must_restore_as_subcatalog,
                ' RESTORE_EXISTING_CATALOG', status);
        IFEND;
      CASEND;
    IFEND;
  PROCEND crack_resec;
MODEND pum$restore_existing_catalog;
