?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Operator Facility : Operator Message Management' ??
MODULE ofm$job_message_routines;

{
{  This module is placed on the following libraries
{   OSF$JOB_TEMPLATE_23D

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ife$error_codes
*copyc jmt$system_supplied_name
*copyc ofc$signal_contents
*copyc ofd$type_definition
*copyc ofe$error_codes
*copyc oft$operator_classes
*copyc oft$operator_message
*copyc oft$display_message_info
*copyc ost$system_flag
*copyc ost$wait
*copyc tmc$signal_identifiers
?? POP ??
*copyc clp$find_current_job_synch_task
*copyc ofp$acknowledge_operator_msg_r1
*copyc ofp$get_active_operator_classes
*copyc ofp$clear_operator_message_r1
*copyc ofp$display_status_msg_helper
*copyc ofp$enable_stop_key_help
*copyc ofp$get_display_message_helper
*copyc ofp$receive_operator_resp_r1
*copyc ofp$send_operator_message_r1
*copyc ofp$task_end_helper
*copyc osp$copy_local_status_to_status
*copyc osp$set_status_abnormal
*copyc pmp$dispose_interactive_cond
*copyc pmp$establish_condition_handler
*copyc pmp$get_global_task_id
*copyc pmp$log_ascii
*copyc pmp$send_signal
?? OLDTITLE ??
?? NEWTITLE := 'ofp$acknowledge_operator_msg', EJECT ??

*copyc ofh$acknowledge_operator_msg

  PROCEDURE [XDCL, #GATE] ofp$acknowledge_operator_msg
    (    message_id: oft$operator_message_id;
         response: ost$string;
     VAR status: ost$status);

    VAR
      active_operator_classes: oft$operator_classes,
      local_status: ost$status,
      parameter_error_string: string (16),
      parameter_error_string_length: integer;

    status.normal := TRUE;
    IF (response.size > osc$max_string_size) THEN
      STRINGREP (parameter_error_string, parameter_error_string_length, osc$max_string_size);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$response_too_long,
            parameter_error_string (1, parameter_error_string_length), status);
    ELSEIF (message_id > ofc$max_message_ordinal) THEN
      STRINGREP (parameter_error_string, parameter_error_string_length, ofc$max_message_ordinal);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$invalid_message_id,
            parameter_error_string (1, parameter_error_string_length), status);
    ELSE
      ofp$get_active_operator_classes (active_operator_classes);
      ofp$acknowledge_operator_msg_r1 (message_id, active_operator_classes, response, local_status);
      osp$copy_local_status_to_status (local_status, status);
    IFEND;
  PROCEND ofp$acknowledge_operator_msg;

?? OLDTITLE ??
?? NEWTITLE := 'ofp$clear_operator_message', EJECT ??

*copyc ofh$clear_operator_message

  PROCEDURE [XDCL, #GATE] ofp$clear_operator_message
    (    operator_class: oft$operator_class;
     VAR status: ost$status);

    VAR
      invalid_class_string: string (16),
      invalid_class_string_size: integer,
      local_status: ost$status;

    status.normal := TRUE;
    IF NOT ((operator_class >= 0) AND (operator_class <= ofc$max_valid_operator_class)) THEN
      STRINGREP (invalid_class_string, invalid_class_string_size, ofc$max_valid_operator_class);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$invalid_operator_class,
            invalid_class_string (1, invalid_class_string_size), status);
    ELSE
      ofp$clear_operator_message_r1 (operator_class, local_status);
      osp$copy_local_status_to_status (local_status, status);
    IFEND;

  PROCEND ofp$clear_operator_message;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$display_status_message', EJECT ??
*copyc ofh$display_status_message

  PROCEDURE [XDCL, #GATE] ofp$display_status_message
    (    display_message: string ( * );
     VAR status: ost$status);

    VAR
      local_message_p: ^string ( * ),
      local_status: ost$status;

    status.normal := TRUE;
    local_status.normal := TRUE;

    PUSH local_message_p: [#SIZE (display_message)];
    local_message_p^ := display_message;

    ofp$display_status_msg_helper (local_message_p^, local_status);
    osp$copy_local_status_to_status (local_status, status);

  PROCEND ofp$display_status_message;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$enable_stop_key', EJECT ??

  PROCEDURE [XDCL, #GATE] ofp$enable_stop_key;

    ofp$enable_stop_key_help;

  PROCEND ofp$enable_stop_key;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$get_display_status_message', EJECT ??
*copyc ofh$get_display_status_message

  PROCEDURE [XDCL, #GATE] ofp$get_display_status_message
    (    job_seq_number: jmt$system_supplied_name;
     VAR display_message: oft$display_message;
     VAR status: ost$status);

    status.normal := TRUE;
    ofp$get_display_message_helper (job_seq_number, display_message, status);

  PROCEND ofp$get_display_status_message;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$handle_operator_break_flag', EJECT ??

  PROCEDURE [XDCL] ofp$handle_operator_break_flag
    (    flag_id: ost$system_flag);

    VAR
      tid: pmt$task_id,
      gid: ost$global_task_id,
      signal: pmt$signal,
      status: ost$status;

    clp$find_current_job_synch_task (tid, status);
    IF status.normal THEN
      pmp$get_global_task_id (tid, gid, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      signal.identifier := ofc$signal;
      signal.contents [1] := ofc$break_id;
      pmp$send_signal (gid, signal, status);
    IFEND;

  PROCEND ofp$handle_operator_break_flag;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$handle_signal_processor', EJECT ??

  PROCEDURE [XDCL] ofp$handle_signal_processor
    (    originator: ost$global_task_id;
         signal: pmt$signal);

    IF signal.contents [1] = ofc$break_id THEN
      pmp$dispose_interactive_cond (ifc$pause_break);
    IFEND;

  PROCEND ofp$handle_signal_processor;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$receive_operator_resp_r3', EJECT ??

*copyc ofh$receive_operator_resp_r3

  PROCEDURE [XDCL, #GATE] ofp$receive_operator_resp_r3
    (    operator_class: oft$operator_class;
     VAR response: ost$string;
     VAR status: ost$status);

    VAR
      invalid_class_string: string (16),
      invalid_class_string_size: integer,
      local_response: ost$string,
      local_status: ost$status;

    status.normal := TRUE;
    IF (operator_class >= 0) AND (operator_class <= ofc$max_valid_operator_class) THEN
      ofp$receive_operator_resp_r1 (operator_class, local_response, local_status);
      response := local_response;
      osp$copy_local_status_to_status (local_status, status);
    ELSE
      STRINGREP (invalid_class_string, invalid_class_string_size, ofc$max_valid_operator_class);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$invalid_operator_class,
            invalid_class_string (1, invalid_class_string_size), status);
    IFEND;

  PROCEND ofp$receive_operator_resp_r3;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$send_formatted_operator_msg', EJECT ??

*copyc ofh$send_formatted_operator_msg

  PROCEDURE [XDCL, #GATE] ofp$send_formatted_operator_msg
    (    formatted_message: oft$formatted_operator_message;
         operator_class: oft$operator_class;
         acknowledgement_allowed: boolean;
     VAR status: ost$status);

    VAR
      ignore_status: ost$status,
      index: oft$number_of_displayable_lines,
      local_status: ost$status,
      message_error_string: string (16),
      message_error_string_length: integer,
      number_of_message_lines: oft$number_of_displayable_lines;

    status.normal := TRUE;
    IF NOT ((operator_class >= 0 ) AND (operator_class <= ofc$max_valid_operator_class)) THEN
      STRINGREP (message_error_string, message_error_string_length, ofc$max_valid_operator_class);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$invalid_operator_class,
            message_error_string (1, message_error_string_length), status);
      RETURN;
    IFEND;

    number_of_message_lines := 1;

   /search_for_end_of_lines/
    FOR index := UPPERBOUND (formatted_message) DOWNTO LOWERBOUND (formatted_message) DO
      IF formatted_message [index] <> ' ' THEN
        number_of_message_lines := index;
        EXIT /search_for_end_of_lines/;
      IFEND;
    FOREND /search_for_end_of_lines/;

    ofp$send_operator_message_r1 (formatted_message, number_of_message_lines, operator_class,
          acknowledgement_allowed, FALSE, local_status);
    osp$copy_local_status_to_status (local_status, status);
    IF status.normal THEN
      IF acknowledgement_allowed THEN
        pmp$log_ascii (' Message Sent to Operator - Acknowledgement Allowed:',
          $pmt$ascii_logset [pmc$system_log],  pmc$msg_origin_program, ignore_status);
      ELSE
        pmp$log_ascii (' Message Sent to Operator - Acknowledgement Not Allowed:',
          $pmt$ascii_logset [pmc$system_log],  pmc$msg_origin_program, ignore_status);
      IFEND;
      FOR index := LOWERBOUND (formatted_message) TO number_of_message_lines DO
        pmp$log_ascii (formatted_message [index], $pmt$ascii_logset [pmc$system_log], pmc$msg_origin_program,
          ignore_status);
      FOREND;
    IFEND;

  PROCEND ofp$send_formatted_operator_msg;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$send_operator_message_v1', EJECT ??

  PROCEDURE [XDCL, #GATE] ofp$send_operator_message_v1
    (    message: oft$operator_message;
         operator_class: oft$operator_class;
         acknowledgement_allowed: boolean;
         clear_message_when_acknowledged: boolean;
     VAR status: ost$status);

    VAR
      ch: string(1),
      formatted_message: oft$formatted_operator_message,
      fragment_length: integer,
      fragment_start: integer,
      ignore_status: ost$status,
      index: integer,
      line_number: oft$number_of_displayable_lines,
      local_status: ost$status,
      message_error_string: string (16),
      message_error_string_length: integer,
      message_size: integer;

    status.normal := TRUE;
    IF #SIZE (message) > ofc$max_operator_message_size THEN
      STRINGREP (message_error_string, message_error_string_length, ofc$max_operator_message_size);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$message_too_long,
            message_error_string (1, message_error_string_length), status);
      RETURN;
    IFEND;

    IF NOT ((operator_class >= 0 ) AND (operator_class <= ofc$max_valid_operator_class)) THEN
      STRINGREP (message_error_string, message_error_string_length, ofc$max_valid_operator_class);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$invalid_operator_class,
            message_error_string (1, message_error_string_length), status);
      RETURN;
    IFEND;

    { Output message line(s).  The message will be broken into fragments of at most
    { 72 characters.  Each fragment will be broken at a separator character if such
    { a character appears in the last 31 characters of the fragment.  Otherwise,
    { the fragment will be broken on the 72nd character.

    line_number := 1;
    message_size := #SIZE(message);
    fragment_start := 1;
    REPEAT
      fragment_length := 72;
      IF (fragment_length + fragment_start) > message_size THEN
        fragment_length := message_size - fragment_start + 1;
      ELSEIF message(fragment_start+fragment_length,1) = ' ' THEN
        fragment_length := fragment_length + 1;
      ELSE

        { Search for a separator character in last 31 columns.

       /find_separator/
        FOR index := fragment_length DOWNTO fragment_length-31 DO
          ch := message(fragment_start+index-1,1);
          IF (ch = ' ') OR (ch = '_') OR (ch = '.') OR (ch = '-') THEN
            fragment_length := index;
            EXIT /find_separator/;
          IFEND;
        FOREND /find_separator/;
      IFEND;

      formatted_message [line_number] (1, 4) := ' ';
      formatted_message [line_number] (5, *) := message (fragment_start, fragment_length);
      line_number := line_number + 1;
      fragment_start := fragment_start + fragment_length;
    UNTIL fragment_start >= message_size;

    FOR index := line_number to UPPERBOUND(formatted_message) DO
      formatted_message[index] := ' ';
    FOREND;

    ofp$send_operator_message_r1 (formatted_message, (line_number - 1), operator_class,
          acknowledgement_allowed, clear_message_when_acknowledged, local_status);
    IF local_status.normal THEN
      IF acknowledgement_allowed THEN
        pmp$log_ascii (' Message Sent to Operator - Acknowledgement Allowed:',
              $pmt$ascii_logset [pmc$system_log],  pmc$msg_origin_program, ignore_status);
      ELSE
        pmp$log_ascii (' Message Sent to Operator - Acknowledgement Not Allowed:',
              $pmt$ascii_logset [pmc$system_log],  pmc$msg_origin_program, ignore_status);
      IFEND;
      FOR index := 1 TO (line_number - 1) DO
        pmp$log_ascii (formatted_message [index], $pmt$ascii_logset [pmc$system_log], pmc$msg_origin_program,
              ignore_status);
      FOREND;
    IFEND;
    osp$copy_local_status_to_status (local_status, status);


  PROCEND ;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$send_operator_message', EJECT ??

*copyc ofh$send_operator_message

  PROCEDURE [XDCL, #GATE] ofp$send_operator_message
    (    message: oft$operator_message;
         operator_class: oft$operator_class;
         acknowledgement_allowed: boolean;
     VAR status: ost$status);

ofp$send_operator_message_v1 (message, operator_class, acknowledgement_allowed, false, status);

  PROCEND ofp$send_operator_message;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$send_to_operator', EJECT ??
*copyc ofh$send_to_operator

  PROCEDURE [XDCL, #GATE] ofp$send_to_operator
    (    send_message_text: string ( * );
         operator_id: oft$operator_id;
     VAR status: ost$status);

    VAR
      message_error_string: string (16),
      message_error_string_length: integer,
      message_length: integer;

    status.normal := TRUE;
    message_length := #SIZE (send_message_text);
    IF message_length > ofc$max_send_message THEN
      ofp$send_operator_message (send_message_text (1, ofc$max_send_message), ofc$system_operator,
            TRUE, status);
    ELSE
      ofp$send_operator_message (send_message_text (1, message_length), ofc$system_operator, TRUE, status);
    IFEND;

    IF status.normal AND (message_length > ofc$max_send_message) THEN
      STRINGREP (message_error_string, message_error_string_length, ofc$max_send_message);
      osp$set_status_abnormal (ofc$operator_facility_id, ofe$message_too_long,
            message_error_string (1, message_error_string_length), status);
      RETURN;
    IFEND;

{  If an attempt was made to send too many messages from this job, then change
{  the error code returned from ring 3 so that this procedure remains compatible
{  with its functionality prior to implementation of the Remote Operator feature.

    IF NOT status.normal THEN
      IF status.condition = ofe$max_job_operator_messages THEN
        osp$set_status_abnormal (ofc$operator_facility_id, ofe$max_job_operator_actions, ' ', status);
      ELSEIF status.condition = ofe$message_outstanding THEN
        osp$set_status_abnormal (ofc$operator_facility_id, ofe$previous_msg_not_cleared, ' ', status);
      IFEND;
    IFEND;

  PROCEND ofp$send_to_operator;
?? OLDTITLE ??
?? NEWTITLE := 'ofp$task_end', EJECT ??
*copyc ofh$task_end

  PROCEDURE [XDCL] ofp$task_end;

    ofp$task_end_helper;

  PROCEND ofp$task_end;
MODEND ofm$job_message_routines;
