?? NEWTITLE := '  NOS/VE Set Management ' ??
MODULE stm$get_set_info;
?? RIGHT := 110 ??

{  PURPOSE:
{    This module contains those procedures that return information
{    to device management.  These routines all return a list of volumes.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc stc$max_num_members_on_set
*copyc ste$error_condition_codes
*copyc ost$status
*copyc stt$number_of_members
*copyc stt$set_list
*copyc stt$set_name
*copyc stt$set_ordinal
*copyc stt$volume_list
?? POP ??
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
*copyc stp$clear_read_access
*copyc stp$get_active_set_list
*copyc stp$get_volumes_by_ast_index
*copyc stp$search_ast_by_internal_vsn
*copyc stp$search_ast_by_set
*copyc stp$search_ast_by_unique_set
*copyc stp$search_ast_by_volume
*copyc stp$set_read_access
?? OLDTITLE ??
?? NEWTITLE := 'STP$GET_ALL_VOLUMES_IN_SET', EJECT ??

{ PURPOSE:
{   This procedure takes a list of sets, and for each set gets a list of
{   volumes, sums the number of volumes, and transfers the list of volumes for
{   each set to the supplied list of volumes.

  PROCEDURE p$get_all_volumes_in_sets
    (    list_of_sets: stt$set_list;
         number_of_sets: integer;
     VAR volume_list: stt$volume_list;
     VAR actual_number_of_volumes: integer;
     VAR status: ost$status);

    VAR
      found_ast_entry: stt$active_set_entry,
      found_ast_index: stt$ast_index,
      master_vol: stt$volume_info,
      number_of_members_in_set: stt$number_of_members,
      set_found: boolean,
      set_index: integer;

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

  /for_each_set_loop/
    FOR set_index := 1 TO number_of_sets DO
      stp$search_ast_by_set (list_of_sets [set_index], found_ast_entry, found_ast_index, set_found);
      IF set_found THEN
        stp$get_volumes_by_ast_index (found_ast_index, (actual_number_of_volumes + 1), master_vol,
              volume_list, number_of_members_in_set);
        actual_number_of_volumes := actual_number_of_volumes + number_of_members_in_set + 1; {the master}
        IF actual_number_of_volumes <= UPPERBOUND (volume_list) THEN
          volume_list [actual_number_of_volumes] := master_vol;
        IFEND;
      IFEND;
    FOREND /for_each_set_loop/;

    IF actual_number_of_volumes = 0 THEN
      osp$set_status_abnormal (stc$set_management_id, ste$no_scratch_volumes, stc$null_parameter, status);
    IFEND;

  PROCEND p$get_all_volumes_in_sets;

?? OLDTITLE ??
?? NEWTITLE := '[xdcl] STP$GET_INTERNAL_VOLUMES_SET', EJECT ??
*copyc sth$get_internal_volumes_set

  PROCEDURE [XDCL] stp$get_internal_volumes_set
    (    volume: dmt$internal_vsn;
     VAR set_name: stt$set_name;
     VAR status: ost$status);

    VAR
      ast_entry: stt$active_set_entry,
      ast_index: stt$ast_index,
      volume_found: boolean;

    {stp$set_read_access;
    stp$search_ast_by_internal_vsn (volume, ast_entry, ast_index, volume_found);
    IF volume_found THEN
      set_name := ast_entry.set_name;
      status.normal := TRUE;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$vol_not_found, 'internal_vsn', status);
    IFEND;
    {stp$clear_read_access;

  PROCEND stp$get_internal_volumes_set;

?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] STP$GET_ACTIVE_VOLUME_LIST', EJECT ??
*copyc sth$get_active_volume_list

  PROCEDURE [XDCL, #GATE] stp$get_active_volume_list
    (VAR volume_list: stt$volume_list;
     VAR actual_number_of_volumes: integer;
     VAR status: ost$status);

    VAR
      current_set_list_size: integer,
      number_of_sets: stt$number_of_sets,
      p_set_list: ^stt$set_list;

    number_of_sets := 10;
    REPEAT
      current_set_list_size := number_of_sets;
      PUSH p_set_list: [1 .. current_set_list_size];
      stp$get_active_set_list (p_set_list^, number_of_sets);
    UNTIL number_of_sets <= current_set_list_size;

    p$get_all_volumes_in_sets (p_set_list^, number_of_sets, volume_list, actual_number_of_volumes, status);

  PROCEND stp$get_active_volume_list;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] STP$GET_VOLUMES_BY_SET_ORDINAL', EJECT ??
*copyc sth$get_volumes_by_set_ordinal

  PROCEDURE [XDCL, #GATE] stp$get_volumes_by_set_ordinal
    (    set_ordinal: stt$set_ordinal;
     VAR master_vol: stt$volume_info;
     VAR member_vol_list: stt$volume_list;
     VAR actual_number_of_members: stt$number_of_members;
     VAR status: ost$status);

    VAR
      ast_entry: stt$active_set_entry,
      external_set_name: stt$set_name,
      found_ast_index: stt$ast_index,
      set_key_found: boolean;

    IF set_ordinal.entry_type = stc$valid THEN
      {stp$set_read_access;
      stp$search_ast_by_unique_set (set_ordinal.unique_set_name, ast_entry, found_ast_index, set_key_found);
      IF set_key_found THEN
        IF (ast_entry.master_ever_up) AND (ast_entry.master_volume_activity.volume_activity_status =
              stc$active) THEN
          stp$get_volumes_by_ast_index (found_ast_index, 1, master_vol, member_vol_list,
                actual_number_of_members);
          status.normal := TRUE;
        ELSE
          osp$set_status_abnormal (stc$set_management_id, ste$master_not_active, ast_entry.master_vsn,
                status);
          osp$append_status_parameter (osc$status_parameter_delimiter, ast_entry.set_name, status);
        IFEND;
      ELSE
        osp$set_status_abnormal (stc$set_management_id, ste$set_not_active, stc$null_parameter, status);
      IFEND;
      {stp$clear_read_access;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$set_ord_not_set, stc$null_parameter, status);
    IFEND;

  PROCEND stp$get_volumes_by_set_ordinal;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] STP$GET_VOLUMES_IN_SET', EJECT ??
*copyc sth$get_volumes_in_set

  PROCEDURE [XDCL, #GATE] stp$get_volumes_in_set
    (    set_name: stt$set_name;
     VAR master_vol: stt$volume_info;
     VAR member_vol_list: stt$volume_list;
     VAR actual_number_of_members: stt$number_of_members;
     VAR status: ost$status);

    VAR
      ast_entry: stt$active_set_entry,
      found_ast_index: stt$ast_index,
      set_key_found: boolean;

    {stp$set_read_access;
    stp$search_ast_by_set (set_name, ast_entry, found_ast_index, set_key_found);
    IF set_key_found THEN
      IF (ast_entry.master_ever_up) AND (ast_entry.master_volume_activity.volume_activity_status = stc$active)
            THEN
        stp$get_volumes_by_ast_index (found_ast_index, 1, master_vol, member_vol_list,
              actual_number_of_members);
        status.normal := TRUE;
      ELSE
        osp$set_status_abnormal (stc$set_management_id, ste$master_not_active, ast_entry.master_vsn, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, ast_entry.set_name, status);
      IFEND;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$set_not_active, stc$null_parameter, status);
    IFEND;
    {stp$clear_read_access;

  PROCEND stp$get_volumes_in_set;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] STP$GET_VOLUMES_SET_NAME', EJECT ??
*copyc sth$get_volumes_set_name

  PROCEDURE [XDCL, #GATE] stp$get_volumes_set_name
    (    volume: rmt$recorded_vsn;
     VAR set_name: stt$set_name;
     VAR status: ost$status);

    VAR
      ast_entry: stt$active_set_entry,
      ast_index: stt$ast_index,
      volume_found: boolean;

    {stp$set_read_access;
    stp$search_ast_by_volume (volume, ast_entry, ast_index, volume_found);
    IF volume_found THEN
      set_name := ast_entry.set_name;
      status.normal := TRUE;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$vol_not_found, volume, status);
    IFEND;
    {stp$clear_read_access;

  PROCEND stp$get_volumes_set_name;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl, #gate] STP$IS_VOLUME_IN_SET', EJECT ??
*copyc sth$is_volume_in_set

  PROCEDURE [XDCL, #GATE] stp$is_volume_in_set
    (    volume: rmt$recorded_vsn;
         set_name: stt$set_name;
     VAR volume_info: stt$volume_info;
     VAR status: ost$status);

    VAR
      master_info: stt$volume_info,
      number_of_members: stt$number_of_members,
      p_member_list: ^stt$volume_list;

    PUSH p_member_list: [1 .. stc$max_num_members_on_set];
    stp$get_volumes_in_set (set_name, master_info, p_member_list^, number_of_members, status);
    IF status.normal THEN
      IF volume = master_info.recorded_vsn THEN
        volume_info := master_info;
      ELSE
        stp$search_member_list (volume, p_member_list^, number_of_members, volume_info, status);
      IFEND;
    IFEND;

  PROCEND stp$is_volume_in_set;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl] STP$SEARCH_MEMBER_LIST', EJECT ??
*copyc sth$search_member_list

  PROCEDURE [XDCL] stp$search_member_list
    (    volume: rmt$recorded_vsn;
         member_list: stt$volume_list;
         number_of_members: stt$number_of_members;
     VAR volume_info: stt$volume_info;
     VAR status: ost$status);

    VAR
      i: integer,
      maximum_loop: integer,
      volume_found: boolean;

    IF (UPPERBOUND (member_list)) < number_of_members THEN
      maximum_loop := UPPERBOUND (member_list);
    ELSE
      maximum_loop := number_of_members;
    IFEND;

    volume_found := FALSE;

  /search_for_rec_vsn/
    FOR i := 1 TO maximum_loop DO
      volume_info := member_list [i];
      IF volume_info.recorded_vsn = volume THEN
        volume_found := TRUE;
        EXIT /search_for_rec_vsn/; {----->
      IFEND;
    FOREND /search_for_rec_vsn/;
    IF volume_found THEN
      status.normal := TRUE;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$vol_not_in_set, volume, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, member_list [1].set_name, status);
    IFEND;

  PROCEND stp$search_member_list;
?? OLDTITLE ??
MODEND stm$get_set_info;
