?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Job Management: Handle Conditions' ??
MODULE jmm$handle_conditions;

?? NEWTITLE := '  Global Declarations Referenced by this Module', EJECT ??
?? PUSH (LISTEXT := ON) ??

*copyc jme$job_management_conditions
*copyc jmd$job_resource_condition
*copyc ost$status
*copyc oss$job_paged_literal
*copyc pmt$condition

?? POP ??

*copyc amp$get_next
*copyc clp$convert_integer_to_string
*copyc clp$convert_string_to_integer
*copyc clp$put_job_output
*copyc clp$trimmed_string_size
*copyc fsp$close_file
*copyc fsp$open_file
*copyc jmp$logout
*copyc jmp$set_job_resource_condition
*copyc jmv$job_resource_condition
*copyc osp$append_status_integer
*copyc osp$append_status_parameter
*copyc osp$generate_log_message
*copyc osp$generate_output_message
*copyc osp$set_status_abnormal
*copyc osv$lower_to_upper
*copyc pmp$continue_to_cause
*copyc pmp$disestablish_cond_handler
*copyc pmp$dispose_interactive_cond
*copyc pmp$establish_condition_handler
*copyc pmp$exit
*copyc pmp$get_job_mode
*copyc sfp$change_job_warning_limit
*copyc sfp$get_job_limit
*copyc sfp$get_job_limit_name

?? TITLE := '  [XDCL] jmp$default_job_resource_hndlr', EJECT ??

  PROCEDURE [XDCL] jmp$default_job_resource_hndlr
    (    complete_condition: pmt$condition;
     VAR status: ost$status);

{ PURPOSE:
{
{   This is the default job resource condition handler.
{
{ DESIGN:
{
{   If this is a batch job, JMP$LOGOUT is called to terminate the job.
{
{
{   If this is an interactive job, the condition handler displays information
{ about the limit that has been hit to the user and then prompts the user to
{ enter an integer increment that will be added to the current accumulator value
{ to arrive at a new job warning limit value for the limit.  If the user does
{ not want the job to continue, LOGOUT may be entered in response to the prompt,
{ and the JMP$LOGOUT is called to terminate the job.
{
{   The job will not be allowed to continue unless the user enters an increment
{ that will increase the job warning limit value for the limit that has been
{ hit.


    VAR
      condition: jmt$job_resource_condition,
      condition_status: ost$status,
      error_conditions: [STATIC, READ, oss$job_paged_literal] pmt$condition :=
            [pmc$condition_combination, $pmt$condition_combination
            [jmc$job_resource_condition, ifc$interactive_condition, pmc$pit_condition]],
      established_descriptor: pmt$established_handler,
      ignored_status: ost$status,
      job_mode: jmt$job_mode,
      limit_name: ost$name;

?? NEWTITLE := '    condition_handler', EJECT ??

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_description: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      VAR
        ignored_status: ost$status,
        message_status: ost$status;

      IF condition.selector = ifc$interactive_condition THEN
        CASE condition.interactive_condition OF
        = ifc$pause_break =
          osp$set_status_abnormal ('JM', jme$pause_break_ignored, '', message_status);
          osp$generate_output_message (message_status, ignored_status);

        = ifc$terminate_break =
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
          osp$set_status_abnormal ('JM', jme$terminate_break_ignored, '', message_status);
          osp$generate_output_message (message_status, ignored_status);

        = ifc$job_reconnect =
          osp$set_status_abnormal ('JM', jme$job_reconnected, '', message_status);
          osp$generate_output_message (message_status, ignored_status);

        ELSE

{do nothing

        CASEND;
      IFEND;

    PROCEND condition_handler;

?? TITLE := '    default_interactive_handler', EJECT ??

    PROCEDURE default_interactive_handler
      (    condition: jmt$job_resource_condition;
       VAR status: ost$status);

      VAR
        overlimit_handled: boolean,
        condition_handled: boolean,
        file_id: amt$file_identifier,
        ignored_status: ost$status,
        input_line: ost$string,
        limit_name: ost$name;

?? TITLE := '      display_limit_information', EJECT ??

      PROCEDURE display_limit_information
        (    limit_name: ost$name;
         VAR status: ost$status);

        VAR
          limit_information: sft$limit,
          message_status: ost$status;

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

        sfp$get_job_limit (limit_name, limit_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        osp$set_status_abnormal ('JM', jme$resource_condition, limit_name, message_status);
        osp$generate_output_message (message_status, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        osp$set_status_abnormal ('JM', jme$current_accumulator_is, '', message_status);
        osp$append_status_integer (osc$status_parameter_delimiter, limit_information.accumulator, 10, FALSE,
              message_status);
        osp$generate_output_message (message_status, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF limit_information.job_abort_limit <> sfc$unlimited THEN
          osp$set_status_abnormal ('JM', jme$maximum_limit_is, '', message_status);
          osp$append_status_integer (osc$status_parameter_delimiter, limit_information.job_abort_limit, 10,
                FALSE, message_status);

          IF limit_information.job_abort_limit < limit_information.accumulator THEN
            overlimit_handled := TRUE;
            RETURN;
          IFEND;
        ELSE
          osp$set_status_abnormal ('JM', jme$maximum_limit_is, 'UNLIMITED', message_status);
        IFEND;
        osp$generate_output_message (message_status, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

      PROCEND display_limit_information;

?? TITLE := '      display_range_message', EJECT ??

      PROCEDURE display_range_message
        (    limit_name: ost$name;
         VAR status: ost$status);

        VAR
          limit_information: sft$limit,
          message_status: ost$status;

        status.normal := TRUE;

        sfp$get_job_limit (limit_name, limit_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        osp$set_status_abnormal ('JM', jme$increment_range, '', message_status);
        osp$append_status_integer (osc$status_parameter_delimiter, 1, 10, FALSE, message_status);
        IF limit_information.job_abort_limit = sfc$unlimited THEN
          osp$append_status_parameter (osc$status_parameter_delimiter, 'UNLIMITED', message_status);
        ELSE
          osp$append_status_integer (osc$status_parameter_delimiter,
                limit_information.job_abort_limit - limit_information.accumulator, 10, FALSE, message_status);
        IFEND;
        osp$generate_output_message (message_status, status);

      PROCEND display_range_message;

?? TITLE := '      get_user_input', EJECT ??

      PROCEDURE get_user_input
        (    file_id: amt$file_identifier;
         VAR input_line: ost$string;
         VAR status: ost$status);

        VAR
          byte_address: amt$file_byte_address,
          file_position: amt$file_position,
          message_status: ost$status,
          transfer_count: amt$transfer_count,
          working_storage_area: string (osc$max_string_size);

        osp$set_status_abnormal ('JM', jme$increment_prompt, '', message_status);
        osp$generate_output_message (message_status, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        working_storage_area := ' ';
        amp$get_next (file_id, ^working_storage_area, osc$max_string_size, transfer_count, byte_address,
              file_position, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF transfer_count <> 0 THEN
          #TRANSLATE (osv$lower_to_upper, working_storage_area, input_line.value);
          input_line.size := clp$trimmed_string_size (input_line.value (1, transfer_count));
        ELSE
          input_line.value := ' ';
          input_line.size := 1;
        IFEND;

      PROCEND get_user_input;

?? TITLE := '      open_input_file', EJECT ??

      PROCEDURE open_input_file
        (VAR file_id: amt$file_identifier;
         VAR status: ost$status);

        VAR
          attribute_override: array [1 .. 3] of fst$file_cycle_attribute,
          file_attachment: array [1 .. 3] of fst$attachment_option;

        file_attachment [1].selector := fsc$access_and_share_modes;
        file_attachment [1].access_modes.selector := fsc$specific_access_modes;
        file_attachment [1].access_modes.value := $fst$file_access_options [fsc$read];
        file_attachment [1].share_modes.selector := fsc$specific_share_modes;
        file_attachment [1].share_modes.value := $fst$file_access_options [fsc$read, fsc$execute];
        file_attachment [2].selector := fsc$open_share_modes;
        file_attachment [2].open_share_modes := $fst$file_access_options [fsc$read, fsc$execute];
        file_attachment [3].selector := fsc$create_file;
        file_attachment [3].create_file := FALSE;

        attribute_override [1].selector := fsc$block_type;
        attribute_override [1].block_type := amc$system_specified;
        attribute_override [2].selector := fsc$record_type;
        attribute_override [2].record_type := amc$undefined;
        attribute_override [3].selector := fsc$file_organization;
        attribute_override [3].file_organization := amc$sequential;

        fsp$open_file (':$LOCAL.INPUT.1', amc$record, ^file_attachment, NIL, NIL, NIL, ^attribute_override,
              file_id, status);

      PROCEND open_input_file;

?? TITLE := '      update_warning_limit', EJECT ??

      PROCEDURE update_warning_limit
        (    limit_name: ost$name;
             input_line: string ( * );
         VAR status: ost$status);

        VAR
          ignored_status: ost$status,
          increment: clt$integer,
          limit_information: sft$limit,
          new_warning_limit: sft$counter;

        status.normal := TRUE;

        sfp$get_job_limit (limit_name, limit_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF input_line = 'UNLIMITED' THEN
          new_warning_limit := sfc$unlimited;
        ELSE
          clp$convert_string_to_integer (input_line, increment, status);
          IF NOT status.normal THEN
            osp$set_status_abnormal ('JM', jme$not_integer_or_logout, input_line, status);
            osp$generate_output_message (status, ignored_status);
            RETURN;
          IFEND;
          new_warning_limit := limit_information.accumulator + increment.value;
        IFEND;

        sfp$change_job_warning_limit (limit_name, new_warning_limit, status);

      PROCEND update_warning_limit;

?? OLDTITLE, EJECT ??

      jmp$set_job_resource_condition (condition, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      sfp$get_job_limit_name (jmv$job_resource_condition, limit_name, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      display_limit_information (limit_name, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF NOT overlimit_handled THEN
        open_input_file (file_id, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        condition_handled := FALSE;

        REPEAT

          get_user_input (file_id, input_line, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          IF input_line.value = 'LOGOUT' THEN
            jmp$logout (status);
          ELSEIF (input_line.value = 'TERMINATE_COMMAND') OR (input_line.value = 'TERC') THEN
            pmp$dispose_interactive_cond (ifc$terminate_break);
            condition_handled := TRUE;
          ELSEIF (input_line.value = '?') OR (input_line.value = ' ') THEN
            display_range_message (limit_name, status);
          ELSE
            update_warning_limit (limit_name, input_line.value (1, input_line.size), status);
            IF NOT status.normal THEN
              status.normal := TRUE;
              display_range_message (limit_name, status);
            ELSE
              condition_handled := TRUE;
            IFEND;
          IFEND;
        UNTIL condition_handled OR NOT status.normal;

        fsp$close_file (file_id, ignored_status);
      IFEND;
    PROCEND default_interactive_handler;

?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    ignored_status.normal := TRUE;
    condition := complete_condition.job_resource_condition;

    pmp$establish_condition_handler (error_conditions, ^condition_handler, ^established_descriptor, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$get_job_mode (job_mode, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF condition = jmc$time_limit_condition THEN
      osp$set_status_abnormal ('JM', jme$time_limit_condition, '', condition_status);
    ELSE
      sfp$get_job_limit_name (condition, limit_name, ignored_status);
      osp$set_status_abnormal ('JM', jme$resource_condition, limit_name, condition_status);
    IFEND;

    osp$generate_log_message ($pmt$ascii_logset [pmc$system_log, pmc$job_log], condition_status,
          ignored_status);

    IF condition = jmc$time_limit_condition THEN
      clp$put_job_output (' JOB TIME LIMIT REACHED.', ignored_status);
    IFEND;

    IF job_mode = jmc$batch THEN
      jmp$logout (ignored_status);
    ELSE
      default_interactive_handler (condition, status);
      IF NOT status.normal THEN
        jmp$logout (ignored_status);
      IFEND;
    IFEND;

    pmp$disestablish_cond_handler (error_conditions, status);

  PROCEND jmp$default_job_resource_hndlr;

MODEND jmm$handle_conditions;
