?? RIGHT := 110 ??
?? NEWTITLE := 'INSTALL_SOFTWARE Utility: RAP$PERFORM_INSTALLATION subcommand.' ??
MODULE ram$perform_installation;

{ PURPOSE:
{   This module contains the interface that performs the installation
{   defined by an installation control file.
{
{ DESIGN:
{   The compiled module resides in RAF$LIBRARY.
{
{ NOTES:
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rat$installation_control_record
*copyc rat$path
?? POP ??
*copyc clp$evaluate_parameters
*copyc fsp$close_file
*copyc mmp$delete_scratch_segment
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc rap$init_processing_seq_fr_file
*copyc rap$perform_installation_steps
*copyc rav$installation_defaults
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] rap$perform_installation', EJECT ??

{ PURPOSE:
{   This interface installs the subproducts assigned to the specified job as
{   defined by the installation control file.  This interface is used in
{   batch processing.  The subproducts may be of any type.
{
{ DESIGN:
{   The installation control record is re-established for the execution of
{   the installation steps.  The installation control file contains a
{   copy of the processing sequence that was originally created prior to
{   submitting the batch job in which this interface is executing.  The
{   processing sequence is re-created from the installation control file and
{   the packing list is re-accessed.
{
{   The global rav$installation_defaults are reset to the values from the
{   installation control file.  This will put the INSTALL_SOFTWARE
{   environment for this batch job in agreement with the INSTALL_SOFTWARE
{   environment established in the originator job.
{
{   The job identifier that was passed in identifies the job and will guide
{   the step processing to perform only the work assigned to this job.
{
{   Once the installation control record is re-established the installation
{   steps are executed.
{
{ NOTES:
{   On the call to RAP$PERFORM_INSTALLATION_STEPS the log is not saved
{   because in this instance it is being called from a batch job and the
{   entire batch job log is already being saved.
{

  PROCEDURE [XDCL] rap$perform_installation
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);


{ PROCEDURE peri_pdt (
{   installation_control_file, icf: file = $required
{   job_identifier, ji: name = $required
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 5] of clt$pdt_parameter_name,
        parameters: array [1 .. 3] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
        recend,
        type2: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        type3: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [88, 6, 29, 15, 48, 52, 12], clc$command, 5, 3, 2, 0, 0, 0, 3, 'INSP_PDT'],
            [['ICF                            ', clc$abbreviation_entry, 1],
            ['INSTALLATION_CONTROL_FILE      ', clc$nominal_entry, 1],
            ['JI                             ', clc$abbreviation_entry, 2],
            ['JOB_IDENTIFIER                 ', clc$nominal_entry, 2],
            ['STATUS                         ', clc$nominal_entry, 3]], [
{ PARAMETER 1
      [2, clc$normal_usage_entry, clc$non_secure_parameter, $clt$parameter_spec_methods
            [clc$specify_by_name, clc$specify_positionally], clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$required_parameter, 0, 0],
{ PARAMETER 2
      [4, clc$normal_usage_entry, clc$non_secure_parameter, $clt$parameter_spec_methods
            [clc$specify_by_name, clc$specify_positionally], clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 5, clc$required_parameter, 0, 0],
{ PARAMETER 3
      [5, 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$file_type]],
{ PARAMETER 2
      [[1, 0, clc$name_type], [1, osc$max_name_size]],
{ PARAMETER 3
      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$installation_control_file = 1,
      p$job_identifier = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    VAR
      packing_list_opened: boolean,
      installation_control_record: rat$installation_control_record,
      local_status: ost$status,
      packing_list_fid: amt$file_identifier,
      processing_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 return the processing
{   segment and packing list 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;


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

      fsp$close_file (packing_list_fid, ignore_status);

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??


    status.normal := TRUE;

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

    installation_control_record.job_identifier := pvt [p$job_identifier].value^.name_value;
    installation_control_record.job_status_record_p := NIL;

    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

      rap$init_processing_seq_fr_file (pvt [p$installation_control_file].value^.file_value^,
            installation_control_record, processing_segment_pointer, packing_list_fid, packing_list_opened,
            status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      rav$installation_defaults := installation_control_record.processing_header_p^.installation_defaults;

      rap$perform_installation_steps (installation_control_record, status);

    END /main/;

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

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

    osp$disestablish_cond_handler;

  PROCEND rap$perform_installation;
MODEND ram$perform_installation;
