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

?? NEWTITLE := '   Global Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rmd$volume_declarations
*copyc cle$ecc_miscellaneous
*copyc pue$error_condition_codes
*copyc pft$volume_list
*copyc put$include_volumes_option
?? POP ??
*copyc clp$evaluate_parameters
*copyc clp$get_set_count
*copyc clp$get_value
*copyc clp$scan_parameter_list
*copyc osp$set_status_abnormal
*copyc pup$display_line
*copyc stp$get_pf_volumes
*copyc clv$non_alphanumeric
*copyc osv$lower_to_upper
*copyc puv$include_data_options
?? TITLE := '    Global Variables', EJECT ??

  VAR
    puv$include_volumes_option: [XDCL, STATIC] put$include_volumes_option := puc$multiple_volumes,
    puv$p_included_volumes: [XDCL, STATIC] ^array [1 .. * ] of rmt$recorded_vsn := NIL;

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

  FUNCTION [XDCL] pup$all_volumes_included: boolean;

    pup$all_volumes_included := (puv$p_included_volumes = NIL);
  FUNCEND pup$all_volumes_included;

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

  PROCEDURE [XDCL] pup$check_if_volume_included
    (    p_volume_list: ^pft$volume_list;
     VAR volume_included: boolean);

    VAR
      file_volume: integer,
      included_volume: integer;

    IF puv$p_included_volumes = NIL THEN
      volume_included := TRUE;
    ELSEIF p_volume_list = NIL THEN
      volume_included := FALSE;
    ELSE
      volume_included := FALSE;

      IF puv$include_volumes_option = puc$initial_volume THEN

      /search_for_volume_one/
        FOR included_volume := 1 TO UPPERBOUND (puv$p_included_volumes^) DO
          IF p_volume_list^ [1] = puv$p_included_volumes^ [included_volume] THEN
            volume_included := TRUE;
            EXIT /search_for_volume_one/;
          IFEND;
        FOREND /search_for_volume_one/;

       ELSE { multiple volumes

       /search_included_volumes/
         FOR included_volume := 1 TO UPPERBOUND (puv$p_included_volumes^) DO
            FOR file_volume := 1 to UPPERBOUND(p_volume_list^) DO
              IF p_volume_list^ [file_volume] = puv$p_included_volumes^ [included_volume] THEN
                volume_included := TRUE;
                EXIT /search_included_volumes/;
              IFEND;
            FOREND;
         FOREND;
      IFEND;
    IFEND;
  PROCEND pup$check_if_volume_included;

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

  PROCEDURE [XDCL] pup$display_included_volumes (parameter_list: clt$parameter_list;
    VAR status: ost$status);
{ PDT display_volumes_pdt (status)

?? PUSH (LISTEXT := ON) ??

    VAR
      display_volumes_pdt: [STATIC, READ, cls$pdt] clt$parameter_descriptor_table :=
        [^display_volumes_pdt_names, ^display_volumes_pdt_params];

    VAR
      display_volumes_pdt_names: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 1] of
        clt$parameter_name_descriptor := [['STATUS', 1]];

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

{ 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, display_volumes_pdt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_included_volumes ({display_cycle_selection =} TRUE, status);
  PROCEND pup$display_included_volumes;

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

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

{ PROCEDURE display_volumes_pdt (
{   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, 13, 12, 38, 13, 570],
    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;
    VAR
      current_pf_guess: integer,
      i: integer,
      number_of_volumes: integer,
      p_volume_list: ^pft$volume_list;

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

    number_of_volumes := 2;
    REPEAT
      current_pf_guess := number_of_volumes;
      PUSH p_volume_list: [1 .. current_pf_guess];
      stp$get_pf_volumes (p_volume_list^, number_of_volumes, status);
    UNTIL (NOT status.normal) OR (current_pf_guess >= number_of_volumes);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    FOR i := 1 TO number_of_volumes DO
      pup$display_line (p_volume_list^ [i], status);
    FOREND;

  PROCEND pup$display_volumes_command;
?? TITLE := '    pup$backup_include_volumes_cmd ', EJECT ??

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

{ PDT backup_include_vol_pdt (
{   recorded_vsns, recorded_vsn, rvsn: list of name 1 .. 6 or key all = $required
{   cycle_selection, cs: key initial_volume, iv, multiple_volumes, mv = multiple_volumes
{   status)

?? PUSH (LISTEXT := ON) ??

  VAR
    backup_include_vol_pdt: [STATIC, READ, cls$pdt] clt$parameter_descriptor_table := [
      ^backup_include_vol_pdt_names, ^backup_include_vol_pdt_params];

  VAR
    backup_include_vol_pdt_names: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 6] of
      clt$parameter_name_descriptor := [['RECORDED_VSNS', 1], ['RECORDED_VSN', 1], ['RVSN', 1], [
      'CYCLE_SELECTION', 2], ['CS', 2], ['STATUS', 3]];

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

{ RECORDED_VSNS RECORDED_VSN RVSN }
    [[clc$required], 1, clc$max_value_sets,1, 1, clc$value_range_not_allowed, [^backup_include_vol_pdt_kv1,
      clc$name_value, 1, 6]],

{ CYCLE_SELECTION CS }
    [[clc$optional_with_default, ^backup_include_vol_pdt_dv2], 1, 1, 1, 1, clc$value_range_not_allowed, [^
      backup_include_vol_pdt_kv2, clc$keyword_value]],

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

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

  VAR
    backup_include_vol_pdt_kv2: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 4] of ost$name := [
      'INITIAL_VOLUME','IV','MULTIPLE_VOLUMES','MV'];

  VAR
    backup_include_vol_pdt_dv2: [STATIC, READ, cls$pdt_names_and_defaults] string (16) := 'multiple_volumes';

?? POP ??

    VAR
      number_of_volumes: 0 .. clc$max_value_sets,
      p_volume_list: ^pft$volume_list,
      temp_include_volumes_option: put$include_volumes_option;

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

    clp$get_set_count ('RECORDED_VSNS', number_of_volumes, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    PUSH p_volume_list: [1..number_of_volumes];
    crack_recorded_vsn (p_volume_list, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    crack_cycle_selection (temp_include_volumes_option, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF p_volume_list <> NIL THEN
      IF puc$include_offline_data IN puv$include_data_options THEN
        osp$set_status_abnormal (puc$pf_utility_id, pue$incv_and_offline_conflict, '', status);
        RETURN;
      IFEND;
    IFEND;

    IF puv$p_included_volumes <> NIL THEN
      FREE puv$p_included_volumes;
    IFEND;

    IF p_volume_list = NIL THEN
      { include all volumes
      puv$p_included_volumes := NIL;
    ELSE
      ALLOCATE puv$p_included_volumes: [1 .. UPPERBOUND (p_volume_list^)];
      puv$p_included_volumes^ := p_volume_list^;
    IFEND;
    puv$include_volumes_option := temp_include_volumes_option;
    display_included_volumes ({display_cycle_selection =} TRUE, status);
  PROCEND pup$backup_include_volumes_cmd;

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

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

{ PDT restore_include_vol_pdt (
{   recorded_vsns, recorded_vsn, rvsn: list of name 1 .. 6 or key all = $required
{   status)

?? PUSH (LISTEXT := ON) ??

  VAR
    restore_include_vol_pdt: [STATIC, READ, cls$pdt] clt$parameter_descriptor_table := [
      ^restore_include_vol_pdt_names, ^restore_include_vol_pdt_params];

  VAR
    restore_include_vol_pdt_names: [STATIC, READ, cls$pdt_names_and_defaults] array [1 .. 4] of
      clt$parameter_name_descriptor := [['RECORDED_VSNS', 1], ['RECORDED_VSN', 1], ['RVSN', 1], ['STATUS', 2]
      ];

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

{ RECORDED_VSNS RECORDED_VSN RVSN }
    [[clc$required], 1, clc$max_value_sets,1, 1, clc$value_range_not_allowed, [^restore_include_vol_pdt_kv1,
      clc$name_value, 1, 6]],

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

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

?? POP ??

    VAR
      number_of_volumes: 0 .. clc$max_value_sets,
      p_volume_list: ^pft$volume_list;

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

    clp$get_set_count ('RECORDED_VSNS', number_of_volumes, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    PUSH p_volume_list: [1..number_of_volumes];
    crack_recorded_vsn (p_volume_list, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF puv$p_included_volumes <> NIL THEN
      FREE puv$p_included_volumes;
    IFEND;

    IF p_volume_list = NIL THEN
      { Include all volumes.
      puv$p_included_volumes := NIL;
    ELSE
      ALLOCATE puv$p_included_volumes: [1 .. UPPERBOUND (p_volume_list^)];
      puv$p_included_volumes^ := p_volume_list^;
    IFEND;

    display_included_volumes ({display_cycle_selection =} FALSE, status);

  PROCEND pup$restore_include_volumes_cmd;
?? TITLE := '    [XDCL] pup$verify_volume_list ', EJECT ??

  PROCEDURE [XDCL] pup$verify_volume_list (volume_list: array [1 .. * ] OF rmt$recorded_vsn;
    VAR status: ost$status);

{ This verifies that all volumes in the volume_list are active in the system

    VAR
      current_pf_guess: integer,
      i: integer,
      j: integer,
      number_of_volumes: integer,
      p_pf_volume_list: ^array [1 .. * ] of rmt$recorded_vsn,
      volume_found: boolean;

    {Get active volumes
    number_of_volumes := 2;
    REPEAT
      current_pf_guess := number_of_volumes;
      PUSH p_pf_volume_list: [1 .. current_pf_guess];
      stp$get_pf_volumes (p_pf_volume_list^, number_of_volumes, status);
    UNTIL (NOT status.normal) OR (current_pf_guess >= number_of_volumes);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    FOR i := 1 TO UPPERBOUND (volume_list) DO
      volume_found := FALSE;
      { search the active pf volume list for this volume

    /check_if_volume_active/
      FOR j := 1 TO number_of_volumes DO
        IF volume_list [i] = p_pf_volume_list^ [j] THEN
          volume_found := TRUE;
          EXIT /check_if_volume_active/;
        IFEND;
      FOREND /check_if_volume_active/;
      IF NOT volume_found THEN
        osp$set_status_abnormal (puc$pf_utility_id, pue$volume_not_active, volume_list [i], status);
        RETURN;
      IFEND;
    FOREND;
  PROCEND pup$verify_volume_list;

?? TITLE := '    crack_recorded_vsn ', EJECT ??

  PROCEDURE crack_recorded_vsn (
    VAR p_volume_list: ^pft$volume_list;
    VAR status: ost$status);

    VAR
      i: integer,
      value: clt$value;

    FOR i := 1 TO UPPERBOUND(p_volume_list^) DO
      clp$get_value ('RECORDED_VSNS', i, 1, clc$low, value, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF value.name.value = 'ALL' THEN
        IF i = 1 THEN
          p_volume_list := NIL;
        ELSE
          osp$set_status_abnormal (puc$pf_utility_id, cle$all_must_be_used_alone, 'RECORDED_VSNS', status);
        IFEND;
        RETURN;
      IFEND;
      p_volume_list^ [i] := value.name.value;
    FOREND;

  PROCEND crack_recorded_vsn;

?? TITLE := '    crack_cycle_selection ', EJECT ??

  PROCEDURE crack_cycle_selection (
    VAR include_volumes_option: put$include_volumes_option;
    VAR status: ost$status);

    VAR
      value: clt$value;

    clp$get_value ('CYCLE_SELECTION', 1, 1, clc$low, value, status);
    IF NOT status.normal THEN
       RETURN;
    IFEND;
    IF value.name.value (1) = 'I' THEN
      include_volumes_option := puc$initial_volume;
    ELSE
      include_volumes_option := puc$multiple_volumes;
    IFEND;
  PROCEND crack_cycle_selection;

?? TITLE := '    display_included_volumes ', EJECT ??

  PROCEDURE display_included_volumes (
         display_cycle_selection: boolean;
     VAR status: ost$status);

    VAR
      i: integer;

    IF puv$p_included_volumes = NIL THEN
      pup$display_line (' INCLUDE_VOLUMES ALL ', status);
    ELSE
      pup$display_line (' INCLUDE_VOLUMES: ', status);
      FOR i := 1 TO UPPERBOUND (puv$p_included_volumes^) DO
        pup$display_line (puv$p_included_volumes^ [i], status);
      FOREND;
      IF display_cycle_selection THEN
      IF puv$include_volumes_option = puc$initial_volume THEN
          pup$display_line (' CYCLE_SELECTION=INITIAL_VOLUME', status);
        ELSE
          pup$display_line (' CYCLE_SELECTION=MULTIPLE_VOLUME', status);
        IFEND;
      IFEND;
    IFEND;
  PROCEND display_included_volumes;

MODEND pum$include_volumes;
