?? RIGHT := 110 ??
?? NEWTITLE := 'INSTALL_SOFTWARE Utility: RAP$ACCESS_DIRECTORY_FOR_READ Interface.' ??
MODULE ram$access_directory_for_read;

{ PURPOSE:
{   This module contains the interface that opens the IDB Directory and
{   returns a record of pointers to the major components of the directory.
{
{ DESIGN:
{   The compiled module resides in RAF$LIBRARY.
{
{ NOTES:
{
?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rae$install_software_cc
*copyc rac$idb_directory_name
*copyc fst$path
*copyc rat$idb_directory_pointers
*copyc rat$path
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$get_segment_pointer
*copyc amp$set_segment_eoi
*copyc fsp$close_file
*copyc fsp$open_file
*copyc osp$establish_block_exit_hndlr
*copyc osp$disestablish_cond_handler
*copyc rap$establish_directory_ptrs
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] rap$access_directory_for_read', EJECT ??

{ PURPOSE:
{   This interface opens the IDB Directory file and returns a record of
{   pointers to the caller.
{
{ DESIGN:
{   The path to the installation database catalog that contains the
{   directory is passed in.  The IDB Directory file is opened as a segment
{   access file for read only.  The directory's major components are
{   accessed and the file is verified as a directory.  The pointers to
{   the major components are returned in a record.
{
{   The calling sequence is responsible for closing the file.
{
{ NOTES:
{   The parameter INSTALLATION_DATABASE on the RAP$GET_DIRECTORY_POINTERS
{   is used only in error message templates.
{


  PROCEDURE [XDCL] rap$access_directory_for_read
    (    installation_database: rat$path;
     VAR directory_pointers: rat$idb_directory_pointers;
     VAR directory_fid: amt$file_identifier;
     VAR file_opened: boolean;
     VAR status: ost$status);


    VAR
      attachment_options: array [1 .. 3] of fst$attachment_option,
      directory: rat$path,
      ignore_status: ost$status,
      local_status: ost$status,
      segment_pointer: amt$segment_pointer;


?? NEWTITLE := 'abort_handler', EJECT ??

{ PURPOSE:
{   This procedure cleans up when an abort situation occurs within the
{   block structure.
{
{ DESIGN:
{   The function of this condition handler is to close the IDB directory
{   file when an abort condition arises.
{
{ NOTES:
{

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      fsp$close_file (directory_fid, ignore_status);

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    attachment_options [1].selector := fsc$access_and_share_modes;
    attachment_options [1].access_modes.selector := fsc$specific_access_modes;
    attachment_options [1].access_modes.value := $fst$file_access_options [fsc$read];
    attachment_options [1].share_modes.selector := fsc$determine_from_access_modes;
    attachment_options [2].selector := fsc$create_file;
    attachment_options [2].create_file := FALSE;
    attachment_options [3].selector := fsc$wait_for_attachment;
    attachment_options [3].wait_for_attachment.wait := osc$wait;
    attachment_options [3].wait_for_attachment.wait_time := fsc$longest_wait_time;

{ Assemble the path to the IDB Directory using the installation database path
{ and the directory name.

    STRINGREP (directory.path, directory.size, installation_database.path (1, installation_database.size),
          '.', rac$idb_directory_name);

    osp$establish_block_exit_hndlr (^abort_handler);

  /main/
    BEGIN

      file_opened := TRUE;
      fsp$open_file (directory.path (1, directory.size), amc$segment, ^attachment_options, NIL, NIL, NIL, NIL,
            directory_fid, status);
      IF NOT status.normal THEN
        file_opened := FALSE;
        EXIT /main/;
      IFEND;

      amp$get_segment_pointer (directory_fid, amc$sequence_pointer, segment_pointer, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      directory_pointers.sequence_p := segment_pointer.sequence_pointer;

      rap$establish_directory_ptrs (installation_database, directory_pointers, status);

    END /main/;

    IF (file_opened) AND (NOT status.normal) THEN
      fsp$close_file (directory_fid, ignore_status);
      file_opened := FALSE;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND rap$access_directory_for_read;

MODEND ram$access_directory_for_read;

