?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE System Core : Process Deadstart Commands' ??
MODULE sym$process_deadstart_commands;

{ PURPOSE:
{   This module contains the system core command processor to process system core commands during deadstart.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc i#enable_traps
*copyc oss$mainframe_paged_literal
*copyc dsc$max_dcfile_length
*copyc ave$duplicate_setso_command
*copyc ave$unknown_security_option
*copyc cme$physical_configuration_mgr
*copyc dse$misc_ds_errors_part_a
*copyc avt$security_option
*copyc avt$security_option_name
*copyc bat$record_header_type
*copyc dmt$sc_flaw_command
*copyc dst$deadstart_condition
*copyc ost$time
*copyc rat$installation_tape_values
*copyc syt$command_table_entry
*copyc syt$value_kinds
?? POP ??
*copyc clp$trimmed_string_size
*copyc dmp$store_sc_flaw_command
*copyc dpp$get_next_line
*copyc dpp$put_next_line
*copyc dsp$access_vcu_cda_data
*copyc dsp$change_date_time_info
*copyc dsp$change_secure_analysis
*copyc dsp$check_interval
*copyc dsp$check_password_for_inisd
*copyc dsp$fetch_boot_data
*copyc dsp$get_entry_from_ssr
*copyc dsp$process_setoi_command
*copyc dsp$process_setop_command
*copyc dsp$read_date_time_information
*copyc dsp$save_sys_status_current_ds
*copyc dsp$test_resource_requests
*copyc lgp$add_entry_to_system_log
*copyc osp$change_date_time
*copyc osp$clear_mainframe_sig_lock
*copyc osp$set_mainframe_sig_lock
*copyc osp$set_status_abnormal
*copyc osp$system_error
*copyc pmp$get_date
*copyc pmp$get_date_time_at_timestamp
*copyc pmp$get_time
*copyc syp$binary_to_ascii
*copyc syp$crack_command
*copyc syp$display_deadstart_message
*copyc syp$fetch_system_constant
*copyc syp$get_token
*copyc syp$invoke_system_debugger
*copyc syp$process_deadstart_status
*copyc syp$save_system_constants
*copyc syp$store_system_constant
?? EJECT ??
*copyc avv$security_options
*copyc cmv$system_device_data
*copyc dmv$p_sc_flaw_commands
*copyc dmv$system_device_information
*copyc dpv$system_core_display
*copyc dsv$mainframe_type
*copyc dsv$sub_mainframe_type
*copyc osv$mainframe_wired_heap
*copyc osv$deadstart_phase
*copyc osv$os_defaults
*copyc osv$recover_system_set_phase
*copyc stv$system_set_name
*copyc syv$debug_control
*copyc syv$repeatable_command_p
*copyc syv$run_all_timestamp
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    cmv$use_installed_configuration: [XDCL, #GATE] boolean := TRUE,
    osv$configuration_prolog_name: [XDCL, #GATE] ost$string := [0, * ],
    osv$operator_intervention: [XDCL, #GATE] boolean := FALSE,
    rav$installation_tape_values: [XDCL, #GATE] rat$installation_tape_values := [ '', '', '', ''],
    syv$inhibit_core_cmd_logging: [XDCL, #GATE] boolean := FALSE,
    syv$reading_dcfile: [XDCL] boolean := FALSE,

    v$auto_mode_requested: boolean := FALSE,

    { This table defines the system core command names and the procedures used to process the command.

    v$command_table: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 21] of
          syt$command_table_entry := [
{  1    } ['?       ', 'HELP                           ', FALSE, ^command_help],
{  2    } ['AUTO    ', 'AUTO                           ', FALSE, ^command_auto],
{  3    } ['CHAD    ', 'CHANGE_DATE                    ', FALSE, ^command_chad],
{  4    } ['CHAT    ', 'CHANGE_TIME                    ', FALSE, ^command_chat],
{  5    } ['DEFMSF  ', 'DEFINE_MS_FLAW                 ', FALSE, ^command_defmsf],
{  6    } ['DISDT   ', 'DISPLAY_DATE_TIME              ', FALSE, ^command_disdt],
{  7    } ['DISSA   ', 'DISPLAY_SYSTEM_ATTRIBUTE       ', FALSE, ^command_dissa],
{  8    } ['DISTZ   ', 'DISPLAY_TIME_ZONE              ', FALSE, ^command_distz],
{  9    } ['INIDD   ', 'INITIALIZE_DEADSTART_DEVICE    ', FALSE, ^command_inisd],
{ 10    } ['INISD   ', 'INITIALIZE_SYSTEM_DEVICE       ', FALSE, ^command_inisd],
{ 11    } ['INITDD  ', 'INITDD                         ', FALSE, ^command_inisd], {delete at R.1.3.1?
{ 12    } ['SETIT   ', 'SET_INSTALLATION_TAPE          ', FALSE, ^command_setit],
{ 13    } ['SETOI   ', 'SET_OPERATION_INTERVAL         ', FALSE, ^dsp$process_setoi_command],
{ 14    } ['SETOP   ', 'SET_OPERATION_PASSWORD         ', FALSE, ^dsp$process_setop_command],
{ 15    } ['SETSA   ', 'SET_SYSTEM_ATTRIBUTE           ', FALSE, ^command_setsa],
{ 16    } ['SETSO   ', 'SET_SECURITY_OPTION            ', FALSE, ^command_setso],
{ 17    } ['SETTZ   ', 'SET_TIME_ZONE                  ', FALSE, ^command_settz],
{ 18    } ['SYSDEBUG', 'SYSDEBUG                       ', FALSE, ^syp$invoke_system_debugger],
{ 19    } ['TESRR   ', 'TEST_RESOURCE_REQUESTS         ', FALSE, ^dsp$test_resource_requests],
{ 20    } ['USECP   ', 'USE_CONFIGURATION_PROLOG       ', FALSE, ^command_usecp],
{ 21    } ['USEIC   ', 'USE_INSTALLED_CONFIGURATION    ', FALSE, ^command_useic]];

{The following constants are used to find the appropriate help text for a command.

  CONST
    c$help = 1,
    c$auto = 2,
    c$chad = 3,
    c$chat = 4,
    c$defmsf = 5,
    c$disdt = 6,
    c$dissa = 7,
    c$distz = 8,
    c$inisd = 10,
    c$setit = 12,
    c$setsa = 15,
    c$setso = 16,
    c$settz = 17,
    c$sysdebug = 18,
    c$tesrr = 19,
    c$usecp = 20,
    c$useic = 21;

  TYPE
    t$help_texts = array [1 .. * ] of t$help_text,
    t$help_text = record
      size: 0 .. 255,
      value: string (80),
    recend;

  VAR
    v$command_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 20] of t$help_text := [
{   } [19, 'Available Commands:'],
{   } [06, '  AUTO'],
{   } [19, '  CHANGE_DATE, CHAD'],
{   } [19, '  CHANGE_TIME, CHAT'],
{   } [24, '  DEFINE_MS_FLAW, DEFMSF'],
{   } [26, '  DISPLAY_DATE_TIME, DISDT'],
{   } [33, '  DISPLAY_SYSTEM_ATTRIBUTE, DISSA'],
{   } [26, '  DISPLAY_TIME_ZONE, DISTZ'],
{   } [09, '  HELP, ?'],
{   } [33, '  INITIALIZE_SYSTEM_DEVICE, INISD'],
{   } [30, '  SET_INSTALLATION_TAPE, SETIT'],
{   } [28, '  SET_SECURITY_OPTION, SETSO'],
{   } [29, '  SET_SYSTEM_ATTRIBUTE, SETSA'],
{   } [22, '  SET_TIME_ZONE, SETTZ'],
{   } [10, '  SYSDEBUG'],
{   } [31, '  TEST_RESOURCE_REQUESTS, TESRR'],
{   } [33, '  USE_CONFIGURATION_PROLOG, USECP'],
{   } [36, '  USE_INSTALLED_CONFIGURATION, USEIC'],
{   } [01, ''],
{   } [66, 'For further information on a particular command enter HELP,command']];

  VAR

  v$auto_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 7] OF t$help_text := [
{   } [17, 'Names:   AUTO'],
{   } [01, ''],
{   } [77, 'Terminates the system core command processor and causes the deadstart process'],
{   } [76, 'to continue to completion; no further operator pauses occur except for error'],
{   } [26, 'conditions. (See also GO).'],
{   } [01, ''],
{   } [17, 'Parameters: none.']],

  v$chad_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 8] OF t$help_text := [
{   } [27, 'Names:   CHANGE_DATE,  CHAD'],
{   } [01, ''],
{   } [24, 'Changes the system date.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [34, '  MONTH: integer 1..12 = $required'],
{   } [32, '  DAY: integer 1..31 = $required'],
{   } [38, '  YEAR: integer 1990..2155 = $required']],

  v$chat_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 8] OF t$help_text := [
{   } [27, 'Names:   CHANGE_TIME,  CHAT'],
{   } [01, ''],
{   } [24, 'Changes the system time.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [33, '  HOUR: integer 0..23 = $required'],
{   } [35, '  MINUTE: integer 0..59 = $required'],
{   } [27, '  SECOND: integer 0..59 = 0']],

  v$defmsf_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 10] OF t$help_text := [
{   } [17, 'Names:   DEFINE_MS_FLAW,  DEFMSF'],
{   } [01, ''],
{   } [68, 'Defines to NOS/VE the location of a mass storage defect. For further'],
{   } [40, 'information see SPAM Volume 2, Page 4-4.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [28, '  VSN: name 1..6 = $required'],
{   } [40, '  CYLINDER: positive integer = $required'],
{   } [37, '  TRACK: positive integer = $required'],
{   } [38, '  SECTOR: positive integer = $required']],

  v$disdt_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 5] OF t$help_text := [
{   } [17, 'Names:   DISPLAY_DATE_TIME,  DISDT'],
{   } [01, ''],
{   } [37, 'Displays NOS/VE system date and time.'],
{   } [01, ''],
{   } [17, 'Parameters: none.']],

  v$dissa_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 7] OF t$help_text := [
{   } [41, 'Names:   DISPLAY_SYSTEM_ATTRIBUTE,  DISSA'],
{   } [01, ''],
{   } [73, 'Displays the current value of a system attribute. For further information'],
{   } [29, 'see SPAM Volume 1, Chapter 2.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [29, '  ATTRIBUTE: name = $required']],

  v$distz_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 5] OF t$help_text := [
{   } [34, 'Names:   DISPLAY_TIME_ZONE,  DISTZ'],
{   } [01, ''],
{   } [70, 'Displays time zone information relative to universal time coordinates.'],
{   } [01, ''],
{   } [17, 'Parameters: none.']],

  v$inisd_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 10] OF t$help_text := [
{   } [41, 'Names:   INITIALIZE_SYSTEM_DEVICE,  INISD'],
{   } [01, ''],
{   } [74, 'Initializes the volume on the deadstart disk unit and assigns a VSN to the'],
{   } [63, 'volume. For further information, see SPAM Volume 2, Page 4-7/8.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [28, '  VSN: name 1..6 = $required'],
{   } [37, '  RETAIN_DEVICE_FLAWS: boolean = true'],
{   } [63, '  RECOVER_SYSTEM_SET: key RECOVER_SYSTEM_SET keyend = $optional'],
{   } [32, '  SYSTEM_SET_NAME: name = NVESET']],

  v$setit_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 13] OF t$help_text := [
{   } [38, 'Names:   SET_INSTALLATION_TAPE,  SETIT'],
{   } [01, ''],
{   } [76, 'Specifies the volume serial numbers and tape type of the tape containing the'],
{   } [77, 'packing list and the name of the file in which to store the packing list. The'],
{   } [70, 'system uses this information later when you install software using the'],
{   } [78, 'INSTALL_SOFTWARE utility. For further information see SPAM Volume 2, Page 4-10'],
{   } [14, 'and chapter 7.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [32, '  PACKING_LIST: name = $required'],
{   } [39, '  EXTERNAL_VSN: string 1..6 = $optional'],
{   } [39, '  RECORDED_VSN: string 1..6 = $optional'],
{   } [54, '  TYPE: key MT9$1600, MT9$6250, MT18$38000 = $optional']],

  v$setsa_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 8] OF t$help_text := [
{   } [37, 'Names:   SET_SYSTEM_ATTRIBUTE,  SETSA'],
{   } [01, ''],
{   } [72, 'Changes the current value of a system attribute. For further information'],
{   } [29, 'see SPAM Volume 1, Chapter 2.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [29, '  ATTRIBUTE: name = $required'],
{   } [37, '  VALUE: positive integer = $required']],

  v$setso_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 8] OF t$help_text := [
{   } [36, 'Names:   SET_SECURITY_OPTION,  SETSO'],
{   } [01, ''],
{   } [59, 'Activates or deactivates optional NOS/VE security features.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [77, '  OPTION: key ALL, CONSOLE_OPERATION_ONLY, SECURE_ANALYSIS, SECURITY_AUDIT ..'],
{   } [28, '          keyend = $required'],
{   } [28, '  VALUE: boolean = $required']],

  v$settz_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 8] OF t$help_text := [
{   } [30, 'Names:   SET_TIME_ZONE,  SETTZ'],
{   } [01, ''],
{   } [66, 'Sets time zone information relative to universal time coordinated.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [37, '  HOURS: integer -12 ..12 = $required'],
{   } [32, '  MINUTES: integer -30 .. 30 = 0'],
{   } [27, '  DAYLIGHT: boolean = false']],

  v$sysdebug_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 5] OF t$help_text := [
{   } [17, 'Names:   SYSDEBUG'],
{   } [01, ''],
{   } [35, 'Initiates the System Core Debugger.'],
{   } [01, ''],
{   } [76, 'Note: Critical Window is not yet defined. So it cannot be called from there.']],

  v$tesrr_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 3] OF t$help_text := [
{   } [39, 'Names:   TEST_RESOURCE_REQUESTS,  TESRR'],
{   } [01, ''],
{   } [45, 'Initiates the Test Resource Requests Utility.']],

  v$usecp_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 7] OF t$help_text := [
{   } [30, 'Names:   USE_CONFIGURATION_PROLOG,  USECP'],
{   } [01, ''],
{   } [70, 'Specifies which configuration prolog is to be used for an installation'],
{   } [10, 'deadstart.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [24, '  NAME: name = $required']],

  v$useic_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 12] OF t$help_text := [
{   } [44, 'Names:   USE_INSTALLED_CONFIGURATION,  USEIC'],
{   } [01, ''],
{   } [74, 'For a NOS/VE continuation deadstart, this command specifies which physical'],
{   } [38, 'configuration file is to be installed.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [24, '  VALUE: boolean = false'],
{   } [01, ''],
{   } [08, 'Remarks:'],
{   } [63, '  VALUE = TRUE:  Reinstalls the current physical configuration.'],
{   } [77, '  VALUE = FALSE: Installs the physical configuration defined on the deadstart'],
{   } [68, '                 file, replacing the current physical configuration.']],

  v$go_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 6] OF t$help_text := [
{   } [17, 'Names:   GO'],
{   } [01, ''],
{   } [77, 'Terminates the system core command processor and causes the deadstart process'],
{   } [59, 'to continue until the next operator pause. (See also AUTO).'],
{   } [01, ''],
{   } [17, 'Parameters: none.']],

    v$help_help_text: [STATIC, READ, oss$mainframe_paged_literal] array [1 .. 6] of t$help_text := [
{   } [17, 'Names:   HELP,  ?'],
{   } [01, ''],
{   } [48, 'Displays Help Information about DCFile Commands.'],
{   } [01, ''],
{   } [11, 'Parameters:'],
{   } [40, '  COMMAND: key ALL or any DCFile command']];

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

{ PURPOSE:
{   This procedure checks that the time zone data and the System Operation Interval and Password data, on
{   China mainframes, on the CIP device is initialized.  If the data is garbaged or is not initialized,
{   then operator intervention will be forced.

  PROCEDURE check_for_initialized_data
    (VAR data_initialized: boolean);

    VAR
      local_status: ost$status,
      password_data: dst$vcu_password_data,
      password_data_seq_p: ^SEQ ( * ),
      time_zone_data: dst$vcu_time_zone_data,
      time_zone_data_seq_p: ^SEQ ( * );

    data_initialized := TRUE;

    time_zone_data_seq_p := #SEQ (time_zone_data);
    dsp$access_vcu_cda_data (dsc$vcu_read_access, dsc$vcu_time_zone_data, time_zone_data_seq_p,
          local_status);
    IF NOT local_status.normal AND (local_status.condition <> dse$read_invalid_time_zone) THEN
      syp$process_deadstart_status (' ', FALSE, local_status);
      osp$system_error ('Unable to read time zone data from CDA.', ^local_status);
    ELSEIF (local_status.condition = dse$read_invalid_time_zone) OR NOT time_zone_data.initialized THEN
      data_initialized := FALSE;
      dpp$put_next_line (dpv$system_core_display,
            'WARNING -- The time zone data is not initialized.  The operator must use the', local_status);
      dpp$put_next_line (dpv$system_core_display,
            '           SET_TIME_ZONE command to initialize the data.', local_status);
    ELSE
      osp$set_mainframe_sig_lock (osv$os_defaults.lock);
      osv$os_defaults.system_time_zone := time_zone_data.time_zone;
      osv$os_defaults.defaults_changed := TRUE;
      osp$clear_mainframe_sig_lock (osv$os_defaults.lock);
    IFEND;

    IF dsv$sub_mainframe_type = dsc$smt_china_mainframe THEN
      password_data_seq_p := #SEQ (password_data);
      dsp$access_vcu_cda_data (dsc$vcu_read_access, dsc$vcu_password_data, password_data_seq_p, local_status);
      IF NOT local_status.normal THEN
        syp$process_deadstart_status (' ', FALSE, local_status);
        osp$system_error ('Unable to read password data from CDA.', ^local_status);
      IFEND;
      IF NOT password_data.password_initialized THEN
        data_initialized := FALSE;
        dpp$put_next_line (dpv$system_core_display,
              'WARNING -- The Operation Password is not initialized.  The operator must use', local_status);
        dpp$put_next_line (dpv$system_core_display,
              '           the SET_OPERATION_PASSWORD command to initialize the data.', local_status);
      ELSEIF NOT password_data.interval_initialized THEN
        data_initialized := FALSE;
        dpp$put_next_line (dpv$system_core_display,
              'WARNING -- The Operation Interval is not initialized.  The operator must use', local_status);
        dpp$put_next_line (dpv$system_core_display,
              '           the SET_OPERATION_INTERVAL command to initialize the data.', local_status);
      IFEND;
    IFEND;

  PROCEND check_for_initialized_data;
?? OLDTITLE ??
?? NEWTITLE := 'command_auto', EJECT ??

{ PURPOSE:
{   This procedure disables operator intervention.

  PROCEDURE command_auto
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    status.normal := TRUE;

    v$auto_mode_requested := TRUE;
    osv$operator_intervention := FALSE;

  PROCEND command_auto;
?? OLDTITLE ??
?? NEWTITLE := 'command_chad', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command change_date (chad)
{   It changes the OS Date.

  PROCEDURE command_chad
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      chad_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 3] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'MONTH   ', syc$integer_value, 0, 1, 12],
             [TRUE,  2, 'DAY     ', syc$integer_value, 0, 1, 31],
             [TRUE,  3, 'YEAR    ', syc$integer_value, 0, 1990, 2155]],
      os_default: ost$operating_system_default,
      pvt: ARRAY [1 .. 4] OF syt$parameter_value;

    status.normal := TRUE;
    syp$crack_command (chad_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    os_default.kind := osc$date_time;
    os_default.free_running_clock := #FREE_RUNNING_CLOCK (0);
    pmp$get_date_time_at_timestamp (os_default.free_running_clock, pmc$use_system_local_time,
          os_default.date_time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    os_default.date_time.month := pvt [1].int;
    os_default.date_time.day := pvt [2].int;
    os_default.date_time.year := pvt [3].int - 1900;

    osp$change_date_time (TRUE {= use OS Defaults}, os_default, status);

  PROCEND command_chad;
?? OLDTITLE ??
?? NEWTITLE := 'command_chat', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command change_date (chad)
{   It changes the OS Time.

  PROCEDURE command_chat
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      chat_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 3] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'HOUR    ', syc$integer_value, 0, 0, 23],
             [TRUE,  2, 'MINUTE  ', syc$integer_value, 0, 0, 59],
             [FALSE, 3, 'SECOND  ', syc$integer_value, 0, 0, 59]],
      os_default: ost$operating_system_default,
      pvt: ARRAY [1 .. 4] OF syt$parameter_value;

    status.normal := TRUE;
    syp$crack_command (chat_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    os_default.kind := osc$date_time;
    os_default.free_running_clock := #FREE_RUNNING_CLOCK (0);
    pmp$get_date_time_at_timestamp (os_default.free_running_clock, pmc$use_system_local_time,
          os_default.date_time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    os_default.date_time.hour := pvt [1].int;
    os_default.date_time.minute := pvt [2].int;
    os_default.date_time.second := pvt [3].int;
    os_default.date_time.millisecond := 0;

    osp$change_date_time (TRUE {= use OS Defaults}, os_default, status);

  PROCEND command_chat;
?? OLDTITLE ??
?? NEWTITLE := 'command_defmsf', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command define_ms_flaw (defmsf).
{   It saves flaw commands for use later during system deadstart.
{       FORMAT: defmsf rvsn cylinder track sector

  PROCEDURE command_defmsf
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      defmsf_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 4] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'RVSN    ', syc$name_value, * ],
             [TRUE,  2, 'CYLINDER', syc$integer_value, 0, 0, 0ffffffffffff(16)],
             [TRUE,  3, 'TRACK   ', syc$integer_value, 0, 0, 0ffffffffffff(16)],
             [TRUE,  4, 'SECTOR  ', syc$integer_value, 0, 0, 0ffffffffffff(16)]],
      pvt: ARRAY [1 .. 4] OF syt$parameter_value,
      sc_flaw_p: ^dmt$sc_flaw_command;

    status.normal := TRUE;
    syp$crack_command (defmsf_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt [1].name (rmc$recorded_vsn_size+1, 1) <> ' ' THEN
      dpp$put_next_line (id, 'ERROR -- Recorded VSN contains more than 6 characters', status);
      RETURN;
    IFEND;

    PUSH sc_flaw_p;
    sc_flaw_p^.rvsn := pvt [1].name (1, rmc$recorded_vsn_size);
    sc_flaw_p^.phys_adrs.cylinder := pvt [2].int;
    sc_flaw_p^.phys_adrs.track := pvt [3].int;
    sc_flaw_p^.phys_adrs.sector := pvt [4].int;
    sc_flaw_p^.trk_specified := TRUE;
    sc_flaw_p^.sec_specified := TRUE;
    sc_flaw_p^.flaw_processed := FALSE;

    dmp$store_sc_flaw_command (sc_flaw_p);

  PROCEND command_defmsf;
?? OLDTITLE ??
?? NEWTITLE := 'command_disdt', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command display_date_time (disdt).
{   It displays the current system date time.

  PROCEDURE command_disdt
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    TYPE
      t$date_time = record
        case 0 .. 2 of
        = 0 =
          string_part: string (40),
        = 1 =
          head: string (18),
          hms: ost$hms_time,
          space_1: string (1),
          iso: ost$iso_date,
        casend,
      recend;

    VAR
      date: ost$date,
      date_time_string: t$date_time,
      time: ost$time;

    status.normal := TRUE;

    time.time_format := osc$hms_time;
    pmp$get_time (time.time_format, time, status);
    date.date_format := osc$iso_date;
    pmp$get_date (date.date_format, date, status);
    date_time_string.string_part := ' ';
    date_time_string.head := 'System Date Time: ';
    date_time_string.hms := time.hms;
    date_time_string.iso := date.iso;

    dpp$put_next_line (id, date_time_string.string_part, status);

  PROCEND command_disdt;
?? OLDTITLE ??
?? NEWTITLE := 'command_dissa', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command display_system_attribute (dissa).
{   It displays values of system core constants during system deadstart.
{       FORMAT: dissa name

  PROCEDURE command_dissa
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      constant_value: integer,
      dissa_pdt: [STATIC, READ, oss$mainframe_paged_literal] array
            [1 .. 1] of syt$parameter_descriptor := [[TRUE, 1, 'NAME    ', syc$name_value, * ]],
      display_all: boolean,
      display_everything: boolean,
      index: integer,
      output_string: string (80),
      tempname: ost$name,
      pvt: array [1 .. 1] of syt$parameter_value;

    status.normal := TRUE;
    syp$crack_command (dissa_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    index := 0;
    tempname := pvt [1].name;
    display_all := FALSE;
    display_everything := FALSE;

    IF tempname = 'ALL' THEN
      display_all := TRUE;
      index := 1;
    ELSEIF tempname = 'EVERYTHING' THEN
      display_everything := TRUE;
      index := 1;
    IFEND;

  /display/
    REPEAT
      syp$fetch_system_constant (tempname, index, constant_value, status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

      IF tempname <> 'dummy' THEN
        output_string := ' ';
        output_string (2, 31) := tempname;
        output_string (33, 3) := ' = ';
        syp$binary_to_ascii (constant_value, output_string, 10, 54);
        syp$binary_to_ascii (constant_value, output_string, 16, 72);
        output_string (73, 4) := '(16)';
        output_string (55) := ',';
        dpp$put_next_line (id, output_string, status);
      IFEND;

      IF display_everything THEN
        tempname := 'EVERYTHING';
      ELSEIF display_all THEN
        tempname := 'ALL';
      IFEND;
    UNTIL index = 0 {/display/} ;

  PROCEND command_dissa;
?? OLDTITLE ??
?? NEWTITLE := 'command_distz', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command display_time_zone (distz).
{   It displays the time zone data stored in the VCU CDA sector.
{       FORMAT: distz

  PROCEDURE command_distz
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      date_time_information: dst$date_time_information,
      output_string: string (65),
      time_zone: ost$time_zone,
      time_zone_data: dst$vcu_time_zone_data,
      time_zone_data_seq_p: ^SEQ ( * );

    status.normal := TRUE;

    time_zone_data_seq_p := #SEQ (time_zone_data);
    dsp$access_vcu_cda_data (dsc$vcu_read_access, dsc$vcu_time_zone_data, time_zone_data_seq_p, status);
    IF NOT status.normal THEN
      syp$process_deadstart_status (' ', FALSE, status);
      RETURN;
    IFEND;
    IF time_zone_data.initialized THEN
      time_zone := time_zone_data.time_zone;
    ELSE
      output_string := 'The time zone data is not initialized.';
      dpp$put_next_line (id, output_string, status);
      RETURN;
    IFEND;

    output_string := ' ';
    output_string (3, 8) := 'HOURS = ';
    syp$binary_to_ascii (time_zone.hours_from_gmt, output_string, 10, 14);
    output_string (15, 12) := ', MINUTES = ';
    syp$binary_to_ascii (time_zone.minutes_offset, output_string, 10, 30);
    output_string (31, 25) := ', DAYLIGHT SAVING TIME = ';
    IF time_zone.daylight_saving_time THEN
      output_string (56, 5) := 'TRUE.';
    ELSE
      output_string (56, 6) := 'FALSE.';
    IFEND;
    dpp$put_next_line (id, output_string, status);

  PROCEND command_distz;
?? OLDTITLE ??
?? NEWTITLE := 'command_help', EJECT ??

{ PURPOSE:
{   This procedure displays the available commands.

  PROCEDURE command_help
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      command_found: boolean,
      command_help_p: ^t$help_texts,
      help_pdt: [STATIC, READ, oss$mainframe_paged_literal] array
            [1 .. 1] of syt$parameter_descriptor := [[FALSE, 1, 'COMMAND        ', syc$name_value, 'ALL  ']],
      i: integer,
      pvt: array [1 .. 2] of syt$parameter_value,
      str: string (60);

    status.normal := TRUE;
    syp$crack_command (help_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    command_help_p := NIL;
    command_found := FALSE;

    IF pvt [1].name = 'ALL' THEN
      command_help_p := ^v$command_help_text;

    ELSEIF pvt [1].name = 'GO' THEN
      { GO is the quit command and therefore not in the command table.
      command_help_p := ^v$go_help_text;

    ELSE { command must be defined in the command table.

    /scan_command_table/
      FOR i := LOWERBOUND (v$command_table) TO UPPERBOUND (v$command_table) DO
        IF (pvt [1].name = v$command_table [i].short_name)
{     } OR (pvt [1].name = v$command_table [i].long_name) THEN
          command_found := TRUE;
          EXIT /scan_command_table/ {----->
        IFEND;
      FOREND /scan_command_table/;

      IF command_found THEN
        CASE i OF
        = c$help =
          command_help_p := ^v$help_help_text;
        = c$auto =
          command_help_p := ^v$auto_help_text;
        = c$chad =
          command_help_p := ^v$chad_help_text;
        = c$chat =
          command_help_p := ^v$chat_help_text;
        = c$defmsf =
          command_help_p := ^v$defmsf_help_text;
        = c$disdt =
          command_help_p := ^v$disdt_help_text;
        = c$dissa =
          command_help_p := ^v$dissa_help_text;
        = c$distz =
          command_help_p := ^v$distz_help_text;
        = c$inisd =
          command_help_p := ^v$inisd_help_text;
        = c$setit =
          command_help_p := ^v$setit_help_text;
        = c$setsa =
          command_help_p := ^v$setsa_help_text;
        = c$setso =
          command_help_p := ^v$setso_help_text;
        = c$settz =
          command_help_p := ^v$settz_help_text;
        = c$sysdebug =
          command_help_p := ^v$sysdebug_help_text;
        = c$tesrr =
          command_help_p := ^v$tesrr_help_text;
        = c$usecp =
          command_help_p := ^v$usecp_help_text;
        = c$useic =
          command_help_p := ^v$useic_help_text;
        CASEND;
      IFEND;
    IFEND;

    IF command_help_p = NIL THEN
      str := '-- ERROR -- Unknown Command: ';
      str (30, * ) := pvt [1].name;
      dpp$put_next_line (id, str, status);
    ELSE
      FOR i := LOWERBOUND (command_help_p^) TO UPPERBOUND (command_help_p^) DO
        dpp$put_next_line (id, command_help_p^ [i].value (1, command_help_p^ [i].size), status);
        IF NOT status.normal THEN
          RETURN; {----->
        IFEND;
      FOREND;
    IFEND;

  PROCEND command_help;
?? OLDTITLE ??
?? NEWTITLE := 'command_inisd', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command initialize_system_device (inisd)
{   It is used during deadstart to initialize the system device.
{       FORMAT: inisd vsn rdf rss sysset

  PROCEDURE command_inisd
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      error_string: string (256),
      ignore: ost$status,
      inisd_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 4] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'VSN     ', syc$name_value, * ],
             [FALSE, 2, 'RDF     ', syc$boolean_value, TRUE],
             [FALSE, 3, 'RSS     ', syc$name_value, * ],
             [FALSE, 4, 'SYSSET  ', syc$name_value, '       ']],
      line_received: boolean,
      operator_dialog_complete: boolean,
      operator_dialog_pdt:  [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 1] OF
            syt$parameter_descriptor :=
            [[TRUE,  1, 'YES/NO  ', syc$name_value, *]],
      operator_dialog_pvt: ARRAY [1 .. 1] OF syt$parameter_value,
      operator_input: string (80),
      output_string: string (80),
      output_string_size: integer,
      password_valid: boolean,
      pvt: ARRAY [1 .. 4] OF syt$parameter_value;

    status.normal := TRUE;
    IF NOT cmv$system_device_data [cmc$sdt_tape_device].specified THEN
      dpp$put_next_line (id, 'The INISD command is not allowed during a disk deadstart', status);
      RETURN;
    IFEND;

    IF syv$reading_dcfile THEN
      error_string (20, *) := 'WARNING -- The INISD command must be entered by an operator, not from a file.';
      dpp$put_next_line (id, error_string (20, 79), ignore);
      error_string (1, 19) := 'SysCore Cmd error: ';
      log_system_core_text (error_string);
      RETURN;
    IFEND;

    dsp$check_password_for_inisd (id, password_valid);
    IF NOT password_valid THEN
      RETURN;
    IFEND;

    IF (cmv$system_device_data [cmc$sdt_disk_device].channel_name (2,1) = 'C') AND
          (cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number = '  $895') THEN
      dpp$put_next_line (id,
            'WARNING -- NOS/VE can not determine if CIP resides on a device which is only', status);
      dpp$put_next_line (id,
            '          accessable to NOS/VE via a CIO channel.  The INISD command will', status);
      dpp$put_next_line (id,
            '          destroy CIP if it is present on the system device.  IF the second', status);
      dpp$put_next_line (id,
            '          access, to the device, is a NIO channel, you must redeadstart and', status);
      dpp$put_next_line (id,
            '          use the NIO channel to preserve CIP.', status);
    IFEND;

    syp$crack_command (inisd_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt [1].name (rmc$recorded_vsn_size+1, 1) <> ' ' THEN
      dpp$put_next_line (id, 'ERROR -- Recorded VSN contains more than 6 characters', status);
      RETURN;
    IFEND;

    stv$system_set_name := pvt [4].name;

    IF pvt[3].defined THEN
      IF (pvt[3].name = 'RSS') OR (pvt[3].name = 'RECOVER_SYSTEM_SET') THEN

        { Perform operator dialog to determine if recorded vsn for system device is correct.

        dpp$put_next_line (id, 'The VSN for the system disk unit must either be:', status);
        dpp$put_next_line (id, '  1) The same as it was when last initialized or ', status);
        dpp$put_next_line (id, '  2) Different from all other VSN''s in the current configuration', status);
        STRINGREP (output_string, output_string_size, 'Is ', pvt [1].name (1, rmc$recorded_vsn_size),
              ' correct for the current configuration (enter YES or NO)?');
        dpp$put_next_line (id, output_string (1, output_string_size) , status);

        operator_dialog_complete := false;
        /operator_dialog/
        REPEAT
          dpp$get_next_line (id, osc$wait, operator_input, line_received);
          dpp$put_next_line (id, operator_input, status);
          syp$crack_command (operator_dialog_pdt, operator_input, operator_dialog_pvt, status);
          IF NOT status.normal THEN
            dpp$put_next_line (id, 'Enter just YES or NO:  ', status);
            CYCLE /operator_dialog/;
          IFEND;
          IF operator_dialog_pvt [1].name = 'YES' THEN
            osv$recover_system_set_phase := osc$reinitialize_system_device;
            operator_dialog_complete := TRUE;
          ELSEIF operator_dialog_pvt [1].name = 'NO' THEN
            dpp$put_next_line (id, 'Reenter the INITIALIZE_SYSTEM_DEVICE command with a', status);
            dpp$put_next_line (id, 'unique VSN for the system disk unit.', status);
            RETURN;
          ELSE
            dpp$put_next_line (id, 'Enter either YES or NO:  ', status);
            CYCLE /operator_dialog/;
          IFEND;
        UNTIL operator_dialog_complete;

      ELSE
        dpp$put_next_line (id, 'ERROR -- Unknown value for parameter.', status);
        RETURN;
      IFEND;
    IFEND;

    dmv$system_device_recorded_vsn := pvt [1].name (1, rmc$recorded_vsn_size);
    dmv$retain_system_device_flaws := pvt [2].bool;

    osv$deadstart_phase := osc$installation_deadstart;
    dsp$save_sys_status_current_ds (dsc$ssr_sds_sdas_installation);

  PROCEND command_inisd;
?? OLDTITLE ??
?? NEWTITLE := 'command_setit', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command set_installation_tape (setit)
{   It is used during deadstart to enter the name of the tape containing products to be
{   installed and to enter the name of the file to which the packing list will be written.
{       FORMAT: setit packlist evsn rvsn type

  PROCEDURE command_setit
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      pvt: ARRAY [1 .. 4] OF syt$parameter_value,
      setit_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 4] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'PACKLIST', syc$name_value, * ],
             [FALSE, 2, 'EVSN    ', syc$string_value, * ],
             [FALSE, 3, 'RVSN    ', syc$string_value, * ],
             [FALSE, 4, 'TYPE    ', syc$name_value, * ]];

    status.normal := TRUE;
    syp$crack_command (setit_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt[1].name(1) = '''' THEN
      dpp$put_next_line (id, 'ERROR -- The PACKING_LIST parameter value must be of type name.',
            status);
      RETURN;
    IFEND;

    IF clp$trimmed_string_size (pvt [1].name) > 16 THEN
      dpp$put_next_line (id, 'ERROR -- The PACKING_LIST parameter can have a maximum of 16 characters.',
            status);
      RETURN;
    IFEND;

    IF (NOT pvt [2].defined) AND (NOT pvt [3].defined) THEN
      dpp$put_next_line (id, 'ERROR -- Either the EVSN or RVSN parameter must be entered.', status);
      RETURN;
    IFEND;

    IF (pvt [2].defined) AND (pvt [2].text.size > 6) THEN
      dpp$put_next_line (id, 'ERROR -- The EVSN parameter can have a maximum of 6 characters.', status);
      RETURN;
    IFEND;

    IF (pvt [3].defined) AND (pvt [3].text.size > 6) THEN
      dpp$put_next_line (id, 'ERROR -- The RVSN parameter can have a maximum of 6 characters.', status);
      RETURN;
    IFEND;

    IF (pvt [4].defined) AND (pvt [4].name <> 'MT9$1600') AND (pvt [4].name <> 'MT9$6250') AND
          (pvt [4].name <> 'MT18$38000') THEN
      dpp$put_next_line (id, 'ERROR -- The TYPE parameter must be MT9$1600, MT9$6250 or MT18$38000.',
            status);
      RETURN;
    IFEND;

    rav$installation_tape_values.packing_list := pvt [1].name;

    IF pvt [2].defined THEN
      rav$installation_tape_values.evsn := pvt [2].text.value (1, pvt [2].text.size);
    ELSE
      rav$installation_tape_values.evsn := '';
    IFEND;

    IF pvt [3].defined THEN
      rav$installation_tape_values.rvsn := pvt [3].text.value (1, pvt [3].text.size);
    ELSE
      rav$installation_tape_values.rvsn := '';
    IFEND;

    IF pvt [4].defined THEN
      rav$installation_tape_values.tape_type := pvt [4].name;
    ELSE
      rav$installation_tape_values.tape_type := '';
    IFEND;

  PROCEND command_setit;
?? OLDTITLE ??
?? NEWTITLE := 'command_setsa', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command set_system_attribute (setsa).
{   It updates values of system core constants during system deadstart.
{       FORMAT: setsa name value

  PROCEDURE command_setsa
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      pvt: ARRAY [1 .. 2] OF syt$parameter_value,
      setsa_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 2] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'NAME    ', syc$name_value, * ],
             [TRUE,  2, 'VALUE   ', syc$integer_value, 0, 0, 0ffffffffffff(16)]];

    status.normal := TRUE;
    syp$crack_command (setsa_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    syp$store_system_constant (pvt [1].name, pvt [2].int, status);

  PROCEND command_setsa;
?? OLDTITLE ??
?? NEWTITLE := 'command_setso', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command set_security_option (setso).  It is used to turn on
{   or off special security features.
{       FORMAT: setso name value
{               where name is a key of
{                           ALL
{                           CONSOLE_OPERATION_ONLY
{                           SECURE_ANALYSIS
{                           SECURITY_AUDIT
{
{                     value is a boolean indicating whether the option is
{                           to be turned on or off
{ DESIGN
{   When any security option is set either on or off it's associated "activated" and "specified" booleans are
{   set.  This is done to ensure that any security option is only set once per deadstart.

  PROCEDURE command_setso
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      message: string (80),
      message_length: integer,
      pvt: ARRAY [1 .. 2] OF syt$parameter_value,
      setso_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 2] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'NAME    ', syc$name_value, * ],
             [TRUE,  2, 'VALUE   ', syc$boolean_value, TRUE]];

    status.normal := TRUE;
    syp$crack_command (setso_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { If any security option has previously been specified then ALL is not allowed.

    IF pvt [1].name = 'ALL' THEN

      { Note: Any new security options must be added to this list.

      IF (avv$security_options [avc$vso_console_operation_only].specified OR
            avv$security_options [avc$vso_secure_analysis].specified OR
            avv$security_options [avc$vso_security_audit].specified) THEN
        osp$set_status_abnormal ('AV', ave$duplicate_setso_command,
              'SET_SECURITY_OPTION has already been issued for one or more options.', status);
      ELSE
        avv$security_options [avc$vso_console_operation_only].active := pvt [2].bool;
        avv$security_options [avc$vso_console_operation_only].specified := TRUE;
        avv$security_options [avc$vso_secure_analysis].active := pvt [2].bool;
        avv$security_options [avc$vso_secure_analysis].specified := TRUE;
        avv$security_options [avc$vso_security_audit].active := pvt [2].bool;
        avv$security_options [avc$vso_security_audit].specified := TRUE;
      IFEND;
    ELSEIF pvt [1].name = avc$console_operation_only THEN
      IF NOT avv$security_options [avc$vso_console_operation_only].specified THEN
        avv$security_options [avc$vso_console_operation_only].active := pvt [2].bool;
        avv$security_options [avc$vso_console_operation_only].specified := TRUE;
      ELSE
        STRINGREP (message, message_length, 'SET_SECURITY_OPTION has already been issued for ',
              pvt [1].name (1, clp$trimmed_string_size (pvt [1].name)), '.');
        osp$set_status_abnormal ('AV', ave$duplicate_setso_command, message (1, message_length), status);
      IFEND;
    ELSEIF pvt [1].name = avc$secure_analysis THEN
      IF NOT avv$security_options [avc$vso_secure_analysis].specified THEN
        avv$security_options [avc$vso_secure_analysis].active := pvt [2].bool;
        avv$security_options [avc$vso_secure_analysis].specified := TRUE;
      ELSE
        STRINGREP (message, message_length, 'SET_SECURITY_OPTION has already been issued for ',
              pvt [1].name (1, clp$trimmed_string_size (pvt [1].name)), '.');
        osp$set_status_abnormal ('AV', ave$duplicate_setso_command, message (1, message_length), status);
      IFEND;
    ELSEIF pvt [1].name = avc$security_audit THEN
      IF NOT avv$security_options [avc$vso_security_audit].specified THEN
        avv$security_options [avc$vso_security_audit].active := pvt [2].bool;
        avv$security_options [avc$vso_security_audit].specified := TRUE;
      ELSE
        STRINGREP (message, message_length, 'SET_SECURITY_OPTION has already been issued for ',
              pvt [1].name (1, clp$trimmed_string_size (pvt [1].name)), '.');
        osp$set_status_abnormal ('AV', ave$duplicate_setso_command, message (1, message_length), status);
      IFEND;
    ELSE
      STRINGREP (message, message_length, pvt [1].name (1, clp$trimmed_string_size (pvt [1].name)),
            ' is not a valid security option.');
      osp$set_status_abnormal ('AV', ave$unknown_security_option, message (1, message_length), status);
    IFEND;

  PROCEND command_setso;
?? OLDTITLE ??
?? NEWTITLE := 'command_settz', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command set_time_zone (settz).
{   It updates time zone data stored in the VCU CDA sector.
{       FORMAT: settz hours minutes daylight

  PROCEDURE command_settz
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      date_time_information: dst$date_time_information,
      pvt: ARRAY [1 .. 3] OF syt$parameter_value,
      settz_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 3] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'HOURS   ', syc$integer_value, 0, -12, 12],
             [FALSE, 2, 'MINUTES ', syc$integer_value, 0, -30, 30],
             [FALSE, 3, 'DAYLIGHT', syc$boolean_value, FALSE]],
      time_zone: ost$time_zone,
      time_zone_data: dst$vcu_time_zone_data,
      time_zone_data_seq_p: ^SEQ ( * );

    status.normal := TRUE;
    syp$crack_command (settz_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    time_zone.hours_from_gmt := pvt [1].int;
    time_zone.minutes_offset := pvt [2].int;
    time_zone.daylight_saving_time := pvt [3].bool;

    time_zone_data.initialized := TRUE;
    time_zone_data.time_zone := time_zone;
    time_zone_data_seq_p := #SEQ (time_zone_data);
    dsp$access_vcu_cda_data (dsc$vcu_write_access, dsc$vcu_time_zone_data, time_zone_data_seq_p, status);
    IF NOT status.normal THEN
      syp$process_deadstart_status (' ', FALSE, status);
      RETURN;
    IFEND;

  PROCEND command_settz;
?? OLDTITLE ??
?? NEWTITLE := 'command_usecp', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command use_configuration_prolog (usecp)
{   It specifies the name of the configuration prolog to use.
{       FORMAT: usecp name

  PROCEDURE command_usecp
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      index: integer,
      pvt: ARRAY [1 .. 1] OF syt$parameter_value,
      usecp_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 1] OF syt$parameter_descriptor :=
            [[TRUE,  1, 'NAME    ', syc$name_value, * ]];

    status.normal := TRUE;
    syp$crack_command (usecp_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    osv$configuration_prolog_name.value := pvt [1].name;
    osv$configuration_prolog_name.size := 1;

    FOR index := 1 TO #SIZE (pvt [1].name) DO
      IF pvt [1].name (index) = ' ' THEN
        RETURN;
      IFEND;
      osv$configuration_prolog_name.size := index;
    FOREND;

  PROCEND command_usecp;
?? OLDTITLE ??
?? NEWTITLE := 'command_useic', EJECT ??

{ PURPOSE:
{   This procedure is called from the system core command use_installed_configuration (useic)
{   It states whether or not to use the installed configuration.
{       FORMAT: useic boolean

  PROCEDURE command_useic
    (    text: string ( * );
         id: dpt$window_id;
     VAR status: ost$status);

    VAR
      pvt: ARRAY [1 .. 1] OF syt$parameter_value,
      useic_pdt: [STATIC, READ, oss$mainframe_paged_literal] ARRAY [1 .. 1] OF syt$parameter_descriptor :=
            [[FALSE, 1, 'VALUE   ', syc$boolean_value, TRUE]];

    status.normal := TRUE;
    syp$crack_command (useic_pdt, text, pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    cmv$use_installed_configuration := pvt [1].bool;

  PROCEND command_useic;
?? OLDTITLE ??
?? NEWTITLE := 'log_system_core_text', EJECT ??

{ PURPOSE:
{   This procedure is called during system_core command processing to log text to the system log.

  PROCEDURE log_system_core_text
    (    text: string (*));

    VAR
      ignore_status: ost$status,
      log_time: ost$time,
      trim_size: integer;

    IF NOT syv$inhibit_core_cmd_logging THEN
      FOR trim_size := STRLENGTH (text) DOWNTO 1 DO
        IF text (trim_size) <> ' ' THEN
          lgp$add_entry_to_system_log (pmc$msg_origin_system, text (1, trim_size), log_time, ignore_status);
          RETURN;
        IFEND;
      FOREND;
    IFEND;

  PROCEND log_system_core_text;
?? OLDTITLE ??
?? NEWTITLE := 'process_dcfile', EJECT ??

{ PURPOSE:
{   This procedure processes each line of the DCFILE.

  PROCEDURE process_dcfile
    (VAR force_operator_intervention: boolean);

    VAR
      bam_record_header_p: ^bat$record_header,
      dcfile_length_p: ^0 .. dsc$max_dcfile_length,
      dcfile_line_p: ^string (*),
      dcfile_seq_p: ^SEQ ( * ),
      save_dcfile_line_seq_p: ^SEQ ( * ),
      save_dcfile_line_p: ^string (*),
      save_length: 0 .. dsc$max_dcfile_length,
      status: ost$status;

    { Retrieve the dcfile data.

    PUSH dcfile_seq_p: [[REP dsc$max_dcfile_length OF cell]];
    RESET dcfile_seq_p;
    dsp$fetch_boot_data (dsc$dcfile_data, dcfile_seq_p);
    RESET dcfile_seq_p;
    NEXT dcfile_length_p IN dcfile_seq_p;
    IF dcfile_length_p^ = 0 THEN
      force_operator_intervention := TRUE;
      dpp$put_next_line (dpv$system_core_display,
            'WARNING -- The DCFILE was either NOT specified OR NOT found on the deadstart', status);
      dpp$put_next_line (dpv$system_core_display,
            '           device.  Operator must enter the DCFILE commands at the console.', status);
      RETURN;
    IFEND;

    PUSH save_dcfile_line_seq_p: [[REP dsc$max_dcfile_length OF cell]];
    syv$reading_dcfile := TRUE;

   /process_the_dcfile/
    WHILE dcfile_length_p^ >= #SIZE (bat$record_header) DO
      NEXT bam_record_header_p IN dcfile_seq_p;
      dcfile_length_p^ := dcfile_length_p^ - #SIZE (bam_record_header_p^);
      IF dcfile_length_p^ < bam_record_header_p^.length THEN
        EXIT /process_the_dcfile/;
      IFEND;

      IF bam_record_header_p^.length > 0 THEN
        IF bam_record_header_p^.header_type = bac$start_record THEN
          RESET save_dcfile_line_seq_p;
          save_length := 0;

          { Concatenate any broken "bam records".

         /concatenate_the_line/
          WHILE TRUE DO
            IF bam_record_header_p^.length > 0 THEN
              NEXT save_dcfile_line_p: [bam_record_header_p^.length] IN save_dcfile_line_seq_p;
              NEXT dcfile_line_p: [bam_record_header_p^.length] IN dcfile_seq_p;
              dcfile_length_p^ := dcfile_length_p^ - #SIZE (dcfile_line_p^);
              save_length := save_length + bam_record_header_p^.length;
              save_dcfile_line_p^ := dcfile_line_p^;
            IFEND;
            IF bam_record_header_p^.header_type = bac$end_record THEN
              EXIT /concatenate_the_line/;
            IFEND;
            IF dcfile_length_p^ < #SIZE (bam_record_header_p^) THEN
              EXIT /process_the_dcfile/;
            IFEND;
            NEXT bam_record_header_p IN dcfile_seq_p;
            dcfile_length_p^ := dcfile_length_p^ - #SIZE (bam_record_header_p^);
          WHILEND /concatenate_the_line/;
          RESET save_dcfile_line_seq_p;
          NEXT dcfile_line_p: [save_length] IN save_dcfile_line_seq_p;

        ELSE
          NEXT dcfile_line_p: [bam_record_header_p^.length] IN dcfile_seq_p;
          dcfile_length_p^ := dcfile_length_p^ - #SIZE (dcfile_line_p^);
        IFEND;

        dpp$put_next_line (dpv$system_core_display, dcfile_line_p^, status);
        syp$process_command_line (dcfile_line_p^, NIL, dpv$system_core_display, status);
        IF v$auto_mode_requested THEN
          v$auto_mode_requested := FALSE;
          EXIT /process_the_dcfile/;
        IFEND;
      IFEND;
    WHILEND /process_the_dcfile/;
    syv$reading_dcfile := FALSE;

  PROCEND process_dcfile;
?? OLDTITLE ??
?? NEWTITLE := 'syp$process_command_line', EJECT ??

{ PURPOSE:
{   This procedure processes a system core command line.  System core commands are subject to the following
{   restrictions:
{     . one command per command line
{     . no continuation lines are permitted
{     . positional parameters only
{     . parameters separated by comma and/or blank(s)

  PROCEDURE [XDCL] syp$process_command_line
    (    text: string ( * );
         aux_command_table_p: ^ARRAY [1 .. * ] OF syt$command_table_entry;
         window: dpt$window_id;
     VAR status: ost$status);

    VAR
      error_string: string (128),
      ignore: ost$status,
      index: integer,
      system_core_cmd_error_string: string (256),
      token: ost$string,
      token_index: 0 .. 255;

    status.normal := TRUE;
    system_core_cmd_error_string := 'SysCore Cmd error: ';

    { Log the command to the system log.

    log_system_core_text (text);

    { Get the command name from the command line.

    token_index := 1;
    syp$get_token (text, TRUE {upper_case}, token_index, token, status);
    IF NOT status.normal THEN
      dpp$put_next_line (window, 'WARNING -- Invalid command.', ignore);
      system_core_cmd_error_string (20, *) := 'WARNING -- Invalid command.';
      log_system_core_text (system_core_cmd_error_string);
      RETURN;
    IFEND;
    IF token.size = 0 THEN
      RETURN;
    IFEND;

    { Scan the aux command table for the command name and call the command processor.

    IF aux_command_table_p <> NIL THEN
      FOR index := LOWERBOUND (aux_command_table_p^) TO UPPERBOUND (aux_command_table_p^) DO
        IF (token.value (1, token.size) = aux_command_table_p^ [index].short_name) OR
              (token.value (1, token.size) = aux_command_table_p^ [index].long_name) THEN
          aux_command_table_p^ [index].proc_p^ (text (token_index, * ), window, status);
          IF NOT status.normal THEN
            error_string := 'WARNING -- Returned abnormal status from command ';
            error_string (50, *) := token.value (1, token.size);
            dpp$put_next_line (window, error_string (1, token.size + 50), ignore);
            system_core_cmd_error_string (20, *) := error_string (1, token.size + 50);
            log_system_core_text (system_core_cmd_error_string);
            error_string := 'ERROR -- ';
            error_string (10, *) := status.text.value (2, status.text.size - 1);
            dpp$put_next_line (window, error_string (1, status.text.size + 9), ignore);
            system_core_cmd_error_string (20, *) := error_string (1, status.text.size + 9);
            log_system_core_text (system_core_cmd_error_string);
          ELSEIF aux_command_table_p^ [index].repeatable_command THEN
            IF syv$repeatable_command_p <> NIL THEN
              FREE syv$repeatable_command_p IN osv$mainframe_wired_heap^;
            IFEND;
            ALLOCATE syv$repeatable_command_p: [STRLENGTH (text)] IN osv$mainframe_wired_heap^;
            syv$repeatable_command_p^ := text;
          IFEND;
          RETURN;
        IFEND;
      FOREND;
    IFEND;

    { Scan the command table for the command name and call the command processor.

    FOR index := LOWERBOUND (v$command_table) TO UPPERBOUND (v$command_table) DO
      IF (token.value (1, token.size) = v$command_table [index].short_name) OR
            (token.value (1, token.size) = v$command_table [index].long_name) THEN
        v$command_table [index].proc_p^ (text (token_index, * ), window, status);
        IF NOT status.normal THEN
          error_string := 'ERROR -- ';
          error_string (10, *) := status.text.value (1, status.text.size);
          dpp$put_next_line (window, error_string (1, status.text.size + 10), ignore);
          system_core_cmd_error_string (20, *) := error_string (1, status.text.size + 10);
          log_system_core_text (system_core_cmd_error_string);
        IFEND;
        RETURN;
      IFEND;
    FOREND;

    dpp$put_next_line (window, 'WARNING -- Invalid command name', ignore);
    log_system_core_text ('WARNING -- Invalid command name');

  PROCEND syp$process_command_line;
?? OLDTITLE ??
?? NEWTITLE := 'syp$process_core_commands', EJECT ??

{ PURPOSE:
{   This procedure is called during deadstart (and by debug if system debug is active) to process
{   commands from the operator.

  PROCEDURE [XDCL] syp$process_core_commands
    (    window: dpt$window_id;
         quit_command: string ( * );
         aux_command_table_p: ^ARRAY [1 .. * ] OF syt$command_table_entry;
     VAR status: ost$status);

    VAR
      ignore: ost$status,
      line_received: boolean,
      output_line: string (256),
      text: string (70),
      token: ost$string,
      token_index: 0 .. 255;

    status.normal := TRUE;

   /scan_command_table/
    WHILE TRUE DO
      REPEAT
        dpp$get_next_line (window, osc$wait, text, line_received);
      UNTIL text <> ' ';

      output_line := ' ';
      output_line (3, *) := text;
      dpp$put_next_line (window, output_line (1, (#SIZE (text) + 2)), ignore);

      token_index := 1;
      syp$get_token (text, TRUE {upper_case}, token_index, token, status);
      IF NOT status.normal THEN
        dpp$put_next_line (window, 'ERROR -- Invalid command, enter valid command.', ignore);
        CYCLE /scan_command_table/;
      IFEND;
      IF token.value (1, token.size) = quit_command THEN
        token_index := token.size + 1;
        syp$get_token (text, TRUE {upper_case}, token_index, token, status);
        IF NOT status.normal THEN
          dpp$put_next_line (window, 'WARNING -- Invalid parameter.', ignore);
        ELSEIF (token.size <> 0) AND (token.value (1, token.size) = 'ALL') THEN
          syv$run_all_timestamp := #FREE_RUNNING_CLOCK (0);
        IFEND;
        output_line := text;
        output_line (#SIZE (text) + 1, *) := ' "End System_Core_Commands/SYSDEBUG session"';
        log_system_core_text (output_line (1, #SIZE (text) + 44));
        EXIT /scan_command_table/;
      IFEND;

      syp$process_command_line (text, aux_command_table_p, window, status);
      IF v$auto_mode_requested THEN
        v$auto_mode_requested := FALSE;
        EXIT /scan_command_table/;
      IFEND;
    WHILEND /scan_command_table/;

  PROCEND syp$process_core_commands;
?? OLDTITLE ??
?? NEWTITLE := 'syp$process_deadstart_commands', EJECT ??

{ PURPOSE:
{   This procedure is called very early in system deadstart to process system core commands from the
{   deadstart device (dcfile) or the operator.  Prior to calling this routine the following must be true:
{     .  Memory manager must be initialized to the point that a page fault for a new page of an existing
{        segment is allowed.
{     .  Mainframe heaps must be initialized so that new tables can be ALLOCATED.
{   The system core commands allow the installation to specify their own values for sizes of system tables.

  PROCEDURE [XDCL] syp$process_deadstart_commands
    (VAR status: ost$status);

    VAR
      data_initialized: boolean,
      force_operator_intervention: boolean,
      ssr_entry: dst$ssr_entry,
      traps: 0 .. 3;

    status.normal := TRUE;
    syv$debug_control.debug_active := FALSE;
    force_operator_intervention := FALSE;
    syp$display_deadstart_message ('Processing deadstart commands ...');

{Save the system constants before the DCFILE as OS Default values.
    syp$save_system_constants (syc$scsv_os_default_values);

{ Process the commands in the DCFILE.  If no DCFILE exists then operator intervention will be forced.
    process_dcfile (force_operator_intervention);

    check_for_initialized_data (data_initialized);
    force_operator_intervention := (force_operator_intervention OR NOT data_initialized);

{ Retrieve the operator intervention flag from the SSR.
    dsp$get_entry_from_ssr (dsc$ssr_operator_intervention, ssr_entry);
    osv$operator_intervention := (ssr_entry.whole_slot = 1);

{ Allow the operator to enter deadstart commands.
    IF osv$operator_intervention OR force_operator_intervention THEN
      REPEAT
        osv$operator_intervention := TRUE;
        syp$display_deadstart_message ('Enter system core commands:');
        syp$process_core_commands (dpv$system_core_display, 'GO  ', NIL, status);
        check_for_initialized_data (data_initialized);
      UNTIL data_initialized;
    IFEND;

{Save the system constants after the DCFILE as DCFILE values.
    syp$save_system_constants (syc$scsv_dc_file_values);

    dsp$check_interval;

    { If debug breakpoints have been set then enable traps.

    IF syv$debug_control.debug_active THEN
      i#enable_traps (traps);
    IFEND;

    { If the secured analysis security option is not specified then default it to FALSE.

    IF NOT avv$security_options [avc$vso_secure_analysis].specified THEN
      avv$security_options [avc$vso_secure_analysis].active := FALSE;
    IFEND;

    { Set the secure analysis bit in the MRT.

    dsp$change_secure_analysis (avv$security_options [avc$vso_secure_analysis].active, status);

  PROCEND syp$process_deadstart_commands;
?? OLDTITLE ??
MODEND sym$process_deadstart_commands;
