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

{ PURPOSE:
{   This module includes all modules that read the volume set table but do not
{   modify it
{
{ DESIGN:
{   This module lives in the system core library with ring brackets 133.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ste$error_condition_codes
*copyc dmt$internal_vsn
*copyc gft$system_file_identifier
*copyc ost$status
*copyc pft$p_root
*copyc stt$member_list_locator
*copyc stt$member_vsn_list
*copyc stt$mvl_index
*copyc stt$number_of_members
*copyc stt$sequence_record
*copyc stt$vol_set_table
?? POP ??
*copyc osp$set_status_abnormal
*copyc stp$open_vst
*copyc stp$return_opened_vst
*copyc stp$search_ast_by_set
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$build_member_list_locator', EJECT ??
*copyc sth$build_member_list_locator

  PROCEDURE [XDCL] stp$build_member_list_locator
    (    p_member_list: ^stt$member_vsn_list;
         p_vol_set_table: ^stt$vol_set_table;
     VAR member_list_locator: stt$member_list_locator);

    VAR
      p_cell: ^cell;

    IF p_member_list = NIL THEN
      member_list_locator.array_size := 0;
    ELSE
      member_list_locator.array_size := UPPERBOUND (p_member_list^);
      p_cell := #LOC (p_member_list^);
      member_list_locator.relative_cell_pointer := #REL (p_cell, p_vol_set_table^);
    IFEND;

  PROCEND stp$build_member_list_locator;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$build_member_list_pointer', EJECT ??
*copyc sth$build_member_list_pointer

  PROCEDURE [XDCL] stp$build_member_list_pointer
    (    member_list_locator: stt$member_list_locator;
         p_vol_set_table: ^stt$vol_set_table;
     VAR p_member_list: ^stt$member_vsn_list);

    VAR
      p_sequence: ^stt$sequence,
      p_sequence_record: ^stt$sequence_record;

    IF member_list_locator.array_size = 0 THEN
      p_member_list := NIL;
    ELSE
      p_sequence_record := #PTR (member_list_locator.relative_cell_pointer, p_vol_set_table^);
      p_sequence := ^p_sequence_record^.sequence;
      RESET p_sequence;
      NEXT p_member_list: [1 .. member_list_locator.array_size] IN p_sequence;
    IFEND;

  PROCEND stp$build_member_list_pointer;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$build_pf_root_locator', EJECT ??
*copyc sth$build_pf_root_locator

  PROCEDURE [XDCL] stp$build_pf_root_locator
    (    p_pf_root: pft$p_root;
         p_vol_set_table: ^stt$vol_set_table;
     VAR pf_root_locator: stt$pf_root_locator);

    VAR
      p_cell: ^cell;

    IF p_pf_root = NIL THEN
      pf_root_locator.length := 0;
    ELSE
      pf_root_locator.length := #SIZE (p_pf_root^);
      p_cell := #LOC (p_pf_root^);
      pf_root_locator.relative_cell_pointer := #REL (p_cell, p_vol_set_table^);
    IFEND;

  PROCEND stp$build_pf_root_locator;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$build_pf_root_pointer', EJECT ??
*copyc sth$build_pf_root_pointer

  PROCEDURE [XDCL] stp$build_pf_root_pointer
    (    pf_root_locator: stt$pf_root_locator;
         p_vol_set_table: ^stt$vol_set_table;
     VAR p_pf_root: pft$p_root);

    VAR
      p_sequence: ^stt$sequence,
      p_sequence_record: ^stt$sequence_record;

    IF pf_root_locator.length = 0 THEN
      p_pf_root := NIL;
    ELSE
      p_sequence_record := #PTR (pf_root_locator.relative_cell_pointer, p_vol_set_table^);
      p_sequence := ^p_sequence_record^.sequence;
      RESET p_sequence;
      NEXT p_pf_root: [[REP pf_root_locator.length OF cell]] IN p_sequence;
    IFEND;

  PROCEND stp$build_pf_root_pointer;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$get_root_recreated', EJECT ??

  PROCEDURE [XDCL, #GATE] stp$get_root_recreated
    (    set_name: stt$set_name;
     VAR root_recreated: boolean;
     VAR status: ost$status);

    VAR
      ast_entry: stt$active_set_entry,
      ast_index: stt$ast_index,
      local_status: ost$status,
      master_vol: rmt$recorded_vsn,
      master_vst_segment_pointer: mmt$segment_pointer,
      masters_sfid: gft$system_file_identifier,
      p_master_vst: ^stt$vol_set_table,
      set_found_in_ast: boolean;

    stp$search_ast_by_set (set_name, ast_entry, ast_index, set_found_in_ast);
    IF set_found_in_ast THEN
      master_vol := ast_entry.master_vsn;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$set_not_active, set_name, status);
      RETURN; {----->
    IFEND;
    stp$open_vst (master_vol, FALSE, masters_sfid, master_vst_segment_pointer, status);
    IF status.normal THEN
      p_master_vst := master_vst_segment_pointer.cell_pointer;
      root_recreated := p_master_vst^.root_recreated = stc$root_recreated;
      stp$return_opened_vst (masters_sfid, master_vst_segment_pointer, local_status);
    IFEND;

  PROCEND stp$get_root_recreated;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$obtain_master_vst_info', EJECT ??
*copyc sth$obtain_master_vst_info

  PROCEDURE [XDCL, #GATE] stp$obtain_master_vst_info
    (    p_vol_set_table: ^stt$vol_set_table;
     VAR set_owner: ost$user_identification;
     VAR dm_packet_storage: stt$dm_packet_storage;
     VAR member_list: array [ * ] of stt$member_vsn_entry;
     VAR size_of_member_list: stt$number_of_members;
     VAR pf_root_stored: boolean;
     VAR pf_root_size: pft$root_size;
     VAR pf_root_locator: stt$pf_root_locator);

    VAR
      input_list_size: integer,
      member_vol_index: integer,
      new_p_member_vsn_list: ^stt$member_vsn_list;

    set_owner := p_vol_set_table^.set_owner;
    pf_root_stored := p_vol_set_table^.pf_root_storage.pf_root_ever_stored;
    IF pf_root_stored THEN
      pf_root_size := p_vol_set_table^.pf_root_storage.pf_root_size;
      pf_root_locator := p_vol_set_table^.pf_root_storage.pf_root_locator;
    IFEND;
    dm_packet_storage := p_vol_set_table^.master_dm_packet_storage;
    stp$build_member_list_pointer (p_vol_set_table^.member_vsn_list_locator, p_vol_set_table,
          new_p_member_vsn_list);
    IF new_p_member_vsn_list = NIL THEN
      size_of_member_list := 0;
    ELSE
      input_list_size := UPPERBOUND (member_list);
      size_of_member_list := UPPERBOUND (new_p_member_vsn_list^);

    /loop_through_member_list/
      FOR member_vol_index := 1 TO size_of_member_list DO
        IF member_vol_index > input_list_size THEN
          EXIT /loop_through_member_list/; {----->
        ELSE
          member_list [member_vol_index] := new_p_member_vsn_list^ [member_vol_index];
        IFEND;
      FOREND /loop_through_member_list/;
    IFEND;

  PROCEND stp$obtain_master_vst_info;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$obtain_member_vst_info', EJECT ??
*copyc sth$obtain_member_vst_info

  PROCEDURE [XDCL, #GATE] stp$obtain_member_vst_info
    (    p_vol_set_table: ^stt$vol_set_table;
     VAR master_vsn: rmt$recorded_vsn;
     VAR master_internal_vsn: dmt$internal_vsn);

    master_internal_vsn := p_vol_set_table^.master_internal_vsn;
    master_vsn := p_vol_set_table^.master_vsn;

  PROCEND stp$obtain_member_vst_info;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL, #GATE] stp$obtain_vst_header', EJECT ??
*copyc sth$obtain_vst_header

  PROCEDURE [XDCL, #GATE] stp$obtain_vst_header
    (    p_vol_set_table: ^stt$vol_set_table;
     VAR volume: rmt$recorded_vsn;
     VAR internal_vsn: dmt$internal_vsn;
     VAR volume_in_set: boolean;
     VAR set_name: stt$set_name;
     VAR unique_set_name: stt$unique_set_name;
     VAR volume_status_in_set: stt$vol_status_in_set);

    volume := p_vol_set_table^.vsn;
    internal_vsn := p_vol_set_table^.internal_vsn;
    volume_in_set := p_vol_set_table^.entry_type = stc$valid;
    IF volume_in_set THEN
      set_name := p_vol_set_table^.set_name;
      unique_set_name := p_vol_set_table^.unique_set_name;
      volume_status_in_set := p_vol_set_table^.vol_status_in_set;
    IFEND;

  PROCEND stp$obtain_vst_header;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$obtain_vst_pf_root', EJECT ??
*copyc sth$obtain_vst_pf_root

  PROCEDURE [XDCL] stp$obtain_vst_pf_root
    (    p_master_vst: ^stt$vol_set_table;
     VAR pf_root: pft$root;
     VAR status: ost$status);

    VAR
      dm_packet_storage: stt$dm_packet_storage,
      input_root_size: pft$root_size,
      number_of_members: stt$number_of_members,
      p_member_list: ^array [ * ] of stt$member_vsn_entry,
      p_stored_pf_root: ^pft$root,
      pf_root_ever_stored: boolean,
      pf_root_locator: stt$pf_root_locator,
      set_owner: ost$user_identification,
      stored_pf_root_size: pft$root_size;

    status.normal := TRUE;
    PUSH p_member_list: [1 .. 1];
    stp$obtain_master_vst_info (p_master_vst, set_owner, dm_packet_storage, p_member_list^, number_of_members,
          pf_root_ever_stored, stored_pf_root_size, pf_root_locator);
    IF pf_root_ever_stored THEN
      input_root_size := #SIZE (pf_root);
      IF input_root_size <> stored_pf_root_size THEN
        osp$set_status_abnormal (stc$set_management_id, ste$incorrect_root_size, p_master_vst^.set_name,
              status);
      ELSE
        stp$build_pf_root_pointer (pf_root_locator, p_master_vst, p_stored_pf_root);
        IF p_stored_pf_root <> NIL THEN
          pf_root := p_stored_pf_root^;
        ELSE
          osp$set_status_abnormal (stc$set_management_id, ste$pf_root_not_stored, p_master_vst^.set_name,
                status);
        IFEND;
      IFEND;
    ELSE
      osp$set_status_abnormal (stc$set_management_id, ste$pf_root_not_stored, p_master_vst^.set_name, status);
    IFEND;

  PROCEND stp$obtain_vst_pf_root;
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] stp$search_mvt_for_vol', EJECT ??

  PROCEDURE [XDCL] stp$search_mvl_for_vol
    (    member_vol: rmt$recorded_vsn;
         p_mvl: ^stt$member_vsn_list;
     VAR mvl_index: stt$mvl_index;
     VAR vol_found: boolean);

{  PURPOSE:
{   This procedure searches the volume list of the master volume, for
{ a given volume.

    VAR
      temp_mvl_index: integer,
      upper: integer;

    vol_found := FALSE;
    IF p_mvl <> NIL THEN
      temp_mvl_index := LOWERBOUND (p_mvl^);
      upper := UPPERBOUND (p_mvl^);
      REPEAT
        IF p_mvl^ [temp_mvl_index].entry_type = stc$valid THEN
          IF p_mvl^ [temp_mvl_index].member_vsn = member_vol THEN
            vol_found := TRUE;
            mvl_index := temp_mvl_index;
          ELSE
            temp_mvl_index := temp_mvl_index + 1;
          IFEND;
        ELSE
          temp_mvl_index := temp_mvl_index + 1;
        IFEND;
      UNTIL (vol_found OR (temp_mvl_index > upper));
    IFEND;

  PROCEND stp$search_mvl_for_vol;
?? OLDTITLE ??
MODEND stm$read_vst;
