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

{ PURPOSE:
{   This module contains the interface and procedures that initializes the
{   processing sequence from a installation control file.  This is to
{   include accessing the packing list when not already contained in the
{   installation control file.
{
{ DESIGN:
{   The compiled module resides in RAF$LIBRARY.
{
{ NOTES:
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rac$control_file_name
*copyc rae$install_software_cc
*copyc rat$installation_control_record
*copyc rat$installation_defaults
?? POP ??
*copyc amp$get_segment_pointer
*copyc fsp$close_file
*copyc fsp$open_file
*copyc mmp$create_scratch_segment
*copyc mmp$delete_scratch_segment
*copyc osp$append_status_parameter
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc rap$establish_icr_packlist_ptrs
*copyc rap$establish_icr_subp_ptrs
*copyc rap$open_packing_list_using_icr
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] rap$init_processing_seq_fr_fileuence', EJECT ??

{ PURPOSE:
{   This interface creates and initializes the processing sequence that is
{   used by the installation control record from the installation control
{   file.  The processing sequence holds records that describe how the
{   processing will be done.  The packing list is also accessed when not
{   part of the installation control file.
{
{ DESIGN:
{   A memory scratch segment is created to contain the processing sequence.
{   (The calling interface is expected to delete the scratch segment.)
{
{   The installation control file is copied into the just created processing
{   sequence (The installation control file is a copy of the original
{   processing sequence that was created just before the batch jobs were
{   submitted.)
{
{   After the copy is made the processing header is re-established.  The
{   relative pointers to the processing records are converted to real
{   pointers in the installation control record.  All major pointers are
{   reestablshed.
{
{ NOTES:
{

  PROCEDURE [XDCL] rap$init_processing_seq_fr_file
    (    installation_control_file: fst$file_reference;
     VAR installation_control_record {input, output} : rat$installation_control_record;
     VAR processing_segment_pointer: amt$segment_pointer;
     VAR packing_list_fid: amt$file_identifier;
     VAR packing_list_opened: boolean;
     VAR status: ost$status);


    VAR
      ignore_status: ost$status,
      processing_seq_eoi_p: ^cell;


?? 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 return the scratch
{   segment 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;


      IF processing_segment_pointer.sequence_pointer <> NIL THEN
        mmp$delete_scratch_segment (processing_segment_pointer, ignore_status);
        processing_segment_pointer.sequence_pointer := NIL;
      IFEND;

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??


    status.normal := TRUE;
    processing_segment_pointer.kind := amc$sequence_pointer;
    processing_segment_pointer.sequence_pointer := NIL;

    packing_list_opened := FALSE;

    osp$establish_block_exit_hndlr (^abort_handler);

  /main/
    BEGIN


      init_processing_seq_and_header (installation_control_file, installation_control_record,
            processing_segment_pointer, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      IF installation_control_record.processing_header_p^.packing_list_seq_rel_p = NIL THEN

        rap$open_packing_list_using_icr (installation_control_record, packing_list_fid,
              packing_list_opened, status);

      ELSE {Packing list is already in processing sequence}

        installation_control_record.packing_list_pointers.sequence_p :=
              #PTR (installation_control_record.processing_header_p^.packing_list_seq_rel_p,
              installation_control_record.processing_seq_p^);

      IFEND;

      { Establish packing list pointers.

      rap$establish_icr_packlist_ptrs (installation_control_record, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      { Re-establish the pointers to the processing records.  These are fields in the
      { installation control record.

      installation_control_record.job_processing_records_p :=
            #PTR (installation_control_record.processing_header_p^.job_processing_rec_rel_p,
            installation_control_record.processing_seq_p^);

      installation_control_record.medium_processing_records_p :=
            #PTR (installation_control_record.processing_header_p^.medium_processing_rec_rel_p,
            installation_control_record.processing_seq_p^);

      installation_control_record.subproduct_processing_records_p :=
            #PTR (installation_control_record.processing_header_p^.subproduct_processing_rec_rel_p,
            installation_control_record.processing_seq_p^);

      rap$establish_icr_subp_ptrs (installation_control_record, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

    END /main/;

    IF (NOT status.normal) AND (processing_segment_pointer.sequence_pointer <> NIL) THEN
      mmp$delete_scratch_segment (processing_segment_pointer, ignore_status);
      processing_segment_pointer.sequence_pointer := NIL;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND rap$init_processing_seq_fr_file;

?? OLDTITLE ??
?? NEWTITLE := 'init_processing_seq_and_header', EJECT ??

{ PURPOSE:
{   This procedure writes the contents of the installation control file to
{   the processing sequence in memory.
{
{ DESIGN:
{   The file is opened as segment access and a file contents pointer is
{   established.  A sequence contents file is created for the same size and
{   the file contents are assigned to the memory processing sequence
{   contents (using assignment of deferred pointers).
{
{ NOTES:
{

  PROCEDURE init_processing_seq_and_header
    (    installation_control_file: fst$file_reference;
     VAR installation_control_record {input, output} : rat$installation_control_record;
     VAR processing_segment_pointer: amt$segment_pointer;
     VAR status: ost$status);


    VAR
      attachment_options: array [1 .. 3] of fst$attachment_option,
      control_file_contents_p: ^SEQ ( * ),
      control_file_fid: amt$file_identifier,
      control_file_length: integer,
      control_file_opened: boolean,
      control_file_segment_pointer: amt$segment_pointer,
      local_status: ost$status,
      processing_seq_contents_p: ^SEQ ( * );


?? 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 return the installation
{   control 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 (control_file_fid, ignore_status);

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??


    status.normal := TRUE;
    control_file_opened := FALSE;

    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;

    osp$establish_block_exit_hndlr (^abort_handler);

  /main/
    BEGIN

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, processing_segment_pointer, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;
      installation_control_record.processing_seq_p := processing_segment_pointer.sequence_pointer;

      control_file_opened := TRUE;
      fsp$open_file (installation_control_file, amc$segment, ^attachment_options, NIL, NIL, NIL, NIL,
            control_file_fid, status);
      IF NOT status.normal THEN
        control_file_opened := FALSE;
        EXIT /main/;
      IFEND;

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

      { Establish the pointer to the control file contents.

      control_file_length := #SIZE (control_file_segment_pointer.sequence_pointer^);

      RESET control_file_segment_pointer.sequence_pointer;
      NEXT control_file_contents_p: [[REP control_file_length OF cell]] IN
            control_file_segment_pointer.sequence_pointer;
      IF control_file_contents_p = NIL THEN
        osp$set_status_abnormal ('RA', rae$accessed_beyond_segment_eoi, rac$control_file_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'CONTENTS', status);
        EXIT /main/;
      IFEND;

      { Establish the pointer to the processing sequence contents for the same length.

      RESET installation_control_record.processing_seq_p;
      NEXT processing_seq_contents_p: [[REP control_file_length OF cell]] IN
            installation_control_record.processing_seq_p;
      IF processing_seq_contents_p = NIL THEN
        osp$set_status_abnormal ('RA', rae$accessed_beyond_segment_eoi, 'PROCESSING SEQUENCE', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'CONTENTS', status);
        EXIT /main/;
      IFEND;

      { Assign the contents of the control file to the contents of the processing sequence.

      processing_seq_contents_p^ := control_file_contents_p^;

      { Establish the pointer to the processing header.

      RESET installation_control_record.processing_seq_p;

      NEXT installation_control_record.processing_header_p IN installation_control_record.processing_seq_p;
      IF installation_control_record.processing_header_p = NIL THEN
        osp$set_status_abnormal ('RA', rae$accessed_beyond_segment_eoi, 'PROCESSING SEQUENCE', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'HEADER', status);
        EXIT /main/;
      IFEND;

    END /main/;

    IF control_file_opened THEN
      fsp$close_file (control_file_fid, local_status);
      IF status.normal AND (NOT local_status.normal) THEN
        status := local_status;
      IFEND;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND init_processing_seq_and_header;
MODEND ram$init_processing_seq_fr_file;
