?? RIGHT := 110 ??
?? NEWTITLE := 'INSTALL_SOFTWARE Utility: APPLY_ALL_CORRECTIONS Subcommand.' ??
MODULE ram$apply_all_corrections_cmd;

{ PURPOSE:
{   This module contains the command interface that installs all the
{   corrections defined by the packing list and generates a new deadstart
{   catalog or tape when required.
{
{ DESIGN:
{   The compiled module resides in RAF$LIBRARY.
{
{ NOTES:
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc rac$control_job_identifier
*copyc rac$idb_directory_name
*copyc rac$special_product_designators
*copyc rac$tape_types
*copyc rae$install_software_cc
*copyc rat$installation_control_record
*copyc rat$subproduct_info_pointers
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$put_next
*copyc clp$evaluate_parameters
*copyc clp$include_line
*copyc clp$put_job_command_response
*copyc clp$trimmed_string_size
*copyc clp$include_line
*copyc fsp$close_file
*copyc fsp$open_file
*copyc mmp$delete_scratch_segment
*copyc osp$append_status_file
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc rap$convert_path_to_str
*copyc rap$display_job_log_to_cmd_log
*copyc rap$establish_processing_cntrls
*copyc rap$init_processing_seq
*copyc rap$perform_installation_steps
*copyc rap$submit_batch_jobs
*copyc rap$validate_for_installation
*copyc rav$installation_defaults
*copyc rav$subproduct_type
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

?? OLDTITLE ??
?? NEWTITLE := '[XDCL] rap$apply_all_corrections_cmd', EJECT ??

{ PURPOSE:
{   This command interface installs all the corrections described by the
{   packing list.  A new deadstart catalog or tape is generated when a
{   correction to the subproduct associated with the deadstart components is
{   encountered.
{
{ DESIGN:
{   This interface can be viewed as combining the INSTALL_PRODUCT and
{   GENERATE_VE_DEADSTART_CATALOG commands into one.
{   See the documentation for ...
{
{ NOTES:
{   The scratch segment is used for the processing sequence and is created
{   in RAP$INIT_PROCESSING_SEQ.
{

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

{       PROCEDURE appac_pdt (
{         packing_list, pl: name 1..16 = $required
{         new_ve_deadstart_tape, nvdt: record
{             external_vsn: any of
{                 string 1..6
{                 name 1..6
{               anyend = $required
{             recorded_vsn: any of
{                 string 1..6
{                 name 1..6
{               anyend = $optional
{             type: key
{                 mt9$1600, mt9$6250, mt18$38000
{               keyend = $optional
{             unload_deadstart_tape: boolean = $optional
{           recend = $optional
{         configuration_files_catalog, cfc: file = $system.site_os_maintenance.deadstart_commands
{         force_reinstall, fr: boolean = false
{         installation_option, io: key
{             (immediate, i) (deferred, d)
{           keyend = deferred
{         save_previous_cycles, spc: boolean = false
{         execute_in_job_of_caller, eijoc: (BY_NAME, HIDDEN) boolean = false
{         status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 15] of clt$pdt_parameter_name,
      parameters: array [1 .. 8] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$record_type_qualifier,
        field_spec_1: clt$field_specification,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$union_type_qualifier,
          type_size_1: clt$type_specification_size,
          element_type_spec_1: record
            header: clt$type_specification_header,
            qualifier: clt$string_type_qualifier,
          recend,
          type_size_2: clt$type_specification_size,
          element_type_spec_2: record
            header: clt$type_specification_header,
            qualifier: clt$name_type_qualifier,
          recend,
        recend,
        field_spec_2: clt$field_specification,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$union_type_qualifier,
          type_size_1: clt$type_specification_size,
          element_type_spec_1: record
            header: clt$type_specification_header,
            qualifier: clt$string_type_qualifier,
          recend,
          type_size_2: clt$type_specification_size,
          element_type_spec_2: record
            header: clt$type_specification_header,
            qualifier: clt$name_type_qualifier,
          recend,
        recend,
        field_spec_3: clt$field_specification,
        element_type_spec_3: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 3] of clt$keyword_specification,
        recend,
        field_spec_4: clt$field_specification,
        element_type_spec_4: record
          header: clt$type_specification_header,
        recend,
      recend,
      type3: record
        header: clt$type_specification_header,
        default_value: string (46),
      recend,
      type4: record
        header: clt$type_specification_header,
        default_value: string (5),
      recend,
      type5: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 4] of clt$keyword_specification,
        default_value: string (8),
      recend,
      type6: record
        header: clt$type_specification_header,
        default_value: string (5),
      recend,
      type7: record
        header: clt$type_specification_header,
        default_value: string (5),
      recend,
      type8: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [94, 12, 21, 0, 29, 46, 845],
    clc$command, 15, 8, 1, 0, 1, 0, 8, ''], [
    ['CFC                            ',clc$abbreviation_entry, 3],
    ['CONFIGURATION_FILES_CATALOG    ',clc$nominal_entry, 3],
    ['EIJOC                          ',clc$abbreviation_entry, 7],
    ['EXECUTE_IN_JOB_OF_CALLER       ',clc$nominal_entry, 7],
    ['FORCE_REINSTALL                ',clc$nominal_entry, 4],
    ['FR                             ',clc$abbreviation_entry, 4],
    ['INSTALLATION_OPTION            ',clc$nominal_entry, 5],
    ['IO                             ',clc$abbreviation_entry, 5],
    ['NEW_VE_DEADSTART_TAPE          ',clc$nominal_entry, 2],
    ['NVDT                           ',clc$abbreviation_entry, 2],
    ['PACKING_LIST                   ',clc$nominal_entry, 1],
    ['PL                             ',clc$abbreviation_entry, 1],
    ['SAVE_PREVIOUS_CYCLES           ',clc$nominal_entry, 6],
    ['SPC                            ',clc$abbreviation_entry, 6],
    ['STATUS                         ',clc$nominal_entry, 8]],
    [
{ PARAMETER 1
    [11, 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 2
    [9, 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, 338,
  clc$optional_parameter, 0, 0],
{ PARAMETER 3
    [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$optional_default_parameter, 0, 46],
{ PARAMETER 4
    [5, 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$optional_default_parameter, 0, 5],
{ PARAMETER 5
    [7, 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, 155,
  clc$optional_default_parameter, 0, 8],
{ PARAMETER 6
    [13, 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$optional_default_parameter, 0, 5],
{ PARAMETER 7
    [4, clc$hidden_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 5],
{ PARAMETER 8
    [15, 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$name_type], [1, 16]],
{ PARAMETER 2
    [[1, 0, clc$record_type], [4],
    ['EXTERNAL_VSN                   ', clc$required_field, 33], [[1, 0, clc$union_type], [[
      clc$name_type, clc$string_type],
      TRUE, 2],
      8, [[1, 0, clc$string_type], [1, 6, FALSE]],
      5, [[1, 0, clc$name_type], [1, 6]]
      ],
    ['RECORDED_VSN                   ', clc$optional_field, 33], [[1, 0, clc$union_type], [[
      clc$name_type, clc$string_type],
      TRUE, 2],
      8, [[1, 0, clc$string_type], [1, 6, FALSE]],
      5, [[1, 0, clc$name_type], [1, 6]]
      ],
    ['TYPE                           ', clc$optional_field, 118], [[1, 0, clc$keyword_type], [3], [
      ['MT18$38000                     ', clc$nominal_entry, clc$normal_usage_entry, 3],
      ['MT9$1600                       ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['MT9$6250                       ', clc$nominal_entry, clc$normal_usage_entry, 2]]
      ],
    ['UNLOAD_DEADSTART_TAPE          ', clc$optional_field, 3], [[1, 0, clc$boolean_type]]
    ],
{ PARAMETER 3
    [[1, 0, clc$file_type],
    '$system.site_os_maintenance.deadstart_commands'],
{ PARAMETER 4
    [[1, 0, clc$boolean_type],
    'false'],
{ PARAMETER 5
    [[1, 0, clc$keyword_type], [4], [
    ['D                              ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
    ['DEFERRED                       ', clc$nominal_entry, clc$normal_usage_entry, 2],
    ['I                              ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
    ['IMMEDIATE                      ', clc$nominal_entry, clc$normal_usage_entry, 1]]
    ,
    'deferred'],
{ PARAMETER 6
    [[1, 0, clc$boolean_type],
    'false'],
{ PARAMETER 7
    [[1, 0, clc$boolean_type],
    'false'],
{ PARAMETER 8
    [[1, 0, clc$status_type]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$packing_list = 1,
      p$new_ve_deadstart_tape = 2,
      p$configuration_files_catalog = 3,
      p$force_reinstall = 4,
      p$installation_option = 5,
      p$save_previous_cycles = 6,
      p$execute_in_job_of_caller = 7,
      p$status = 8;

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

    VAR
      ignore_status: ost$status,
      install_proc_info_file: rat$path,
      installation_control_record: rat$installation_control_record,
      installation_tasks: rat$task_selections,
      local_status: ost$status,
      packing_list_fid: amt$file_identifier,
      packing_list_opened: boolean,
      processing_segment_pointer: amt$segment_pointer,
      product_list: clt$data_value;


?? 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.
{
{   When the processing segment pointer is not NIL, attempt to display the
{   job log to the command log.
{
{ 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
        rap$display_job_log_to_cmd_log (installation_control_record.processing_header_p^.
              installation_defaults.installation_logs, installation_control_record.processing_header_p^.
              installation_identifier, ignore_status);
        mmp$delete_scratch_segment (processing_segment_pointer, ignore_status);
        processing_segment_pointer.sequence_pointer := NIL;
      IFEND;

      fsp$close_file (packing_list_fid, ignore_status);

      IF install_proc_info_file.size <> 0 THEN
        purge_install_proc_info_file (install_proc_info_file.path (1, install_proc_info_file.size),
              ignore_status);
      IFEND;

    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;

    check_directory_presence (rav$installation_defaults.installation_database, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$include_line ('$system.display_log do=last o=$null', TRUE, osc$null_name, ignore_status);

    install_proc_info_file.size := 0;

    product_list.kind := clc$keyword;
    product_list.keyword_value := 'ALL';

    installation_control_record.job_identifier := rac$control_job_identifier;
    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 (pvt [p$packing_list].value^.name_value,
            pvt [p$save_previous_cycles].value^.boolean_value.value, rac$install_correction, rac$correction,
            rav$installation_defaults, installation_control_record, processing_segment_pointer,
            packing_list_fid, packing_list_opened, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      {  Get the task set pertaining to the installation option parameter.

      get_task_set (pvt [p$installation_option].value^.keyword_value,
            installation_control_record.processing_header_p, installation_tasks);

      rap$validate_for_installation (^product_list, NIL {ignore excluded product list} ,
            pvt[p$force_reinstall].value^.boolean_value.value, installation_tasks,
            installation_control_record, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      {  If this is a deferred installation, search for those subproducts
      {  corrections that are forced to be installed immediate based on
      {  information in the additional products field.

      IF pvt [p$installation_option].value^.keyword_value = 'DEFERRED' THEN
        force_some_products_immediate (installation_control_record, status);
        IF NOT status.normal THEN
          EXIT /main/;
        IFEND;
      IFEND;

      rap$establish_processing_cntrls (FALSE {multiple job processing} ,
            pvt [p$execute_in_job_of_caller].value^.boolean_value.value, installation_control_record, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      setup_nosve_maint_install_proc (pvt [p$installation_option].value^.keyword_value,
            pvt [p$new_ve_deadstart_tape], pvt [p$configuration_files_catalog].value^.file_value,
            installation_control_record, install_proc_info_file, status);
      IF NOT status.normal THEN
        EXIT /main/;
      IFEND;

      IF pvt [p$execute_in_job_of_caller].value^.boolean_value.value THEN

        rap$perform_installation_steps (installation_control_record, status);

      ELSE {execute in batch}

        rap$submit_batch_jobs (installation_control_record, status);

      IFEND;

    END /main/;

    IF (NOT status.normal) AND (install_proc_info_file.size <> 0) THEN
      purge_install_proc_info_file (install_proc_info_file.path (1, install_proc_info_file.size),
            ignore_status);
    IFEND;

    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
      rap$display_job_log_to_cmd_log (installation_control_record.processing_header_p^.installation_defaults.
            installation_logs, installation_control_record.processing_header_p^.installation_identifier,
            ignore_status);
      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$apply_all_corrections_cmd;

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

{ PURPOSE:
{   This procedure checks for the presence fo the IDB Directory as defined
{   by the installation database path.  Bad status is returned when not
{   found.
{
{ DESIGN:
{
{ NOTES:
{

  PROCEDURE check_directory_presence
    (    installation_database: rat$path;
     VAR status: ost$status);


    VAR
      directory: rat$path,
      existing_file: boolean,
      ignore_attributes: array [1 .. 1] of amt$get_item,
      ignore_contains_data: boolean,
      local_file: boolean;


    status.normal := TRUE;
    ignore_attributes [1].key := amc$file_length;

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

    amp$get_file_attributes (directory.path (1, directory.size), ignore_attributes, local_file, existing_file,
          ignore_contains_data, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF (NOT local_file) AND (NOT existing_file) THEN
      osp$set_status_abnormal ('RA', rae$directory_required_for_corr, '', status);
      osp$append_status_file (osc$status_parameter_delimiter, directory.path (1, directory.size), status);
      RETURN;
    IFEND;

  PROCEND check_directory_presence;

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

{ PURPOSE:
{   This procedure searches for subproducts with the special additional
{   product IMMEDIATE and sets them to be installed immediate instead
{   of whatever the installer specified on the installation option
{   parameter.
{
{
{ DESIGN:
{   The special name IMMEDIATE is established in the additional
{   products field of the SIF for some product corrections.  These
{   corrections are searched for in the installation control record
{   and their task sets are specifically set  to reflect immediate
{   installation.
{
{
{ NOTES:
{   The special name IMMEDIATE is preceeded by the special use
{   designator.
{

  PROCEDURE force_some_products_immediate
    (VAR installation_control_record {input, output} : rat$installation_control_record;
     VAR status: ost$status);


    VAR
      install_immediate: ost$name,
      immediate_installation_tasks: rat$task_selections,
      j: 0 .. rac$max_additional_products,
      subproduct_index: rat$subproduct_count,
      subproduct_pointers: rat$subproduct_info_pointers;


    status.normal := TRUE;

    get_task_set ('IMMEDIATE                      ', installation_control_record.processing_header_p,
          immediate_installation_tasks);
    install_immediate (1, *) := rac$special_use_designator;
    install_immediate (clp$trimmed_string_size (rac$special_use_designator) + 1, * ) :=
          'IMMEDIATE                      ';

  /force/
    FOR subproduct_index := 1 TO UPPERBOUND (installation_control_record.subproduct_processing_records_p^) DO

      IF rac$load_files_task IN
             installation_control_record.subproduct_processing_records_p^[subproduct_index].task_set THEN
        { Process only those subproducts that were set to be installed deferred in the first place.

        subproduct_pointers := installation_control_record.subproduct_processing_records_p^
              [subproduct_index].subproduct_info_pointers;

      /immediate_check/
        FOR j := 1 TO UPPERBOUND (subproduct_pointers.attributes_p^.additional_products) DO

          IF subproduct_pointers.attributes_p^.additional_products [j] = install_immediate THEN

            {  Set this subproduct to install immediate.
            installation_control_record.subproduct_processing_records_p^ [subproduct_index].task_set :=
                  immediate_installation_tasks;
            EXIT /immediate_check/;
          IFEND;

        FOREND /immediate_check/;
      IFEND;

    FOREND /force/;

  PROCEND force_some_products_immediate;

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

{ PURPOSE:
{   This procedure returns the set of tasks to be performed on the selected
{   products.  The step set and number of steps are registered in the
{   processing header record.
{
{ DESIGN:
{   For the installation of corrections all tasks are performed except the
{   deletion of previous cycles when save_previous_cycles is true.  In
{   addition, if the installation option is deferred, the tasks to
{   activate the files, execute installer procedures and delete previous
{   cycles are removed.
{
{   Currently the number of steps to be performed relates directly to the
{   number of tasks.  That is why the number of steps is computed by
{   subtracting the number of tasks removed from processing.
{
{ NOTES:
{

  PROCEDURE get_task_set
    (    installation_option: ost$name;
         processing_header_p {input, output} : ^rat$processing_header;
     VAR installation_tasks: rat$task_selections);


{ Determine the installation step and task sets.  The '-' means to take the complement.

    IF installation_option = 'DEFERRED' THEN
      processing_header_p^.step_set := -$rat$step_selections
            [rac$activate_subproducts_step, rac$execute_installer_proc_step, rac$delete_previous_cycles_step];
      processing_header_p^.number_of_steps := rac$max_number_of_steps - 3;
      installation_tasks := -$rat$task_selections [rac$activate_files_task, rac$execute_installer_proc_task,
            rac$delete_previous_cycles_task];
    ELSE {installation option is immedidate}
      IF processing_header_p^.save_previous_cycles THEN
        processing_header_p^.step_set := -$rat$step_selections [rac$delete_previous_cycles_step];
        processing_header_p^.number_of_steps := rac$max_number_of_steps - 1;
        installation_tasks := -$rat$task_selections [rac$delete_previous_cycles_task];
      ELSE {delete previous cycles}
        processing_header_p^.step_set := -$rat$step_selections [];
        processing_header_p^.number_of_steps := rac$max_number_of_steps;
        installation_tasks := -$rat$task_selections [];
      IFEND;
    IFEND;

  PROCEND get_task_set;

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

{ PURPOSE:
{   This procedure purges the file used to build the special delete job file.
{
{ DESIGN:
{   The only reason this is a separate procedure is because it is called in
{   two places.
{
{ NOTES:
{

  PROCEDURE purge_install_proc_info_file
    (    info_file: fst$file_reference;
     VAR status: ost$status);


    VAR
      command_line: string (800),
      command_line_length: integer;


    status.normal := TRUE;

    STRINGREP (command_line, command_line_length, '$system.delete_file f=', info_file);

    clp$include_line (command_line (1, command_line_length), TRUE, osc$null_name, status);

  PROCEND purge_install_proc_info_file;

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

{ PURPOSE:
{   This procedure, when the nosve maintenance subproduct is being corrected,
{   will setup the necessary installer procedure input file.
{
{
{ DESIGN:
{
{
{ NOTES:
{   When a correction is generated by the DEFINE_SUBPRODUCT utility,
{   RAC$CORRECT_FILES_TASK is removed from the task set by
{   RAP$VALIDATE_FOR_CORRECTION.  Therefore, RAC$LOAD_FILES_TASK is used in
{   the IF test.
{

  PROCEDURE setup_nosve_maint_install_proc
    (    installation_option: ost$name;
         new_ve_deadstart_tape: clt$parameter_value;
         configuration_files_catalog_p: ^fst$file_reference;
     VAR installation_control_record {input, output} : rat$installation_control_record;
     VAR install_proc_info_file: rat$path;
     VAR status: ost$status);


    VAR
      installation_tasks: rat$task_selections,
      subproduct_index: rat$subproduct_count;


    status.normal := TRUE;

  /setup/
    FOR subproduct_index := 1 TO UPPERBOUND (installation_control_record.subproduct_processing_records_p^) DO

      IF (installation_control_record.subproduct_processing_records_p^ [subproduct_index].
            subproduct_info_pointers.attributes_p^.name = 'NOSVE_MAINTENANCE') AND
            (rac$load_files_task IN installation_control_record.
            subproduct_processing_records_p^ [subproduct_index].task_set) THEN
        { The nosve maintenance subproduct is being corrected.  (See note above.)

        { Display message that a deadstart tape or catalog will be created.

        IF new_ve_deadstart_tape.specified THEN
          clp$put_job_command_response (
                '0A deadstart tape will be generated due to corrections to NOSVE MAINTENANCE.',
                status);
        ELSE { write catalog }
          clp$put_job_command_response (
                '0A deadstart catalog will be generated due to corrections to NOSVE MAINTENANCE.',
                status);
        IFEND;
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        { Create nosve maintenance installer procedure's input file.

        write_install_proc_info_file (new_ve_deadstart_tape, configuration_files_catalog_p,
              installation_control_record.processing_header_p^.installation_identifier,
              installation_control_record.subproduct_processing_records_p^ [subproduct_index].
              installation_catalog_p, install_proc_info_file, status);

        EXIT /setup/;

      IFEND;
    FOREND /setup/;

  PROCEND setup_nosve_maint_install_proc;

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

{ PURPOSE:
{   This procedure adds a file to the special delete job.  The delete job is
{   required for files that were open during the execution of the delete
{   previous cycles step and therefore could not be deleted.
{
{ DESIGN:
{   The special delete job is collected in a file.  If the file is not yet
{   opened, the file is opened and initialized.  In any case the required
{   SCL delete commands are added.
{
{   The user job name for the special delete job will be the job identifier
{   with the command abbreviation replaced by 'DELF'.
{
{ NOTES:
{

  PROCEDURE write_install_proc_info_file
    (    new_ve_deadstart_tape: clt$parameter_value;
         configuration_files_catalog_p: ^fst$file_reference;
         installation_identifier: rat$installation_identifier;
         installation_catalog_p: ^pft$path;
     VAR install_proc_info_file: rat$path;
     VAR status: ost$status);


    CONST
      external_vsn_field_index = 1,
      recorded_vsn_field_index = 2,
      type_field_index = 3,
      udv_field_index = 4;

    VAR
      attachment_options: array [1 .. 3] of fst$attachment_option,
      evsn_string: string(6),
      evsn_value_p: ^clt$string_value,
      ignore_byte_address: amt$file_byte_address,
      ignore_status: ost$status,
      info_file_fid: amt$file_identifier,
      info_file_opened: boolean,
      installation_catalog: rat$path,
      local_status: ost$status,
      rvsn_string: string(6),
      rvsn_value_p: ^clt$string_value,
      type_value: clt$keyword;

?? 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 installer
{   proc's input 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 (info_file_fid, ignore_status);

      purge_install_proc_info_file (install_proc_info_file.path (1, install_proc_info_file.size),
            ignore_status);

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??

?? NEWTITLE := 'write_line', EJECT ??

{ PURPOSE:
{   This procedure writes a line to to a file.
{
{ DESIGN:
{   If the pointer to the optional string variable is not NIL, it is added
{   to the initial string along with the closing string.
{
{   The line once constructed is written to eoi of the file.
{
{ NOTES:
{   Status is checked at the beginning of this procedure to determine if the
{   command should be completed.  This was done to limit the status check to
{   one place rather than after each call to this procedure in the main
{   procedure.
{

    PROCEDURE write_line
      (    initial_string: string ( * );
           string_p: ^string ( * );
           closing_string: string ( * ));

      VAR
        length: integer,
        output_line: string (osc$max_string_size);


      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF string_p <> NIL THEN
        STRINGREP (output_line, length, initial_string, string_p^, closing_string);
      ELSE
        STRINGREP (output_line, length, initial_string, closing_string);
      IFEND;

      amp$put_next (info_file_fid, ^output_line, length, ignore_byte_address, status);

    PROCEND write_line;

?? OLDTITLE, EJECT ??


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

    { Assemble the path to the installer proc's info file.

    rap$convert_path_to_str (installation_catalog_p^, installation_catalog);
    STRINGREP (install_proc_info_file.path, install_proc_info_file.size, installation_catalog.
          path (1, installation_catalog.size), '.RAF$APPAC_DEADSTART_INFO');

    osp$establish_block_exit_hndlr (^abort_handler);

  /main/
    BEGIN

      { Open the info file that will be used by nosve maintenance installer proc.

      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, fsc$shorten, fsc$append, fsc$modify];
      attachment_options [1].share_modes.selector := fsc$specific_share_modes;
      attachment_options [1].share_modes.value := $fst$file_access_options [];
      attachment_options [2].selector := fsc$create_file;
      attachment_options [2].create_file := TRUE;
      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;

      info_file_opened := TRUE;
      fsp$open_file (install_proc_info_file.path (1, install_proc_info_file.size), amc$record,
            ^attachment_options, NIL, NIL, NIL, NIL, info_file_fid, status);
      IF NOT status.normal THEN
        info_file_opened := FALSE;
        EXIT /main/;
      IFEND;

      evsn_string := ' ';
      rvsn_string := ' ';

      IF new_ve_deadstart_tape.specified THEN
        IF new_ve_deadstart_tape.value^.field_values^ [external_vsn_field_index].value^.kind = clc$string THEN
          evsn_value_p := new_ve_deadstart_tape.value^.field_values^ [external_vsn_field_index].value^.
               string_value;
        ELSE
          evsn_string := new_ve_deadstart_tape.value^.field_values^ [external_vsn_field_index].
                value^.name_value(1,clp$trimmed_string_size(new_ve_deadstart_tape.
                value^.field_values^ [external_vsn_field_index].value^.name_value));
          evsn_value_p := ^evsn_string;
        IFEND;
        IF new_ve_deadstart_tape.value^.field_values^ [recorded_vsn_field_index].value <> NIL THEN
          IF new_ve_deadstart_tape.value^.field_values^ [recorded_vsn_field_index].value^.kind
                           = clc$string THEN
            rvsn_value_p := new_ve_deadstart_tape.value^.field_values^ [recorded_vsn_field_index].value^.
                string_value;
          ELSE
            rvsn_string := new_ve_deadstart_tape.value^.field_values^ [recorded_vsn_field_index].
                value^.name_value(1,clp$trimmed_string_size(new_ve_deadstart_tape.
                value^.field_values^ [recorded_vsn_field_index].value^.name_value));
            rvsn_value_p := ^rvsn_string;
          IFEND;
        ELSE { use default }
          rvsn_value_p := evsn_value_p;
        IFEND;

        IF new_ve_deadstart_tape.value^.field_values^ [type_field_index].value <> NIL THEN
          type_value := new_ve_deadstart_tape.value^.field_values^ [type_field_index].value^.keyword_value;
        ELSE { use default }
          type_value := rac$mt9$6250;
        IFEND;

        write_line ('VAR', NIL, '');
        write_line ('  rav#appac_deadstart_medium: name = tape', NIL, '');
        write_line ('  rav#appac_evsn: string 1..6 = ''', evsn_value_p, '''');
        write_line ('  rav#appac_rvsn: string 1..6 = ''', rvsn_value_p, '''');
        write_line ('  rav#appac_type: name = ', ^type_value, '');
        IF ((new_ve_deadstart_tape.value^.field_values^ [udv_field_index].value = NIL) OR
            (new_ve_deadstart_tape.value^.field_values^ [udv_field_index].value^.boolean_value.value)) THEN
          write_line ('  rav#appac_udv: boolean = TRUE', NIL, '');
        ELSE
          write_line ('  rav#appac_udv: boolean = FALSE', NIL, '');
        IFEND;
        write_line ('  rav#appac_cfc_catalog: file = ', configuration_files_catalog_p, '');
        write_line ('  rav#appac_installation_id: name = ', ^installation_identifier, '');
        write_line ('VAREND', NIL, '');

      ELSE { write deadstart catalog }

        write_line ('VAR', NIL, '');
        write_line ('  rav#appac_deadstart_medium: name = disk', NIL, '');
        write_line ('  rav#appac_cfc_catalog: file = ', configuration_files_catalog_p, '');
        write_line ('  rav#appac_installation_id: name = ', ^installation_identifier, '');
        write_line ('VAREND', NIL, '');

      IFEND;

    END /main/;

    IF info_file_opened THEN
      fsp$close_file (info_file_fid, local_status);
      IF NOT status.normal THEN
        purge_install_proc_info_file (install_proc_info_file.path (1, install_proc_info_file.size),
              ignore_status);
      ELSEIF NOT local_status.normal THEN
        status := local_status;
      IFEND;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND write_install_proc_info_file;
MODEND ram$apply_all_corrections_cmd;
