?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Operator Facility : System Operator Utility' ??
MODULE ofm$system_operator_utility_2dd;

{ PURPOSE:
{   This module contains the command processing procedures for the System
{   Operator Utility (SOU).

?? TITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clc$standard_file_names
*copyc clt$integer
*copyc ofd$type_definition
*copyc ofe$error_codes
*copyc oft$menu_selections
*copyc oft$operator_alarm
*copyc oft$operator_menu_descriptor
*copyc oss$job_paged_literal
*copyc ost$status
*copyc ost$string
?? POP ??
*copyc amp$get_next
*copyc amp$put_next
*copyc avp$accounting_administrator
*copyc avp$configuration_administrator
*copyc avp$family_administrator
*copyc avp$removable_media_admin
*copyc avp$removable_media_operator
*copyc avp$system_administrator
*copyc avp$system_displays
*copyc avp$system_operator
*copyc clp$close_display
*copyc clp$convert_string_to_file_ref
*copyc clp$evaluate_parameters
*copyc clp$evaluate_token
*copyc clp$get_value
*copyc clp$include_line
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc clp$scan_parameter_list
*copyc clp$trimmed_string_size
*copyc fsp$close_file
*copyc fsp$open_file
*copyc ofp$get_active_operator_alarms
*copyc ofp$get_first_operator_menu
*copyc ofp$get_menu_help_text
*copyc ofp$get_next_operator_menu
*copyc ofp$store_menu_choice
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc pmp$long_term_wait

?? TITLE := 'ofp$display_active_capabilities', EJECT ??

  PROCEDURE [XDCL, #GATE] ofp$display_active_capabilities
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE (osm$sysou_disac) display_active_capabilities (
{   output, o: file = $output
{   status)

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 3] of clt$pdt_parameter_name,
        parameters: array [1 .. 2] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          default_value: string (7),
        recend,
        type2: record
          header: clt$type_specification_header,
        recend,
      recend := [[1, [88, 7, 5, 12, 22, 6, 856], clc$command, 3, 2, 0, 0, 0, 0, 2, 'OSM$DISAC'],
            [['O                              ', clc$abbreviation_entry, 1],
            ['OUTPUT                         ', clc$nominal_entry, 1],
            ['STATUS                         ', clc$nominal_entry, 2]], [

{ PARAMETER 1

      [2, clc$normal_usage_entry, clc$non_secure_parameter, $clt$parameter_spec_methods
            [clc$specify_by_name, clc$specify_positionally], clc$pass_by_value, clc$immediate_evaluation,
            clc$standard_parameter_checking, 3, clc$optional_default_parameter, 0, 7],

{ PARAMETER 2

      [3, clc$normal_usage_entry, clc$non_secure_parameter, $clt$parameter_spec_methods [clc$specify_by_name],
            clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
            clc$optional_parameter, 0, 0]],

{ PARAMETER 1

      [[1, 0, clc$file_type], '$output'],

{ PARAMETER 2

      [[1, 0, clc$status_type]]];

?? POP ??

    CONST
      p$output = 1,
      p$status = 2;

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

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

{ PURPOSE:
{   The purpose of this command is to display a list of the capabilities that
{   are currently active within the System Operator Utility.
{

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

      IF output_open THEN
        clp$close_display (display_control, handler_status);
        output_open := FALSE;
      IFEND;
      handler_status.normal := TRUE;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    CONST
      blank_line = ' ',
      title_line = 'The following SOU capabilities are currently active:';

    VAR
      capability_active: boolean,
      default_ring_attributes: amt$ring_attributes,
      display_control: clt$display_control,
      local_status: ost$status,
      output: fst$parsed_file_reference,
      output_open: boolean;

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

    IF pvt [p$output].specified THEN
      clp$convert_string_to_file_ref (pvt [p$output].value^.file_value^, output, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    ELSE
      output.path := clc$standard_output;
    IFEND;

    output_open := FALSE;
    osp$establish_block_exit_hndlr (^abort_handler);
    default_ring_attributes.r1 := #RING (^default_ring_attributes);
    default_ring_attributes.r2 := #RING (^default_ring_attributes);
    default_ring_attributes.r3 := #RING (^default_ring_attributes);
    clp$open_display_reference (output.path, NIL, fsc$list, default_ring_attributes, display_control,
          status);
    IF NOT status.normal THEN
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

    output_open := TRUE;

  /display_capabilities/
    BEGIN
      clp$put_display (display_control, blank_line, clc$trim, status);
      IF NOT status.normal THEN
        EXIT /display_capabilities/;
      IFEND;

      clp$put_display (display_control, title_line, clc$trim, status);
      IF NOT status.normal THEN
        EXIT /display_capabilities/;
      IFEND;

      clp$put_display (display_control, blank_line, clc$trim, status);
      IF NOT status.normal THEN
        EXIT /display_capabilities/;
      IFEND;

      capability_active := FALSE;

      IF avp$accounting_administrator () THEN
        clp$put_display (display_control, '    accounting_administration', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF avp$configuration_administrator () THEN
        clp$put_display (display_control, '    configuration_administration', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF avp$family_administrator () THEN
        clp$put_display (display_control, '    family_administration', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF avp$removable_media_admin () THEN
        clp$put_display (display_control, '    removable_media_administration', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF avp$removable_media_operator () THEN
        clp$put_display (display_control, '    removable_media_operation', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF avp$system_administrator () THEN
        clp$put_display (display_control, '    system_administration', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF avp$system_displays () THEN
        clp$put_display (display_control, '    system_displays', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF avp$system_operator () THEN
        clp$put_display (display_control, '    system_operation', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;

        capability_active := TRUE;
      IFEND;

      IF NOT capability_active THEN
        clp$put_display (display_control, '    *** NONE ***', clc$trim, status);
        IF NOT status.normal THEN
          EXIT /display_capabilities/;
        IFEND;
      IFEND;

      clp$put_display (display_control, blank_line, clc$trim, status);
      IF NOT status.normal THEN
        EXIT /display_capabilities/;
      IFEND;

    END /display_capabilities/;

    clp$close_display (display_control, local_status);
    output_open := FALSE;
    IF status.normal AND (NOT local_status.normal) THEN
      status := local_status;
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND ofp$display_active_capabilities;

?? TITLE := 'ofp$display_operator_menus_cmd', EJECT ??

{ PURPOSE:
{   The purpose of this command is to display entries in the list of operator
{   action menus and to store an operator's choice from a menu.
{

  PROCEDURE [XDCL, #GATE] ofp$display_operator_menus_cmd
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE (osm$disoam) display_operator_action_menus, disoam (
{   STATUS)

?? PUSH (LISTEXT := ON) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [88, 8, 15, 9, 40, 37, 856],
    clc$command, 1, 1, 0, 0, 0, 0, 1, 'OSM$DISOAM'], [
    ['STATUS                         ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, 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$status_type]]];

?? POP ??

  CONST
    p$status = 1;

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

    CONST
      title_line_size = 36;

    VAR
      blank_line: [READ, oss$job_paged_literal] string (2) := '  ',
      choice: clt$lexical_token,
      condition_cleared_message: [READ, oss$job_paged_literal] string (71) :=
            ' --INFORMATIVE-- The condition described by this menu no longer exists.',
      error_line_p: ^string ( * <= 80),
      file_position: amt$file_position,
      help_text_found: boolean,
      help_text_line_count: oft$number_of_displayable_lines,
      help_text_p: ^oft$menu_selections,
      iba: amt$file_byte_address,
      ignore_status: ost$status,
      index: clt$string_index,
      input: amt$file_identifier,
      invalid_input_message: [READ, oss$job_paged_literal] string (66) :=
            ' --ERROR-- You must enter +, QUIT, or the number of a menu choice.',
      menu_current: oft$menu_id,
      menu_descriptor: oft$operator_menu_descriptor,
      menu_line: 1 .. ofc$max_menu_lines,
      oba: amt$file_byte_address,
      one_menu_available_message: [READ, oss$job_paged_literal] string (64) :=
            ' --INFORMATIVE-- Only the current menu is available for display.',
      output: amt$file_identifier,
      press_return_line_advance: [READ, oss$job_paged_literal] string (42) :=
            ' Press RETURN to advance to the next menu.',
      press_return_line_continue: [READ, oss$job_paged_literal] string (37) :=
            ' Press RETURN when ready to continue.',
      prompt_line1: [READ, oss$job_paged_literal] string (64) :=
            ' Enter the number of your choice, + to advance, or QUIT to exit.',
      prompt_line2: [READ, oss$job_paged_literal] string (61) :=
            ' For help, enter ? or n? (where n is the number of a choice).',
      reply: string (80),
      response_string: ost$string,
      spaces_preceded_token: boolean,

{ If the size of the title is changed, the size of the title_line variable should also
{ be changed. The proper relationship is calculated as follows:
{
{            SIZE of title_line = SIZE of title + 1 + jmc$system_supplied_name_size

      title: [READ, oss$job_paged_literal] string (36) := '1NOS/VE Operator Action Menu for job',
      title_line: string (title_line_size + 1 + jmc$system_supplied_name_size),
      transfer_count: amt$transfer_count;

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

    ofp$get_first_operator_menu (menu_descriptor, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    fsp$open_file (clc$standard_output, amc$record, NIL, NIL, NIL, NIL, NIL, output, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    fsp$open_file (clc$standard_input, amc$record, NIL, NIL, NIL, NIL, NIL, input, status);
    IF NOT status.normal THEN
      fsp$close_file (output, ignore_status);
      RETURN;
    IFEND;

    error_line_p := NIL;

{ The following loop is the main processing code for operator interaction with
{ the menu list. The code allows the operator to advance in a circular manner
{ through the list of menus. The normal exit from the loop occurs as  soon as the
{ operator makes a valid choice for one of the menus or when the operator types
{ the word QUIT.

  /display/
    WHILE TRUE DO
      IF error_line_p <> NIL THEN
        amp$put_next (output, error_line_p, #SIZE (error_line_p^), oba, status);
        IF NOT status.normal THEN
          EXIT /display/;
        IFEND;

        IF error_line_p <> ^condition_cleared_message THEN
          amp$put_next (output, ^press_return_line_continue, #SIZE (press_return_line_continue),
                oba, status);
          IF NOT status.normal THEN
            EXIT /display/;
          IFEND;

        ELSE
          amp$put_next (output, ^press_return_line_advance, #SIZE (press_return_line_advance),
                oba, status);
          IF NOT status.normal THEN
            EXIT /display/;
          IFEND;
        IFEND;

        amp$get_next (input, ^reply, #SIZE (reply), transfer_count, iba, file_position, status);
        IF NOT status.normal THEN
          EXIT /display/;
        IFEND;

        IF error_line_p = ^condition_cleared_message THEN
          menu_current := menu_descriptor.menu_id;
          ofp$get_next_operator_menu (menu_current, menu_descriptor, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

        error_line_p := NIL;
      IFEND;

      title_line (1, #SIZE (title) + 1) := title;
      title_line (#SIZE (title) + 2, jmc$system_supplied_name_size) := menu_descriptor.job_name;
      amp$put_next (output, ^title_line, #SIZE (title_line), oba, status);
      IF NOT status.normal THEN
        EXIT /display/;
      IFEND;

      amp$put_next (output, ^blank_line, #SIZE (blank_line), oba, status);
      IF NOT status.normal THEN
        EXIT /display/;
      IFEND;

      FOR menu_line := 1 TO menu_descriptor.number_of_displayable_lines DO
        amp$put_next (output, ^menu_descriptor.menu_text [menu_line],
              #SIZE (menu_descriptor.menu_text [menu_line]), oba, status);
        IF NOT status.normal THEN
          EXIT /display/;
        IFEND;
      FOREND;

      amp$put_next (output, ^blank_line, #SIZE (blank_line), oba, status);
      IF NOT status.normal THEN
        EXIT /display/;
      IFEND;

      amp$put_next (output, ^prompt_line1, #SIZE (prompt_line1), oba, status);
      IF NOT status.normal THEN
        EXIT /display/;
      IFEND;

      amp$put_next (output, ^prompt_line2, #SIZE (prompt_line2), oba, status);
      IF NOT status.normal THEN
        EXIT /display/;
      IFEND;

      reply := ' ';
      amp$get_next (input, ^reply, #SIZE (reply), transfer_count, iba, file_position, status);
      IF NOT status.normal THEN
        EXIT /display/;
      IFEND;

      IF transfer_count = 0 THEN
        error_line_p := ^invalid_input_message;
        CYCLE /display/;
      IFEND;

      index := 1;
      clp$evaluate_token (reply, $clt$token_evaluation_options [], index, spaces_preceded_token, choice,
            status);
      IF NOT (status.normal AND (choice.text_size > 0)) THEN
        error_line_p := ^invalid_input_message;
        status.normal := TRUE;
        CYCLE /display/;
      IFEND;

      IF (choice.kind = clc$name_token) THEN
        IF (choice.str.value = 'QUIT') OR (choice.str.value = 'QUI') THEN
          EXIT /display/;
        ELSE
          error_line_p := ^invalid_input_message;
        IFEND;
      ELSEIF (choice.kind = clc$add_token) THEN
        menu_current := menu_descriptor.menu_id;
        ofp$get_next_operator_menu (menu_current, menu_descriptor, status);
        IF NOT status.normal THEN
          IF status.condition = ofe$one_menu_available THEN
            error_line_p := ^one_menu_available_message;
            status.normal := TRUE;
            CYCLE /display/;
          IFEND;
          EXIT /display/;
        IFEND;
      ELSE
        IF (choice.kind = clc$query_token) THEN
          response_string.size := 1;
          response_string.value (1, 1) := '?';
          choice.int.value := ofc$max_menu_lines;
        ELSEIF (choice.kind = clc$unsigned_integer_token) AND (choice.int.value > 0) AND
              (choice.int.value <= menu_descriptor.number_of_choices) THEN
          response_string.size := clp$trimmed_string_size (reply (index, 81 - index));
          IF response_string.size > 0 THEN
            response_string.value (1, response_string.size) := reply (index, response_string.size);
          ELSE
            response_string.value := '';
          IFEND;
        ELSE
          error_line_p := ^invalid_input_message;
          CYCLE /display/;
        IFEND;

{ The operator has made a valid choice from the menu. Store the choice in the
{ menu descriptor.

        ofp$store_menu_choice (menu_descriptor.menu_id, choice.int.value, response_string, status);
        IF NOT status.normal THEN
          IF status.condition = ofe$invalid_menu_id THEN
            error_line_p := ^condition_cleared_message;
            status.normal := TRUE;
            CYCLE /display/;
          IFEND;
          EXIT /display/;
        IFEND;

        IF response_string.value (1, 1) = '?' THEN
          PUSH help_text_p;
          REPEAT
            pmp$long_term_wait (500, 200);
            ofp$get_menu_help_text (menu_descriptor.menu_id, menu_descriptor.source_task, help_text_p,
                  help_text_found, help_text_line_count, status);
            IF NOT status.normal THEN
              IF status.condition = ofe$invalid_menu_id THEN
                error_line_p := ^condition_cleared_message;
                status.normal := TRUE;
                CYCLE /display/;
              IFEND;
              EXIT /display/;
            IFEND;
          UNTIL help_text_found;
          FOR menu_line := 1 TO help_text_line_count DO
            amp$put_next (output, ^help_text_p^ [menu_line], #SIZE (help_text_p^ [menu_line]), oba, status);
            IF NOT status.normal THEN
              EXIT /display/;
            IFEND;
          FOREND;
          amp$put_next (output, ^press_return_line_continue, #SIZE (press_return_line_continue),
                oba, status);
          IF NOT status.normal THEN
            EXIT /display/;
          IFEND;
          amp$get_next (input, ^reply, #SIZE (reply), transfer_count, iba, file_position, status);
          IF NOT status.normal THEN
            EXIT /display/;
          IFEND;

        ELSE
          ofp$get_next_operator_menu (menu_descriptor.menu_id, menu_descriptor, status);
          IF NOT status.normal THEN
            IF status.condition = ofe$no_menus_available THEN
              status.normal := TRUE;
            IFEND;
            EXIT /display/;
          IFEND;
        IFEND;
      IFEND;

    WHILEND /display/;

    fsp$close_file (output, ignore_status);
    fsp$close_file (input, ignore_status);

  PROCEND ofp$display_operator_menus_cmd;

?? TITLE := 'ofp$display_operator_status_cmd', EJECT ??

{ PURPOSE:
{   The purpose of this command is to inform the operator of any
{   existing conditions which require operator action.

  PROCEDURE [XDCL, #GATE] ofp$display_operator_status_cmd
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{  PROCEDURE (osm$disoas) display_operator_action_status, disoas (
{    wait, w : boolean = FALSE
{    status)

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

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 3] of clt$pdt_parameter_name,
      parameters: array [1 .. 2] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        default_value: string (5),
      recend,
      type2: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [89, 7, 11, 15, 34, 53, 847],
    clc$command, 3, 2, 0, 0, 0, 0, 2, 'OSM$DISOAS'], [
    ['STATUS                         ',clc$nominal_entry, 2],
    ['W                              ',clc$abbreviation_entry, 1],
    ['WAIT                           ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [3, 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 2
    [1, 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$boolean_type],
    'FALSE'],
{ PARAMETER 2
    [[1, 0, clc$status_type]]];

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

    CONST
      p$wait = 1,
      p$status = 2;

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

    VAR
      active_operator_alarms: oft$operator_alarms,
      blank_line: [READ, oss$job_paged_literal] string (2) := '  ',
      choice: string (80),
      choice_m: [READ, oss$job_paged_literal] string (35) := '      - M to process operator menus',
      choice_o: [READ, oss$job_paged_literal] string (38) := '      - O to process operator messages',
      choice_quit: [READ, oss$job_paged_literal] string (52) :=
            '      - QUIT to terminate operator action processing',
      choice_t: [READ, oss$job_paged_literal] string (40) := '      - T to process tape mount requests',
      choice_token: clt$lexical_token,
      display_op_action_menus_command: [READ, oss$job_paged_literal] string (29) :=
            'display_operator_action_menus',
      error_line_p: ^string ( * <= 80),
      file_position: amt$file_position,
      iba: amt$file_byte_address,
      ignore_status: ost$status,
      index: clt$string_index,
      input: amt$file_identifier,
      invalid_choice: [READ, oss$job_paged_literal] string (38) := ' --ERROR-- An invalid choice was made.',
      multiple_alarm_choice_header: [READ, oss$job_paged_literal] string (35) :=
            ' Please enter one of the following:',
      multiple_alarm_header: [READ, oss$job_paged_literal] string (43) :=
            '1Multiple operator action conditions exist.',
      oba: amt$file_byte_address,
      output: amt$file_identifier,
      press_return_line: [READ, oss$job_paged_literal] string (37) := ' Press RETURN when ready to continue.',
      spaces_preceeded_token: boolean,
      transfer_count: amt$transfer_count,
      vedisplay_om_command: [READ, oss$job_paged_literal] string (29) := 'vedisplay do=operator_message',
      vedisplay_tm_command: [READ, oss$job_paged_literal] string (23) := 'vedisplay do=tape_mount';

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

{ If the operator specified WAIT = TRUE, then the following loop will wait
{ until an alarm condition becomes active. Though the caller may terminate
{ the command in order to perform other tasks, the WAIT option is primarily
{ intended for remote operators (i.e. not the operator at the main console)
{ who intend to use their terminal strictly to process alarm conditions.

    REPEAT
      ofp$get_active_operator_alarms (active_operator_alarms);
      IF (active_operator_alarms = $oft$operator_alarms []) THEN
        IF NOT pvt [p$wait].value^.boolean_value.value THEN
          osp$set_status_abnormal (ofc$operator_facility_id, ofe$no_alarms_active, ' ', status);
          RETURN;
        ELSE
          pmp$long_term_wait (10000, 10000);
        IFEND;
      IFEND;
    UNTIL active_operator_alarms <> $oft$operator_alarms [];

    IF active_operator_alarms = $oft$operator_alarms [ofc$tape_mounts] THEN
      clp$include_line (vedisplay_tm_command, TRUE, osc$null_name, status);
      RETURN;
    ELSEIF active_operator_alarms = $oft$operator_alarms [ofc$menu_requests] THEN
      clp$include_line (display_op_action_menus_command, TRUE, osc$null_name, status);
      RETURN;
    ELSEIF active_operator_alarms = $oft$operator_alarms [ofc$operator_messages] THEN
      clp$include_line (vedisplay_om_command, TRUE, osc$null_name, status);
      RETURN;
    IFEND;

{ Multiple alarm conditions exist. Give the operator the opportunity to select the
{ condition to be processed.

    fsp$open_file (clc$standard_output, amc$record, NIL, NIL, NIL, NIL, NIL, output, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    fsp$open_file (clc$standard_input, amc$record, NIL, NIL, NIL, NIL, NIL, input, status);
    IF NOT status.normal THEN
      fsp$close_file (output, ignore_status);
      RETURN;
    IFEND;

    error_line_p := NIL;

  /process_alarms/
    WHILE TRUE DO
      IF error_line_p <> NIL THEN
        amp$put_next (output, error_line_p, #SIZE (error_line_p^), oba, status);
        IF NOT status.normal THEN
          EXIT /process_alarms/;
        IFEND;

        error_line_p := NIL;
        amp$put_next (output, ^press_return_line, #SIZE (press_return_line), oba, status);
        IF NOT status.normal THEN
          EXIT /process_alarms/;
        IFEND;

        amp$get_next (input, ^choice, #SIZE (choice), transfer_count, iba, file_position, status);
        IF NOT status.normal THEN
          EXIT /process_alarms/;
        IFEND;
      IFEND;

      amp$put_next (output, ^multiple_alarm_header, #SIZE (multiple_alarm_header), oba, status);
      IF NOT status.normal THEN
        EXIT /process_alarms/;
      IFEND;

      amp$put_next (output, ^multiple_alarm_choice_header, #SIZE (multiple_alarm_choice_header), oba, status);
      IF NOT status.normal THEN
        EXIT /process_alarms/;
      IFEND;

      amp$put_next (output, ^blank_line, #SIZE (blank_line), oba, status);
      IF NOT status.normal THEN
        EXIT /process_alarms/;
      IFEND;

      IF ofc$menu_requests IN active_operator_alarms THEN
        amp$put_next (output, ^choice_m, #SIZE (choice_m), oba, status);
        IF NOT status.normal THEN
          EXIT /process_alarms/;
        IFEND;
      IFEND;

      IF ofc$operator_messages IN active_operator_alarms THEN
        amp$put_next (output, ^choice_o, #SIZE (choice_o), oba, status);
        IF NOT status.normal THEN
          EXIT /process_alarms/;
        IFEND;
      IFEND;

      IF ofc$tape_mounts IN active_operator_alarms THEN
        amp$put_next (output, ^choice_t, #SIZE (choice_t), oba, status);
        IF NOT status.normal THEN
          EXIT /process_alarms/;
        IFEND;
      IFEND;

      amp$put_next (output, ^blank_line, #SIZE (blank_line), oba, status);
      IF NOT status.normal THEN
        EXIT /process_alarms/;
      IFEND;

      amp$put_next (output, ^choice_quit, #SIZE (choice_quit), oba, status);
      IF NOT status.normal THEN
        EXIT /process_alarms/;
      IFEND;

      choice := ' ';
      amp$get_next (input, ^choice, #SIZE (choice), transfer_count, iba, file_position, status);
      IF NOT status.normal THEN
        EXIT /process_alarms/;
      IFEND;

      index := 1;
      clp$evaluate_token (choice, $clt$token_evaluation_options [], index, spaces_preceeded_token,
            choice_token, status);
      IF ((NOT status.normal) AND (choice_token.text_size > 0)) OR (NOT (choice_token.kind = clc$name_token))
            THEN
        error_line_p := ^invalid_choice;
        CYCLE /process_alarms/;
      IFEND;

      IF (choice_token.str.value = 'QUIT') OR (choice_token.str.value = 'QUI') THEN
        EXIT /process_alarms/;
      IFEND;

      IF ((choice_token.str.value = 'M') AND (ofc$menu_requests IN active_operator_alarms)) THEN
        clp$include_line (display_op_action_menus_command, TRUE, osc$null_name, status);
        EXIT /process_alarms/;
      ELSEIF ((choice_token.str.value = 'O') AND (ofc$operator_messages IN active_operator_alarms)) THEN
        clp$include_line (vedisplay_om_command, TRUE, osc$null_name, status);
        EXIT /process_alarms/;
      ELSEIF ((choice_token.str.value = 'T') AND (ofc$tape_mounts IN active_operator_alarms)) THEN
        clp$include_line (vedisplay_tm_command, TRUE, osc$null_name, status);
        EXIT /process_alarms/;
      ELSE
        error_line_p := ^invalid_choice;
      IFEND;
    WHILEND /process_alarms/;

    fsp$close_file (output, ignore_status);
    fsp$close_file (input, ignore_status);

  PROCEND ofp$display_operator_status_cmd;
MODEND ofm$system_operator_utility_2dd;
