?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE: Job Management Queued Files Job Interfaces' ??
MODULE jmm$queue_file_job_manager;

{ PURPOSE:
{   This module contains the queue file job management interfaces.  These interfaces control access to,
{ submission of, and manipulation of jobs.
{
{ DESIGN:
{   The program interfaces contained in this module are designed in such a fashion that binary
{ compatibility can be maintained.  Any change to the size of a record element in a variant record
{ will result in an interface breakage.  These procedures operate in rings 2 and 3 with a call bracket
{ of ring 13.

?? NEWTITLE := 'Global Declarations Referenced by this Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc amt$file_attributes
*copyc amt$local_file_name
*copyc avc$validation_field_names
*copyc avc$system_defined_limit_names
*copyc ave$validation_interface_errors
*copyc avt$name_list_size
*copyc avt$password
*copyc cle$ecc_lexical
*copyc clt$command_line_size
*copyc fst$file_reference
*copyc jmc$change_input_attributes
*copyc jmc$class_names
*copyc jmc$get_input_attributes
*copyc jmc$get_job_status
*copyc jmc$job_management_id
*copyc jmc$maximum_system_label_length
*copyc jmc$submit_job
*copyc jmc$system_family
*copyc jmc$terminate_job
*copyc jme$job_categorization_errors
*copyc jme$job_history_conditions
*copyc jme$job_on_another_mainframe
*copyc jme$job_scheduler_conditions
*copyc jme$no_space_for_file
*copyc jme$operator_queue_restore
*copyc jme$queued_file_conditions
*copyc jme$served_family_unavailable
*copyc jme$work_area_too_small
*copyc jmt$attribute_keys_set
*copyc jmt$clock_time
*copyc jmt$full_job_category_list
*copyc jmt$input_application_index
*copyc jmt$input_attribute_changes
*copyc jmt$input_attribute_options
*copyc jmt$input_attribute_results
*copyc jmt$input_descriptor
*copyc jmt$input_file_location
*copyc jmt$job_class_limits
*copyc jmt$job_control_block
*copyc jmt$job_counts
*copyc jmt$job_count_range
*copyc jmt$job_state_set
*copyc jmt$job_status_count
*copyc jmt$job_status_options
*copyc jmt$job_status_results
*copyc jmt$job_submission_options
*copyc jmt$job_system_label
*copyc jmt$job_termination_options
*copyc jmt$leveled_job_connect_data
*copyc jmt$mainframe_leveling_data
*copyc jmt$mainframes_searched_list
*copyc jmt$maximum_mainframes
*copyc jmt$name
*copyc jmt$name_list
*copyc jmt$output_disposition
*copyc jmt$output_system_label
*copyc jmt$queue_file_password
*copyc jmt$queue_file_path
*copyc jmt$release_input_file_list
*copyc jmt$results_keys
*copyc jmt$submit_job_variations
*copyc jmt$system_supplied_name
*copyc jmt$terminate_job_action
*copyc jmt$user_supplied_name
*copyc jmt$work_area
*copyc ofe$error_codes
*copyc osc$deadstart
*copyc osc$dual_state_interactive
*copyc osc$file_transfer_server
*copyc osc$space_unavailable_condition
*copyc osc$submit_job
*copyc osc$timesharing
*copyc osc$xterm_application_name
*copyc osd$integer_limits
*copyc osd$virtual_address
*copyc oss$task_private
*copyc oss$task_shared
*copyc ost$caller_identifier
*copyc ost$date_time
*copyc ost$status
*copyc ost$user_identification
*copyc pmt$family_name_list
*copyc sfc$unlimited
*copyc sye$job_recovery_conditions
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$return
*copyc avp$configuration_administrator
*copyc avp$get_capability
*copyc avp$prevalidate_job
*copyc avp$security_option_active
*copyc avp$system_administrator
*copyc avp$system_displays
*copyc avp$system_operator
*copyc clp$convert_file_ref_to_string
*copyc clp$evaluate_file_reference
*copyc clp$convert_string_to_file_ref
*copyc clp$get_job_parameters
*copyc clp$get_login_parameters
*copyc clp$pop_parameters
*copyc clp$push_sub_parameters_block
*copyc clp$trimmed_string_size
*copyc clp$validate_name
*copyc dfp$check_job_recovery
*copyc dfp$get_family_access
*copyc dfp$get_partner_mainframes
*copyc dfp$send_remote_procedure_call
*copyc fsp$close_file
*copyc fsp$open_file
*copyc fsp$subsystem_copy_file
*copyc i#current_sequence_position
*copyc i#move
*copyc ifp$invoke_pause_utility
*copyc jmp$convert_date_time_dif_to_us
*copyc jmp$copy_seq_to_result_array
*copyc jmp$determine_job_class
*copyc jmp$emit_communication_stat
*copyc jmp$emit_job_history_statistics
*copyc jmp$general_purpose_cluster_rpc
*copyc jmp$get_attribute_name
*copyc jmp$get_data_packet_size
*copyc jmp$get_jm_work_area
*copyc jmp$get_result_size
*copyc jmp$get_scheduling_admin_status
*copyc jmp$expand_job_class_abbrev
*copyc jmp$mainframe_get_leveling_data
*copyc jmp$select_interactive_job_dest
*copyc jmp$system_job
*copyc jmp$validate_attribute_options
*copyc jmp$validate_name
*copyc jmp$validate_status_options
*copyc mmp$create_scratch_segment
*copyc mmp$delete_scratch_segment
*copyc nap$parse_accounting_data
*copyc nap$set_server_job_init_pending
*copyc osp$append_status_parameter
*copyc osp$disestablish_cond_handler
*copyc osp$check_client_leveled_access
*copyc osp$establish_block_exit_hndlr
*copyc osp$establish_condition_handler
*copyc osp$force_access_violation
*copyc osp$get_status_condition_name
*copyc osp$is_caller_system_privileged
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc osp$set_status_from_condition
*copyc osp$verify_system_privilege
*copyc pfp$attach
*copyc pfp$begin_system_authority
*copyc pfp$define
*copyc pfp$define_catalog
*copyc pfp$end_system_authority
*copyc pfp$purge
*copyc pmp$continue_to_cause
*copyc pmp$convert_binary_mainframe_id
*copyc pmp$convert_mainframe_to_binary
*copyc pmp$execute
*copyc pmp$get_account_project
*copyc pmp$get_compact_date_time
*copyc pmp$get_job_names
*copyc pmp$get_mainframe_id
*copyc pmp$get_microsecond_clock
*copyc pmp$get_pseudo_mainframe_id
*copyc pmp$get_unique_name
*copyc pmp$get_user_identification
*copyc pmp$wait
*copyc qfp$acquire_modified_input
*copyc qfp$acquire_new_input
*copyc qfp$activate_deferred_family
*copyc qfp$assign_system_supplied_name
*copyc qfp$categorize_job
*copyc qfp$change_input_attributes
*copyc qfp$change_terminate_job_action
*copyc qfp$check_for_profile_mismatch
*copyc qfp$defer_deactivated_family
*copyc qfp$determine_mainframe_fitness
*copyc qfp$get_input_file_location
*copyc qfp$get_input_q_from_unassigned
*copyc qfp$get_job_counts
*copyc qfp$get_job_status
*copyc qfp$read_job_system_label
*copyc qfp$rebuild_executing_job
*copyc qfp$rebuild_input_queue
*copyc qfp$register_input_application
*copyc qfp$release_input_files
*copyc qfp$remove_job_from_kjl
*copyc qfp$set_input_completed
*copyc qfp$set_input_initiated
*copyc qfp$set_job_class_limits
*copyc qfp$submit_job
*copyc qfp$terminate_acquired_input
*copyc qfp$terminate_job
*copyc qfp$validate_input_file_access
*copyc qfp$write_job_system_label
*copyc sfp$emit_audit_statistic
*copyc syp$system_is_idling
*copyc clv$standard_files
*copyc jmv$default_job_attributes
*copyc jmv$enable_queue_file_access
*copyc jmv$job_attributes
*copyc jmv$job_category_data
*copyc jmv$job_class_table_p
*copyc jmv$job_history_active
*copyc jmv$job_management_work_area_p
*copyc jmv$job_scheduler_table
*copyc jmv$kjl_p
*copyc jmv$kjlx_p
*copyc jmv$known_job_list
*copyc jmv$sched_profile_is_loading
*copyc jmv$system_job_ssn
*copyc osv$lower_to_upper
*copyc osv$task_private_heap
*copyc qfv$terminate_job_action_set

?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  CONST
    uppercase_required = 'REQUIRED';

  TYPE
    mainframe_chaia_parameters = record
      system_job_name: jmt$system_supplied_name,
      login_family: ost$name,
      input_file_location: jmt$input_file_location,
      system_changing_attributes: boolean,
      privileged_for_status: boolean,
      beginning_job_class: jmt$job_class_name,
      attribute_change_count: ost$non_negative_integers,
    recend;

  TYPE
    mainframe_getia_parameters = record
      status_option_count: ost$non_negative_integers,
      attach_file: boolean,
      results_keys_count: ost$non_negative_integers,
    recend;

  TYPE
    mainframe_getjs_parameters = record
      user_identification: ost$user_identification,
      caller_ssn: jmt$system_supplied_name,
      privileged_job: boolean,
      valid_for_scheduling_displays: boolean,
      status_option_count: ost$non_negative_integers,
      status_results_count: ost$non_negative_integers,
    recend;

  TYPE
    server_submit_job_parameters = record
      immediate_initiation_candidate: boolean,
      executing_on_server: boolean,
      origin_mainframe_id: pmt$mainframe_id,
    recend;

  TYPE
    terminate_job_request = record
      job_state_set: jmt$job_state_set,
      output_disposition_key_known: boolean,
      output_disposition_key: jmt$output_disposition_keys,
      operator_job: boolean,
      reason: ost$name,
      case server: boolean of
      = TRUE =
        server_mainframe_id: pmt$mainframe_id,
      = FALSE =
        ,
      casend,
    recend;

  VAR
    task_has_registered_application: [STATIC, oss$task_private] boolean := FALSE,
    task_status_p: [STATIC, oss$task_private] ^pmt$task_status := NIL;

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

{ PURPOSE:
{   The purpose of this request is to acquire a file from the input queue.  What this means is to attach
{ the file and read its input system label information.  A subset of this information is then placed in
{ a descriptor that describes the file being acquired.

  PROCEDURE acquire_input
    (    input_destination_usage: jmt$destination_usage;
         new_input: boolean;
     VAR input_descriptor: jmt$input_descriptor;
     VAR status: ost$status);

    VAR
      cycle_selector: pft$cycle_selector,
      ignore_status: ost$status,
      input_name: jmt$name,
      local_file_name: amt$local_file_name,
      password: pft$password,
      path_p: ^pft$path,
      system_label: jmt$job_system_label,
      usage_selections: pft$usage_selections;

?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;

?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    ignore_status.normal := TRUE;

    IF syp$system_is_idling () THEN
      osp$set_status_condition (jme$input_queue_is_empty, status);
      RETURN;
    IFEND;

{ Acquire the file

    IF new_input THEN
      qfp$acquire_new_input (input_destination_usage, input_descriptor, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    ELSE
      qfp$acquire_modified_input (input_destination_usage, input_descriptor, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Attach the file so we can read the system label and get the attributes

    pmp$get_unique_name (local_file_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ This can only be the store-and-forward queue.  Jobs that belong to the local VE system(s) will not have
{ their command files touched by this request.  The only applications that can have files attached are
{ applications that access the store-and-forward queue.  With this in mind, osc$null_name is supplied as
{ the family name.

    determine_file_path (jmc$ifl_store_and_forward_queue, osc$null_name, input_descriptor.system_job_name,
          path_p);
    cycle_selector.cycle_option := pfc$specific_cycle;
    cycle_selector.cycle_number := 1;
    password := osc$null_name;
    usage_selections := $pft$usage_selections [pfc$read];

    osp$establish_block_exit_hndlr (^handle_block_exit);
    pfp$begin_system_authority;
    pfp$attach (local_file_name, path_p^, cycle_selector, password, usage_selections, usage_selections,
          pfc$wait, status);
    pfp$end_system_authority;
    osp$disestablish_cond_handler;
    IF NOT status.normal THEN
      input_name.kind := jmc$system_supplied_name;
      input_name.system_supplied_name := input_descriptor.system_job_name;
      jmp$terminate_job (input_name, NIL, ignore_status);
      RETURN;
    IFEND;

{ Read the input file's system label

    qfp$read_job_system_label (local_file_name, system_label, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      RETURN;
    IFEND;

{ Release the file in case somebody needs it for write

    amp$return (local_file_name, status);

{ Set up the fields in the input descriptor

    input_descriptor.comment_banner := system_label.job_attributes.comment_banner;
    input_descriptor.control_family := system_label.job_attributes.job_controller.family;
    input_descriptor.control_user := system_label.job_attributes.job_controller.user;
    input_descriptor.copies := system_label.job_attributes.copy_count;
    input_descriptor.data_declaration := system_label.data_declaration;
    input_descriptor.data_mode := system_label.data_mode;
    input_descriptor.device := system_label.job_attributes.device;
    input_descriptor.disposition_code := system_label.disposition_code;
    input_descriptor.earliest_run_time := system_label.job_attributes.earliest_run_time;
    input_descriptor.earliest_print_time := system_label.job_attributes.earliest_print_time;
    input_descriptor.external_characteristics := system_label.job_attributes.external_characteristics;
    input_descriptor.forms_code := system_label.job_attributes.forms_code;
    input_descriptor.implicit_routing_text := system_label.job_attributes.implicit_routing_text;
    input_descriptor.job_class := system_label.job_class_name;
    input_descriptor.job_destination_family := system_label.job_destination_family;
    input_descriptor.job_destination_usage := system_label.job_destination_usage;
    input_descriptor.job_execution_ring := system_label.job_execution_ring;
    input_descriptor.job_input_device := system_label.job_attributes.job_input_device;
    input_descriptor.job_size := system_label.job_attributes.job_size;
    input_descriptor.job_submission_time := system_label.job_attributes.job_submission_time;
    input_descriptor.latest_run_time := system_label.job_attributes.latest_run_time;
    input_descriptor.latest_print_time := system_label.job_attributes.latest_print_time;
    input_descriptor.login_account := system_label.login_account;
    input_descriptor.login_command_supplied := system_label.job_attributes.login_command_supplied;
    input_descriptor.login_family := system_label.login_user_identification.family;
    input_descriptor.login_project := system_label.login_project;
    input_descriptor.login_user := system_label.login_user_identification.user;
    input_descriptor.originating_application_name := system_label.job_attributes.originating_application_name;
    input_descriptor.originating_login_account := system_label.originating_login_account;
    input_descriptor.originating_login_family := system_label.originating_login_family;
    input_descriptor.originating_login_project := system_label.originating_login_project;
    input_descriptor.originating_login_user := system_label.originating_login_user;
    input_descriptor.originating_system_job_name := system_label.job_attributes.originating_ssn;
    input_descriptor.output_class := system_label.job_attributes.output_class;
    input_descriptor.output_destination := system_label.job_attributes.output_destination;
    input_descriptor.output_destination_family := system_label.job_attributes.output_destination_family;
    input_descriptor.output_destination_usage := system_label.job_attributes.output_destination_usage;
    input_descriptor.output_disposition.key := system_label.job_attributes.output_disposition_key;
    input_descriptor.output_disposition.standard_output_path := NIL;
    input_descriptor.output_priority := system_label.job_attributes.output_priority;
    input_descriptor.purge_delay := system_label.job_attributes.purge_delay;
    input_descriptor.remote_host_directive := system_label.job_attributes.remote_host_directive;
    input_descriptor.routing_banner := system_label.job_attributes.routing_banner;
    input_descriptor.site_information := system_label.job_attributes.site_information;
    input_descriptor.source_logical_id := system_label.job_attributes.source_logical_id;
    input_descriptor.station := system_label.job_attributes.station;
    input_descriptor.station_operator := system_label.job_attributes.station_operator;
    input_descriptor.system_job_name := system_label.system_job_name;
    input_descriptor.system_job_parameters := system_label.job_attributes.system_job_parameters;
    input_descriptor.system_routing_text := system_label.job_attributes.system_routing_text;
    input_descriptor.user_information := system_label.job_attributes.user_information;
    input_descriptor.user_job_name := system_label.user_job_name;
    input_descriptor.vertical_print_density := system_label.job_attributes.vertical_print_density;
    input_descriptor.vfu_load_procedure := system_label.job_attributes.vfu_load_procedure;
  PROCEND acquire_input;
?? OLDTITLE ??
?? NEWTITLE := 'call_server_submit_job', EJECT ??

{ PURPOSE:
{   The purpose of this request is to call the server mainframe for processing
{   a submitted job.  Batch jobs are placed in the server's Known Job List (KJL).
{   The server must be called for interactive leveled jobs to determine where the
{   job should execute.  If it is determined that the interactive job should
{   execute on the server, the job will be placed in the server's KJL.

  PROCEDURE call_server_submit_job
    (    job_system_label: jmt$job_system_label;
         immediate_initiation_candidate: boolean;
         originating_mainframe_id: pmt$mainframe_id;
     VAR destination_mainframe_id: pmt$mainframe_id;
     VAR status: ost$status);

    VAR
      data_size: dft$send_data_size,
      ignore_recovery_occurred: boolean,
      ignore_status_p: ^ost$status,
      local_job_system_label_p: ^jmt$job_system_label,
      local_dest_mainframe_id_p: ^pmt$mainframe_id,
      parameter_size: dft$send_parameter_size,
      queue_entry_location: dft$rpc_queue_entry_location,
      receive_from_server_data_p: dft$p_receive_data,
      receive_from_server_params_p: dft$p_receive_parameters,
      send_to_server_data_p: dft$p_send_data,
      send_to_server_parameters_p: dft$p_send_parameters,
      server_location: dft$server_location,
      server_submit_job_params_p: ^server_submit_job_parameters;

?? NEWTITLE := 'dfp$remote_procedure_call_ch', EJECT ??

{ PURPOSE:
{   This procedure is a condition handler established to call a routine to clear the assignment of a task
{   services queue_entry if a task aborts with a queue_entry assigned to it.  The queue_entry must be clear
{   before the task can safely exit.

    PROCEDURE dfp$remote_procedure_call_ch
      (    condition: pmt$condition;
           cond_desc: ^pmt$condition_information;
           save: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      dfp$ch_cleanup;
      osp$set_status_from_condition (dfc$file_server_id, condition, save, status, ignore_status);
      EXIT call_server_submit_job;

    PROCEND dfp$remote_procedure_call_ch;
*block
*copyc dfp$begin_ch_remote_proc_call
*copyc dfp$end_ch_remote_proc_call
*blockend
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    server_location.server_location_selector := dfc$family_name;
    server_location.family_name := job_system_label.login_user_identification.family;

    REPEAT
      dfp$begin_ch_remote_proc_call (server_location, { allowed_when_server_deactivated } TRUE,
            queue_entry_location, send_to_server_parameters_p, send_to_server_data_p, status);
      IF NOT status.normal THEN

{***  Now what?? - the command file is on the server yet we can't make a KJL entry...
{ assume that the server crashed and will re-queue the job when it re-deadstarts?

        RETURN;
      IFEND;

{ Build the data and parameters to send to the server.
{ The RPC sequences have already been reset.

      NEXT server_submit_job_params_p IN send_to_server_parameters_p;
      server_submit_job_params_p^.immediate_initiation_candidate := immediate_initiation_candidate;
      server_submit_job_params_p^.executing_on_server := TRUE;
      server_submit_job_params_p^.origin_mainframe_id := originating_mainframe_id;

      NEXT local_job_system_label_p IN send_to_server_data_p;
      local_job_system_label_p^ := job_system_label;

      parameter_size := i#current_sequence_position (send_to_server_parameters_p);
      data_size := i#current_sequence_position (send_to_server_data_p);

      dfp$send_remote_procedure_call (queue_entry_location, dfc$rpc_jl_submit_job, parameter_size, data_size,
            receive_from_server_params_p, receive_from_server_data_p, status);
      IF status.normal THEN
        NEXT local_dest_mainframe_id_p IN receive_from_server_params_p;
        destination_mainframe_id := local_dest_mainframe_id_p^;

        dfp$end_ch_remote_proc_call (queue_entry_location, status);
      ELSE
        PUSH ignore_status_p;
        dfp$end_ch_remote_proc_call (queue_entry_location, ignore_status_p^);
        IF status.condition = dfe$job_needs_recovery THEN
          dfp$check_job_recovery (ignore_recovery_occurred);
        IFEND;
      IFEND;
    UNTIL status.normal OR (status.condition <> dfe$job_needs_recovery);
  PROCEND call_server_submit_job;
?? OLDTITLE ??
?? NEWTITLE := 'convert_limit_information', EJECT ??

{ PURPOSE:
{   The purpose of this request is to translate the user's requested limit information
{ into an assigned set of limits.  This request also ensures that if job qualifiers
{ are required that they are indeed present.

  PROCEDURE convert_limit_information
    (VAR system_label {input, output} : jmt$job_system_label;
     VAR status: ost$status);

    VAR
      job_qualifier_index: 1 .. jmc$maximum_job_qualifiers;

    status.normal := TRUE;

    IF system_label.limit_information.cpu_time_limit_specified THEN
      system_label.limit_information.cpu_time_limit_assigned :=
            system_label.limit_information.cpu_time_limit_requested;
    ELSE
      system_label.limit_information.cpu_time_limit_assigned := jmc$unspecified_cpu_time_limit;
    IFEND;
    IF system_label.limit_information.cpu_time_limit_assigned = jmc$system_default_cpu_time_lim THEN
      system_label.limit_information.cpu_time_limit_assigned :=
            jmv$default_job_attributes [system_label.job_mode].cpu_time_limit;
    IFEND;
    IF (system_label.limit_information.cpu_time_limit_assigned = jmc$required_cpu_time_limit) OR
          ((system_label.limit_information.cpu_time_limit_assigned = jmc$unspecified_cpu_time_limit) AND
          (jmv$default_job_attributes [system_label.job_mode].cpu_time_limit = jmc$required_cpu_time_limit))
          THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'CPU_TIME_LIMIT', status);
      RETURN;
    IFEND;

    IF system_label.limit_information.magnetic_tape_limit_specified THEN
      system_label.limit_information.magnetic_tape_limit_assigned :=
            system_label.limit_information.magnetic_tape_limit_requested;
    ELSE
      system_label.limit_information.magnetic_tape_limit_assigned := jmc$unspecified_mag_tape_limit;
    IFEND;
    IF system_label.limit_information.magnetic_tape_limit_assigned = jmc$system_default_mag_tape_lim THEN
      system_label.limit_information.magnetic_tape_limit_assigned :=
            jmv$default_job_attributes [system_label.job_mode].magnetic_tape_limit;
    IFEND;
    IF (system_label.limit_information.magnetic_tape_limit_assigned = jmc$required_mag_tape_limit) OR
          ((system_label.limit_information.magnetic_tape_limit_assigned = jmc$unspecified_mag_tape_limit) AND
          (jmv$default_job_attributes [system_label.job_mode].magnetic_tape_limit =
          jmc$required_mag_tape_limit)) THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'MAGNETIC_TAPE_LIMIT', status);
      RETURN;
    IFEND;

    IF system_label.limit_information.maximum_working_set_specified THEN
      system_label.limit_information.maximum_working_set_assigned :=
            system_label.limit_information.maximum_working_set_requested;
    ELSE
      system_label.limit_information.maximum_working_set_assigned := jmc$unspecified_work_set_size;
    IFEND;
    IF system_label.limit_information.maximum_working_set_assigned = jmc$system_default_work_set_siz THEN
      system_label.limit_information.maximum_working_set_assigned :=
            jmv$default_job_attributes [system_label.job_mode].maximum_working_set;
    IFEND;
    IF (system_label.limit_information.maximum_working_set_assigned = jmc$required_working_set_size) OR
          ((system_label.limit_information.maximum_working_set_assigned = jmc$unspecified_work_set_size) AND
          (jmv$default_job_attributes [system_label.job_mode].maximum_working_set =
          jmc$required_working_set_size)) THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'MAXIMUM_WORKING_SET', status);
      RETURN;
    IFEND;

    IF system_label.limit_information.sru_limit_specified THEN
      system_label.limit_information.sru_limit_assigned := system_label.limit_information.sru_limit_requested;
    ELSE
      system_label.limit_information.sru_limit_assigned := jmc$unspecified_sru_limit;
    IFEND;
    IF system_label.limit_information.sru_limit_assigned = jmc$system_default_sru_limit THEN
      system_label.limit_information.sru_limit_assigned :=
            jmv$default_job_attributes [system_label.job_mode].sru_limit;
    IFEND;
    IF (system_label.limit_information.sru_limit_assigned = jmc$required_sru_limit) OR
          ((system_label.limit_information.sru_limit_assigned = jmc$unspecified_sru_limit) AND
          (jmv$default_job_attributes [system_label.job_mode].sru_limit = jmc$required_cpu_time_limit)) THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'SRU_LIMIT', status);
      RETURN;
    IFEND;

    IF jmv$default_job_attributes [system_label.job_mode].job_qualifier_list [1] = uppercase_required THEN

    /search_for_specified_qualifiers/
      FOR job_qualifier_index := 1 TO jmc$maximum_job_qualifiers DO
        IF (system_label.job_attributes.job_qualifier_list [job_qualifier_index] <> osc$null_name) AND
              (system_label.job_attributes.job_qualifier_list [job_qualifier_index] <>
              uppercase_required) THEN
          EXIT /search_for_specified_qualifiers/;
        ELSEIF job_qualifier_index = jmc$maximum_job_qualifiers THEN
          osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'JOB_QUALIFIER', status);
        IFEND;
      FOREND /search_for_specified_qualifiers/;
    IFEND;
  PROCEND convert_limit_information;
?? OLDTITLE ??
?? NEWTITLE := '[INLINE] determine_file_path', EJECT ??

{ PURPOSE:
{   The purpose of this request is to PUSH the correct path name for an input file on the requestor's
{ stack.  The correct path is determined by the input file's destination usage and family name.
{
{ NOTES:
{   This procedure MUST be INLINE.

  PROCEDURE [INLINE] determine_file_path
    (    input_file_location: jmt$input_file_location;
         family_name: ost$name;
         system_job_name: jmt$system_supplied_name;
     VAR path_p: ^pft$path);

    PUSH path_p: [1 .. 4];
    path_p^ [2] := jmc$system_user;

    path_p^ [4] := system_job_name;

    determine_file_catalogs (input_file_location, family_name, path_p^ [1], path_p^ [3]);
  PROCEND determine_file_path;
?? OLDTITLE ??
?? NEWTITLE := '[INLINE] determine_file_catalogs', EJECT ??

{ PURPOSE:
{   The purpose of this request is to determine which sub-catalog a file is in based on its job
{   destination usage and family name.
{
{ NOTES:
{   This request will return a file path of the store and forward queue for a file that has no
{   input file.  This should never happen - only the system job does not have an input file.

  PROCEDURE [INLINE] determine_file_catalogs
    (    input_file_location: jmt$input_file_location;
         family_name: ost$name;
     VAR master_catalog: ost$name;
     VAR sub_catalog: ost$name);

    IF input_file_location = jmc$ifl_system_input_queue THEN
      master_catalog := jmc$system_family;
      sub_catalog := jmc$job_input_catalog;

    ELSEIF input_file_location = jmc$ifl_login_family_queue THEN
      master_catalog := family_name;
      sub_catalog := jmc$job_input_catalog;
    ELSE { IF input_file_location = jmc$ifl_store_and_forward_queue THEN
      master_catalog := jmc$system_family;
      sub_catalog := jmc$sf_job_input_catalog;
    IFEND;
  PROCEND determine_file_catalogs;
?? OLDTITLE ??
?? NEWTITLE := 'get_terminal_name' ??
?? EJECT ??

{ PURPOSE:
{   The purpose of this request is get the terminal name from the accounting
{ information contained in the job_input_device.

  PROCEDURE get_terminal_name
    (    system_label: jmt$job_system_label;
     VAR terminal_name_found: boolean;
     VAR terminal_name: ost$name);

    VAR
      get_accounting_data_p: ^nat$accounting_data_fields,
      local_status: ost$status,
      peer_accounting_information_p: ^string ( * ),
      submit_job_variation: jmt$submit_job_variations;

    terminal_name_found := FALSE;

    IF system_label.job_attributes.originating_application_name = osc$timesharing THEN

{ If this is an ordinary timesharing job, get the terminal name from the job input attributes.

      IF system_label.job_attributes.system_job_parameters.system_job_parameter_count = 0 THEN
        PUSH peer_accounting_information_p: [system_label.job_attributes.job_input_device.size];
        peer_accounting_information_p^ := system_label.job_attributes.job_input_device.text;
      ELSE
        i#move (^system_label.job_attributes.system_job_parameters.system_job_parameter,
              ^submit_job_variation, #SIZE (submit_job_variation));

{ If this is a submit resulting from a detach job or leveled job, get the terminal name from
{ the original job.  Otherwise, there is no terminal name.

        IF (submit_job_variation.kind = jmc$connection_switch) OR
              (submit_job_variation.kind = jmc$remote_connection_switch) THEN
          PUSH peer_accounting_information_p: [jmv$job_attributes.job_input_device.size];
          peer_accounting_information_p^ := jmv$job_attributes.job_input_device.text;
        ELSE
          peer_accounting_information_p := NIL;
        IFEND;
      IFEND;

      IF peer_accounting_information_p <> NIL THEN
        PUSH get_accounting_data_p: [1 .. 1];
        get_accounting_data_p^ [1].kind := nac$ca_device_name;
        nap$parse_accounting_data (peer_accounting_information_p, NIL, get_accounting_data_p, local_status);
        IF local_status.normal THEN
          terminal_name := get_accounting_data_p^ [1].device_name;
          terminal_name_found := TRUE;
        IFEND;
      IFEND;
    IFEND;

  PROCEND get_terminal_name;
?? OLDTITLE ??
?? NEWTITLE := 'terminate_job', EJECT ??

{ The purpose of this request is to terminate a job.  This request is made on the
{ server mainframe on which the job resides.

  PROCEDURE terminate_job
    (    system_job_name: jmt$system_supplied_name;
         job_state_set: jmt$job_state_set;
         output_disposition_key_known: boolean;
         output_disposition_key: jmt$output_disposition_keys;
         operator_job: boolean;
         reason: ost$name;
     VAR status: ost$status);

    VAR
      client_location: dft$server_location,
      client_mainframe_id: pmt$mainframe_id,
      cycle_selector: pft$cycle_selector,
      data_size: dft$send_data_size,
      delete_input_file: boolean,
      family_name: ost$name,
      ignore_status: ost$status,
      input_file_location: jmt$input_file_location,
      job_assigned_to_client: boolean,
      local_remove_job_from_kjl_p: ^boolean,
      local_system_job_name_p: ^jmt$system_supplied_name,
      local_terminate_job_request_p: ^terminate_job_request,
      parameter_size: dft$send_parameter_size,
      password: pft$password,
      path_p: ^pft$path,
      queue_entry_location: dft$rpc_queue_entry_location,
      receive_from_server_data_p: dft$p_receive_data,
      receive_from_server_params_p: dft$p_receive_parameters,
      remove_job_from_kjl: boolean,
      send_to_server_data_p: dft$p_send_data,
      send_to_server_parameters_p: dft$p_send_parameters;

?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;
?? OLDTITLE ??
?? NEWTITLE := 'dfp$remote_procedure_call_ch', EJECT ??

{ PURPOSE:
{   This procedure is a condition handler established to call a routine to clear the assignment of a task
{   services queue_entry if a task aborts with a queue_entry assigned to it.  The queue_entry must be clear
{   before the task can safely exit.

    PROCEDURE dfp$remote_procedure_call_ch
      (    condition: pmt$condition;
           cond_desc: ^pmt$condition_information;
           save: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      dfp$ch_cleanup;
      osp$set_status_from_condition (dfc$file_server_id, condition, save, status, ignore_status);
      EXIT terminate_job;

    PROCEND dfp$remote_procedure_call_ch;
*block
*copyc dfp$begin_ch_remote_proc_call
*copyc dfp$end_ch_remote_proc_call
*blockend
?? OLDTITLE, EJECT ??

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

    qfp$terminate_job (system_job_name, job_state_set, output_disposition_key_known, output_disposition_key,
          operator_job, family_name, delete_input_file, input_file_location, job_assigned_to_client,
          client_mainframe_id, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF job_assigned_to_client THEN
      client_location.server_location_selector := dfc$mainframe_id;
      client_location.server_mainframe := client_mainframe_id;

      dfp$begin_ch_remote_proc_call (client_location, { allowed_when_server_deactivated } FALSE,
            queue_entry_location, send_to_server_parameters_p, send_to_server_data_p, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

{ Build the data and parameters to send to the server.
{ The RPC sequences have already been reset.

      NEXT local_system_job_name_p IN send_to_server_parameters_p;
      local_system_job_name_p^ := system_job_name;
      NEXT local_terminate_job_request_p IN send_to_server_parameters_p;
      local_terminate_job_request_p^.server := FALSE;
      local_terminate_job_request_p^.job_state_set := job_state_set;
      local_terminate_job_request_p^.output_disposition_key_known := output_disposition_key_known;
      local_terminate_job_request_p^.output_disposition_key := output_disposition_key;
      local_terminate_job_request_p^.operator_job := operator_job;
      local_terminate_job_request_p^.reason := reason;
      parameter_size := i#current_sequence_position (send_to_server_parameters_p);
      data_size := i#current_sequence_position (send_to_server_data_p);

      dfp$send_remote_procedure_call (queue_entry_location, dfc$rpc_jl_terminate_job, parameter_size,
            data_size, receive_from_server_params_p, receive_from_server_data_p, status);
      IF status.normal THEN
        NEXT local_remove_job_from_kjl_p IN receive_from_server_params_p;
        remove_job_from_kjl := local_remove_job_from_kjl_p^;
        delete_input_file := remove_job_from_kjl;
        dfp$end_ch_remote_proc_call (queue_entry_location, status);
      ELSE
        dfp$end_ch_remote_proc_call (queue_entry_location, ignore_status);
      IFEND;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF remove_job_from_kjl THEN
      qfp$remove_job_from_kjl (system_job_name);
    IFEND;

    IF delete_input_file THEN

      IF jmv$job_history_active THEN
        jmp$emit_job_history_statistics (jml$job_file_deleted, osc$null_name, system_job_name,
              jmc$blank_system_supplied_name, NIL, NIL, reason, jmc$blank_system_supplied_name, status);
      IFEND;

      determine_file_path (input_file_location, family_name, system_job_name, path_p);
      cycle_selector.cycle_option := pfc$specific_cycle;
      cycle_selector.cycle_number := 1;
      password := osc$null_name;
      osp$establish_block_exit_hndlr (^handle_block_exit);
      pfp$begin_system_authority;
      pfp$purge (path_p^, cycle_selector, password, status);
      pfp$end_system_authority;
      osp$disestablish_cond_handler;
    IFEND;
  PROCEND terminate_job;
?? OLDTITLE ??
?? NEWTITLE := 'terminate_job_on_server', EJECT ??

{ PURPOSE:
{   The purpose of this request is to terminate a job that resides on a mainframe.
{ other than the requesting mainframe.  This request is used to locate the server
{ mainframe on which a job resides.

  PROCEDURE terminate_job_on_server
    (    system_job_name: jmt$system_supplied_name;
         server_mainframe_id: pmt$mainframe_id;
         server_terminate_job_request: terminate_job_request;
     VAR mainframes_searched_count: { input, output } jmt$maximum_mainframes;
     VAR mainframes_searched_list: { input, output } jmt$mainframes_searched_list;
     VAR job_terminated: boolean;
     VAR status: ost$status);

?? NEWTITLE := 'dfp$remote_procedure_call_ch', EJECT ??

{ PURPOSE:
{   This procedure is a condition handler established to call a routine to clear the assignment of a task
{   services queue_entry if a task aborts with a queue_entry assigned to it.  The queue_entry must be clear
{   before the task can safely exit.

    PROCEDURE dfp$remote_procedure_call_ch
      (    condition: pmt$condition;
           cond_desc: ^pmt$condition_information;
           save: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      dfp$ch_cleanup;
      osp$set_status_from_condition (dfc$file_server_id, condition, save, status, ignore_status);
      EXIT terminate_job_on_server;

    PROCEND dfp$remote_procedure_call_ch;
*block
*copyc dfp$begin_ch_remote_proc_call
*copyc dfp$end_ch_remote_proc_call
*blockend
?? OLDTITLE, EJECT ??

    VAR
      data_size: dft$send_data_size,
      local_job_terminated_p: ^boolean,
      local_mf_searched_count_p: ^jmt$maximum_mainframes,
      local_mf_searched_list_p: ^jmt$mainframes_searched_list,
      local_status: ost$status,
      local_system_job_name_p: ^jmt$system_supplied_name,
      local_terminate_job_request_p: ^terminate_job_request,
      parameter_size: dft$send_parameter_size,
      queue_entry_location: dft$rpc_queue_entry_location,
      receive_from_server_data_p: dft$p_receive_data,
      receive_from_server_params_p: dft$p_receive_parameters,
      send_to_server_data_p: dft$p_send_data,
      send_to_server_parameters_p: dft$p_send_parameters,
      server_location: dft$server_location;

    status.normal := TRUE;
    job_terminated := FALSE;
    server_location.server_location_selector := dfc$mainframe_id;
    server_location.server_mainframe := server_mainframe_id;

{ If the server can't be called, then return and try elsewhere.

    dfp$begin_ch_remote_proc_call (server_location, { allowed_when_server_deactivated } FALSE,
          queue_entry_location, send_to_server_parameters_p, send_to_server_data_p, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;

{ Build the data and parameters to send to the server.
{ The RPC sequences have already been reset.

    NEXT local_system_job_name_p IN send_to_server_parameters_p;
    local_system_job_name_p^ := system_job_name;
    NEXT local_terminate_job_request_p IN send_to_server_parameters_p;
    local_terminate_job_request_p^ := server_terminate_job_request;

    NEXT local_mf_searched_count_p IN send_to_server_data_p;
    local_mf_searched_count_p^ := mainframes_searched_count;
    NEXT local_mf_searched_list_p IN send_to_server_data_p;
    local_mf_searched_list_p^ := mainframes_searched_list;

    parameter_size := i#current_sequence_position (send_to_server_parameters_p);
    data_size := i#current_sequence_position (send_to_server_data_p);

    dfp$send_remote_procedure_call (queue_entry_location, dfc$rpc_jl_terminate_job, parameter_size, data_size,
          receive_from_server_params_p, receive_from_server_data_p, status);
    IF status.normal THEN
      NEXT local_job_terminated_p IN receive_from_server_params_p;
      job_terminated := local_job_terminated_p^;

      NEXT local_mf_searched_count_p IN receive_from_server_data_p;
      mainframes_searched_count := local_mf_searched_count_p^;
      NEXT local_mf_searched_list_p IN receive_from_server_data_p;
      mainframes_searched_list := local_mf_searched_list_p^;

    IFEND;
    dfp$end_ch_remote_proc_call (queue_entry_location, { ignore } local_status);

  PROCEND terminate_job_on_server;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$acquire_modified_input', EJECT ??
*copy jmh$acquire_modified_input

  PROCEDURE [XDCL, #GATE] jmp$acquire_modified_input
    (    input_destination_usage: jmt$destination_usage;
     VAR input_descriptor: jmt$input_descriptor;
     VAR status: ost$status);

    acquire_input (input_destination_usage, FALSE, input_descriptor, status);

  PROCEND jmp$acquire_modified_input;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$acquire_new_input', EJECT ??
*copy jmh$acquire_new_input

  PROCEDURE [XDCL, #GATE] jmp$acquire_new_input
    (    input_destination_usage: jmt$destination_usage;
     VAR input_descriptor: jmt$input_descriptor;
     VAR status: ost$status);

    acquire_input (input_destination_usage, TRUE, input_descriptor, status);

  PROCEND jmp$acquire_new_input;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$activate_deferred_family', EJECT ??
*copy jmh$activate_deferred_family

  PROCEDURE [XDCL] jmp$activate_deferred_family
    (    activated_family_list: ^pmt$family_name_list);

    VAR
      family_name: ost$name,
      family_name_index: ost$non_negative_integers;

    IF activated_family_list <> NIL THEN
      FOR family_name_index := 1 TO UPPERBOUND (activated_family_list^) DO
        family_name := activated_family_list^ [family_name_index];
        qfp$activate_deferred_family (family_name);
      FOREND;
    IFEND;
  PROCEND jmp$activate_deferred_family;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$activate_job', EJECT ??
*copy jmh$activate_job

{ DESIGN:
{   Check if the caller is a system administrator or operator.  If so, call jmp$rebuild_input_queue to
{ recover the job's command file.

  PROCEDURE [XDCL, #GATE] jmp$activate_job
    (    system_job_name: jmt$system_supplied_name;
         family_name: ost$name;
         subcatalog_name: ost$name;
         recover_using_abort_disposition: boolean;
         ignore_client_initiated_jobs: boolean;
     VAR status: ost$status);

    status.normal := TRUE;

    IF NOT (avp$system_administrator () OR avp$system_operator ()) THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'system_administration OR system_operation', status);
      RETURN;
    IFEND;

    jmp$rebuild_input_queue (system_job_name, family_name, subcatalog_name, recover_using_abort_disposition,
          ignore_client_initiated_jobs, {job_deferred_by_operator} FALSE, status);

  PROCEND jmp$activate_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$call_server_terminate_job', EJECT ??
*copy jmh$call_server_terminate_job

  PROCEDURE [XDCL] jmp$call_server_terminate_job
    (    system_job_name: jmt$system_supplied_name;
         server_mainframe_id: pmt$mainframe_id;
         job_state_set: jmt$job_state_set;
         output_disposition_key_known: boolean;
         output_disposition_key: jmt$output_disposition_keys;
         operator_job: boolean;
         reason: ost$name;
     VAR status: ost$status);

    VAR
      job_terminated: boolean,
      mainframe_id: pmt$mainframe_id,
      mainframes_searched_count: jmt$maximum_mainframes,
      mainframes_searched_list: jmt$mainframes_searched_list,
      mainframes_searched_list_index: jmt$maximum_mainframes,
      server_binary_mainframe_id: pmt$binary_mainframe_id,
      server_directly_connected: boolean,
      server_mainframe_count: dft$partner_mainframe_count,
      server_mainframe_index: dft$partner_mainframe_count,
      server_mainframe_list: array [1 .. dfc$maximum_partner_mainframes] of dft$partner_mainframe_entry,
      server_terminate_job_request: terminate_job_request;

    status.normal := TRUE;

{ Place this mainframe in the mainframes searched list.

    mainframes_searched_count := 1;
    pmp$get_pseudo_mainframe_id (mainframes_searched_list [1]);
    pmp$convert_mainframe_to_binary (server_mainframe_id, server_binary_mainframe_id, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    server_directly_connected := FALSE;
    server_terminate_job_request.server := TRUE;
    server_terminate_job_request.server_mainframe_id := server_mainframe_id;
    server_terminate_job_request.job_state_set := job_state_set;
    server_terminate_job_request.output_disposition_key_known := output_disposition_key_known;
    server_terminate_job_request.output_disposition_key := output_disposition_key;
    server_terminate_job_request.operator_job := operator_job;
    server_terminate_job_request.reason := reason;

    dfp$get_partner_mainframes ({ partners_are_servers } TRUE, ^server_mainframe_list,
          server_mainframe_count);

{ See if the server is directly connected to this mainframe.  If so it can simply
{ be called.  If NOT, a remote procedure call will be required until a mainframe is
{ reached which can access the server or the server cannot be found.

  /search_for_server_mainframe/
    FOR server_mainframe_index := 1 TO server_mainframe_count DO
      IF server_mainframe_list [server_mainframe_index].mainframe_id = server_binary_mainframe_id THEN
        server_directly_connected := TRUE;
        terminate_job_on_server (system_job_name, server_mainframe_id, server_terminate_job_request,
              mainframes_searched_count, mainframes_searched_list, job_terminated, status);
        EXIT /search_for_server_mainframe/;
      IFEND;
    FOREND /search_for_server_mainframe/;

    IF NOT server_directly_connected THEN

    /call_each_server_mainframe/
      FOR server_mainframe_index := 1 TO server_mainframe_count DO
        IF mainframes_searched_count < jmc$maximum_mainframes THEN

{ If the server has already been called then try another server.

          FOR mainframes_searched_list_index := 1 TO mainframes_searched_count DO
            IF mainframes_searched_list [mainframes_searched_list_index] =
                  server_mainframe_list [server_mainframe_index].mainframe_id THEN
              CYCLE /call_each_server_mainframe/;
            IFEND;
          FOREND;
          IF server_mainframe_list [server_mainframe_index].partner_state = dfc$active THEN
            pmp$convert_binary_mainframe_id (server_mainframe_list [server_mainframe_index].mainframe_id,
                  mainframe_id, { ignore } status);
            status.normal := TRUE;
            terminate_job_on_server (system_job_name, mainframe_id, server_terminate_job_request,
                  mainframes_searched_count, mainframes_searched_list, job_terminated, status);
            IF job_terminated THEN
              EXIT /call_each_server_mainframe/;
            IFEND;
          IFEND;
        ELSE
          EXIT /call_each_server_mainframe/;
        IFEND;
      FOREND /call_each_server_mainframe/;
    IFEND;
    IF NOT job_terminated THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$name_not_found, system_job_name, status);
    IFEND;
  PROCEND jmp$call_server_terminate_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$change_input_attributes', EJECT ??
*copy jmh$change_input_attributes

  PROCEDURE [XDCL, #GATE] jmp$change_input_attributes
    (    input_name: jmt$name;
         input_attribute_changes: ^jmt$input_attribute_changes;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      change_index: integer,
      ignore_status: ost$status,
      jm_work_area_p: ^jmt$work_area,
      job_status_results_keys_p: ^jmt$results_keys,
      job_status_results_seq_p: ^jmt$work_area,
      job_qualifier_index: 1 .. jmc$maximum_job_qualifiers,
      job_status_options_p: ^jmt$job_status_options,
      job_status_results_p: ^jmt$job_status_results,
      local_attribute_changes_p: ^jmt$input_attribute_changes,
      local_output_disposition_path_p: ^fst$path,
      local_parameters_p: ^mainframe_chaia_parameters,
      local_purge_delay_p: ^jmt$time_increment,
      local_remote_host_directive_p: ^jmt$remote_host_directive,
      local_site_information_p: ^jmt$site_information,
      local_user_information_p: ^jmt$user_information,
      mainframes_processed: jmt$rpc_mainframes_processed,
      number_of_data_packets: ost$non_negative_integers,
      number_of_jobs_found: jmt$job_count_range,
      parsed_file_reference: fst$parsed_file_reference,
      privileged_job: boolean,
      privileged_job_for_status: boolean,
      scl_name: ost$name,
      scratch_segment: amt$segment_pointer,
      size_of_sequence: ost$segment_length,
      system_changing_attributes: boolean,
      target_mainframe_reached: boolean,
      target_options_p: ^SEQ ( * ),
      target_options_size: ost$non_negative_integers,
      valid_name: boolean;

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

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions.

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      CASE condition.selector OF
      = pmc$block_exit_processing =
        mmp$delete_scratch_segment (scratch_segment, ignore_status);
        IF status.normal THEN
          osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
        IFEND;

      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
      CASEND;
    PROCEND condition_handler;

?? OLDTITLE ??
?? EJECT ??

    ignore_status.normal := TRUE;
    status.normal := TRUE;
    #CALLER_ID (caller_id);

    system_changing_attributes := (osp$is_caller_system_privileged () AND (caller_id.ring <= osc$tsrv_ring));
    privileged_job := osp$is_caller_system_privileged () OR jmv$enable_queue_file_access OR
          avp$system_operator ();
    jmp$get_scheduling_admin_status ({local} ignore_status);
    privileged_job_for_status := system_changing_attributes OR avp$system_operator () OR ignore_status.normal;

    PUSH job_status_options_p: [1 .. 4];
    job_status_options_p^ [1].key := jmc$name_list;
    PUSH job_status_options_p^ [1].name_list: [1 .. 1];
    job_status_options_p^ [1].name_list^ [1] := input_name;
    job_status_options_p^ [2].key := jmc$include_the_system_job;
    job_status_options_p^ [2].include_the_system_job := FALSE;
    job_status_options_p^ [3].key := jmc$privilege;
    IF privileged_job_for_status THEN
      job_status_options_p^ [3].privilege := jmc$privileged;
    ELSE
      job_status_options_p^ [3].privilege := jmc$not_privileged;
    IFEND;
    job_status_options_p^ [4].key := jmc$continue_request_to_servers;
    job_status_options_p^ [4].continue_request_to_servers := TRUE;

    PUSH job_status_results_keys_p: [1 .. 7];
    job_status_results_keys_p^ [1] := jmc$system_job_name;
    job_status_results_keys_p^ [2] := jmc$job_state;
    job_status_results_keys_p^ [3] := jmc$input_file_location;
    job_status_results_keys_p^ [4] := jmc$login_family;
    job_status_results_keys_p^ [5] := jmc$job_class;
    job_status_results_keys_p^ [6] := jmc$job_mode;
    job_status_results_keys_p^ [7] := jmc$server_mainframe_id;

    jmp$get_result_size ({number_of_jobs} 1, #SEQ (job_status_results_keys_p^), size_of_sequence);
    PUSH job_status_results_seq_p: [[REP size_of_sequence OF cell]];

{ If we are able to status the input file, we have control over the file
{ so we can change the attributes of the file

    jmp$get_job_status (job_status_options_p, job_status_results_keys_p, job_status_results_seq_p,
          job_status_results_p, number_of_jobs_found, status);
    IF number_of_jobs_found = 0 THEN
      IF input_name.kind = jmc$system_supplied_name THEN
        osp$set_status_abnormal (jmc$job_management_id, jme$name_not_found, input_name.system_supplied_name,
              status);
      ELSE
        osp$set_status_abnormal (jmc$job_management_id, jme$name_not_found, input_name.user_supplied_name,
              status);
      IFEND;
    ELSEIF number_of_jobs_found > 1 THEN
      IF input_name.kind = jmc$system_supplied_name THEN { Can't ever happen
        osp$set_status_abnormal (jmc$job_management_id, jme$duplicate_name, input_name.system_supplied_name,
              status);
      ELSE
        osp$set_status_abnormal (jmc$job_management_id, jme$duplicate_name, input_name.user_supplied_name,
              status);
      IFEND;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF job_status_results_p^ [1]^ [6].job_mode <> jmc$batch THEN
      osp$set_status_condition (jme$cannot_change_interactive, status);
      RETURN;
    IFEND;

    IF job_status_results_p^ [1]^ [2].job_state IN $jmt$job_state_set
          [jmc$initiated_job, jmc$terminating_job] THEN

{ In order for the job state to be terminating, the file must either be initiated or the application
{ responsible for the file will momentarily return the file to queue file management.  In any case,
{ the same error (jme$input_is_initiated) is reported since the latter is not likely to occur.

      IF input_name.kind = jmc$system_supplied_name THEN
        osp$set_status_abnormal (jmc$job_management_id, jme$input_is_initiated,
              input_name.system_supplied_name, status);
      ELSE
        osp$set_status_abnormal (jmc$job_management_id, jme$input_is_initiated, input_name.user_supplied_name,
              status);
      IFEND;
      RETURN;
    IFEND;

    osp$establish_block_exit_hndlr (^condition_handler);
    mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_sequential, scratch_segment, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    RESET scratch_segment.sequence_pointer;

    NEXT local_parameters_p IN scratch_segment.sequence_pointer;
    local_parameters_p^.system_job_name := job_status_results_p^ [1]^ [1].system_job_name;
    local_parameters_p^.login_family := job_status_results_p^ [1]^ [4].login_family;
    local_parameters_p^.input_file_location := job_status_results_p^ [1]^ [3].input_file_location;
    local_parameters_p^.system_changing_attributes := system_changing_attributes;
    local_parameters_p^.privileged_for_status := privileged_job_for_status;
    local_parameters_p^.beginning_job_class := job_status_results_p^ [1]^ [5].job_class;

{ Check attribute changes and setup to call the cluster remote procedure target.

    IF input_attribute_changes = NIL THEN
      local_parameters_p^.attribute_change_count := 0;
    ELSE
      local_parameters_p^.attribute_change_count := UPPERBOUND (input_attribute_changes^);
      NEXT local_attribute_changes_p: [1 .. local_parameters_p^.attribute_change_count] IN
            scratch_segment.sequence_pointer;

    /process_changes/
      FOR change_index := 1 TO local_parameters_p^.attribute_change_count DO
        local_attribute_changes_p^ [change_index].key := input_attribute_changes^ [change_index].key;
        CASE input_attribute_changes^ [change_index].key OF
        = jmc$comment_banner =
          local_attribute_changes_p^ [change_index].comment_banner :=
                input_attribute_changes^ [change_index].comment_banner;

        = jmc$copies =
          local_attribute_changes_p^ [change_index].copies := input_attribute_changes^ [change_index].copies;

        = jmc$cpu_time_limit =
          local_attribute_changes_p^ [change_index].cpu_time_limit :=
                input_attribute_changes^ [change_index].cpu_time_limit;

        = jmc$device =
          clp$validate_name (input_attribute_changes^ [change_index].device, scl_name, valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name, input_attribute_changes^ [change_index].device,
                  status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].device := scl_name;

        = jmc$earliest_print_time =
          local_attribute_changes_p^ [change_index].earliest_print_time :=
                input_attribute_changes^ [change_index].earliest_print_time;

        = jmc$earliest_run_time =
          local_attribute_changes_p^ [change_index].earliest_run_time :=
                input_attribute_changes^ [change_index].earliest_run_time;

        = jmc$encrypted_password =
          IF system_changing_attributes THEN
            IF input_attribute_changes^ [change_index].encrypted_password = osc$null_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    input_attribute_changes^ [change_index].encrypted_password, status);
              EXIT /process_changes/;
            IFEND;
            local_attribute_changes_p^ [change_index].encrypted_password :=
                  input_attribute_changes^ [change_index].encrypted_password;
          ELSE
            osp$force_access_violation;
          IFEND;

        = jmc$external_characteristics =
          #TRANSLATE (osv$lower_to_upper, input_attribute_changes^ [change_index].external_characteristics,
                local_attribute_changes_p^ [change_index].external_characteristics);

        = jmc$forms_code =
          #TRANSLATE (osv$lower_to_upper, input_attribute_changes^ [change_index].forms_code,
                local_attribute_changes_p^ [change_index].forms_code);

        = jmc$job_abort_disposition =
          local_attribute_changes_p^ [change_index].job_abort_disposition :=
                input_attribute_changes^ [change_index].job_abort_disposition;

        = jmc$job_class =
          clp$validate_name (input_attribute_changes^ [change_index].job_class, scl_name, valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name,
                  input_attribute_changes^ [change_index].job_class, status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].job_class := scl_name;

        = jmc$job_deferred_by_operator =
          IF NOT privileged_job THEN
            osp$set_status_abnormal (jmc$job_management_id, jme$requires_operator_privilege,
                  'JOB_DEFERRED_BY_OPERATOR', status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].job_deferred_by_operator :=
                input_attribute_changes^ [change_index].job_deferred_by_operator;

        = jmc$job_deferred_by_user =
          local_attribute_changes_p^ [change_index].job_deferred_by_user :=
                input_attribute_changes^ [change_index].job_deferred_by_user;

        = jmc$job_qualifier_list =
          NEXT local_attribute_changes_p^ [change_index].job_qualifier_list:
                [1 .. jmc$maximum_job_qualifiers] IN scratch_segment.sequence_pointer;
          FOR job_qualifier_index := 1 TO jmc$maximum_job_qualifiers DO
            IF (input_attribute_changes^ [change_index].job_qualifier_list <> NIL) AND
                  (UPPERBOUND (input_attribute_changes^ [change_index].job_qualifier_list^) >=
                  job_qualifier_index) THEN
              IF input_attribute_changes^ [change_index].job_qualifier_list^ [job_qualifier_index] =
                    osc$null_name THEN
                scl_name := osc$null_name;
              ELSE
                clp$validate_name (input_attribute_changes^ [change_index].
                      job_qualifier_list^ [job_qualifier_index], scl_name, valid_name);
                IF NOT valid_name THEN
                  osp$set_status_abnormal ('CL', cle$improper_name,
                        input_attribute_changes^ [change_index].job_qualifier_list^ [job_qualifier_index],
                        status);
                  EXIT /process_changes/;
                IFEND;
              IFEND;
              local_attribute_changes_p^ [change_index].job_qualifier_list^ [job_qualifier_index] := scl_name;
            ELSE
              local_attribute_changes_p^ [change_index].job_qualifier_list^ [job_qualifier_index] :=
                    osc$null_name;
            IFEND;
          FOREND;

        = jmc$job_recovery_disposition =
          local_attribute_changes_p^ [change_index].job_recovery_disposition :=
                input_attribute_changes^ [change_index].job_recovery_disposition;

        = jmc$latest_print_time =
          local_attribute_changes_p^ [change_index].latest_print_time :=
                input_attribute_changes^ [change_index].latest_print_time;

        = jmc$latest_run_time =
          local_attribute_changes_p^ [change_index].latest_run_time :=
                input_attribute_changes^ [change_index].latest_run_time;

        = jmc$login_account =
          IF input_attribute_changes^ [change_index].login_account = osc$null_name THEN
            scl_name := osc$null_name;
          ELSE
            clp$validate_name (input_attribute_changes^ [change_index].login_account, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    input_attribute_changes^ [change_index].login_account, status);
              EXIT /process_changes/;
            IFEND;
          IFEND;
          local_attribute_changes_p^ [change_index].login_account := scl_name;

        = jmc$login_project =
          IF input_attribute_changes^ [change_index].login_project = osc$null_name THEN
            scl_name := osc$null_name;
          ELSE
            clp$validate_name (input_attribute_changes^ [change_index].login_project, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    input_attribute_changes^ [change_index].login_project, status);
              EXIT /process_changes/;
            IFEND;
          IFEND;
          local_attribute_changes_p^ [change_index].login_project := scl_name;

        = jmc$magnetic_tape_limit =
          local_attribute_changes_p^ [change_index].magnetic_tape_limit :=
                input_attribute_changes^ [change_index].magnetic_tape_limit;

        = jmc$maximum_working_set =
          local_attribute_changes_p^ [change_index].maximum_working_set :=
                input_attribute_changes^ [change_index].maximum_working_set;

        = jmc$null_attribute =
          ;

        = jmc$output_class =
          clp$validate_name (input_attribute_changes^ [change_index].output_class, scl_name, valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name,
                  input_attribute_changes^ [change_index].output_class, status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].output_class := scl_name;

        = jmc$output_deferred_by_user =
          local_attribute_changes_p^ [change_index].output_deferred_by_user :=
                input_attribute_changes^ [change_index].output_deferred_by_user;

        = jmc$output_destination =
          clp$validate_name (input_attribute_changes^ [change_index].output_destination, scl_name,
                valid_name);
          IF valid_name THEN
            local_attribute_changes_p^ [change_index].output_destination := scl_name;
          ELSE
            #TRANSLATE (osv$lower_to_upper, input_attribute_changes^ [change_index].output_destination,
                  local_attribute_changes_p^ [change_index].output_destination);
          IFEND;

        = jmc$output_destination_family =
          clp$validate_name (input_attribute_changes^ [change_index].output_destination_family, scl_name,
                valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name,
                  input_attribute_changes^ [change_index].output_destination_family, status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].output_destination_family := scl_name;

        = jmc$output_destination_usage =
          clp$validate_name (input_attribute_changes^ [change_index].output_destination_usage, scl_name,
                valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name,
                  input_attribute_changes^ [change_index].output_destination_usage, status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].output_destination_usage := scl_name;

        = jmc$output_disposition =
          local_attribute_changes_p^ [change_index].output_disposition.key :=
                input_attribute_changes^ [change_index].output_disposition.key;
          IF local_attribute_changes_p^ [change_index].output_disposition.key = jmc$standard_output_path THEN
            NEXT local_output_disposition_path_p IN scratch_segment.sequence_pointer;

            clp$convert_string_to_file_ref (input_attribute_changes^ [change_index].output_disposition.
                  standard_output_path^, parsed_file_reference, status);
            IF NOT status.normal THEN
              EXIT /process_changes/;
            IFEND;
            IF parsed_file_reference.path (parsed_file_reference.first_name.index,
                  parsed_file_reference.first_name.size) = '$LOCAL' THEN
              osp$set_status_condition (jme$permanent_file_required, status);
              EXIT /process_changes/;
            IFEND;
            local_output_disposition_path_p^ := parsed_file_reference.
                  path (1, parsed_file_reference.complete_path_size);
          IFEND;

        = jmc$output_priority =
          clp$validate_name (input_attribute_changes^ [change_index].output_priority, scl_name, valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name,
                  input_attribute_changes^ [change_index].output_priority, status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].output_priority := scl_name;

        = jmc$purge_delay =
          NEXT local_purge_delay_p IN scratch_segment.sequence_pointer;
          local_purge_delay_p^ := input_attribute_changes^ [change_index].purge_delay^;

        = jmc$remote_host_directive =
          NEXT local_remote_host_directive_p IN scratch_segment.sequence_pointer;
          local_remote_host_directive_p^ := input_attribute_changes^ [change_index].remote_host_directive^;

        = jmc$routing_banner =
          local_attribute_changes_p^ [change_index].routing_banner :=
                input_attribute_changes^ [change_index].routing_banner;

        = jmc$site_information =
          IF avp$system_operator () THEN
            NEXT local_site_information_p IN scratch_segment.sequence_pointer;
            local_site_information_p^ := input_attribute_changes^ [change_index].site_information^;
          ELSE
            osp$set_status_abnormal ('OF', ofe$sou_not_active, 'system_operation', status);
            EXIT /process_changes/;
          IFEND;

        = jmc$sru_limit =
          local_attribute_changes_p^ [change_index].sru_limit :=
                input_attribute_changes^ [change_index].sru_limit;

        = jmc$station =
          clp$validate_name (input_attribute_changes^ [change_index].station, scl_name, valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name, input_attribute_changes^ [change_index].station,
                  status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].station := scl_name;

        = jmc$station_operator =
          clp$validate_name (input_attribute_changes^ [change_index].station_operator, scl_name, valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name,
                  input_attribute_changes^ [change_index].station_operator, status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].station_operator := scl_name;

        = jmc$user_information =
          NEXT local_user_information_p IN scratch_segment.sequence_pointer;
          local_user_information_p^ := input_attribute_changes^ [change_index].user_information^;

        = jmc$user_job_name =
          clp$validate_name (input_attribute_changes^ [change_index].user_job_name, scl_name, valid_name);
          IF NOT valid_name THEN
            osp$set_status_abnormal ('CL', cle$improper_name,
                  input_attribute_changes^ [change_index].user_job_name, status);
            EXIT /process_changes/;
          IFEND;
          local_attribute_changes_p^ [change_index].user_job_name := scl_name;

        = jmc$vertical_print_density =
          local_attribute_changes_p^ [change_index].vertical_print_density :=
                input_attribute_changes^ [change_index].vertical_print_density;

          IF local_attribute_changes_p^ [change_index].vertical_print_density >
                jmc$vertical_print_density_6 THEN
            local_attribute_changes_p^ [change_index].vertical_print_density := jmc$vertical_print_density_8;
          IFEND;

        = jmc$vfu_load_procedure =
          IF input_attribute_changes^ [change_index].vfu_load_procedure <> osc$null_name THEN
            clp$validate_name (input_attribute_changes^ [change_index].vfu_load_procedure, scl_name,
                  valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    input_attribute_changes^ [change_index].vfu_load_procedure, status);
              EXIT /process_changes/;
            IFEND;
            local_attribute_changes_p^ [change_index].vfu_load_procedure := scl_name;
          ELSE
            local_attribute_changes_p^ [change_index].vfu_load_procedure := osc$null_name;
          IFEND;

        ELSE
          jmp$get_attribute_name (input_attribute_changes^ [change_index].key, scl_name);
          osp$set_status_abnormal (jmc$job_management_id, jme$invalid_parameter, scl_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, 'INPUT_ATTRIBUTE_CHANGES', status);
          osp$append_status_parameter (osc$status_parameter_delimiter, jmc$change_input_attributes, status);
          EXIT /process_changes/;
        CASEND;
      FOREND /process_changes/;
      IF NOT status.normal THEN
        mmp$delete_scratch_segment (scratch_segment, ignore_status);
        osp$disestablish_cond_handler;
        RETURN;
      IFEND;
    IFEND;

    mainframes_processed.count := 0;
    target_options_size := i#current_sequence_position (scratch_segment.sequence_pointer);
    RESET scratch_segment.sequence_pointer;
    NEXT target_options_p: [[REP target_options_size OF cell]] IN scratch_segment.sequence_pointer;
    RESET target_options_p;
    jm_work_area_p := NIL;

    jmp$general_purpose_cluster_rpc (job_status_results_p^ [1]^ [7].server_mainframe_id,
          jmc$gpro_change_input_attribute, {data_packet_size} 0, mainframes_processed, target_options_p,
          jm_work_area_p, target_mainframe_reached, mainframes_processed, number_of_data_packets, status);

    IF status.normal THEN
      mmp$delete_scratch_segment (scratch_segment, status);
    ELSE
      mmp$delete_scratch_segment (scratch_segment, ignore_status);
    IFEND;
    osp$disestablish_cond_handler;
  PROCEND jmp$change_input_attributes;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$change_terminate_job_action', EJECT ??
*copy jmh$change_terminate_job_action

  PROCEDURE [XDCL, #GATE] jmp$change_terminate_job_action
    (    terminate_job_action_set: jmt$terminate_job_action_set;
     VAR status: ost$status);

    status.normal := TRUE;

    IF NOT avp$configuration_administrator () THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'configuration_administration', status);
      RETURN;
    IFEND;
    qfp$change_terminate_job_action (terminate_job_action_set);
  PROCEND jmp$change_terminate_job_action;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$close_input_file', EJECT ??
*copy jmh$close_input_file

  PROCEDURE [XDCL, #GATE] jmp$close_input_file
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    fsp$close_file (file_identifier, status);

  PROCEND jmp$close_input_file;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$cluster_get_leveling_data', EJECT ??
*copy jmh$cluster_get_leveling_data

  PROCEDURE [XDCL] jmp$cluster_get_leveling_data
    (    target_mainframe_id: pmt$mainframe_id;
         target_options_p: ^SEQ ( * );
         data_packet_size: ost$segment_length;
     VAR data_area_p: {input, output} ^SEQ ( * );
     VAR mainframes_processed: jmt$rpc_mainframes_processed;
     VAR number_of_data_packets: ost$non_negative_integers;
     VAR status: ost$status);

    VAR
      target_mainframe_reached: boolean;

    mainframes_processed.count := 0;

    jmp$general_purpose_cluster_rpc (target_mainframe_id, jmc$gpro_get_leveling_data, data_packet_size,
          mainframes_processed, target_options_p, data_area_p, target_mainframe_reached, mainframes_processed,
          number_of_data_packets, status);

  PROCEND jmp$cluster_get_leveling_data;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$defer_deactivated_family', EJECT ??
*copy jmh$defer_deactivated_family

  PROCEDURE [XDCL] jmp$defer_deactivated_family
    (    deactivated_family_list: ^pmt$family_name_list);

    VAR
      family_name: ost$name,
      family_name_index: ost$non_negative_integers;

    IF deactivated_family_list <> NIL THEN
      FOR family_name_index := 1 TO UPPERBOUND (deactivated_family_list^) DO
        family_name := deactivated_family_list^ [family_name_index];
        qfp$defer_deactivated_family (family_name);
      FOREND;
    IFEND;
  PROCEND jmp$defer_deactivated_family;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$get_input_attributes', EJECT ??
*copy jmh$get_input_attributes

  PROCEDURE [XDCL, #GATE] jmp$get_input_attributes
    (    input_attribute_options_p: ^jmt$input_attribute_options;
         input_attribute_results_keys_p: ^jmt$results_keys;
     VAR work_area_p: ^jmt$work_area;
     VAR input_attribute_results_p: ^jmt$input_attribute_results;
     VAR number_of_jobs_found: jmt$job_status_count;
     VAR status: ost$status);

    VAR
      continue_request_to_servers: boolean,
      ignore_status: ost$status,
      jm_work_area_p: ^jmt$work_area,
      job_status_options_p: ^jmt$job_status_options,
      local_parameters_p: ^mainframe_getia_parameters,
      local_results_keys_p: ^jmt$results_keys,
      local_status_keys_p: ^jmt$results_keys,
      mainframes_processed: jmt$rpc_mainframes_processed,
      number_of_data_packets: ost$non_negative_integers,
      option_index: ost$positive_integers,
      privileged_job: boolean,
      result_element_size: ost$segment_length,
      result_index: ost$positive_integers,
      save_work_area_p: ^jmt$work_area,
      scl_name: ost$name,
      scratch_segment: amt$segment_pointer,
      target_mainframe_id: pmt$mainframe_id,
      target_mainframe_reached: boolean,
      target_options_p: ^SEQ ( * ),
      target_options_size: ost$non_negative_integers;


?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      mmp$delete_scratch_segment (scratch_segment, ignore_status);
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;

?? OLDTITLE ??
?? EJECT ??

{ BEGIN: jmp$get_input_attributes

    status.normal := TRUE;
    ignore_status.normal := TRUE;
    number_of_jobs_found := 0;
    continue_request_to_servers := FALSE;

    privileged_job := avp$system_operator () OR avp$system_displays ();
    IF NOT privileged_job THEN
      jmp$get_scheduling_admin_status (status);
      IF status.normal THEN
        privileged_job := TRUE;
      ELSE
        status.normal := TRUE;
      IFEND;
    IFEND;

    mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_sequential, scratch_segment, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    RESET scratch_segment.sequence_pointer;
    osp$establish_block_exit_hndlr (^handle_block_exit);

    NEXT local_parameters_p IN scratch_segment.sequence_pointer;

    IF input_attribute_options_p = NIL THEN
      local_parameters_p^.status_option_count := 3;

      NEXT job_status_options_p: [1 .. 3] IN scratch_segment.sequence_pointer;
      option_index := 1;

    ELSE
      save_work_area_p := scratch_segment.sequence_pointer;
      jmp$validate_attribute_options (jmc$get_input_attributes, 'INPUT_ATTRIBUTE_OPTIONS_P',
            #SEQ (input_attribute_options_p^), { number_of_options_to_add } 3, continue_request_to_servers,
            local_parameters_p^.status_option_count, scratch_segment.sequence_pointer, status);
      IF NOT status.normal THEN
        mmp$delete_scratch_segment (scratch_segment, ignore_status);
        osp$disestablish_cond_handler;
        RETURN;
      IFEND;

      NEXT job_status_options_p: [1 .. local_parameters_p^.status_option_count] IN save_work_area_p;
      option_index := local_parameters_p^.status_option_count - 2;

    IFEND;

    job_status_options_p^ [option_index].key := jmc$privilege;
    IF privileged_job THEN
      job_status_options_p^ [option_index].privilege := jmc$privileged;
    ELSE
      job_status_options_p^ [option_index].privilege := jmc$not_privileged;
    IFEND;
    job_status_options_p^ [option_index + 1].key := jmc$include_the_system_job;
    job_status_options_p^ [option_index + 1].include_the_system_job := FALSE;
    job_status_options_p^ [option_index + 2].key := jmc$user_identification;
    NEXT job_status_options_p^ [option_index + 2].user_identification IN scratch_segment.sequence_pointer;
    pmp$get_user_identification (job_status_options_p^ [option_index + 2].user_identification^,
          ignore_status);

    local_parameters_p^.attach_file := FALSE;

{ Verify that the result array is only requesting valid fields, i.e. fields that are returned by
{ this request.

    IF input_attribute_results_keys_p = NIL THEN
      local_parameters_p^.results_keys_count := 0;
      result_element_size := 0;
    ELSE
      local_parameters_p^.results_keys_count := UPPERBOUND (input_attribute_results_keys_p^);

{ Make two copies of the results keys.  One for what to return, the other a list of values that the status
{ request is to return.

      NEXT local_results_keys_p: [1 .. local_parameters_p^.results_keys_count] IN
            scratch_segment.sequence_pointer;
      NEXT local_status_keys_p: [1 .. local_parameters_p^.results_keys_count] IN
            scratch_segment.sequence_pointer;

      local_results_keys_p^ := input_attribute_results_keys_p^;
      local_status_keys_p^ := input_attribute_results_keys_p^;

      FOR result_index := 1 TO local_parameters_p^.results_keys_count DO
        CASE local_results_keys_p^ [result_index] OF
        = jmc$comment_banner, jmc$copies, jmc$cpu_time_limit, jmc$data_mode, jmc$device,
              jmc$earliest_print_time, jmc$earliest_run_time, jmc$external_characteristics, jmc$forms_code,
              jmc$job_abort_disposition, jmc$job_category_list, jmc$job_destination_family,
              jmc$job_execution_ring, jmc$job_qualifier_list, jmc$job_recovery_disposition, jmc$job_size,
              jmc$job_submission_time, jmc$latest_print_time, jmc$latest_run_time, jmc$login_account,
              jmc$login_project, jmc$magnetic_tape_limit, jmc$maximum_working_set,
              jmc$origin_application_name, jmc$output_class, jmc$output_deferred_by_user,
              jmc$output_destination, jmc$output_destination_family {operator_family} ,
              jmc$output_destination_usage, jmc$output_disposition, jmc$output_priority, jmc$purge_delay,
              jmc$remote_host_directive, jmc$routing_banner, jmc$site_information, jmc$sru_limit, jmc$station,
              jmc$station_operator {operator_user} , jmc$user_information, jmc$vertical_print_density,
              jmc$vfu_load_procedure =
          local_parameters_p^.attach_file := TRUE;
          local_status_keys_p^ [result_index] := jmc$null_attribute;

        = jmc$control_family, jmc$control_user, jmc$display_message,
              jmc$job_class, jmc$job_deferred_by_operator,
              jmc$job_deferred_by_user, jmc$job_destination_usage, jmc$job_mode, jmc$job_state,
              jmc$login_family, jmc$login_user, jmc$null_attribute, jmc$system_job_name, jmc$user_job_name =

        ELSE
          jmp$get_attribute_name (local_results_keys_p^ [result_index], scl_name);
          osp$set_status_abnormal (jmc$job_management_id, jme$invalid_parameter, scl_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, 'INPUT_ATTRIBUTE_RESULTS_KEYS_P',
                status);
          osp$append_status_parameter (osc$status_parameter_delimiter, jmc$get_input_attributes, status);
          mmp$delete_scratch_segment (scratch_segment, ignore_status);
          osp$disestablish_cond_handler;
          RETURN;
        CASEND;

      FOREND; { result index

      jmp$get_data_packet_size (local_results_keys_p, result_element_size, status);
      IF NOT status.normal THEN
        mmp$delete_scratch_segment (scratch_segment, ignore_status);
        osp$disestablish_cond_handler;
        RETURN;
      IFEND;
    IFEND;

    IF continue_request_to_servers THEN
      target_mainframe_id := pmc$null_mainframe_id;
    ELSE
      pmp$get_mainframe_id (target_mainframe_id, ignore_status);
    IFEND;

    mainframes_processed.count := 0;
    target_options_size := i#current_sequence_position (scratch_segment.sequence_pointer);
    RESET scratch_segment.sequence_pointer;
    NEXT target_options_p: [[REP target_options_size OF cell]] IN scratch_segment.sequence_pointer;
    RESET target_options_p;
    NEXT jm_work_area_p: [[REP (osc$max_segment_length - target_options_size) OF cell]] IN
          scratch_segment.sequence_pointer;
    RESET jm_work_area_p;

    jmp$general_purpose_cluster_rpc (target_mainframe_id, jmc$gpro_get_input_attributes,
          {data_packet_size} result_element_size, mainframes_processed, target_options_p, jm_work_area_p,
          target_mainframe_reached, mainframes_processed, number_of_data_packets, status);
    IF NOT status.normal THEN
      IF status.condition = jme$work_area_too_small THEN
        number_of_jobs_found := number_of_data_packets;
      IFEND;
      mmp$delete_scratch_segment (scratch_segment, ignore_status);
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

    number_of_jobs_found := number_of_data_packets;
    IF number_of_jobs_found = 0 THEN
      osp$set_status_condition (jme$no_jobs_were_found, status);
    ELSEIF input_attribute_results_keys_p <> NIL THEN
      RESET jm_work_area_p;
      save_work_area_p := work_area_p;
      jmp$copy_seq_to_result_array (UPPERBOUND (input_attribute_results_keys_p^), number_of_jobs_found,
            input_attribute_results_keys_p, jm_work_area_p, work_area_p, status);
      NEXT input_attribute_results_p: [1 .. number_of_jobs_found] IN save_work_area_p;
    IFEND;

    IF status.normal THEN
      mmp$delete_scratch_segment (scratch_segment, status);
    ELSE
      mmp$delete_scratch_segment (scratch_segment, ignore_status);
    IFEND;
    osp$disestablish_cond_handler;
  PROCEND jmp$get_input_attributes;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$get_input_q_from_unassigned', EJECT ??
*copy jmh$get_input_q_from_unassigned

  PROCEDURE [XDCL, #GATE] jmp$get_input_q_from_unassigned
    (VAR system_supplied_names: array [1 .. * ] of jmt$system_supplied_name;
     VAR number_of_jobs_found: integer;
     VAR status: ost$status);

    VAR
      local_name_list_p: ^array [1 .. * ] of jmt$system_supplied_name,
      local_status: ost$status;

    status.normal := TRUE;

    jmp$get_scheduling_admin_status (local_status);
    IF NOT local_status.normal THEN
      status := local_status;
      RETURN;
    IFEND;

    number_of_jobs_found := 0;
    PUSH local_name_list_p: [1 .. UPPERBOUND (system_supplied_names)];

    qfp$get_input_q_from_unassigned (local_name_list_p^, number_of_jobs_found, local_status);
    system_supplied_names := local_name_list_p^;
    IF NOT local_status.normal THEN
      status := local_status;
    ELSEIF number_of_jobs_found > UPPERBOUND (system_supplied_names) THEN
      osp$set_status_condition (jme$result_array_too_small, status);
    IFEND;
  PROCEND jmp$get_input_q_from_unassigned;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$get_job_counts', EJECT ??
*copy jmh$get_job_counts

  PROCEDURE [XDCL, #GATE] jmp$get_job_counts
    (VAR job_counts: jmt$job_counts;
     VAR status: ost$status);

    status.normal := TRUE;

    qfp$get_job_counts (job_counts);
  PROCEND jmp$get_job_counts;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$get_job_path_elements', EJECT ??
*copy jmh$get_job_path_elements

  PROCEDURE [XDCL, #GATE] jmp$get_job_path_elements
    (    system_job_name: jmt$system_supplied_name;
     VAR path: jmt$queue_file_path;
     VAR status: ost$status);

    VAR
      candidate_name: jmt$name,
      good_name: jmt$name,
      input_file_location: jmt$input_file_location,
      local_path_p: ^pft$path,
      login_family: ost$family_name;

    status.normal := TRUE;
    IF NOT avp$system_administrator () THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'system_administration', status);
      RETURN;
    IFEND;

    candidate_name.kind := jmc$system_supplied_name;
    candidate_name.system_supplied_name := system_job_name;
    jmp$validate_name (candidate_name, good_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    qfp$get_input_file_location (good_name.system_supplied_name, input_file_location, login_family, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF input_file_location <> jmc$ifl_no_input_file_exists THEN

{ Determine the job's command file path.

      determine_file_path (input_file_location, login_family, good_name.system_supplied_name, local_path_p);
      path := local_path_p^;

    ELSE
      osp$set_status_abnormal (jmc$job_management_id, jme$name_not_found, system_job_name, status);
    IFEND;
  PROCEND jmp$get_job_path_elements;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$get_job_status', EJECT ??
*copy jmh$get_job_status

  PROCEDURE [XDCL, #GATE] jmp$get_job_status
    (    job_status_options_p: ^jmt$job_status_options;
         job_status_results_keys_p: ^jmt$results_keys;
     VAR work_area_p: ^jmt$work_area;
     VAR job_status_results_p: ^jmt$job_status_results;
     VAR number_of_jobs_found: jmt$job_status_count;
     VAR status: ost$status);

    CONST
      bytes_that_can_be_pushed = 32767;

    VAR
      caller_id: ost$caller_identifier,
      caller_privileged: boolean,
      continue_request_to_servers: boolean,
      jm_work_area_p: ^jmt$work_area,
      local_parameters_p: ^mainframe_getjs_parameters,
      local_status: ost$status,
      local_status_results_keys_p: ^jmt$results_keys,
      mainframes_processed: jmt$rpc_mainframes_processed,
      number_of_data_packets: ost$non_negative_integers,
      options_p: ^SEQ ( * ),
      options_size: ost$non_negative_integers,
      result_index: ost$positive_integers,
      save_work_area_p: ^jmt$work_area,
      scl_name: ost$name,
      seq_job_status_results_size: ost$segment_length,
      target_mainframe_id: pmt$mainframe_id,
      target_mainframe_reached: boolean,
      target_options_p: ^SEQ ( * ),
      user_job_name: jmt$user_supplied_name;


    #CALLER_ID (caller_id);
    status.normal := TRUE;
    number_of_jobs_found := 0;
    continue_request_to_servers := FALSE;
    jm_work_area_p := NIL;

    IF work_area_p <> NIL THEN
      IF (jmv$job_management_work_area_p = NIL) AND (#SIZE (work_area_p^) <= bytes_that_can_be_pushed) THEN
        PUSH jm_work_area_p: [[REP #SIZE (work_area_p^) OF cell]];
      ELSE
        jmp$get_jm_work_area (jm_work_area_p, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;
    IFEND;
    PUSH target_options_p: [[REP dfc$maximum_user_data_area OF cell]];

    RESET target_options_p;
    NEXT local_parameters_p IN target_options_p;

    pmp$get_user_identification (local_parameters_p^.user_identification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$get_job_names (user_job_name, local_parameters_p^.caller_ssn, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    local_parameters_p^.privileged_job := avp$system_operator () OR avp$system_displays ();
    IF NOT local_parameters_p^.privileged_job THEN
      jmp$get_scheduling_admin_status (local_status);
      IF local_status.normal THEN
        local_parameters_p^.privileged_job := TRUE;
      IFEND;
    IFEND;

    avp$get_capability (avc$scheduling_displays, avc$user, local_parameters_p^.valid_for_scheduling_displays,
          local_status);
    IF NOT local_status.normal THEN
      local_parameters_p^.valid_for_scheduling_displays := TRUE;
    IFEND;

    IF job_status_options_p = NIL THEN
      local_parameters_p^.status_option_count := 0;
    ELSE

      caller_privileged := (osp$is_caller_system_privileged () AND (caller_id.ring <= osc$tsrv_ring));

      jmp$validate_status_options (jmc$get_job_status, 'JOB_STATUS_OPTIONS_P', #SEQ (job_status_options_p^),
            caller_privileged, local_parameters_p^.privileged_job, local_parameters_p^.user_identification,
            continue_request_to_servers, local_parameters_p^.status_option_count, target_options_p, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

    IFEND;

{ Verify that result is only asking for valid fields, i.e. supported fields.

    IF job_status_results_keys_p = NIL THEN
      local_parameters_p^.status_results_count := 0;
      seq_job_status_results_size := 0;
    ELSE
      local_parameters_p^.status_results_count := UPPERBOUND (job_status_results_keys_p^);
      NEXT local_status_results_keys_p: [1 .. local_parameters_p^.status_results_count] IN target_options_p;

      local_status_results_keys_p^ := job_status_results_keys_p^;

      FOR result_index := 1 TO local_parameters_p^.status_results_count DO
        CASE local_status_results_keys_p^ [result_index] OF
        = jmc$client_mainframe_id, jmc$control_family, jmc$control_user, jmc$cpu_time_used,
              jmc$display_message, jmc$input_file_location, jmc$internal_index, jmc$job_class,
              jmc$job_class_position, jmc$job_deferred_by_operator, jmc$job_deferred_by_user,
              jmc$job_destination_usage, jmc$job_initiation_time, jmc$job_mode, jmc$job_state,
              jmc$login_family, jmc$login_user, jmc$null_attribute, jmc$operator_action_posted,
              jmc$page_faults, jmc$server_mainframe_id, jmc$system_job_name, jmc$user_job_name =
        ELSE
          jmp$get_attribute_name (local_status_results_keys_p^ [result_index], scl_name);
          osp$set_status_abnormal (jmc$job_management_id, jme$invalid_parameter, scl_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, 'JOB_STATUS_RESULTS_KEYS_P', status);
          osp$append_status_parameter (osc$status_parameter_delimiter, jmc$get_job_status, status);
          RETURN;
        CASEND;
      FOREND;

      jmp$get_data_packet_size (local_status_results_keys_p, seq_job_status_results_size, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    IF continue_request_to_servers THEN
      target_mainframe_id := pmc$null_mainframe_id;
    ELSE
      pmp$get_mainframe_id (target_mainframe_id, {ignore} local_status);
    IFEND;
    mainframes_processed.count := 0;
    options_size := i#current_sequence_position (target_options_p);
    RESET target_options_p;
    NEXT options_p: [[REP options_size OF cell]] IN target_options_p;

    jmp$general_purpose_cluster_rpc (target_mainframe_id, jmc$gpro_get_job_status,
          {data_packet_size} seq_job_status_results_size, mainframes_processed, options_p, jm_work_area_p,
          target_mainframe_reached, mainframes_processed, number_of_data_packets, status);
    IF NOT status.normal THEN
      IF status.condition = jme$work_area_too_small THEN
        number_of_jobs_found := number_of_data_packets;
      IFEND;
      RETURN;
    IFEND;

    number_of_jobs_found := number_of_data_packets;
    IF number_of_jobs_found = 0 THEN
      osp$set_status_condition (jme$no_jobs_were_found, status);
    ELSEIF (job_status_results_keys_p <> NIL) THEN
      RESET jm_work_area_p;
      save_work_area_p := work_area_p;
      jmp$copy_seq_to_result_array (UPPERBOUND (job_status_results_keys_p^), number_of_jobs_found,
            job_status_results_keys_p, jm_work_area_p, work_area_p, status);
      NEXT job_status_results_p: [1 .. number_of_jobs_found] IN save_work_area_p;
    IFEND;

  PROCEND jmp$get_job_status;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$get_leveling_data', EJECT ??
*copy jmh$get_leveling_data

  PROCEDURE [XDCL] jmp$get_leveling_data
    (    target_options_p: ^SEQ ( * );
     VAR data_area_p: {input, output} ^SEQ ( * );
     VAR number_of_data_packets: ost$non_negative_integers;
     VAR status: ost$status);

    VAR
      data_size: ost$segment_length,
      leveling_data: ^SEQ ( * ),
      mainframe_leveling_data_p: ^jmt$mainframe_leveling_data,
      segment: amt$segment_pointer;


    status.normal := TRUE;

    mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_sequential, segment, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    RESET segment.sequence_pointer;

    jmp$mainframe_get_leveling_data (target_options_p, segment.sequence_pointer, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    number_of_data_packets := 1;

    data_size := i#current_sequence_position (segment.sequence_pointer);
    NEXT mainframe_leveling_data_p IN data_area_p;
    NEXT leveling_data: [[REP data_size OF cell]] IN data_area_p;

    pmp$get_mainframe_id (mainframe_leveling_data_p^.mainframe_id, {ignore} status);
    mainframe_leveling_data_p^.mainframe_data_size := data_size;

    RESET segment.sequence_pointer;
    i#move (segment.sequence_pointer, leveling_data, data_size);

    mmp$delete_scratch_segment (segment, status);
  PROCEND jmp$get_leveling_data;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$log_restored_job', EJECT ??
*copy jmh$log_restored_job

  PROCEDURE [XDCL, #GATE] jmp$log_restored_job
    (    system_job_name: jmt$system_supplied_name;
     VAR status: ost$status);

    VAR
      candidate_name: jmt$name,
      cycle_selector: pft$cycle_selector,
      ignore_status: ost$status,
      local_file_name: amt$local_file_name,
      operator_restore: ost$name,
      password: pft$password,
      path: jmt$queue_file_path,
      system_label: jmt$job_system_label,
      usage_selections: pft$usage_selections,
      valid_name: jmt$name;

?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    ignore_status.normal := TRUE;

    IF NOT (avp$system_administrator () OR avp$system_operator ()) THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'system_administration OR system_operation', status);
      RETURN;
    IFEND;

{ Check for active job history statistic logging.

    IF NOT jmv$job_history_active THEN
      osp$set_status_condition (jme$jh_job_history_not_active, status);
      RETURN;
    IFEND;

{ Verify that the system_job_name is a legal system supplied name.

    candidate_name.kind := jmc$system_supplied_name;
    candidate_name.system_supplied_name := system_job_name;
    jmp$validate_name (candidate_name, valid_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Attach the job file.

    jmp$get_job_path_elements (valid_name.system_supplied_name, path, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$get_unique_name (local_file_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    cycle_selector.cycle_option := pfc$specific_cycle;
    cycle_selector.cycle_number := 1;
    password := osc$null_name;
    usage_selections := $pft$usage_selections [pfc$read];

    osp$establish_block_exit_hndlr (^handle_block_exit);
    pfp$begin_system_authority;
    pfp$attach (local_file_name, path, cycle_selector, password, usage_selections, usage_selections, pfc$wait,
          status);
    IF NOT status.normal THEN
      pfp$purge (path, cycle_selector, password, ignore_status);
      pfp$end_system_authority;
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

{ Read the job file's system label.

    qfp$read_job_system_label (local_file_name, system_label, status);
    amp$return (local_file_name, ignore_status);

    IF NOT status.normal THEN
      pfp$purge (path, cycle_selector, password, ignore_status);
      pfp$end_system_authority;
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

{ Verify that the system_job_name matches in the label and the catalog.

    IF system_job_name <> system_label.system_job_name THEN
      osp$set_status_condition (sye$job_damaged, status);
      pfp$purge (path, cycle_selector, password, ignore_status);
      pfp$end_system_authority;
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

{ If the job is an interactive job, then don't log it.

    IF system_label.job_mode = jmc$interactive_connected THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$cant_recover_job, 'an interactive queued', status);
      pfp$purge (path, cycle_selector, password, ignore_status);
      pfp$end_system_authority;
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

    pfp$end_system_authority;
    osp$disestablish_cond_handler;

    operator_restore := osc$null_name;
    osp$get_status_condition_name (jme$operator_queue_restore, operator_restore, ignore_status);

    jmp$emit_job_history_statistics (jml$job_queuing_started, osc$null_name, valid_name.system_supplied_name,
          jmc$blank_system_supplied_name, ^system_label, NIL, operator_restore,
          system_label.job_attributes.originating_ssn, status);

  PROCEND jmp$log_restored_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$modified_input_exists', EJECT ??
*copy jmh$modified_input_exists

  FUNCTION [XDCL, #GATE] jmp$modified_input_exists
    (    input_destination_usage: jmt$destination_usage): boolean;

    VAR
      application_index: jmt$input_application_index,
      input_exists: boolean;

    application_index := UPPERBOUND (jmv$known_job_list.application_table);
    WHILE (jmv$known_job_list.application_table [application_index].destination_usage <>
          input_destination_usage) AND (application_index <> jmc$unassigned_input_index) DO
      application_index := application_index - 1;
    WHILEND;

    input_exists := (application_index <> jmc$unassigned_input_index) AND
          (jmv$known_job_list.application_table [application_index].state_data [jmc$kjl_application_modified].
          number_of_entries > 0);
    jmp$modified_input_exists := input_exists AND (NOT syp$system_is_idling ());

  FUNCEND jmp$modified_input_exists;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$new_input_exists', EJECT ??
*copy jmh$new_input_exists

  FUNCTION [XDCL, #GATE] jmp$new_input_exists
    (    input_destination_usage: jmt$destination_usage): boolean;

    VAR
      application_index: jmt$input_application_index,
      input_exists: boolean;

    application_index := UPPERBOUND (jmv$known_job_list.application_table);
    WHILE (jmv$known_job_list.application_table [application_index].destination_usage <>
          input_destination_usage) AND (application_index <> jmc$unassigned_input_index) DO
      application_index := application_index - 1;
    WHILEND;

    input_exists := (application_index <> jmc$unassigned_input_index) AND
          (jmv$known_job_list.application_table [application_index].state_data [jmc$kjl_application_new].
          number_of_entries > 0);
    jmp$new_input_exists := input_exists AND (NOT syp$system_is_idling ());

  FUNCEND jmp$new_input_exists;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$get_terminate_job_action', EJECT ??
*copy jmh$get_terminate_job_action

  PROCEDURE [XDCL, #GATE] jmp$get_terminate_job_action
    (VAR terminate_job_action_set: jmt$terminate_job_action_set;
     VAR status: ost$status);

    status.normal := TRUE;
    IF NOT (avp$configuration_administrator () OR avp$system_displays ()) THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'configuration_administration OR system_displays',
            status);
      RETURN;
    IFEND;

    terminate_job_action_set := qfv$terminate_job_action_set;
  PROCEND jmp$get_terminate_job_action;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$mainframe_change_input_attr', EJECT ??
*copy jmh$mainframe_change_input_attr

  PROCEDURE [XDCL] jmp$mainframe_change_input_attr
    (    target_options_p: ^SEQ ( * );
     VAR data_area_p: {input, output} ^SEQ ( * );
     VAR number_of_data_packets: ost$non_negative_integers;
     VAR status: ost$status);

    VAR
      active_profile_version: ost$name,
      assigned_job_class: jmt$job_class,
      change_index: integer,
      current_date_time: ost$date_time,
      current_microsecond_clock: jmt$clock_time,
      cycle_selector: pft$cycle_selector,
      earliest_clock_time_to_initiate: jmt$clock_time,
      ignore_encrypted_password: ost$name,
      ignore_status: ost$status,
      latest_clock_time_to_initiate: jmt$clock_time,
      leveled_job: boolean,
      local_attribute_changes_p: ^jmt$input_attribute_changes,
      local_file_name: amt$local_file_name,
      local_output_disposition_path_p: ^fst$path,
      local_parameters_p: ^mainframe_chaia_parameters,
      local_purge_delay_p: ^jmt$time_increment,
      local_remote_host_directive_p: ^jmt$remote_host_directive,
      local_site_information_p: ^jmt$site_information,
      local_user_information_p: ^jmt$user_information,
      options_seq_p: ^SEQ ( * ),
      password: pft$password,
      path_p: ^pft$path,
      profile_mismatch: boolean,
      share_selections: pft$share_selections,
      store_and_forward_job: boolean,
      system_label: jmt$job_system_label,
      usage_selections: pft$usage_selections,
      valid_mainframe_set: jmt$valid_mainframe_set,
      wait_option: pft$wait,
      write_label: boolean;

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

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit and interactive
{   conditions that arise from the attempt to attach a file in the input queue.
{   If the file is busy, the attach processor goes into long term wait without
{   establishing a condition handler for interactive conditions - so it does
{   not exit.

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      CASE condition.selector OF
      = pmc$block_exit_processing =
        pfp$end_system_authority;
        IF status.normal THEN
          osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
        IFEND;

      = ifc$interactive_condition =
        IF condition.interactive_condition = ifc$pause_break THEN
          ifp$invoke_pause_utility (handler_status);
        ELSE
          osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
          pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
          EXIT jmp$mainframe_change_input_attr;
        IFEND;

      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
      CASEND;
    PROCEND condition_handler;

?? OLDTITLE ??
?? EJECT ??

    status.normal := TRUE;
    ignore_status.normal := TRUE;
    number_of_data_packets := 0;

    options_seq_p := target_options_p;
    RESET options_seq_p;
    NEXT local_parameters_p IN options_seq_p;

{ Attach the file so we can read the system label and get the attributes

    pmp$get_unique_name (local_file_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    determine_file_path (local_parameters_p^.input_file_location, local_parameters_p^.login_family,
          local_parameters_p^.system_job_name, path_p);
    cycle_selector.cycle_option := pfc$specific_cycle;
    cycle_selector.cycle_number := 1;
    password := osc$null_name;
    IF local_parameters_p^.system_changing_attributes THEN
      wait_option := pfc$no_wait;
      usage_selections := $pft$usage_selections [pfc$read];
      share_selections := $pft$share_selections [pfc$read];
    ELSE
      wait_option := pfc$wait;
      usage_selections := $pft$usage_selections [pfc$read, pfc$modify];
      share_selections := $pft$share_selections [];
    IFEND;

{ Prepare in case the file is busy and the attach goes into long-term-wait.

    osp$establish_condition_handler (^condition_handler, {block_exit} TRUE);

    pfp$begin_system_authority;
    pfp$attach (local_file_name, path_p^, cycle_selector, password, usage_selections, share_selections,
          wait_option, status);
    pfp$end_system_authority;
    osp$disestablish_cond_handler;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Read the input file's system label

    qfp$read_job_system_label (local_file_name, system_label, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      RETURN;
    IFEND;

{ Check attribute changes and change the local copy of the system label

    IF local_parameters_p^.attribute_change_count > 0 THEN
      NEXT local_attribute_changes_p: [1 .. local_parameters_p^.attribute_change_count] IN options_seq_p;

      FOR change_index := 1 TO local_parameters_p^.attribute_change_count DO
        CASE local_attribute_changes_p^ [change_index].key OF
        = jmc$comment_banner =
          system_label.job_attributes.comment_banner := local_attribute_changes_p^ [change_index].
                comment_banner;

        = jmc$copies =
          system_label.job_attributes.copy_count := local_attribute_changes_p^ [change_index].copies;

        = jmc$cpu_time_limit =
          system_label.limit_information.cpu_time_limit_specified := TRUE;
          system_label.limit_information.cpu_time_limit_requested :=
                local_attribute_changes_p^ [change_index].cpu_time_limit;

        = jmc$device =
          system_label.job_attributes.device := local_attribute_changes_p^ [change_index].device;

        = jmc$earliest_print_time =
          system_label.job_attributes.earliest_print_time :=
                local_attribute_changes_p^ [change_index].earliest_print_time;

        = jmc$earliest_run_time =
          system_label.job_attributes.earliest_run_time := local_attribute_changes_p^ [change_index].
                earliest_run_time;

        = jmc$encrypted_password =
          system_label.login_password := local_attribute_changes_p^ [change_index].encrypted_password;

        = jmc$external_characteristics =
          system_label.job_attributes.external_characteristics :=
                local_attribute_changes_p^ [change_index].external_characteristics;

        = jmc$forms_code =
          system_label.job_attributes.forms_code := local_attribute_changes_p^ [change_index].forms_code;

        = jmc$job_abort_disposition =
          system_label.job_abort_disposition := local_attribute_changes_p^ [change_index].
                job_abort_disposition;

        = jmc$job_class =
          system_label.job_class_name := local_attribute_changes_p^ [change_index].job_class;

        = jmc$job_deferred_by_operator =
          system_label.job_deferred_by_operator := local_attribute_changes_p^ [change_index].
                job_deferred_by_operator;

        = jmc$job_deferred_by_user =
          system_label.job_deferred_by_user := local_attribute_changes_p^ [change_index].job_deferred_by_user;

        = jmc$job_qualifier_list =
          NEXT local_attribute_changes_p^ [change_index].job_qualifier_list:
                [1 .. jmc$maximum_job_qualifiers] IN options_seq_p;
          system_label.job_attributes.job_qualifier_list := local_attribute_changes_p^ [change_index].
                job_qualifier_list^;

        = jmc$job_recovery_disposition =
          system_label.job_recovery_disposition := local_attribute_changes_p^ [change_index].
                job_recovery_disposition;

        = jmc$latest_print_time =
          system_label.job_attributes.latest_print_time := local_attribute_changes_p^ [change_index].
                latest_print_time;

        = jmc$latest_run_time =
          system_label.job_attributes.latest_run_time := local_attribute_changes_p^ [change_index].
                latest_run_time;

        = jmc$login_account =
          system_label.login_account := local_attribute_changes_p^ [change_index].login_account;

        = jmc$login_project =
          system_label.login_project := local_attribute_changes_p^ [change_index].login_project;

        = jmc$magnetic_tape_limit =
          system_label.limit_information.magnetic_tape_limit_specified := TRUE;
          system_label.limit_information.magnetic_tape_limit_requested :=
                local_attribute_changes_p^ [change_index].magnetic_tape_limit;

        = jmc$maximum_working_set =
          system_label.limit_information.maximum_working_set_specified := TRUE;
          system_label.limit_information.maximum_working_set_requested :=
                local_attribute_changes_p^ [change_index].maximum_working_set;

        = jmc$null_attribute =
          ;

        = jmc$output_class =
          system_label.job_attributes.output_class := local_attribute_changes_p^ [change_index].output_class;

        = jmc$output_deferred_by_user =
          system_label.job_attributes.output_deferred_by_user :=
                local_attribute_changes_p^ [change_index].output_deferred_by_user;

        = jmc$output_destination =
          system_label.job_attributes.output_destination := local_attribute_changes_p^ [change_index].
                output_destination;

        = jmc$output_destination_family =
          system_label.job_attributes.output_destination_family :=
                local_attribute_changes_p^ [change_index].output_destination_family;

        = jmc$output_destination_usage =
          system_label.job_attributes.output_destination_usage :=
                local_attribute_changes_p^ [change_index].output_destination_usage;

        = jmc$output_disposition =
          system_label.job_attributes.output_disposition_key :=
                local_attribute_changes_p^ [change_index].output_disposition.key;
          IF system_label.job_attributes.output_disposition_key = jmc$standard_output_path THEN
            NEXT local_output_disposition_path_p IN options_seq_p;
            system_label.job_attributes.output_disposition_path := local_output_disposition_path_p^;
          IFEND;

        = jmc$output_priority =
          system_label.job_attributes.output_priority := local_attribute_changes_p^ [change_index].
                output_priority;

        = jmc$purge_delay =
          NEXT local_purge_delay_p IN options_seq_p;
          system_label.job_attributes.purge_delay := local_purge_delay_p^;

        = jmc$remote_host_directive =
          NEXT local_remote_host_directive_p IN options_seq_p;
          system_label.job_attributes.remote_host_directive := local_remote_host_directive_p^;

        = jmc$routing_banner =
          system_label.job_attributes.routing_banner := local_attribute_changes_p^ [change_index].
                routing_banner;

        = jmc$site_information =
          NEXT local_site_information_p IN options_seq_p;
          system_label.job_attributes.site_information := local_site_information_p^;

        = jmc$sru_limit =
          system_label.limit_information.sru_limit_specified := TRUE;
          system_label.limit_information.sru_limit_requested :=
                local_attribute_changes_p^ [change_index].sru_limit;

        = jmc$station =
          system_label.job_attributes.station := local_attribute_changes_p^ [change_index].station;

        = jmc$station_operator =
          system_label.job_attributes.station_operator := local_attribute_changes_p^ [change_index].
                station_operator;

        = jmc$user_information =
          NEXT local_user_information_p IN options_seq_p;
          system_label.job_attributes.user_information := local_user_information_p^;

        = jmc$user_job_name =
          system_label.user_job_name := local_attribute_changes_p^ [change_index].user_job_name;

        = jmc$vertical_print_density =
          system_label.job_attributes.vertical_print_density :=
                local_attribute_changes_p^ [change_index].vertical_print_density;

        = jmc$vfu_load_procedure =
          system_label.job_attributes.vfu_load_procedure := local_attribute_changes_p^ [change_index].
                vfu_load_procedure;

        ELSE
        CASEND;
      FOREND;
    IFEND;

{ set up clock info for deferred jobs

    pmp$get_compact_date_time (current_date_time, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      RETURN;
    IFEND;

    pmp$get_microsecond_clock (current_microsecond_clock, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      RETURN;
    IFEND;

    IF system_label.job_attributes.earliest_run_time.specified THEN
      jmp$convert_date_time_dif_to_us (current_date_time, system_label.job_attributes.earliest_run_time.
            date_time, current_microsecond_clock, earliest_clock_time_to_initiate);
    ELSE
      earliest_clock_time_to_initiate := jmc$earliest_clock_time;
    IFEND;

    IF system_label.job_attributes.latest_run_time.specified THEN
      jmp$convert_date_time_dif_to_us (current_date_time, system_label.job_attributes.latest_run_time.
            date_time, current_microsecond_clock, latest_clock_time_to_initiate);
    ELSE
      latest_clock_time_to_initiate := jmc$latest_clock_time;
    IFEND;

    store_and_forward_job := local_parameters_p^.input_file_location = jmc$ifl_store_and_forward_queue;

{ If the request was not done by an operator or scheduling administrator then
{ change the job submission time.

    IF NOT local_parameters_p^.privileged_for_status THEN
      system_label.job_attributes.job_submission_time := current_date_time;
    IFEND;

  /determine_job_class/
    WHILE TRUE DO
      WHILE jmv$sched_profile_is_loading DO
        pmp$wait (500, 500);
      WHILEND;
      active_profile_version := jmv$job_scheduler_table.profile_identification;
      IF (system_label.job_class_name <> jmc$automatic_class_name) AND
            (system_label.job_class_name <> osc$null_name) AND
            (system_label.job_class_name <> jmc$system_default_class_name) THEN
        jmp$expand_job_class_abbrev (system_label.job_class_name, ignore_status);
      IFEND;

{ If not a store and forward job, prevalidate the job unless it is in the
{ UNASSIGNED job class and was initially submitted under the current scheduler
{ profile.  Refresh the class index of the initial submission job class for the job
{ in UNASSIGNED since it may have changed even if the profile version has the
{ same structure.

      IF NOT store_and_forward_job THEN
        IF (local_parameters_p^.attribute_change_count > 0) OR
              (active_profile_version <> system_label.active_profile_version) OR
              (local_parameters_p^.beginning_job_class <> jmc$unassigned_class_name) THEN

{ Convert the requested limits into preliminary assigned limits.

          convert_limit_information (system_label, status);
          IF NOT status.normal THEN
            amp$return (local_file_name, ignore_status);
            RETURN;
          IFEND;

          prevalidate_job (system_label.login_user_identification, {password_encrypted} TRUE, system_label,
                assigned_job_class, ignore_encrypted_password, status);
          IF NOT status.normal THEN
            qfp$check_for_profile_mismatch (active_profile_version, profile_mismatch);
            IF profile_mismatch OR jmv$sched_profile_is_loading THEN
              CYCLE /determine_job_class/;
            IFEND;
            amp$return (local_file_name, ignore_status);
            RETURN;
          IFEND;
        ELSE
          jmp$determine_job_class (system_label.assigned_job_class, assigned_job_class, status);
          IF NOT status.normal THEN
            qfp$check_for_profile_mismatch (active_profile_version, profile_mismatch);
            IF profile_mismatch OR jmv$sched_profile_is_loading THEN
              status.normal := TRUE;
              CYCLE /determine_job_class/;
            IFEND;
            osp$set_status_abnormal (jmc$job_management_id, jme$job_class_does_not_exist,
                  system_label.assigned_job_class, status);
            amp$return (local_file_name, ignore_status);
            RETURN;
          IFEND;
        IFEND;

{ See if the job fits any mainframes in the scheduling profile.

        leveled_job := (system_label.job_destination_usage <> jmc$ve_local_usage) AND
              (local_parameters_p^.input_file_location = jmc$ifl_login_family_queue);
        qfp$determine_mainframe_fitness (system_label.job_category_set, leveled_job,
              system_label.login_user_identification.family, valid_mainframe_set, status);
        IF NOT status.normal THEN
          qfp$check_for_profile_mismatch (active_profile_version, profile_mismatch);
          IF profile_mismatch OR jmv$sched_profile_is_loading THEN
            status.normal := TRUE;
            CYCLE /determine_job_class/;
          IFEND;
          amp$return (local_file_name, ignore_status);
          RETURN;
        IFEND;
      ELSE
        valid_mainframe_set := $jmt$valid_mainframe_set [];
      IFEND;

{ Update tables

      system_label.active_profile_version := active_profile_version;
      qfp$change_input_attributes (system_label, assigned_job_class,
            local_parameters_p^.privileged_for_status, earliest_clock_time_to_initiate,
            latest_clock_time_to_initiate, current_microsecond_clock, valid_mainframe_set, status);
      IF NOT status.normal THEN
        IF (status.condition <> jme$scheduling_profile_changed) THEN
          amp$return (local_file_name, ignore_status);
          RETURN;
        ELSE
          CYCLE /determine_job_class/;
        IFEND;
      IFEND;

      EXIT /determine_job_class/;
    WHILEND /determine_job_class/;

{ Write the result system label to the input file

    write_label := TRUE;
    qfp$write_job_system_label (local_file_name, write_label, system_label, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      RETURN;
    IFEND;

{ Release the file in case somebody needs it

    amp$return (local_file_name, status);

  PROCEND jmp$mainframe_change_input_attr;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$mainframe_get_input_attribu', EJECT ??
*copy jmh$mainframe_get_input_attribu

  PROCEDURE [XDCL] jmp$mainframe_get_input_attribu
    (    target_options_p: ^SEQ ( * );
     VAR data_area_p: {input, output} ^SEQ ( * );
     VAR number_of_data_packets: ost$non_negative_integers;
     VAR status: ost$status);

    VAR
      boolean_p: ^boolean,
      copies_p: ^jmt$output_copy_count,
      cpu_time_limit_p: ^jmt$cpu_time_limit,
      cycle_selector: pft$cycle_selector,
      data_mode_p: ^jmt$data_mode,
      date_time_p: ^jmt$date_time,
      display_message_p: ^jmt$display_message,
      external_characteristics_p: ^jmt$external_characteristics,
      forms_code_p: ^jmt$forms_code,
      ignore_status: ost$status,
      input_index: jmt$job_count_range,
      job_abort_disposition_p: ^jmt$job_abort_disposition,
      job_category_count_p: ^jmt$job_category_count,
      job_category_index: jmt$job_category_count,
      job_category_list_p: ^jmt$full_job_category_list,
      job_mode_p: ^jmt$job_mode,
      job_qualifier_list_p: ^jmt$job_qualifier_list,
      job_recovery_disposition_p: ^jmt$job_recovery_disposition,
      job_size_p: ^jmt$job_size,
      job_state_p: ^jmt$job_state,
      job_status_results_p: ^jmt$job_status_results,
      kjl_index: jmt$kjl_index,
      local_file_name: amt$local_file_name,
      local_parameters_p: ^mainframe_getia_parameters,
      local_results_keys_p: ^jmt$results_keys,
      local_status_keys_p: ^jmt$results_keys,
      local_status_name_count_p: ^ost$non_negative_integers,
      local_status_options_p: ^jmt$job_status_options,
      magnetic_tape_limit_p: ^jmt$magnetic_tape_limit,
      maximum_working_set_p: ^jmt$working_set_size,
      name_value_p: ^ost$name,
      number_of_jobs_statused: jmt$job_count_range,
      option_index: ost$positive_integers,
      options_seq_p: ^SEQ ( * ),
      os_date_time_p: ^ost$date_time,
      output_disposition_key_p: ^jmt$output_disposition_keys,
      output_disposition_path_p: ^fst$path,
      password: pft$password,
      path_p: ^pft$path,
      remote_host_directive_p: ^jmt$remote_host_directive,
      result_index: ost$positive_integers,
      ring_p: ^ost$ring,
      scratch_segment: amt$segment_pointer,
      site_information_p: ^jmt$site_information,
      sru_limit_p: ^jmt$sru_limit,
      status_results_keys_p: ^jmt$results_keys,
      system_file_name_p: ^jmt$system_supplied_name,
      system_label: jmt$job_system_label,
      system_label_p: ^jmt$job_system_label,
      time_increment_p: ^jmt$time_increment,
      usage_selections: pft$usage_selections,
      user_information_p: ^jmt$user_information,
      vertical_print_density_p: ^jmt$vertical_print_density,
      work_area_full: boolean;

?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      mmp$delete_scratch_segment (scratch_segment, ignore_status);
      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;

?? OLDTITLE ??
?? EJECT ??

    status.normal := TRUE;
    ignore_status.normal := TRUE;

    options_seq_p := target_options_p;
    RESET options_seq_p;
    NEXT local_parameters_p IN options_seq_p;

{ By definition, the number of status options is non-zero.

    NEXT local_status_options_p: [1 .. local_parameters_p^.status_option_count] IN options_seq_p;
    FOR option_index := 1 TO local_parameters_p^.status_option_count DO
      CASE local_status_options_p^ [option_index].key OF
      = jmc$name_list =
        NEXT local_status_name_count_p IN options_seq_p;
        IF local_status_name_count_p^ = 0 THEN
          local_status_options_p^ [option_index].name_list := NIL;
        ELSE
          NEXT local_status_options_p^ [option_index].name_list: [1 .. local_status_name_count_p^] IN
                options_seq_p;
        IFEND;

      = jmc$user_identification =
        NEXT local_status_options_p^ [option_index].user_identification IN options_seq_p;

      ELSE
      CASEND;
    FOREND;

    IF local_parameters_p^.results_keys_count = 0 THEN
      local_results_keys_p := NIL;
      local_status_keys_p := NIL;
      status_results_keys_p := NIL;
    ELSE
      NEXT local_results_keys_p: [1 .. local_parameters_p^.results_keys_count] IN options_seq_p;
      NEXT local_status_keys_p: [1 .. local_parameters_p^.results_keys_count] IN options_seq_p;
      PUSH status_results_keys_p: [1 .. local_parameters_p^.results_keys_count + 5];
      FOR result_index := 1 TO local_parameters_p^.results_keys_count DO
        status_results_keys_p^ [result_index] := local_status_keys_p^ [result_index];
      FOREND;
      status_results_keys_p^ [local_parameters_p^.results_keys_count + 1] := jmc$login_family;
      status_results_keys_p^ [local_parameters_p^.results_keys_count + 2] := jmc$system_job_name;
      status_results_keys_p^ [local_parameters_p^.results_keys_count + 3] := jmc$input_file_location;
      status_results_keys_p^ [local_parameters_p^.results_keys_count + 4] := jmc$internal_index;
      status_results_keys_p^ [local_parameters_p^.results_keys_count + 5] := jmc$job_mode;

    IFEND;

    mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_sequential, scratch_segment, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    RESET scratch_segment.sequence_pointer;

    jmp$get_job_status (local_status_options_p, status_results_keys_p, scratch_segment.sequence_pointer,
          job_status_results_p, number_of_jobs_statused, status);
    IF NOT status.normal THEN
      IF status.condition = jme$no_jobs_were_found THEN
        number_of_jobs_statused := 0;
        status.normal := TRUE;
      ELSE
        mmp$delete_scratch_segment (scratch_segment, ignore_status);
        RETURN;
      IFEND;
    IFEND;

    number_of_data_packets := 0;
    work_area_full := FALSE;
    IF local_results_keys_p <> NIL THEN

    /fetch_attributes_for_files/
      FOR input_index := 1 TO number_of_jobs_statused DO
        IF local_parameters_p^.attach_file THEN
          IF (job_status_results_p^ [input_index]^ [local_parameters_p^.results_keys_count + 5].job_mode =
                jmc$batch) THEN

{ Attach the file so we can read the system label and get the attributes

            pmp$get_unique_name (local_file_name, { ignore } status);
            determine_file_path (job_status_results_p^ [input_index]^
                  [local_parameters_p^.results_keys_count + 3].input_file_location,
                  job_status_results_p^ [input_index]^ [local_parameters_p^.results_keys_count +
                  1].login_family, job_status_results_p^ [input_index]^
                  [local_parameters_p^.results_keys_count + 2].system_job_name, path_p);
            cycle_selector.cycle_option := pfc$specific_cycle;
            cycle_selector.cycle_number := 1;
            password := osc$null_name;
            usage_selections := $pft$usage_selections [pfc$read];

            osp$establish_block_exit_hndlr (^handle_block_exit);
            pfp$begin_system_authority;
            pfp$attach (local_file_name, path_p^, cycle_selector, password, usage_selections,
                  usage_selections, pfc$wait, { local } status);
            pfp$end_system_authority;
            osp$disestablish_cond_handler;
            IF NOT status.normal THEN
              status.normal := TRUE;
              CYCLE /fetch_attributes_for_files/;
            IFEND;

{ Read the input file's system label

            qfp$read_job_system_label (local_file_name, system_label, status);
            IF NOT status.normal THEN
              amp$return (local_file_name, ignore_status);
              mmp$delete_scratch_segment (scratch_segment, ignore_status);
              RETURN;
            IFEND;

{ Release the file in case somebody needs it for write access

            amp$return (local_file_name, status);

          ELSE { job_mode is interactive
            kjl_index := job_status_results_p^ [input_index]^ [local_parameters_p^.results_keys_count +
                  4].internal_index;
            system_label_p := jmv$kjlx_p^ [kjl_index].system_label_p;
            IF system_label_p = NIL THEN
              CYCLE /fetch_attributes_for_files/;
            IFEND;
            system_label := system_label_p^;

{ If the KJL entry has disappeared then skip the entry.

            IF jmv$kjl_p^ [kjl_index].system_job_name <> job_status_results_p^ [input_index]^
                  [local_parameters_p^.results_keys_count + 2].system_job_name THEN
              CYCLE /fetch_attributes_for_files/;
            IFEND;
          IFEND;
        IFEND;

        number_of_data_packets := number_of_data_packets + 1;

        IF NOT work_area_full THEN

        /fill_in_each_result_field/
          FOR result_index := 1 TO local_parameters_p^.results_keys_count DO
            CASE local_results_keys_p^ [result_index] OF
            = jmc$comment_banner =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.comment_banner;

            = jmc$control_family =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := job_status_results_p^ [input_index]^ [result_index].control_family;

            = jmc$control_user =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := job_status_results_p^ [input_index]^ [result_index].control_user;

            = jmc$copies =
              NEXT copies_p IN data_area_p;
              IF copies_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              copies_p^ := system_label.job_attributes.copy_count;

            = jmc$cpu_time_limit =
              NEXT cpu_time_limit_p IN data_area_p;
              IF cpu_time_limit_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              cpu_time_limit_p^ := system_label.limit_information.cpu_time_limit_assigned;

            = jmc$data_mode =
              NEXT data_mode_p IN data_area_p;
              IF data_mode_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              data_mode_p^ := system_label.data_mode;

            = jmc$device =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.device;

            = jmc$display_message =
              NEXT display_message_p IN data_area_p;
              IF display_message_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;

              IF job_status_results_p^ [input_index]^ [result_index].display_message <> NIL THEN
                display_message_p^ := job_status_results_p^ [input_index]^ [result_index].display_message^;
              ELSE
                display_message_p^.size := 0;
                display_message_p^.value := '';
              IFEND;

            = jmc$earliest_print_time =
              NEXT date_time_p IN data_area_p;
              IF date_time_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              date_time_p^ := system_label.job_attributes.earliest_print_time;

            = jmc$earliest_run_time =
              NEXT date_time_p IN data_area_p;
              IF date_time_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              date_time_p^ := system_label.job_attributes.earliest_run_time;

            = jmc$external_characteristics =
              NEXT external_characteristics_p IN data_area_p;
              IF external_characteristics_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              external_characteristics_p^ := system_label.job_attributes.external_characteristics;

            = jmc$forms_code =
              NEXT forms_code_p IN data_area_p;
              IF forms_code_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              forms_code_p^ := system_label.job_attributes.forms_code;

            = jmc$job_abort_disposition =
              NEXT job_abort_disposition_p IN data_area_p;
              IF job_abort_disposition_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              job_abort_disposition_p^ := system_label.job_abort_disposition;

            = jmc$job_category_list =
              NEXT job_category_count_p IN data_area_p;
              IF job_category_count_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              NEXT job_category_list_p IN data_area_p;
              IF job_category_list_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              job_category_count_p^ := 0;
              FOR job_category_index := LOWERBOUND (jmv$job_category_data.category_names^)
                    TO UPPERBOUND (jmv$job_category_data.category_names^) DO
                IF job_category_index IN system_label.job_category_set THEN
                  job_category_count_p^ := job_category_count_p^ +1;
                  job_category_list_p^ [job_category_count_p^] :=
                        jmv$job_category_data.category_names^ [job_category_index].name;
                IFEND;
              FOREND;

            = jmc$job_class =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := job_status_results_p^ [input_index]^ [result_index].job_class;

            = jmc$job_deferred_by_operator =
              NEXT boolean_p IN data_area_p;
              IF boolean_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              boolean_p^ := job_status_results_p^ [input_index]^ [result_index].job_deferred_by_operator;

            = jmc$job_deferred_by_user =
              NEXT boolean_p IN data_area_p;
              IF boolean_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              boolean_p^ := job_status_results_p^ [input_index]^ [result_index].job_deferred_by_user;

            = jmc$job_destination_family =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_destination_family;

            = jmc$job_destination_usage =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := job_status_results_p^ [input_index]^ [result_index].job_destination_usage;

            = jmc$job_execution_ring =
              NEXT ring_p IN data_area_p;
              IF ring_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              ring_p^ := system_label.job_execution_ring;

            = jmc$job_mode =
              NEXT job_mode_p IN data_area_p;
              IF job_mode_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              job_mode_p^ := job_status_results_p^ [input_index]^ [result_index].job_mode;

            = jmc$job_qualifier_list =
              NEXT job_qualifier_list_p: [1 .. jmc$maximum_job_qualifiers] IN data_area_p;
              IF job_qualifier_list_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              job_qualifier_list_p^ := system_label.job_attributes.job_qualifier_list;

            = jmc$job_recovery_disposition =
              NEXT job_recovery_disposition_p IN data_area_p;
              IF job_recovery_disposition_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              job_recovery_disposition_p^ := system_label.job_recovery_disposition;

            = jmc$job_state =
              NEXT job_state_p IN data_area_p;
              IF job_state_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              job_state_p^ := job_status_results_p^ [input_index]^ [result_index].job_state;

            = jmc$job_size =
              NEXT job_size_p IN data_area_p;
              IF job_size_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              job_size_p^ := system_label.job_attributes.job_size;

            = jmc$job_submission_time =
              NEXT os_date_time_p IN data_area_p;
              IF os_date_time_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              os_date_time_p^ := system_label.job_attributes.job_submission_time;

            = jmc$latest_print_time =
              NEXT date_time_p IN data_area_p;
              IF date_time_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              date_time_p^ := system_label.job_attributes.latest_print_time;

            = jmc$latest_run_time =
              NEXT date_time_p IN data_area_p;
              IF date_time_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              date_time_p^ := system_label.job_attributes.latest_run_time;

            = jmc$login_account =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.login_account;

            = jmc$login_family =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := job_status_results_p^ [input_index]^ [result_index].login_family;

            = jmc$login_project =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.login_project;

            = jmc$login_user =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := job_status_results_p^ [input_index]^ [result_index].login_user;

            = jmc$magnetic_tape_limit =
              NEXT magnetic_tape_limit_p IN data_area_p;
              IF magnetic_tape_limit_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              magnetic_tape_limit_p^ := system_label.limit_information.magnetic_tape_limit_assigned;

            = jmc$maximum_working_set =
              NEXT maximum_working_set_p IN data_area_p;
              IF maximum_working_set_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              maximum_working_set_p^ := system_label.limit_information.maximum_working_set_assigned;

            = jmc$null_attribute =
              ;

            = jmc$origin_application_name =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.originating_application_name;

            = jmc$output_class =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.output_class;

            = jmc$output_deferred_by_user =
              NEXT boolean_p IN data_area_p;
              IF boolean_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              boolean_p^ := system_label.job_attributes.output_deferred_by_user;

            = jmc$output_destination =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.output_destination;

            = jmc$output_destination_family = { operator_family
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.output_destination_family;

            = jmc$output_destination_usage =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.output_destination_usage;

            = jmc$output_disposition =
              NEXT output_disposition_key_p IN data_area_p;
              IF output_disposition_key_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              NEXT output_disposition_path_p IN data_area_p;
              IF output_disposition_path_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              output_disposition_key_p^ := system_label.job_attributes.output_disposition_key;
              IF output_disposition_key_p^ = jmc$standard_output_path THEN
                output_disposition_path_p^ := system_label.job_attributes.output_disposition_path;
              IFEND;

            = jmc$output_priority =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.output_priority;

            = jmc$purge_delay =
              NEXT time_increment_p IN data_area_p;
              IF time_increment_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              time_increment_p^ := system_label.job_attributes.purge_delay;

            = jmc$remote_host_directive =
              NEXT remote_host_directive_p IN data_area_p;
              IF remote_host_directive_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              remote_host_directive_p^ := system_label.job_attributes.remote_host_directive;

            = jmc$routing_banner =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.routing_banner;

            = jmc$site_information =
              NEXT site_information_p IN data_area_p;
              IF site_information_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              site_information_p^ := system_label.job_attributes.site_information;

            = jmc$sru_limit =
              NEXT sru_limit_p IN data_area_p;
              IF sru_limit_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              sru_limit_p^ := system_label.limit_information.sru_limit_assigned;

            = jmc$station =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.station;

            = jmc$station_operator = { operator_user
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.station_operator;

            = jmc$system_job_name =
              NEXT system_file_name_p IN data_area_p;
              IF system_file_name_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              system_file_name_p^ := job_status_results_p^ [input_index]^ [result_index].system_job_name;

            = jmc$user_information =
              NEXT user_information_p IN data_area_p;
              IF user_information_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              user_information_p^ := system_label.job_attributes.user_information;

            = jmc$user_job_name =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := job_status_results_p^ [input_index]^ [result_index].user_job_name;

            = jmc$vertical_print_density =
              NEXT vertical_print_density_p IN data_area_p;
              IF vertical_print_density_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              vertical_print_density_p^ := system_label.job_attributes.vertical_print_density;

            = jmc$vfu_load_procedure =
              NEXT name_value_p IN data_area_p;
              IF name_value_p = NIL THEN
                work_area_full := TRUE;
                EXIT /fill_in_each_result_field/;
              IFEND;
              name_value_p^ := system_label.job_attributes.vfu_load_procedure;

            ELSE
            CASEND;
          FOREND /fill_in_each_result_field/;


        IFEND;
      FOREND /fetch_attributes_for_files/;
    IFEND;

    IF work_area_full THEN
      osp$set_status_condition (jme$work_area_too_small, status);
    IFEND;

    mmp$delete_scratch_segment (scratch_segment, ignore_status);
  PROCEND jmp$mainframe_get_input_attribu;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$mainframe_get_job_status', EJECT ??
*copy jmh$mainframe_get_job_status

  PROCEDURE [XDCL] jmp$mainframe_get_job_status
    (    target_options_p: ^SEQ ( * );
     VAR data_area_p: {input, output} ^SEQ ( * );
     VAR number_of_data_packets: ost$non_negative_integers;
     VAR status: ost$status);

    VAR
      local_parameters_p: ^mainframe_getjs_parameters,
      local_status_name_count_p: ^ost$non_negative_integers,
      local_status_options_p: ^jmt$job_status_options,
      local_status_results_keys_p: ^jmt$results_keys,
      number_of_jobs_found: jmt$job_status_count,
      options_seq_p: ^SEQ ( * ),
      status_option_index: ost$non_negative_integers;

    status.normal := TRUE;
    options_seq_p := target_options_p;
    RESET options_seq_p;
    NEXT local_parameters_p IN options_seq_p;

    IF local_parameters_p^.status_option_count = 0 THEN
      local_status_options_p := NIL;
    ELSE
      NEXT local_status_options_p: [1 .. local_parameters_p^.status_option_count] IN options_seq_p;

      FOR status_option_index := 1 TO local_parameters_p^.status_option_count DO
        IF local_status_options_p^ [status_option_index].key = jmc$name_list THEN
          NEXT local_status_name_count_p IN options_seq_p;
          IF local_status_name_count_p^ = 0 THEN
            local_status_options_p^ [status_option_index].name_list := NIL;
          ELSE
            NEXT local_status_options_p^ [status_option_index].name_list: [1 .. local_status_name_count_p^] IN
                  options_seq_p;
          IFEND;
        IFEND;
      FOREND;
    IFEND;

    IF local_parameters_p^.status_results_count = 0 THEN
      local_status_results_keys_p := NIL;
    ELSE
      NEXT local_status_results_keys_p: [1 .. local_parameters_p^.status_results_count] IN options_seq_p;
    IFEND;

    qfp$get_job_status (local_parameters_p^.user_identification, local_parameters_p^.caller_ssn,
          local_parameters_p^.privileged_job, local_parameters_p^.valid_for_scheduling_displays,
          local_status_options_p, local_status_results_keys_p, data_area_p, number_of_jobs_found, status);
    number_of_data_packets := number_of_jobs_found;
  PROCEND jmp$mainframe_get_job_status;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL #GATE] jmp$open_input_file', EJECT ??
*copy jmh$open_input_file

  PROCEDURE [XDCL, #GATE] jmp$open_input_file
    (    system_job_name: jmt$system_supplied_name;
         access_level: amt$access_level;
         destination_usage: jmt$destination_usage;
         queue_file_password: jmt$queue_file_password;
     VAR file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      attachment_options_p: ^fst$attachment_options,
      attribute_override_p: ^fst$file_cycle_attributes,
      caller_id: ost$caller_identifier,
      family_name: ost$name,
      file_path: fst$path,
      file_path_size: 0 .. fsc$max_path_size,
      master_catalog: ost$name,
      sub_catalog: ost$name;

?? NEWTITLE := '    [INLINE] add_to_file_path', EJECT ??

    PROCEDURE [INLINE] add_to_file_path
      (    path_element_string: string ( * <= osc$max_name_size));

      VAR
        string_length: 1 .. osc$max_name_size;

      string_length := clp$trimmed_string_size (path_element_string);
      file_path (file_path_size + 1, string_length) := path_element_string;
      file_path_size := file_path_size + string_length;
    PROCEND add_to_file_path;

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

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;

?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    #CALLER_ID (caller_id);

{ Validate that the caller deserves access to the file.

    qfp$validate_input_file_access (system_job_name, destination_usage, queue_file_password, family_name,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    determine_file_catalogs (jmc$ifl_store_and_forward_queue, family_name, master_catalog, sub_catalog);

{ Build the file path for the open request.

    file_path_size := 0;
    add_to_file_path (':');
    add_to_file_path (master_catalog);
    add_to_file_path ('.');
    add_to_file_path (jmc$system_user);
    add_to_file_path ('.');
    add_to_file_path (sub_catalog);
    add_to_file_path ('.');
    add_to_file_path (system_job_name);

{ Attach the file for read access and open the file with the rings of the caller

    PUSH attribute_override_p: [1 .. 1];
    attribute_override_p^ [1].selector := fsc$ring_attributes;
    attribute_override_p^ [1].ring_attributes.r1 := osc$tsrv_ring;
    attribute_override_p^ [1].ring_attributes.r2 := caller_id.ring;
    attribute_override_p^ [1].ring_attributes.r3 := caller_id.ring;

    PUSH attachment_options_p: [1 .. 2];
    attachment_options_p^ [1].selector := fsc$access_and_share_modes;
    attachment_options_p^ [1].access_modes.selector := fsc$specific_access_modes;
    attachment_options_p^ [1].access_modes.value := $fst$file_access_options [fsc$read];
    attachment_options_p^ [1].share_modes.selector := fsc$specific_share_modes;
    attachment_options_p^ [1].share_modes.value := $fst$file_access_options [fsc$read];
    attachment_options_p^ [2].selector := fsc$open_share_modes;
    attachment_options_p^ [2].open_share_modes := $fst$file_access_options [fsc$read];

    osp$establish_block_exit_hndlr (^handle_block_exit);
    pfp$begin_system_authority;
    fsp$open_file (file_path (1, file_path_size), access_level, attachment_options_p, NIL, NIL, NIL,
          attribute_override_p, file_identifier, status);
    pfp$end_system_authority;
    osp$disestablish_cond_handler;

  PROCEND jmp$open_input_file;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$rebuild_executing_job', EJECT ??
*copy jmh$rebuild_executing_job

  PROCEDURE [XDCL] jmp$rebuild_executing_job
    (    system_job_name: jmt$system_supplied_name;
         jcb_p: ^jmt$job_control_block);

    VAR
      current_microsecond_clock: jmt$clock_time;

    current_microsecond_clock := #FREE_RUNNING_CLOCK (0);

    qfp$rebuild_executing_job (current_microsecond_clock, system_job_name, jcb_p^);
  PROCEND jmp$rebuild_executing_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$rebuild_input_queue', EJECT ??
*copy jmh$rebuild_input_queue

{ DESIGN:
{   If there are any problems attempting to recover a file in the queue the file should be
{ deleted if the problem is with the file.  If the problem is with the configuration, e.g.
{ some fundamental NOS/VE requests do not work leave the file in the queue until the next
{ deadstart.

  PROCEDURE [XDCL] jmp$rebuild_input_queue
    (    system_job_name: jmt$system_supplied_name;
         family_name: ost$name;
         subcatalog_name: ost$name;
         recover_using_abort_disposition: boolean;
         ignore_client_initiated_jobs: boolean;
         job_deferred_by_operator: boolean;
     VAR status: ost$status);

    VAR
      candidate_name: jmt$name,
      current_date_time: ost$date_time,
      current_mainframe_id: pmt$mainframe_id,
      current_microsecond_clock: jmt$clock_time,
      cycle_selector: pft$cycle_selector,
      earliest_clock_time_to_initiate: jmt$clock_time,
      ignore_status: ost$status,
      input_file_location: jmt$input_file_location,
      job_class: jmt$job_class,
      job_submission_time: jmt$clock_time,
      latest_clock_time_to_initiate: jmt$clock_time,
      leveler_status: jmt$jl_job_leveler_status,
      local_family: boolean,
      local_file_name: amt$local_file_name,
      login_family_access: dft$family_access,
      login_family_available: boolean,
      password: pft$password,
      path_p: ^pft$path,
      server_state: dft$server_state,
      system_label: jmt$job_system_label,
      usage_selections: pft$usage_selections,
      valid_name: jmt$name,
      write_label: boolean;


    status.normal := TRUE;
    ignore_status.normal := TRUE;
    write_label := FALSE;

{ Verify that the system_job_name is a legal system supplied name.

    candidate_name.kind := jmc$system_supplied_name;
    candidate_name.system_supplied_name := system_job_name;
    jmp$validate_name (candidate_name, valid_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$get_unique_name (local_file_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    PUSH path_p: [1 .. 4];
    path_p^ [1] := family_name;
    path_p^ [2] := jmc$system_user;
    path_p^ [3] := subcatalog_name;
    path_p^ [4] := system_job_name;
    cycle_selector.cycle_option := pfc$specific_cycle;
    cycle_selector.cycle_number := 1;
    password := osc$null_name;
    usage_selections := $pft$usage_selections [pfc$read];

    pfp$attach (local_file_name, path_p^, cycle_selector, password, usage_selections, usage_selections,
          pfc$wait, status);
    IF NOT status.normal THEN
      pfp$purge (path_p^, cycle_selector, password, ignore_status);
      RETURN;
    IFEND;

{ If we can't read the system label - then we can't recover it

    qfp$read_job_system_label (local_file_name, system_label, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      pfp$purge (path_p^, cycle_selector, password, ignore_status);
      RETURN;
    IFEND;

{ Verify that the system_job_name matches in the label and the catalog

    IF system_job_name <> system_label.system_job_name THEN
      osp$set_status_condition (sye$job_damaged, status);
      amp$return (local_file_name, ignore_status);
      pfp$purge (path_p^, cycle_selector, password, ignore_status);
      RETURN;
    IFEND;

{ If the job is an interactive job - don't recover it

    IF system_label.job_mode = jmc$interactive_connected THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$cant_recover_job, 'an interactive queued', status);
      amp$return (local_file_name, ignore_status);
      pfp$purge (path_p^, cycle_selector, password, ignore_status);
      RETURN;
    IFEND;

    IF recover_using_abort_disposition AND (system_label.job_abort_disposition = jmc$terminate_on_abort) THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$job_recovery_or_abort_set, 'TERMINATED', status);
      amp$return (local_file_name, ignore_status);
      pfp$purge (path_p^, cycle_selector, password, ignore_status);
      RETURN;
    IFEND;

{ If the job was initiated on this mainframe then it should be recovered as queued.
{ If the job was initiated on a client and ignore_client_initiated_jobs is TRUE then
{ the input file should be recovered as queued.

    IF system_label.job_initiation_location <> '' THEN
      pmp$get_mainframe_id (current_mainframe_id, { ignore } status);
      IF (system_label.job_initiation_location = current_mainframe_id) OR ignore_client_initiated_jobs THEN
        system_label.job_initiation_location := '';
        write_label := TRUE;
      IFEND;
    IFEND;

{ If the job should be deferred, set the attribute in the system label.

    IF job_deferred_by_operator THEN
      system_label.job_deferred_by_operator := job_deferred_by_operator;
      write_label := TRUE;
    IFEND;

    IF write_label THEN
      qfp$write_job_system_label (local_file_name, write_label, system_label, status);
    IFEND;

{ Determine the input file's location.

    IF subcatalog_name = jmc$sf_job_input_catalog THEN
      input_file_location := jmc$ifl_store_and_forward_queue;
    ELSEIF family_name = jmc$system_family THEN
      input_file_location := jmc$ifl_system_input_queue;
    ELSE
      input_file_location := jmc$ifl_login_family_queue;
    IFEND;

{ set up clock info for deferred jobs

    pmp$get_compact_date_time (current_date_time, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      RETURN;
    IFEND;
    pmp$get_microsecond_clock (current_microsecond_clock, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
      RETURN;
    IFEND;

    IF system_label.job_attributes.earliest_run_time.specified THEN
      jmp$convert_date_time_dif_to_us (current_date_time, system_label.job_attributes.earliest_run_time.
            date_time, current_microsecond_clock, earliest_clock_time_to_initiate);
    ELSE
      earliest_clock_time_to_initiate := jmc$earliest_clock_time;
    IFEND;

    IF system_label.job_attributes.latest_run_time.specified THEN
      jmp$convert_date_time_dif_to_us (current_date_time, system_label.job_attributes.latest_run_time.
            date_time, current_microsecond_clock, latest_clock_time_to_initiate);
    ELSE
      latest_clock_time_to_initiate := jmc$latest_clock_time;
    IFEND;

{ Calculate the value for the job's job submission time clock value.

    jmp$convert_date_time_dif_to_us (current_date_time, system_label.job_attributes.job_submission_time,
          current_microsecond_clock, job_submission_time);

    IF input_file_location = jmc$ifl_store_and_forward_queue THEN
      job_class := jmc$null_job_class;
    ELSE
      job_class := jmc$unassigned_job_class;
    IFEND;

    dfp$get_family_access (system_label.login_user_identification.family, local_family, login_family_access,
          server_state, leveler_status);
    IF local_family AND (dfc$remote_file_access IN login_family_access) THEN
      login_family_available := (server_state = dfc$active) AND
            ((login_family_access * $dft$family_access [dfc$remote_login_access,
            dfc$job_leveling_access]) <> $dft$family_access []);
    ELSE
      login_family_available := local_family;
    IFEND;

    qfp$rebuild_input_queue (system_label, earliest_clock_time_to_initiate, latest_clock_time_to_initiate,
          current_microsecond_clock, job_submission_time, job_class, input_file_location,
          login_family_available, status);
    IF NOT status.normal THEN
      amp$return (local_file_name, ignore_status);
    ELSE
      amp$return (local_file_name, status);
    IFEND;

  PROCEND jmp$rebuild_input_queue;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$register_input_application', EJECT ??
*copy jmh$register_input_application

  PROCEDURE [XDCL, #GATE] jmp$register_input_application
    (    application_name: ost$name;
         input_destination_usage: jmt$destination_usage;
     VAR queue_file_password: jmt$queue_file_password;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      privileged_job: boolean,
      valid_name: boolean,
      valid_application_name: ost$name,
      valid_destination_usage: ost$name;

    status.normal := TRUE;
    #CALLER_ID (caller_id);

    privileged_job := (caller_id.ring <= osc$sj_ring_3) OR jmv$enable_queue_file_access OR jmp$system_job ();
    IF NOT privileged_job THEN
      osp$force_access_violation;
    IFEND;

    clp$validate_name (application_name, valid_application_name, valid_name);
    IF NOT valid_name THEN
      osp$set_status_abnormal ('CL', cle$improper_name, application_name, status);
      RETURN;
    IFEND;

    clp$validate_name (input_destination_usage, valid_destination_usage, valid_name);
    IF NOT valid_name THEN
      osp$set_status_abnormal ('CL', cle$improper_name, input_destination_usage, status);
      RETURN;
    IFEND;

    pmp$get_unique_name (queue_file_password, status);
    IF status.normal THEN
      qfp$register_input_application (valid_application_name, valid_destination_usage, queue_file_password,
            status);
      IF status.normal THEN
        task_has_registered_application := TRUE;
      IFEND;
    IFEND;

  PROCEND jmp$register_input_application;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$release_input_files', EJECT ??
*copy jmh$release_input_files

  PROCEDURE [XDCL] jmp$release_input_files;

    VAR
      release_file_list: ^jmt$release_input_file_list,
      release_file_count: jmt$job_count_range,
      release_file_index: jmt$job_count_range,
      ignore_status: ost$status,
      path_p: ^pft$path,
      cycle_selector: pft$cycle_selector,
      password: pft$password;

?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        local_status: ost$status;

      pfp$end_system_authority;
      IF ignore_status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, ignore_status, local_status);
      IFEND;
    PROCEND handle_block_exit;

?? OLDTITLE, EJECT ??

    IF NOT task_has_registered_application THEN
      RETURN;
    IFEND;

    ignore_status.normal := TRUE;

    PUSH release_file_list: [1 .. jmc$maximum_job_count];
    release_file_count := 0;

{ Since the release_file_list is at the maximum, no test will be necessary to verify that
{ the release_file_count does not exceed the upperbound of the list.

    qfp$release_input_files (release_file_list, release_file_count);

    cycle_selector.cycle_option := pfc$specific_cycle;
    cycle_selector.cycle_number := 1;
    password := osc$null_name;
    PUSH path_p: [1 .. 4];
    path_p^ [2] := jmc$system_user;

{ This can only be the store-and-forward queue.  Jobs that belong to the local VE system(s) will not have
{ their command files manipulated by this request.  The only applications that can have files attached are
{ applications that access the store-and-forward queue.  With this in mind, osc$null_name is supplied as
{ the family name.

    osp$establish_block_exit_hndlr (^handle_block_exit);
    pfp$begin_system_authority;

  /purge_all_released_files/
    FOR release_file_index := 1 TO release_file_count DO
      determine_file_catalogs (release_file_list^ [release_file_index].input_file_location, osc$null_name,
            path_p^ [1], path_p^ [3]);
      path_p^ [4] := release_file_list^ [release_file_index].system_job_name;
      pfp$purge (path_p^, cycle_selector, password, ignore_status);
    FOREND /purge_all_released_files/;

    pfp$end_system_authority;
    osp$disestablish_cond_handler;
  PROCEND jmp$release_input_files;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$resubmit_queued_input_job', EJECT ??
*copy jmh$resubmit_queued_input_job

  PROCEDURE [XDCL, #GATE] jmp$resubmit_queued_input_job
    (    system_supplied_name: jmt$system_supplied_name;
     VAR status: ost$status);

    VAR
      input_name: jmt$name,
      local_status: ost$status;

    status.normal := TRUE;

    jmp$get_scheduling_admin_status (local_status);
    IF NOT local_status.normal THEN
      status := local_status;
      RETURN;
    IFEND;
    input_name.kind := jmc$system_supplied_name;
    input_name.system_supplied_name := system_supplied_name;
    jmp$change_input_attributes (input_name, NIL, local_status);
    status := local_status;
  PROCEND jmp$resubmit_queued_input_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$server_submit_job', EJECT ??
*copy jmh$server_submit_job

  PROCEDURE [XDCL] jmp$server_submit_job
    (VAR received_from_client_params_p { Input } : dft$p_receive_parameters;
     VAR received_from_client_data_p { Input } : dft$p_receive_data;
     VAR send_to_client_params_p { Output } : dft$p_send_parameters;
     VAR send_to_client_data_p { Output } : dft$p_send_data;
     VAR parameter_size: dft$send_parameter_size;
     VAR data_size: dft$send_data_size;
     VAR status: ost$status);

    VAR
      assigned_job_class: jmt$job_class,
      current_date_time: ost$date_time,
      current_microsecond_clock: jmt$clock_time,
      cycle_selector: pft$cycle_selector,
      destination_mainframe_id: pmt$mainframe_id,
      earliest_clock_time_to_initiate: jmt$clock_time,
      ignore_status: ost$status,
      ignore_job_queued_this_mainfr: boolean,
      job_system_label_p: ^jmt$job_system_label,
      latest_clock_time_to_initiate: jmt$clock_time,
      leveled_job: boolean,
      local_file_name: amt$local_file_name,
      local_mainframe_id_p: ^pmt$mainframe_id,
      password: pft$password,
      path_p: ^pft$path,
      profile_mismatch: boolean,
      profile_mismatch_or_loading: boolean,
      server_submit_job_params_p: ^server_submit_job_parameters,
      submit_variation: jmt$submit_job_variations,
      usage_selections: pft$usage_selections,
      valid_mainframe_set: jmt$valid_mainframe_set;

?? NEWTITLE := 'categorize_job', EJECT ??

{ PURPOSE:
{   The purpose of this request is to assign and validate allowed values
{   for specific job attributes.

    PROCEDURE categorize_job
      (VAR job_system_label: jmt$job_system_label;
       VAR profile_mismatch_or_loading: boolean;
       VAR assigned_job_class: jmt$job_class;
       VAR status: ost$status);

      VAR
        ignore_encrypted_password: ost$name,
        ignore_status: ost$status;


      profile_mismatch_or_loading := FALSE;
      job_system_label_p^.active_profile_version := jmv$job_scheduler_table.profile_identification;

      convert_limit_information (job_system_label, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      prevalidate_job (job_system_label.login_user_identification, { password_encrypted } TRUE,
            job_system_label, assigned_job_class, ignore_encrypted_password, status);
      IF NOT status.normal THEN
        qfp$check_for_profile_mismatch (job_system_label_p^.active_profile_version, profile_mismatch);
        profile_mismatch_or_loading := profile_mismatch OR jmv$sched_profile_is_loading;
      IFEND;
    PROCEND categorize_job;
?? OLDTITLE ??
?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;
?? OLDTITLE ??
?? EJECT ??
    status.normal := TRUE;

{ The RPC sequences have already been reset.
{ Unpack the information passed from the client.

    NEXT server_submit_job_params_p IN received_from_client_params_p;

    NEXT job_system_label_p IN received_from_client_data_p;

    NEXT local_mainframe_id_p IN send_to_client_params_p;
    pmp$get_mainframe_id (local_mainframe_id_p^, ignore_status);
    parameter_size := i#current_sequence_position (send_to_client_params_p);
    data_size := 0;

{ Determine earliest and latest initiation times.

    pmp$get_microsecond_clock (current_microsecond_clock, ignore_status);
    pmp$get_compact_date_time (current_date_time, ignore_status);

    IF job_system_label_p^.job_attributes.earliest_run_time.specified THEN
      jmp$convert_date_time_dif_to_us (current_date_time, job_system_label_p^.job_attributes.
            earliest_run_time.date_time, current_microsecond_clock, earliest_clock_time_to_initiate);
    ELSE
      earliest_clock_time_to_initiate := jmc$earliest_clock_time;
    IFEND;
    IF job_system_label_p^.job_attributes.latest_run_time.specified THEN
      jmp$convert_date_time_dif_to_us (current_date_time, job_system_label_p^.job_attributes.latest_run_time.
            date_time, current_microsecond_clock, latest_clock_time_to_initiate);
    ELSE
      latest_clock_time_to_initiate := jmc$latest_clock_time;
    IFEND;

  /determine_job_class/
    REPEAT

      WHILE jmv$sched_profile_is_loading DO
        pmp$wait (500, 500);
      WHILEND;

{ Verify that the profile identifiers of the two mainframe match.  If the profiles
{ do not match then the job must be categorized on the server.

      qfp$check_for_profile_mismatch (job_system_label_p^.active_profile_version, profile_mismatch);
      IF NOT profile_mismatch THEN
        jmp$determine_job_class (job_system_label_p^.assigned_job_class, assigned_job_class, status);
        IF NOT status.normal THEN
          qfp$check_for_profile_mismatch (job_system_label_p^.active_profile_version, profile_mismatch);
          IF profile_mismatch OR jmv$sched_profile_is_loading THEN
            status.normal := TRUE;
            CYCLE /determine_job_class/;
          ELSE
            osp$set_status_abnormal (jmc$job_management_id, jme$job_class_does_not_exist,
                  job_system_label_p^.assigned_job_class, status);
            EXIT /determine_job_class/;
          IFEND;
        IFEND;

      ELSEIF (job_system_label_p^.job_mode <> jmc$interactive_connected) THEN
        determine_file_path (jmc$ifl_login_family_queue, job_system_label_p^.login_user_identification.family,
              job_system_label_p^.system_job_name, path_p);
        pmp$get_unique_name (local_file_name, ignore_status);
        cycle_selector.cycle_option := pfc$specific_cycle;
        cycle_selector.cycle_number := 1;
        password := osc$null_name;
        usage_selections := $pft$usage_selections [pfc$read];
        osp$establish_block_exit_hndlr (^handle_block_exit);
        pfp$begin_system_authority;
        pfp$attach (local_file_name, path_p^, cycle_selector, password, usage_selections, usage_selections,
              pfc$wait, status);
        pfp$end_system_authority;
        osp$disestablish_cond_handler;

{ Read the input file's system label

        qfp$read_job_system_label (local_file_name, job_system_label_p^, status);
        IF NOT status.normal THEN
          amp$return (local_file_name, ignore_status);
          EXIT /determine_job_class/;
        IFEND;

        categorize_job (job_system_label_p^, profile_mismatch_or_loading, assigned_job_class, status);
        IF NOT status.normal THEN
          IF profile_mismatch_or_loading THEN
            status.normal := TRUE;
            CYCLE /determine_job_class/;
          ELSE
            amp$return (local_file_name, ignore_status);
            EXIT /determine_job_class/;
          IFEND;
        IFEND;

        qfp$write_job_system_label (local_file_name, { write_label } TRUE, job_system_label_p^, status);
        IF NOT status.normal THEN
          amp$return (local_file_name, ignore_status);
          EXIT /determine_job_class/;
        IFEND;

        amp$return (local_file_name, status);
        IF NOT status.normal THEN
          EXIT /determine_job_class/;
        IFEND;

      ELSEIF (job_system_label_p^.job_mode = jmc$interactive_connected) THEN
        categorize_job (job_system_label_p^, profile_mismatch_or_loading, assigned_job_class, status);
        IF NOT status.normal THEN
          IF profile_mismatch_or_loading THEN
            status.normal := TRUE;
            CYCLE /determine_job_class/;
          ELSE
            EXIT /determine_job_class/;
          IFEND;
        IFEND;
      IFEND;

{ Determine the fitness of the job for the mainframes that are available.

      IF server_submit_job_params_p^.executing_on_server THEN
        leveled_job := job_system_label_p^.job_destination_usage = jmc$ve_usage;
        qfp$determine_mainframe_fitness (job_system_label_p^.job_category_set, leveled_job,
              job_system_label_p^.login_user_identification.family, valid_mainframe_set, status);
        IF status.normal THEN
          IF leveled_job AND (job_system_label_p^.job_mode <> jmc$batch) AND
                jmv$job_scheduler_table.enable_job_leveling THEN
            level_interactive_job (valid_mainframe_set, assigned_job_class, earliest_clock_time_to_initiate,
                  latest_clock_time_to_initiate, current_microsecond_clock,
                  server_submit_job_params_p^.origin_mainframe_id, job_system_label_p^, local_mainframe_id_p^,
                  status);
          ELSE
            IF job_system_label_p^.job_mode <> jmc$batch THEN
              submit_variation.kind := jmc$remote_connection_switch;
              job_system_label_p^.job_attributes.system_job_parameters.system_job_parameter_count :=
                    #SIZE (submit_variation);
              i#move (^submit_variation, ^job_system_label_p^.job_attributes.system_job_parameters.
                    system_job_parameter, #SIZE (submit_variation));
              nap$set_server_job_init_pending (osc$timesharing, {server_job_init_pending = } TRUE, status);
            IFEND;

            IF status.normal THEN
              IF jmv$job_history_active THEN
                jmp$emit_job_history_statistics (jml$job_queuing_started, osc$null_name,
                      job_system_label_p^.system_job_name, jmc$blank_system_supplied_name, job_system_label_p,
                      NIL, osc$null_name, job_system_label_p^.job_attributes.originating_ssn, ignore_status);
              IFEND;

              qfp$submit_job (job_system_label_p^, assigned_job_class, earliest_clock_time_to_initiate,
                    latest_clock_time_to_initiate, current_microsecond_clock,
                    {job_submission_time} current_microsecond_clock,
                    server_submit_job_params_p^.immediate_initiation_candidate, jmc$ifl_login_family_queue,
                    valid_mainframe_set, status);
            IFEND;
          IFEND;
        IFEND;
      ELSE

{ NOT server_submit_job_params_p^.executing_on_server - this only occurs when
{ called from call_client_submit_job.

        valid_mainframe_set := $jmt$valid_mainframe_set [1];
        submit_variation.kind := jmc$remote_connection_switch;
        job_system_label_p^.job_attributes.system_job_parameters.system_job_parameter_count :=
              #SIZE (submit_variation);
        i#move (^submit_variation, ^job_system_label_p^.job_attributes.system_job_parameters.
              system_job_parameter, #SIZE (submit_variation));
        nap$set_server_job_init_pending (osc$timesharing, {server_job_init_pending = } TRUE, status);

        IF status.normal THEN
          IF jmv$job_history_active THEN
            jmp$emit_job_history_statistics (jml$job_queuing_started, osc$null_name,
                  job_system_label_p^.system_job_name, jmc$blank_system_supplied_name, job_system_label_p,
                  NIL, osc$null_name, job_system_label_p^.job_attributes.originating_ssn, ignore_status);
          IFEND;

          qfp$submit_job (job_system_label_p^, assigned_job_class, earliest_clock_time_to_initiate,
                latest_clock_time_to_initiate, current_microsecond_clock,
                {job_submission_time} current_microsecond_clock,
                server_submit_job_params_p^.immediate_initiation_candidate, jmc$ifl_login_family_queue,
                valid_mainframe_set, status);
        IFEND;
      IFEND;
    UNTIL status.normal OR (status.condition <> jme$scheduling_profile_changed);

  PROCEND jmp$server_submit_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] jmp$server_terminate_job', EJECT ??
*copy jmh$server_terminate_job

  PROCEDURE [XDCL] jmp$server_terminate_job
    (VAR received_from_client_params_p { Input } : dft$p_receive_parameters;
     VAR received_from_client_data_p { Input } : dft$p_receive_data;
     VAR send_to_client_params_p { Output } : dft$p_send_parameters;
     VAR send_to_client_data_p { Output } : dft$p_send_data;
     VAR parameter_size: dft$send_parameter_size;
     VAR data_size: dft$send_data_size;
     VAR status: ost$status);

    VAR
      binary_server_mainframe_id: pmt$binary_mainframe_id,
      current_binary_mainframe_id: pmt$binary_mainframe_id,
      current_mainframe_id: pmt$mainframe_id,
      ignore_client_mainframe_id: pmt$mainframe_id,
      ignore_family_name: ost$name,
      ignore_input_file_location: jmt$input_file_location,
      ignore_job_assigned_to_client: boolean,
      job_terminated: boolean,
      local_job_terminated_p: ^boolean,
      local_mf_searched_count_p: ^jmt$maximum_mainframes,
      local_mf_searched_list_p: ^jmt$mainframes_searched_list,
      local_remove_job_from_kjl_p: ^boolean,
      local_system_job_name_p: ^jmt$system_supplied_name,
      local_terminate_job_request_p: ^terminate_job_request,
      mainframes_searched_count: jmt$maximum_mainframes,
      mainframes_searched_list: jmt$mainframes_searched_list,
      mainframes_searched_list_index: jmt$maximum_mainframes,
      server_directly_connected: boolean,
      server_mainframe_count: dft$partner_mainframe_count,
      server_mainframe_id: pmt$mainframe_id,
      server_mainframe_index: dft$partner_mainframe_count,
      server_mainframe_list: array [1 .. dfc$maximum_partner_mainframes] of dft$partner_mainframe_entry;

    status.normal := TRUE;

{ The RPC sequences have already been reset.

    NEXT local_system_job_name_p IN received_from_client_params_p;
    NEXT local_terminate_job_request_p IN received_from_client_params_p;

    IF local_terminate_job_request_p^.server THEN
      NEXT local_mf_searched_count_p IN received_from_client_data_p;
      mainframes_searched_count := local_mf_searched_count_p^;
      NEXT local_mf_searched_list_p IN received_from_client_data_p;
      mainframes_searched_list := local_mf_searched_list_p^;

{ Place this mainframe in the mainframes searched list.

      mainframes_searched_count := mainframes_searched_count + 1;
      pmp$get_pseudo_mainframe_id (current_binary_mainframe_id);
      mainframes_searched_list [mainframes_searched_count] := current_binary_mainframe_id;
      pmp$get_mainframe_id (current_mainframe_id, { ignore } status);

{ If this is the server then terminate the job.  If this is not the server then
{ call the server if it is directly connected.  If the server is not directly
{ connected call all other available server mainframes that have not been called.

      IF current_mainframe_id = local_terminate_job_request_p^.server_mainframe_id THEN

        job_terminated := TRUE;

        terminate_job (local_system_job_name_p^, local_terminate_job_request_p^.job_state_set,
              local_terminate_job_request_p^.output_disposition_key_known,
              local_terminate_job_request_p^.output_disposition_key,
              local_terminate_job_request_p^.operator_job, local_terminate_job_request_p^.reason, status);

      ELSE

        dfp$get_partner_mainframes ({ partners_are_servers } TRUE, ^server_mainframe_list,
              server_mainframe_count);

{ See if the server is directly connected to this mainframe.  If so it can simply
{ be called.  If NOT, a remote procedure call will be required until a mainframe is
{ reached which can access the server or the server cannot be found.

        pmp$convert_mainframe_to_binary (local_terminate_job_request_p^.server_mainframe_id,
              binary_server_mainframe_id, { ignore } status);
        status.normal := TRUE;
        server_directly_connected := FALSE;

      /search_for_server_mainframe/
        FOR server_mainframe_index := 1 TO server_mainframe_count DO
          IF server_mainframe_list [server_mainframe_index].mainframe_id = binary_server_mainframe_id THEN
            server_directly_connected := TRUE;
            terminate_job_on_server (local_system_job_name_p^,
                  local_terminate_job_request_p^.server_mainframe_id, local_terminate_job_request_p^,
                  mainframes_searched_count, mainframes_searched_list, job_terminated, status);
            EXIT /search_for_server_mainframe/;
          IFEND;
        FOREND /search_for_server_mainframe/;

        IF NOT server_directly_connected THEN

        /call_each_server_mainframe/
          FOR server_mainframe_index := 1 TO server_mainframe_count DO
            IF mainframes_searched_count < jmc$maximum_mainframes THEN

{ If the server has already been called then try another server.

              FOR mainframes_searched_list_index := 1 TO mainframes_searched_count DO
                IF mainframes_searched_list [mainframes_searched_list_index] =
                      server_mainframe_list [server_mainframe_index].mainframe_id THEN
                  CYCLE /call_each_server_mainframe/;
                IFEND;
              FOREND;
              IF server_mainframe_list [server_mainframe_index].partner_state = dfc$active THEN
                pmp$convert_binary_mainframe_id (server_mainframe_list [server_mainframe_index].mainframe_id,
                      server_mainframe_id, { ignore } status);
                status.normal := TRUE;
                terminate_job_on_server (local_system_job_name_p^, server_mainframe_id,
                      local_terminate_job_request_p^, mainframes_searched_count, mainframes_searched_list,
                      job_terminated, status);
              IFEND;
            ELSE
              EXIT /call_each_server_mainframe/;
            IFEND;
          FOREND /call_each_server_mainframe/;
        IFEND;
      IFEND;
      NEXT local_job_terminated_p IN send_to_client_params_p;
      local_job_terminated_p^ := job_terminated;

      NEXT local_mf_searched_count_p IN send_to_client_data_p;
      local_mf_searched_count_p^ := mainframes_searched_count;
      NEXT local_mf_searched_list_p IN send_to_client_data_p;
      local_mf_searched_list_p^ := mainframes_searched_list;

    ELSE { client request
      NEXT local_remove_job_from_kjl_p IN send_to_client_params_p;
      qfp$terminate_job (local_system_job_name_p^, local_terminate_job_request_p^.job_state_set,
            local_terminate_job_request_p^.output_disposition_key_known,
            local_terminate_job_request_p^.output_disposition_key,
            local_terminate_job_request_p^.operator_job, ignore_family_name,
            { delete_input_file } local_remove_job_from_kjl_p^, ignore_input_file_location,
            ignore_job_assigned_to_client, ignore_client_mainframe_id, status);

{ If the job was not found on the client the job should still be removed from the server.

      IF (NOT status.normal) AND (status.condition = jme$name_not_found) THEN
        local_remove_job_from_kjl_p^ := TRUE;
        status.normal := TRUE;
      IFEND;
    IFEND;
    parameter_size := i#current_sequence_position (send_to_client_params_p);
    data_size := i#current_sequence_position (send_to_client_data_p);
  PROCEND jmp$server_terminate_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$set_input_completed', EJECT ??
*copy jmh$set_input_completed

  PROCEDURE [XDCL, #GATE] jmp$set_input_completed
    (    input_destination_usage: jmt$destination_usage;
         system_job_name: jmt$system_supplied_name;
         completed_successfully: boolean;
     VAR status: ost$status);

    VAR
      cycle_selector: pft$cycle_selector,
      delete_input_file: boolean,
      password: pft$password,
      path_p: ^pft$path;

?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;

?? OLDTITLE, EJECT ??

    qfp$set_input_completed (input_destination_usage, system_job_name, completed_successfully,
          delete_input_file, status);
    IF status.normal THEN
      IF delete_input_file THEN

{ This can only be the store-and-forward queue.  Jobs that belong to the local VE system(s) will not have
{ their command files touched by this request.  The only applications that can have files attached are
{ applications that access the store-and-forward queue.  With this in mind, osc$null_name is supplied as
{ the family name.

        determine_file_path (jmc$ifl_store_and_forward_queue, osc$null_name, system_job_name, path_p);
        cycle_selector.cycle_option := pfc$specific_cycle;
        cycle_selector.cycle_number := 1;
        password := osc$null_name;
        osp$establish_block_exit_hndlr (^handle_block_exit);
        pfp$begin_system_authority;
        pfp$purge (path_p^, cycle_selector, password, status);
        pfp$end_system_authority;
        osp$disestablish_cond_handler;
      IFEND;
    IFEND;

  PROCEND jmp$set_input_completed;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$set_input_initiated', EJECT ??
*copy jmh$set_input_initiated

  PROCEDURE [XDCL, #GATE] jmp$set_input_initiated
    (    input_destination_usage: jmt$destination_usage;
         system_job_name: jmt$system_supplied_name;
     VAR status: ost$status);

    VAR
      ignore_status: ^ost$status;

    qfp$set_input_initiated (input_destination_usage, system_job_name, status);

    IF jmv$job_history_active AND status.normal THEN
      PUSH ignore_status;
      jmp$emit_job_history_statistics (jml$job_forwarding_started, osc$null_name, system_job_name,
            jmc$blank_system_supplied_name, NIL, NIL, osc$null_name, jmc$blank_system_supplied_name,
            ignore_status^);
    IFEND;

  PROCEND jmp$set_input_initiated;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$set_job_class_limits', EJECT ??
*copy jmh$set_job_class_limits

  PROCEDURE [XDCL, #GATE] jmp$set_job_class_limits
    (    job_class_set: jmt$job_class_set;
         class_limit_value: jmt$job_count_range;
     VAR status: ost$status);

    osp$verify_system_privilege;
    status.normal := TRUE;

    IF NOT avp$system_operator () THEN
      osp$set_status_abnormal ('OF', ofe$sou_not_active, 'system_operator', status);
      RETURN;
    IFEND;

    qfp$set_job_class_limits (job_class_set, class_limit_value);
  PROCEND jmp$set_job_class_limits;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$submit_job', EJECT ??
*copy jmh$submit_job

{ DESIGN:
{   This interface will accept multiple occurrences of the same attribute.  Only the last value specified
{ for a particular attribute (submission option) will be used.

  PROCEDURE [XDCL, #GATE] jmp$submit_job
    (    file_reference: fst$file_reference;
         job_submission_options: ^jmt$job_submission_options;
     VAR system_job_name: jmt$system_supplied_name;
     VAR status: ost$status);

    VAR
      assigned_job_class: jmt$job_class,
      caller_identification: ost$caller_identifier,
      command_file_password: pft$password,
      command_file_path_p: ^pft$path,
      current_date_time: ost$date_time,
      current_mainframe_id: pmt$mainframe_id,
      current_microsecond_clock: jmt$clock_time,
      cycle_selector: pft$cycle_selector,
      destination_mainframe_id: pmt$mainframe_id,
      earliest_clock_time_to_initiate: jmt$clock_time,
      encrypted_password: ost$name,
      encrypted_password_supplied: boolean,
      evaluated_file_reference: fst$evaluated_file_reference,
      explicit_login_command_p: ^string ( * ),
      file_path: fst$path,
      file_path_size: fst$path_size,
      ignore_status: ost$status,
      immediate_initiation_candidate: boolean,
      inherit_job_attributes: boolean,
      input_file_location: jmt$input_file_location,
      job_label_exists: boolean,
      job_submission_time: jmt$clock_time,
      latest_clock_time_to_initiate: jmt$clock_time,
      leveled_access: boolean,
      leveled_job: boolean,
      login_family_defined: boolean,
      privileged_job: boolean,
      profile_mismatch: boolean,
      reason: ost$name,
      remote_host_directive_inherited: boolean,
      server_location: dft$server_location,
      statistic_data: jmt$comm_acct_statistic_data,
      store_and_forward_job: boolean,
      submit_job_to_server: boolean,
      submit_of_command_file: boolean,
      submit_variation: jmt$submit_job_variations,
      system_label: jmt$job_system_label,
      user_identification: ost$user_identification,
      valid_mainframe_set: jmt$valid_mainframe_set;

?? NEWTITLE := '    assign_default_attributes', EJECT ??

{ PURPOSE:
{   The purpose of this request is to assign the default job attribute values to a job that is being
{ submitted.
{
{ DESIGN:
{   If the job is being submitted by the system on behalf of a user use the "system" defaults for the
{ job attribute values.  Otherwise, use the submitting users job attribute values as the defaults for
{ the job attribute values.

    PROCEDURE assign_default_attributes
      (    user_identification: ost$user_identification;
           inherit_job_attributes: boolean;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

      VAR
        use_user_attributes: boolean;

      status.normal := TRUE;

{ If the caller is a user, use the user default attributes
{ If the caller is the system, submitting a user job, use system defaults
{ If the caller is the system, submitting system job, use user defaults
{ If the caller asked not to inherit the job attributes use system defaults

      use_user_attributes := (NOT (jmp$system_job () AND (NOT (user_identification =
            system_label.login_user_identification)))) AND inherit_job_attributes;

{ Assign job attribute defaults

      IF use_user_attributes THEN
        system_label.job_attributes.comment_banner := jmv$job_attributes.comment_banner;
        system_label.job_attributes.copy_count := jmv$job_attributes.copy_count;
        system_label.job_attributes.device := jmv$job_attributes.device;
        system_label.job_attributes.earliest_print_time := jmv$job_attributes.earliest_print_time;
        system_label.job_attributes.external_characteristics := jmv$job_attributes.external_characteristics;
        system_label.job_attributes.forms_code := jmv$job_attributes.forms_code;
        system_label.job_attributes.implicit_routing_text := jmv$job_attributes.implicit_routing_text;
        system_label.job_attributes.job_controller := jmv$job_attributes.job_controller;
        system_label.job_attributes.job_input_device := jmv$job_attributes.job_input_device;
        system_label.job_attributes.latest_print_time := jmv$job_attributes.latest_print_time;
        system_label.job_attributes.output_destination := jmv$job_attributes.output_destination;
        system_label.job_attributes.output_destination_family := jmv$job_attributes.output_destination_family;
        system_label.job_attributes.output_destination_usage := jmv$job_attributes.output_destination_usage;
        system_label.job_attributes.output_priority := jmv$job_attributes.output_priority;
        system_label.job_attributes.purge_delay := jmv$job_attributes.purge_delay;
        system_label.job_attributes.remote_host_directive := jmv$job_attributes.remote_host_directive;
        system_label.job_attributes.routing_banner := jmv$job_attributes.routing_banner;
        system_label.job_attributes.source_logical_id := jmv$job_attributes.source_logical_id;
        system_label.job_attributes.station := jmv$job_attributes.station;
        system_label.job_attributes.station_operator := jmv$job_attributes.station_operator;
        IF system_label.job_attributes.user_information = '' THEN
          system_label.job_attributes.user_information := jmv$job_attributes.user_information;
        IFEND;
        system_label.job_attributes.vertical_print_density := jmv$job_attributes.vertical_print_density;
        system_label.job_attributes.vfu_load_procedure := jmv$job_attributes.vfu_load_procedure;
      ELSE
        system_label.job_attributes.comment_banner := '';
        system_label.job_attributes.copy_count := 1;
        system_label.job_attributes.device := jmv$default_job_attributes [system_label.job_mode].device;
        system_label.job_attributes.earliest_print_time.specified := FALSE;
        system_label.job_attributes.external_characteristics :=
              jmv$default_job_attributes [system_label.job_mode].external_characteristics;
        system_label.job_attributes.forms_code := jmv$default_job_attributes [system_label.job_mode].
              forms_code;
        system_label.job_attributes.implicit_routing_text.size := 0;
        system_label.job_attributes.implicit_routing_text.text := '';
        system_label.job_attributes.job_controller := system_label.login_user_identification;
        system_label.job_attributes.job_input_device.size := 0;
        system_label.job_attributes.job_input_device.text := '';
        system_label.job_attributes.latest_print_time.specified := FALSE;
        system_label.job_attributes.output_destination := osc$null_name;
        system_label.job_attributes.output_destination_family := osc$null_name;
        system_label.job_attributes.output_destination_usage :=
              jmv$default_job_attributes [system_label.job_mode].output_destination_usage;
        system_label.job_attributes.output_priority := jmv$default_job_attributes [system_label.job_mode].
              output_priority;
        system_label.job_attributes.purge_delay := jmv$default_job_attributes [system_label.job_mode].
              purge_delay;
        system_label.job_attributes.remote_host_directive.size := 0;
        system_label.job_attributes.remote_host_directive.parameters := '';
        system_label.job_attributes.routing_banner := '';
        system_label.job_attributes.source_logical_id := '';
        system_label.job_attributes.station := 'AUTOMATIC';
        system_label.job_attributes.station_operator := osc$null_name;
        system_label.job_attributes.vertical_print_density :=
              jmv$default_job_attributes [system_label.job_mode].vertical_print_density;
        system_label.job_attributes.vfu_load_procedure := jmv$default_job_attributes [system_label.job_mode].
              vfu_load_procedure;
      IFEND;

{ Override attributes that are not inheritable

      pmp$get_compact_date_time (system_label.job_attributes.job_submission_time, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      system_label.job_attributes.output_class := jmv$default_job_attributes [system_label.job_mode].
            output_class;
      system_label.job_attributes.output_deferred_by_user := FALSE;
      system_label.job_attributes.output_disposition_key := jmc$normal_output_disposition;

      system_label.job_attributes.output_disposition_path := '';
      system_label.job_attributes.site_information := jmv$default_job_attributes [system_label.job_mode].
            site_information;
      system_label.job_attributes.system_job_parameters.system_job_parameter := '';
      system_label.job_attributes.system_job_parameters.system_job_parameter_count := 0;
      system_label.job_attributes.system_routing_text.parameters := '';
      system_label.job_attributes.system_routing_text.size := 0;
    PROCEND assign_default_attributes;

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

{ PURPOSE:
{   The purpose of this procedure is to assign some default values for several items in the job label.
{
{ NOTES:
{   Any attributes that represent parameters on the LOGIN command must be initialized
{ by this procedure.

    PROCEDURE assign_default_label_values
      (    user_identification: ost$user_identification;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

      VAR
        submitter_job_name: jmt$user_supplied_name;

{ system_label.version is not used.

      pmp$get_job_names (submitter_job_name, system_label.job_attributes.originating_ssn, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      system_label.active_profile_version := osc$null_name;
      system_label.assigned_job_class := osc$null_name;
      system_label.data_declaration := '';
      system_label.data_mode := jmc$coded_data;
      system_label.disposition_code := '';
      system_label.job_category_set := $jmt$job_category_set [];
      system_label.job_class_name := osc$null_name;
      system_label.job_deferred_by_user := FALSE;
      system_label.job_destination_family := osc$null_name;
      system_label.job_destination_usage := jmv$default_job_attributes [jmc$batch].job_destination_usage;
      system_label.job_execution_ring := osc$invalid_ring;
      system_label.job_initiation_location := '';
      system_label.job_mode := jmc$batch;
      system_label.job_priority := osc$null_name;
      system_label.limit_information.cpu_time_limit_specified := FALSE;
      system_label.limit_information.cpu_time_limit_assigned := sfc$unlimited;
      system_label.limit_information.magnetic_tape_limit_specified := FALSE;
      system_label.limit_information.magnetic_tape_limit_assigned := 0;
      system_label.limit_information.maximum_working_set_specified := FALSE;
      system_label.limit_information.maximum_working_set_assigned := 20000;
      system_label.limit_information.sru_limit_specified := FALSE;
      system_label.limit_information.sru_limit_assigned := sfc$unlimited;
      system_label.login_account := osc$null_name;
      system_label.login_project := osc$null_name;
      system_label.login_password := osc$null_name;
      system_label.login_user_identification.user := osc$null_name;
      system_label.login_user_identification.family := osc$null_name;
      system_label.optional_user_capability := osc$null_name;
      pmp$get_account_project (system_label.originating_login_account, system_label.originating_login_project,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      system_label.originating_login_family := user_identification.family;
      system_label.originating_login_user := user_identification.user;
      system_label.perform_class_validation := TRUE;
      system_label.required_user_capability := osc$null_name;
      system_label.system_job_name := '';
      system_label.user_job_name := osc$null_name;
      system_label.job_attributes.earliest_run_time.specified := FALSE;
      system_label.job_attributes.latest_run_time.specified := FALSE;
      system_label.job_attributes.login_command_supplied := TRUE;
      system_label.job_attributes.originating_application_name := osc$submit_job;
      system_label.job_attributes.process_user_prolog_and_epilog := TRUE;
      system_label.job_attributes.user_information := '';
    PROCEND assign_default_label_values;

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

{ PURPOSE:
{   This procedure determines if the job being submitted already has its attributes
{   defined (i.e., it has a label associated with it).

    PROCEDURE determine_if_job_label_exists
      (    file_reference: fst$file_reference;
       VAR system_label: jmt$job_system_label;
       VAR job_label_exists: boolean;
       VAR status: ost$status);


{ Try to read a job label from the file being submitted.

      qfp$read_job_system_label (file_reference, system_label, status);
      IF status.normal THEN
        job_label_exists := TRUE;
      ELSEIF status.condition = jme$read_job_system_label THEN
        osp$set_status_condition (jme$sl_version_mismatch, status);
      ELSEIF (status.condition <> jme$sl_version_mismatch) THEN
        status.normal := TRUE;
        job_label_exists := FALSE;
      IFEND;
    PROCEND determine_if_job_label_exists;
?? OLDTITLE ??
?? NEWTITLE := '    determine_job_attributes', EJECT ??

{ PURPOSE:
{   The purpose of this request is to pass through the job submission options and override the default
{ job attribute values with explicit values provided by the caller.

    PROCEDURE determine_job_attributes
      (    job_submission_options_p: ^jmt$job_submission_options;
           privileged_job: boolean;
       VAR system_label: jmt$job_system_label;
       VAR immediate_initiation_candidate: boolean;
       VAR current_date_time: ost$date_time;
       VAR current_microsecond_clock: jmt$clock_time;
       VAR earliest_clock_time_to_initiate: jmt$clock_time;
       VAR latest_clock_time_to_initiate: jmt$clock_time;
       VAR remote_host_directive_inherited: boolean;
       VAR status: ost$status);

      VAR
        option_index: ost$positive_integers,
        parsed_file_reference: fst$parsed_file_reference,
        scl_name: ost$name,
        valid_name: boolean;

      status.normal := TRUE;
      immediate_initiation_candidate := FALSE;
      remote_host_directive_inherited := (system_label.job_attributes.remote_host_directive.size > 0);

{ Override the default values for the system label - if necessary

      IF job_submission_options_p <> NIL THEN
        FOR option_index := 1 TO UPPERBOUND (job_submission_options_p^) DO
          CASE job_submission_options_p^ [option_index].key OF
          = jmc$comment_banner =
            system_label.job_attributes.comment_banner := job_submission_options_p^ [option_index].
                  comment_banner;

          = jmc$copies =
            system_label.job_attributes.copy_count := job_submission_options_p^ [option_index].copies;

          = jmc$device =
            clp$validate_name (job_submission_options_p^ [option_index].device, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].device, status);
              RETURN;
            IFEND;
            system_label.job_attributes.device := scl_name;

          = jmc$earliest_print_time =
            system_label.job_attributes.earliest_print_time :=
                  job_submission_options_p^ [option_index].earliest_print_time;

          = jmc$earliest_run_time =
            system_label.job_attributes.earliest_run_time := job_submission_options_p^ [option_index].
                  earliest_run_time;

          = jmc$external_characteristics =
            #TRANSLATE (osv$lower_to_upper, job_submission_options_p^ [option_index].external_characteristics,
                  system_label.job_attributes.external_characteristics);

          = jmc$forms_code =
            #TRANSLATE (osv$lower_to_upper, job_submission_options_p^ [option_index].forms_code,
                  system_label.job_attributes.forms_code);

          = jmc$job_abort_disposition =
            system_label.job_abort_disposition := job_submission_options_p^ [option_index].
                  job_abort_disposition;

          = jmc$job_recovery_disposition =
            system_label.job_recovery_disposition := job_submission_options_p^ [option_index].
                  job_recovery_disposition;

          = jmc$latest_print_time =
            system_label.job_attributes.latest_print_time := job_submission_options_p^ [option_index].
                  latest_print_time;

          = jmc$latest_run_time =
            system_label.job_attributes.latest_run_time := job_submission_options_p^ [option_index].
                  latest_run_time;

          = jmc$output_deferred_by_user =
            system_label.job_attributes.output_deferred_by_user :=
                  job_submission_options_p^ [option_index].output_deferred_by_user;

          = jmc$output_destination =
            clp$validate_name (job_submission_options_p^ [option_index].output_destination, scl_name,
                  valid_name);
            IF valid_name THEN
              system_label.job_attributes.output_destination := scl_name;
            ELSE { The value must be a string
              #TRANSLATE (osv$lower_to_upper, job_submission_options_p^ [option_index].output_destination,
                    system_label.job_attributes.output_destination);
            IFEND;

          = jmc$output_destination_family =
            clp$validate_name (job_submission_options_p^ [option_index].output_destination_family, scl_name,
                  valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].output_destination_family, status);
              RETURN;
            IFEND;
            system_label.job_attributes.output_destination_family := scl_name;

          = jmc$output_destination_usage =
            clp$validate_name (job_submission_options_p^ [option_index].output_destination_usage, scl_name,
                  valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].output_destination_usage, status);
              RETURN;
            IFEND;
            system_label.job_attributes.output_destination_usage := scl_name;

          = jmc$output_disposition =
            system_label.job_attributes.output_disposition_key :=
                  job_submission_options_p^ [option_index].output_disposition.key;
            IF system_label.job_attributes.output_disposition_key = jmc$standard_output_path THEN
              system_label.job_attributes.output_disposition_path :=
                    job_submission_options_p^ [option_index].output_disposition.standard_output_path^;
              clp$convert_string_to_file_ref (job_submission_options_p^ [option_index].output_disposition.
                    standard_output_path^, parsed_file_reference, status);
              IF NOT status.normal THEN
                RETURN;
              IFEND;
              IF parsed_file_reference.path (parsed_file_reference.first_name.index,
                    parsed_file_reference.first_name.size) = '$LOCAL' THEN
                osp$set_status_condition (jme$permanent_file_required, status);
                RETURN;
              IFEND;
              system_label.job_attributes.output_disposition_path := parsed_file_reference.
                    path (1, parsed_file_reference.complete_path_size);
            IFEND;

          = jmc$purge_delay =
            system_label.job_attributes.purge_delay := job_submission_options_p^ [option_index].purge_delay^;

          = jmc$remote_host_directive =
            system_label.job_attributes.remote_host_directive :=
                  job_submission_options_p^ [option_index].remote_host_directive^;
            remote_host_directive_inherited := FALSE;

          = jmc$routing_banner =
            system_label.job_attributes.routing_banner := job_submission_options_p^ [option_index].
                  routing_banner;

          = jmc$station =
            clp$validate_name (job_submission_options_p^ [option_index].station, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].station, status);
              RETURN;
            IFEND;
            system_label.job_attributes.station := scl_name;

          = jmc$station_operator =
            clp$validate_name (job_submission_options_p^ [option_index].station_operator, scl_name,
                  valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].station_operator, status);
              RETURN;
            IFEND;
            system_label.job_attributes.station_operator := scl_name;

          = jmc$user_information =
            system_label.job_attributes.user_information := job_submission_options_p^ [option_index].
                  user_information^;

          = jmc$vertical_print_density =
            system_label.job_attributes.vertical_print_density :=
                  job_submission_options_p^ [option_index].vertical_print_density;

          = jmc$vfu_load_procedure =
            clp$validate_name (job_submission_options_p^ [option_index].vfu_load_procedure, scl_name,
                  valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].vfu_load_procedure, status);
              RETURN;
            IFEND;
            system_label.job_attributes.vfu_load_procedure := scl_name;

{ The following submission options require special privilege to specify them


          = jmc$control_family =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            clp$validate_name (job_submission_options_p^ [option_index].control_family, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].control_family, status);
              RETURN;
            IFEND;
            system_label.job_attributes.job_controller.family := scl_name;

          = jmc$control_user =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            clp$validate_name (job_submission_options_p^ [option_index].control_user, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].control_user, status);
              RETURN;
            IFEND;
            system_label.job_attributes.job_controller.user := scl_name;

          = jmc$data_mode =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.data_mode := job_submission_options_p^ [option_index].data_mode;

          = jmc$data_declaration =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.data_declaration := job_submission_options_p^ [option_index].data_declaration;

          = jmc$disposition_code =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.disposition_code := job_submission_options_p^ [option_index].disposition_code;

          = jmc$immediate_init_candidate =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            immediate_initiation_candidate := job_submission_options_p^ [option_index].
                  immediate_init_candidate;

          = jmc$implicit_routing_text =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.job_attributes.implicit_routing_text :=
                  job_submission_options_p^ [option_index].implicit_routing_text^;

          = jmc$job_input_device =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.job_attributes.job_input_device := job_submission_options_p^ [option_index].
                  job_input_device^;

          = jmc$site_information =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.job_attributes.site_information := job_submission_options_p^ [option_index].
                  site_information^;

          = jmc$source_logical_id =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.job_attributes.source_logical_id := job_submission_options_p^ [option_index].
                  source_logical_id;

          = jmc$system_job_parameters =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.job_attributes.system_job_parameters :=
                  job_submission_options_p^ [option_index].system_job_parameters^;

          = jmc$system_routing_text =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.job_attributes.system_routing_text :=
                  job_submission_options_p^ [option_index].system_routing_text^;

          ELSE
            ; { nothing }
          CASEND;
        FOREND;
      IFEND;


{ Determine earliest and latest initiation times.

      pmp$get_microsecond_clock (current_microsecond_clock, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      pmp$get_compact_date_time (current_date_time, { ignore } status);

      IF system_label.job_attributes.earliest_run_time.specified THEN
        jmp$convert_date_time_dif_to_us (current_date_time,
              system_label.job_attributes.earliest_run_time.date_time, current_microsecond_clock,
              earliest_clock_time_to_initiate);
      ELSE
        earliest_clock_time_to_initiate := jmc$earliest_clock_time;
      IFEND;
      IF system_label.job_attributes.latest_run_time.specified THEN
        jmp$convert_date_time_dif_to_us (current_date_time,
              system_label.job_attributes.latest_run_time.date_time, current_microsecond_clock,
              latest_clock_time_to_initiate);
      ELSE
        latest_clock_time_to_initiate := jmc$latest_clock_time;
      IFEND;

{ Make sure that station_operator and output_destination_family are set

      IF system_label.job_attributes.station_operator = osc$null_name THEN
        system_label.job_attributes.station_operator := system_label.login_user_identification.user;
      IFEND;
      IF system_label.job_attributes.output_destination_family = osc$null_name THEN
        system_label.job_attributes.output_destination_family :=
              system_label.login_user_identification.family;
      IFEND;
      IF system_label.job_attributes.output_destination = osc$null_name THEN
        system_label.job_attributes.output_destination := system_label.login_user_identification.family;
      IFEND;

{ If the job is interactive, override the attributes of earliest_run_time, latest_run_time
{ job_deferred_by_user, and job_destination_usage.

      IF system_label.job_mode <> jmc$batch THEN
        system_label.job_deferred_by_user := FALSE;
        system_label.job_attributes.earliest_run_time.specified := FALSE;
        system_label.job_attributes.latest_run_time.specified := FALSE;
        IF (system_label.job_destination_usage <> jmc$ve_usage) AND
              (system_label.job_destination_usage <> jmc$ve_local_usage) AND
              (system_label.job_destination_usage <> jmc$ve_family_usage) THEN
          system_label.job_destination_usage := jmv$default_job_attributes [jmc$interactive_connected].
                job_destination_usage;
        IFEND;
        IF (system_label.job_attributes.originating_application_name <> osc$timesharing) THEN
          system_label.job_destination_usage := jmc$ve_local_usage;
        IFEND;
        earliest_clock_time_to_initiate := jmc$earliest_clock_time;
        latest_clock_time_to_initiate := jmc$latest_clock_time;
      IFEND;

{ If the usage is NTF the control_family and control_user are re-assigned.

      IF system_label.job_destination_usage = jmc$ntf_usage THEN
        system_label.job_attributes.job_controller.family :=
              system_label.job_attributes.output_destination_family;
        system_label.job_attributes.job_controller.user := system_label.job_attributes.station_operator;
      IFEND;

    PROCEND determine_job_attributes;

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

{ PURPOSE:
{   The purpose of this request is to check the job_destination_family to see if it is a local family
{   and reset the job_destination_family and job_destination_usage as necessary.
{
{ DESIGN:
{   If the job_destination_usage is supplied with a remote value and the job_destination_family
{   is undefined an error is returned.
{
{   If the login_family is a local family and the job_destination_usage is jmc$ve_qtf_usage the
{   job_destination_usage will be reset to jmc$ve_usage.
{
{   If the login_family is NOT a local family and the job_destination_usage is jmc$ve_qtf_usage
{   the job_destination_usage will be reset to jmc$qtf_usage.
{
{   If the job_destination_family is undefined, it is given a value of the login family.
{
{ NOTES:
{   If a job is destined for a remote system via QTF and the output_disposition is supplied
{ as a permanent file an error is returned by this request.  When QTF supports
{ allowing a permanent file this restriction will be removed.

    PROCEDURE determine_job_destination
      (    login_family_defined: boolean;
           remote_host_directive_inherited: boolean;
       VAR system_label: { input, output } jmt$job_system_label;
       VAR input_file_location: jmt$input_file_location;
       VAR store_and_forward_job: boolean;
       VAR submit_job_to_server: boolean;
       VAR leveled_job: boolean;
       VAR status: ost$status);

      VAR
        leveler_status: jmt$jl_job_leveler_status,
        local_family: boolean,
        login_family_access: dft$family_access,
        operation_information_p: ^sft$audit_information,
        original_job_destination_usage: jmt$destination_usage,
        private_or_shared_family: boolean,
        served_family: boolean,
        server_state: dft$server_state,
        terminal_name: ost$name,
        terminal_name_found: boolean;


?? EJECT ??
      status.normal := TRUE;
      dfp$get_family_access (system_label.login_user_identification.family, local_family, login_family_access,
            server_state, leveler_status);

      IF local_family AND (dfc$remote_file_access IN login_family_access) THEN
        IF server_state <> dfc$active THEN
          osp$set_status_abnormal (jmc$job_management_id, jme$served_family_unavailable,
                system_label.login_user_identification.family, status);
          RETURN;
        IFEND;
      IFEND;
      IF NOT local_family THEN
        login_family_access := $dft$family_access [];
      IFEND;
      private_or_shared_family := local_family AND (login_family_access = $dft$family_access []);
      served_family := ((login_family_access * $dft$family_access
            [dfc$remote_login_access, dfc$job_leveling_access]) <> $dft$family_access []);
      original_job_destination_usage := system_label.job_destination_usage;
      IF system_label.job_destination_usage = jmc$ve_qtf_usage THEN
        IF local_family THEN
          system_label.job_destination_usage := jmc$ve_usage;
        ELSE
          system_label.job_destination_usage := jmc$qtf_usage;
        IFEND;
      IFEND;

      IF system_label.job_destination_usage = jmc$ve_local_usage THEN
        submit_job_to_server := FALSE;
        IF private_or_shared_family THEN
          input_file_location := jmc$ifl_login_family_queue;
        ELSEIF served_family THEN
          input_file_location := jmc$ifl_system_input_queue;
        ELSE
          osp$set_status_abnormal (jmc$job_management_id, pfe$unknown_family,
                system_label.login_user_identification.family, status);
          IF avp$security_option_active (avc$vso_security_audit) THEN
            PUSH operation_information_p;
            operation_information_p^.audited_operation := sfc$ao_val_prevalidate_user;
            operation_information_p^.user_identification.family_name_p :=
                  ^system_label.login_user_identification.family;
            operation_information_p^.user_identification.user_name_p :=
                  ^system_label.login_user_identification.user;
            operation_information_p^.user_identification.account_name_p := ^system_label.login_account;
            operation_information_p^.user_identification.project_name_p := ^system_label.login_project;

            get_terminal_name (system_label, terminal_name_found, terminal_name);
            IF terminal_name_found THEN
              operation_information_p^.user_identification.terminal_name_p := ^terminal_name;
            ELSE
              operation_information_p^.user_identification.terminal_name_p := NIL;
            IFEND;

            sfp$emit_audit_statistic (operation_information_p^, status);
          IFEND;
          RETURN;
        IFEND;

      ELSEIF system_label.job_destination_usage = jmc$ve_family_usage THEN
        IF NOT local_family THEN
          osp$set_status_abnormal (jmc$job_management_id, pfe$unknown_family,
                system_label.login_user_identification.family, status);
          IF avp$security_option_active (avc$vso_security_audit) THEN
            PUSH operation_information_p;
            operation_information_p^.audited_operation := sfc$ao_val_prevalidate_user;
            operation_information_p^.user_identification.family_name_p :=
                  ^system_label.login_user_identification.family;
            operation_information_p^.user_identification.user_name_p :=
                  ^system_label.login_user_identification.user;
            operation_information_p^.user_identification.account_name_p := ^system_label.login_account;
            operation_information_p^.user_identification.project_name_p := ^system_label.login_project;

            get_terminal_name (system_label, terminal_name_found, terminal_name);
            IF terminal_name_found THEN
              operation_information_p^.user_identification.terminal_name_p := ^terminal_name;
            ELSE
              operation_information_p^.user_identification.terminal_name_p := NIL;
            IFEND;

            sfp$emit_audit_statistic (operation_information_p^, status);
          IFEND;
          RETURN;
        IFEND;
        input_file_location := jmc$ifl_login_family_queue;

{ Submit the job to the server only if this is not the job's server.

        submit_job_to_server := NOT private_or_shared_family;
        system_label.job_destination_usage := jmc$ve_local_usage;

      ELSEIF system_label.job_destination_usage = jmc$ve_usage THEN
        IF NOT (private_or_shared_family OR served_family) THEN
          osp$set_status_abnormal (jmc$job_management_id, pfe$unknown_family,
                system_label.login_user_identification.family, status);
          IF avp$security_option_active (avc$vso_security_audit) THEN
            PUSH operation_information_p;
            operation_information_p^.audited_operation := sfc$ao_val_prevalidate_user;
            operation_information_p^.user_identification.family_name_p :=
                  ^system_label.login_user_identification.family;
            operation_information_p^.user_identification.user_name_p :=
                  ^system_label.login_user_identification.user;
            operation_information_p^.user_identification.account_name_p := ^system_label.login_account;
            operation_information_p^.user_identification.project_name_p := ^system_label.login_project;

            get_terminal_name (system_label, terminal_name_found, terminal_name);
            IF terminal_name_found THEN
              operation_information_p^.user_identification.terminal_name_p := ^terminal_name;
            ELSE
              operation_information_p^.user_identification.terminal_name_p := NIL;
            IFEND;

            sfp$emit_audit_statistic (operation_information_p^, status);
          IFEND;
          RETURN;
        IFEND;
        IF served_family AND (NOT (dfc$job_leveling_access IN login_family_access)) THEN
          input_file_location := jmc$ifl_system_input_queue;
        ELSE
          input_file_location := jmc$ifl_login_family_queue;
        IFEND;
        submit_job_to_server := (dfc$job_leveling_access IN login_family_access);

      ELSE { QTF and others
        input_file_location := jmc$ifl_store_and_forward_queue;
        submit_job_to_server := FALSE;
      IFEND;

      store_and_forward_job := (input_file_location = jmc$ifl_store_and_forward_queue);
      leveled_job := (system_label.job_destination_usage = jmc$ve_usage) AND (NOT served_family);

{ If the job_destination_family is unassigned give it the login family as a value.

      IF system_label.job_destination_family = osc$null_name THEN
        IF store_and_forward_job AND (original_job_destination_usage <> jmc$ve_qtf_usage) THEN
          osp$set_status_abnormal (jmc$job_management_id, jme$parameter_required_when, 'JOB_DESTINATION',
                status);
          osp$append_status_parameter (osc$status_parameter_delimiter, 'JOB_DESTINATION_USAGE', status);
          RETURN;
        IFEND;
        system_label.job_destination_family := system_label.login_user_identification.family;
      IFEND;

      IF store_and_forward_job AND (NOT login_family_defined) THEN
        system_label.login_user_identification.family := osc$null_name;
      IFEND;

      IF (system_label.job_destination_usage = jmc$qtf_usage) AND
            (system_label.job_attributes.output_disposition_key = jmc$standard_output_path) THEN
        osp$set_status_abnormal (jmc$job_management_id, jme$invalid_parameter_value, '<file value>', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'OUTPUT_DISPOSITION', status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'SUBMIT_JOB', status);
      IFEND;

      IF store_and_forward_job AND remote_host_directive_inherited THEN
        system_label.job_attributes.remote_host_directive.size := 0;
        system_label.job_attributes.remote_host_directive.parameters := '';
      IFEND;
    PROCEND determine_job_destination;
?? OLDTITLE ??
?? NEWTITLE := '    determine_login_defaults', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to traverse the submission options array and override any login
{ related default attributes.  This procedure also attempts to validate that the user is only using
{ supported submission options.
{
{ DESIGN:
{   In validating the submission options only the key selectors are validated.  Should the users
{ submission options be subject to change by some user process (such as an asynchronous task) the
{ only impact that it can have is for options to be ignored later.  The major reason for even
{ checking this is an attempt to provide callers with an appropriate diagnostic if possible.
{ Validation for values of specific submission options is done when each option is being used.
{ Any time that an attribute is added it must be added to the set or to the case statement.
{ It should only be added to the case statement if it is a login default.

    PROCEDURE determine_login_defaults
      (    job_submission_options_p: ^jmt$job_submission_options;
           privileged_job: boolean;
       VAR system_label: jmt$job_system_label;
       VAR explicit_login_command_p: ^string ( * );
       VAR status: ost$status);

      VAR
        candidate_system_job_name: jmt$name,
        option_index: ost$positive_integers,
        scl_name: ost$name,
        valid_name: boolean,
        valid_system_job_name: jmt$name;

      status.normal := TRUE;
      explicit_login_command_p := NIL;

      IF job_submission_options_p <> NIL THEN

      /assign_and_validate/
        FOR option_index := 1 TO UPPERBOUND (job_submission_options_p^) DO
          IF NOT (job_submission_options_p^ [option_index].key IN $jmt$attribute_keys_set [

          jmc$comment_banner, jmc$copies, jmc$cpu_time_limit, jmc$device, jmc$earliest_print_time,
                jmc$earliest_run_time, jmc$encrypted_password, jmc$external_characteristics, jmc$forms_code,
                jmc$inherit_job_attributes, jmc$job_abort_disposition, jmc$job_class,
                jmc$job_deferred_by_operator, jmc$job_deferred_by_user, jmc$job_destination_family,
                jmc$job_destination_usage, jmc$job_execution_ring, jmc$job_priority, jmc$job_qualifier_list,
                jmc$job_recovery_disposition, jmc$latest_print_time, jmc$latest_run_time, jmc$login_account,
                jmc$login_family, jmc$login_password, jmc$login_project, jmc$login_user,
                jmc$magnetic_tape_limit, jmc$maximum_working_set, jmc$null_attribute,
                jmc$output_deferred_by_user, jmc$output_destination, jmc$output_destination_family,
                jmc$output_destination_usage, jmc$output_disposition, jmc$purge_delay,
                jmc$remote_host_directive, jmc$routing_banner, jmc$sru_limit, jmc$station,
                jmc$station_operator, jmc$user_information, jmc$user_job_name, jmc$vertical_print_density,
                jmc$vfu_load_procedure, jmc$control_family, jmc$control_user, jmc$data_declaration,
                jmc$data_mode, jmc$disposition_code, jmc$immediate_init_candidate, jmc$implicit_routing_text,
                jmc$job_input_device, jmc$optional_user_capability, jmc$required_user_capability,
                jmc$site_information, jmc$source_logical_id, jmc$system_job_parameters,
                jmc$system_routing_text]) THEN

            CASE job_submission_options_p^ [option_index].key OF
            = jmc$default_login_account =
              clp$validate_name (job_submission_options_p^ [option_index].default_login_account, scl_name,
                    valid_name);
              IF NOT valid_name THEN
                osp$set_status_abnormal ('CL', cle$improper_name,
                      job_submission_options_p^ [option_index].default_login_account, status);
                EXIT /assign_and_validate/;
              IFEND;
              system_label.login_account := scl_name;

            = jmc$default_login_family =
              clp$validate_name (job_submission_options_p^ [option_index].default_login_family, scl_name,
                    valid_name);
              IF NOT valid_name THEN
                osp$set_status_abnormal ('CL', cle$improper_name,
                      job_submission_options_p^ [option_index].default_login_family, status);
                EXIT /assign_and_validate/;
              IFEND;
              system_label.login_user_identification.family := scl_name;

            = jmc$default_login_project =
              clp$validate_name (job_submission_options_p^ [option_index].default_login_project, scl_name,
                    valid_name);
              IF NOT valid_name THEN
                osp$set_status_abnormal ('CL', cle$improper_name,
                      job_submission_options_p^ [option_index].default_login_project, status);
                EXIT /assign_and_validate/;
              IFEND;
              system_label.login_project := scl_name;

            = jmc$default_login_user =
              clp$validate_name (job_submission_options_p^ [option_index].default_login_user, scl_name,
                    valid_name);
              IF NOT valid_name THEN
                osp$set_status_abnormal ('CL', cle$improper_name,
                      job_submission_options_p^ [option_index].default_login_user, status);
                EXIT /assign_and_validate/;
              IFEND;
              system_label.login_user_identification.user := scl_name;

{ The following require special privilege

            = jmc$login_command =

{ If the caller is not privileged abort the task by forcing an access violation.

              IF NOT privileged_job THEN
                osp$force_access_violation;
              IFEND;

{ The caller has specified an explict login command.  Save a pointer to it so we can build a
{ parameter list and process the login after other default attributes are set.

              explicit_login_command_p := job_submission_options_p^ [option_index].login_command;

            = jmc$login_command_supplied =

{ If the caller is not privileged abort the task by forcing an access violation.

              IF NOT privileged_job THEN
                osp$force_access_violation;
              IFEND;
              system_label.job_attributes.login_command_supplied :=
                    job_submission_options_p^ [option_index].login_command_supplied;

            = jmc$omit_class_validation =

{ If the caller is not privileged abort the task by forcing an access violation.

              IF NOT privileged_job THEN
                osp$force_access_violation;
              IFEND;
              system_label.perform_class_validation := NOT job_submission_options_p^ [option_index].
                    omit_class_validation;

            = jmc$omit_user_prolog_and_epilog =

{ If the caller is not privileged abort the task by forcing an access violation.

              IF NOT privileged_job THEN
                osp$force_access_violation;
              IFEND;
              system_label.job_attributes.process_user_prolog_and_epilog :=
                    NOT job_submission_options_p^ [option_index].omit_user_prolog_and_epilog;

            = jmc$origin_application_name =

{ If the caller is not privileged abort the task by forcing an access violation.

              IF NOT privileged_job THEN
                osp$force_access_violation;
              IFEND;
              clp$validate_name (job_submission_options_p^ [option_index].origin_application_name, scl_name,
                    valid_name);
              IF NOT valid_name THEN
                osp$set_status_abnormal ('CL', cle$improper_name,
                      job_submission_options_p^ [option_index].origin_application_name, status);
                EXIT /assign_and_validate/;
              IFEND;
              system_label.job_attributes.originating_application_name := scl_name;

            = jmc$system_job_name =

{ If the caller is not privileged abort the task by forcing an access violation.

              IF NOT privileged_job THEN
                osp$force_access_violation;
              IFEND;

{ Specifying a blank system supplied name forces a NEW system supplied name to be assigned to a file.
{ This allows an application to "Loopback" on the same mainframe.

              IF job_submission_options_p^ [option_index].system_job_name <>
                    jmc$blank_system_supplied_name THEN
                candidate_system_job_name.kind := jmc$system_supplied_name;
                candidate_system_job_name.system_supplied_name :=
                      job_submission_options_p^ [option_index].system_job_name;
                jmp$validate_name (candidate_system_job_name, valid_system_job_name, status);
                IF NOT status.normal THEN
                  EXIT /assign_and_validate/;
                IFEND;
                system_label.system_job_name := valid_system_job_name.system_supplied_name;
              ELSE
                system_label.system_job_name := jmc$blank_system_supplied_name;
              IFEND;

            ELSE
              jmp$get_attribute_name (job_submission_options_p^ [option_index].key, scl_name);
              osp$set_status_abnormal (jmc$job_management_id, jme$invalid_parameter, scl_name, status);
              osp$append_status_parameter (osc$status_parameter_delimiter, 'JOB_SUBMISSION_OPTIONS', status);
              osp$append_status_parameter (osc$status_parameter_delimiter, jmc$submit_job, status);
              EXIT /assign_and_validate/;
            CASEND;
          IFEND;
        FOREND /assign_and_validate/;
      IFEND;
    PROCEND determine_login_defaults;

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

{ PURPOSE:
{   The purpose of this request is to "crack" the login command supplied with the job and then pass through
{ the submission options to determine any additional login related attributes.

    PROCEDURE determine_login_elements
      (    file_reference: fst$file_reference;
           caller_ring: ost$valid_ring;
           user_identification: ost$user_identification;
           job_submission_options_p: ^jmt$job_submission_options;
           privileged_job: boolean;
           explicit_login_command_p: ^string ( * );
           job_label_exists: boolean;
       VAR encrypted_password_supplied: boolean;
       VAR login_family_defined: boolean;
       VAR inherit_job_attributes: boolean;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

      VAR
        candidate_usn: jmt$name,
        ignore_status: ost$status,
        job_qualifier_index: 1 .. jmc$maximum_job_qualifiers,
        login_command_in_file: boolean,
        option_index: ost$positive_integers,
        parameter_list_seq_p: ^clt$parameter_list,
        parameter_list_size_p: ^clt$command_line_size,
        parameter_list_text_p: ^string ( * ),
        scl_name: ost$name,
        valid_name: boolean,
        valid_usn: jmt$name;

      status.normal := TRUE;
      ignore_status.normal := TRUE;
      encrypted_password_supplied := FALSE;
      inherit_job_attributes := TRUE;

{ Change the job mode if necessary

      IF (system_label.job_attributes.originating_application_name = osc$dual_state_interactive) OR
            (system_label.job_attributes.originating_application_name = osc$timesharing) OR
            (system_label.job_attributes.originating_application_name = osc$xterm_application_name) THEN
        system_label.job_mode := jmc$interactive_connected;
      IFEND;

{ Set LOGIN values that are dependent on the job mode.

      IF NOT job_label_exists THEN
        system_label.job_abort_disposition := jmv$default_job_attributes [system_label.job_mode].
              job_abort_disposition;
        system_label.job_destination_usage := jmv$default_job_attributes [system_label.job_mode].
              job_destination_usage;
        system_label.job_recovery_disposition := jmv$default_job_attributes [system_label.job_mode].
              job_recovery_disposition;
        system_label.job_attributes.job_qualifier_list := jmv$default_job_attributes [system_label.job_mode].
              job_qualifier_list;
      IFEND;
      system_label.job_deferred_by_operator := jmv$default_job_attributes [system_label.job_mode].
            job_deferred_by_operator;

{ Test for valid use of $NULL as the file name

      IF (file_reference = ':$LOCAL.$NULL.1') AND ((system_label.job_mode <> jmc$interactive_connected) OR
            system_label.job_attributes.login_command_supplied) THEN
        osp$set_status_condition (jme$cant_use_$null, status);
        RETURN;
      IFEND;

{ Crack the login statement in the command file.  If the command file has the login command of another
{ type of system this request will return a status that indicates that the login command in the command
{ file is invalid.  If there is a login command it MUST be valid.

      IF system_label.job_attributes.login_command_supplied AND (NOT job_label_exists) THEN
        clp$get_job_parameters (caller_ring, file_reference, system_label, login_command_in_file, status);
        IF NOT status.normal THEN
          IF login_command_in_file THEN
            RETURN;
          ELSE
            status.normal := TRUE;
          IFEND;
        IFEND;
      IFEND;

{ Crack the user supplied login command if there is one.  The login command must be converted to a
{ parameter_list and then cracked as the parameters of a login command.

      IF explicit_login_command_p <> NIL THEN
        PUSH parameter_list_seq_p: [[REP (STRLENGTH (explicit_login_command_p^) +
              #SIZE (clt$command_line_size)) OF cell]];
        RESET parameter_list_seq_p;
        NEXT parameter_list_size_p IN parameter_list_seq_p;
        parameter_list_size_p^ := STRLENGTH (explicit_login_command_p^);
        NEXT parameter_list_text_p: [parameter_list_size_p^] IN parameter_list_seq_p;
        parameter_list_text_p^ := explicit_login_command_p^;

        clp$push_sub_parameters_block ({ lookup_functions_and_variables } FALSE);
        clp$get_login_parameters (parameter_list_seq_p^, system_label, status);
        clp$pop_parameters (ignore_status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

{ Make a pass through submission options to determine specified parameters.

      IF job_submission_options_p <> NIL THEN

      /assign_login_elements/
        FOR option_index := 1 TO UPPERBOUND (job_submission_options_p^) DO
          CASE job_submission_options_p^ [option_index].key OF
          = jmc$cpu_time_limit =
            system_label.limit_information.cpu_time_limit_specified := TRUE;
            system_label.limit_information.cpu_time_limit_requested :=
                  job_submission_options_p^ [option_index].cpu_time_limit;

          = jmc$job_class =
            clp$validate_name (job_submission_options_p^ [option_index].job_class, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].job_class, status);
              RETURN;
            IFEND;
            system_label.job_class_name := scl_name;

          = jmc$job_deferred_by_user =
            system_label.job_deferred_by_user := job_submission_options_p^ [option_index].
                  job_deferred_by_user;

          = jmc$job_destination_family =
            clp$validate_name (job_submission_options_p^ [option_index].job_destination_family, scl_name,
                  valid_name);
            IF valid_name THEN
              system_label.job_destination_family := scl_name;
            ELSE { The value must be a string.
              #TRANSLATE (osv$lower_to_upper, job_submission_options_p^ [option_index].job_destination_family,
                    system_label.job_destination_family);
            IFEND;

          = jmc$job_destination_usage =
            clp$validate_name (job_submission_options_p^ [option_index].job_destination_usage, scl_name,
                  valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].job_destination_usage, status);
              RETURN;
            IFEND;
            system_label.job_destination_usage := scl_name;

          = jmc$job_execution_ring =
            system_label.job_execution_ring := job_submission_options_p^ [option_index].job_execution_ring;

          = jmc$job_qualifier_list =
            FOR job_qualifier_index := 1 TO jmc$maximum_job_qualifiers DO
              IF (job_submission_options_p^ [option_index].job_qualifier_list <> NIL) AND
                    (UPPERBOUND (job_submission_options_p^ [option_index].job_qualifier_list^) >=
                    job_qualifier_index) THEN
                IF job_submission_options_p^ [option_index].job_qualifier_list^ [job_qualifier_index] =
                      osc$null_name THEN
                  scl_name := osc$null_name;
                ELSE
                  clp$validate_name (job_submission_options_p^ [option_index].
                        job_qualifier_list^ [job_qualifier_index], scl_name, valid_name);
                  IF NOT valid_name THEN
                    osp$set_status_abnormal ('CL', cle$improper_name,
                          job_submission_options_p^ [option_index].job_qualifier_list^ [job_qualifier_index],
                          status);
                    RETURN;
                  IFEND;
                IFEND;
                system_label.job_attributes.job_qualifier_list [job_qualifier_index] := scl_name;
              ELSE
                system_label.job_attributes.job_qualifier_list [job_qualifier_index] := osc$null_name;
              IFEND;
            FOREND;

          = jmc$login_account =
            clp$validate_name (job_submission_options_p^ [option_index].login_account, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].login_account, status);
              RETURN;
            IFEND;
            system_label.login_account := scl_name;

          = jmc$login_family =
            clp$validate_name (job_submission_options_p^ [option_index].login_family, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].login_family, status);
              RETURN;
            IFEND;
            system_label.login_user_identification.family := scl_name;

          = jmc$login_password =
            clp$validate_name (job_submission_options_p^ [option_index].login_password, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].login_password, status);
              RETURN;
            IFEND;
            system_label.login_password := scl_name;

          = jmc$login_project =
            clp$validate_name (job_submission_options_p^ [option_index].login_project, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].login_project, status);
              RETURN;
            IFEND;
            system_label.login_project := scl_name;

          = jmc$login_user =
            clp$validate_name (job_submission_options_p^ [option_index].login_user, scl_name, valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].login_user, status);
              RETURN;
            IFEND;
            system_label.login_user_identification.user := scl_name;

          = jmc$magnetic_tape_limit =
            system_label.limit_information.magnetic_tape_limit_specified := TRUE;
            system_label.limit_information.magnetic_tape_limit_requested :=
                  job_submission_options_p^ [option_index].magnetic_tape_limit;

          = jmc$maximum_working_set =
            system_label.limit_information.maximum_working_set_specified := TRUE;
            system_label.limit_information.maximum_working_set_requested :=
                  job_submission_options_p^ [option_index].maximum_working_set;

          = jmc$sru_limit =
            system_label.limit_information.sru_limit_specified := TRUE;
            system_label.limit_information.sru_limit_requested :=
                  job_submission_options_p^ [option_index].sru_limit;

          = jmc$user_job_name =
            candidate_usn.kind := jmc$user_supplied_name;
            candidate_usn.user_supplied_name := job_submission_options_p^ [option_index].user_job_name;
            jmp$validate_name (candidate_usn, valid_usn, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
            system_label.user_job_name := valid_usn.user_supplied_name;

{ The following require special privilege

          = jmc$job_deferred_by_operator =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            system_label.job_deferred_by_operator := job_submission_options_p^ [option_index].
                  job_deferred_by_operator;

          = jmc$encrypted_password =
            IF caller_ring > osc$sj_ring_3 THEN
              osp$force_access_violation;
            IFEND;
            encrypted_password_supplied := TRUE;
            system_label.login_password := job_submission_options_p^ [option_index].encrypted_password;

          = jmc$inherit_job_attributes =
            IF caller_ring > osc$sj_ring_3 THEN
              osp$force_access_violation;
            IFEND;
            inherit_job_attributes := job_submission_options_p^ [option_index].inherit_job_attributes;

          = jmc$required_user_capability =

{ If the caller is not privileged abort the task by forcing an access violation.

            IF NOT privileged_job THEN
              osp$force_access_violation;
            IFEND;
            clp$validate_name (job_submission_options_p^ [option_index].required_user_capability, scl_name,
                  valid_name);
            IF NOT valid_name THEN
              osp$set_status_abnormal ('CL', cle$improper_name,
                    job_submission_options_p^ [option_index].required_user_capability, status);
              RETURN;
            IFEND;
            system_label.required_user_capability := scl_name;

          ELSE
            ; { nothing }
          CASEND;
        FOREND /assign_login_elements/;
      IFEND;


{ Assign the correct default login family

      login_family_defined := (system_label.login_user_identification.family <> osc$null_name);

      IF NOT login_family_defined THEN
        IF system_label.job_attributes.originating_application_name = osc$submit_job THEN
          system_label.login_user_identification.family := user_identification.family;
        ELSE
          system_label.login_user_identification.family := jmv$default_job_attributes [system_label.job_mode].
                login_family;
        IFEND;
      IFEND;

{ Check to see if there is a user_job_name

      IF system_label.user_job_name = osc$null_name THEN
        system_label.user_job_name := system_label.login_user_identification.user;
      IFEND;
    PROCEND determine_login_elements;

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

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;

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

{ PURPOSE:
{   The purpose of this request is to place the command file into the proper input queue and
{ correctly write the job system label to the file.

    PROCEDURE process_command_file_and_label
      (    file_reference: fst$file_reference;
           path_p: ^pft$path;
           command_file_password: pft$password;
           caller_ring: ost$ring;
           job_label_exists: boolean;
           store_and_forward_job: boolean;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

      CONST
        unit_separator = $CHAR (1f(16));

      VAR
        command_file_name: amt$local_file_name,
        contains_data: boolean,
        cycle_selector: pft$cycle_selector,
        file_identifier: amt$file_identifier,
        get_attributes_p: ^amt$get_attributes,
        ignore_status: ost$status,
        input_attachment_options_p: ^fst$attachment_options,
        input_catalog_path_p: ^pft$path,
        input_validation_attributes_p: ^fst$file_cycle_attributes,
        local_file: boolean,
        mandated_creation_attributes: ^fst$file_cycle_attributes,
        null_file_access_procedure: pmt$entry_point_reference,
        old_file: boolean,
        output_attachment_options_p: ^fst$attachment_options,
        system_job_name_assigned: boolean,
        write_label: boolean;

?? NEWTITLE := 'handle_out_of_space', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with the out of space condition.

      PROCEDURE handle_out_of_space
        (    condition: pmt$condition;
             condition_information_p: ^pmt$condition_information;
             sfsa_p: ^ost$stack_frame_save_area;
         VAR handler_status: ost$status);

        VAR
          ignore_status: ost$status;

        IF (condition.selector = pmc$user_defined_condition) AND
              (condition.user_condition_name = osc$space_unavailable_condition) THEN
          osp$set_status_condition (jme$no_space_for_file, status);
          amp$return (command_file_name, ignore_status);
          osp$establish_block_exit_hndlr (^handle_block_exit);
          pfp$begin_system_authority;
          pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
          pfp$end_system_authority;
          osp$disestablish_cond_handler;
          EXIT process_command_file_and_label;
        ELSEIF condition.selector = pmc$block_exit_processing THEN
          pfp$end_system_authority;
          IF status.normal THEN
            osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
          IFEND;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, handler_status);
        IFEND;
      PROCEND handle_out_of_space;
?? OLDTITLE ??
?? EJECT ??
      status.normal := TRUE;
      cycle_selector.cycle_option := pfc$specific_cycle;
      cycle_selector.cycle_number := 1;

{ If the system supplied name in the label has a value then one does not need to be assigned.

      system_job_name_assigned := system_label.system_job_name <> '';

{ Force variables used by the out of space condition handler to memory.
{ Establish the condition handler.

      #SPOIL (command_file_name, cycle_selector);

      osp$establish_condition_handler (^handle_out_of_space, {block_exit} TRUE);
      pfp$begin_system_authority;

      REPEAT
        IF NOT system_job_name_assigned THEN
          qfp$assign_system_supplied_name (system_label.system_job_name);
        IFEND;
        command_file_name := system_label.system_job_name;
        path_p^ [4] := command_file_name;
        pfp$define (command_file_name, path_p^, cycle_selector, command_file_password, pfc$maximum_retention,
              pfc$log, status);
        IF NOT status.normal THEN
          IF (status.condition = pfe$unknown_last_subcatalog) OR
                (status.condition = pfe$unknown_nth_subcatalog) THEN
            PUSH input_catalog_path_p: [1 .. 3];
            input_catalog_path_p^ [1] := path_p^ [1];
            input_catalog_path_p^ [2] := path_p^ [2];
            input_catalog_path_p^ [3] := path_p^ [3];
            pfp$define_catalog (input_catalog_path_p^, status);
            IF status.normal THEN
              osp$set_status_condition (pfe$duplicate_cycle, status)
            IFEND;
          ELSEIF (status.condition = pfe$duplicate_cycle) THEN
            system_job_name_assigned := FALSE;
          IFEND;
        IFEND;
      UNTIL (status.normal) OR (status.condition <> pfe$duplicate_cycle);
      pfp$end_system_authority;
      osp$disestablish_cond_handler;
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF jmv$job_history_active THEN
        IF (NOT jmp$system_job ()) OR (jmp$system_job () AND
              (system_label.job_mode <> jmc$interactive_connected)) THEN
          jmp$emit_job_history_statistics (jml$submit_job_executed, osc$null_name,
                system_label.system_job_name, jmc$blank_system_supplied_name, ^system_label, NIL,
                osc$null_name, jmc$blank_system_supplied_name, ignore_status);
        IFEND;
      IFEND;


{ Create the file in the input queue.

      IF (file_reference = ':$LOCAL.$NULL.1') THEN
        IF system_label.job_mode = jmc$interactive_connected THEN
          PUSH mandated_creation_attributes: [1 .. 2];
          mandated_creation_attributes^ [1].selector := fsc$file_contents_and_processor;
          mandated_creation_attributes^ [1].file_contents := fsc$legible_data;
          mandated_creation_attributes^ [1].file_processor := fsc$scl;
          mandated_creation_attributes^ [2].selector := fsc$ring_attributes;
          mandated_creation_attributes^ [2].ring_attributes.r1 := osc$tsrv_ring;
          mandated_creation_attributes^ [2].ring_attributes.r2 := osc$tsrv_ring;
          mandated_creation_attributes^ [2].ring_attributes.r3 := osc$tsrv_ring;

{ In order to put ring attributes on the file and force the label to be written it is necessary to
{ open and close the input file.

          fsp$open_file (command_file_name, amc$record, NIL, NIL, mandated_creation_attributes, NIL, NIL,
                file_identifier, status);
          IF NOT status.normal THEN
            fsp$close_file (file_identifier, ignore_status);
            amp$return (command_file_name, ignore_status);
            osp$establish_block_exit_hndlr (^handle_block_exit);
            pfp$begin_system_authority;
            pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
            pfp$end_system_authority;
            osp$disestablish_cond_handler;
            RETURN;
          IFEND;

          fsp$close_file (file_identifier, status);
          IF NOT status.normal THEN
            amp$return (command_file_name, ignore_status);
            osp$establish_block_exit_hndlr (^handle_block_exit);
            pfp$begin_system_authority;
            pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
            pfp$end_system_authority;
            osp$disestablish_cond_handler;
            RETURN;
          IFEND;
        ELSE

{ Can't get here - this should have been precluded in determine_login_elements

          osp$set_status_condition (jme$cant_use_$null, status);
          amp$return (command_file_name, ignore_status);
          osp$establish_block_exit_hndlr (^handle_block_exit);
          pfp$begin_system_authority;
          pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
          pfp$end_system_authority;
          osp$disestablish_cond_handler;
          RETURN;
        IFEND;
      ELSE
        null_file_access_procedure.entry_point := osc$null_name;
        null_file_access_procedure.object_library := '';
        PUSH input_validation_attributes_p: [1 .. 1];
        input_validation_attributes_p^ [1].selector := fsc$file_access_procedure_name;
        input_validation_attributes_p^ [1].file_access_procedure_name := ^null_file_access_procedure;

        PUSH input_attachment_options_p: [1 .. 9];
        input_attachment_options_p^ [1].selector := fsc$access_and_share_modes;
        input_attachment_options_p^ [1].access_modes.selector := fsc$specific_access_modes;
        input_attachment_options_p^ [1].access_modes.value := $fst$file_access_options [fsc$read];
        input_attachment_options_p^ [1].share_modes.selector := fsc$specific_share_modes;
        input_attachment_options_p^ [1].share_modes.value := $fst$file_access_options [fsc$read, fsc$execute];
        input_attachment_options_p^ [2].selector := fsc$allowed_device_classes;
        input_attachment_options_p^ [2].allowed_device_classes := $fst$device_classes
              [fsc$mass_storage_device];
        input_attachment_options_p^ [3].selector := fsc$create_file;
        input_attachment_options_p^ [3].create_file := FALSE;
        input_attachment_options_p^ [4].selector := fsc$free_behind;
        input_attachment_options_p^ [4].free_behind := TRUE;
        input_attachment_options_p^ [5].selector := fsc$open_position;
        input_attachment_options_p^ [5].open_position := amc$open_at_boi;
        input_attachment_options_p^ [6].selector := fsc$private_read;
        input_attachment_options_p^ [6].private_read := TRUE;
        input_attachment_options_p^ [7].selector := fsc$sequential_access;
        input_attachment_options_p^ [7].sequential_access := TRUE;
        input_attachment_options_p^ [8].selector := fsc$validation_ring;
        input_attachment_options_p^ [8].validation_ring := caller_ring;

{ The access mode of EXECUTE is required to allow jmp$submit_job to copy a file
{ with execute only permission.  This can only be done from ring 3.

        input_attachment_options_p^ [9].selector := fsc$access_and_share_modes;
        input_attachment_options_p^ [9].access_modes.selector := fsc$specific_access_modes;
        input_attachment_options_p^ [9].access_modes.value := $fst$file_access_options [fsc$execute];
        input_attachment_options_p^ [9].share_modes.selector := fsc$specific_share_modes;
        input_attachment_options_p^ [9].share_modes.value := $fst$file_access_options [fsc$read, fsc$execute];

        PUSH output_attachment_options_p: [1 .. 2];
        output_attachment_options_p^ [1].selector := fsc$free_behind;
        output_attachment_options_p^ [1].free_behind := TRUE;
        output_attachment_options_p^ [2].selector := fsc$sequential_access;
        output_attachment_options_p^ [2].sequential_access := TRUE;

        IF NOT store_and_forward_job THEN
          PUSH mandated_creation_attributes: [1 .. 5];
          mandated_creation_attributes^ [1].selector := fsc$ring_attributes;
          mandated_creation_attributes^ [1].ring_attributes.r1 := osc$tsrv_ring;
          mandated_creation_attributes^ [1].ring_attributes.r2 := osc$tsrv_ring;
          mandated_creation_attributes^ [1].ring_attributes.r3 := osc$tsrv_ring;
          mandated_creation_attributes^ [2].selector := fsc$file_contents_and_processor;
          mandated_creation_attributes^ [2].file_contents := fsc$legible_data;
          mandated_creation_attributes^ [2].file_processor := fsc$scl;
          mandated_creation_attributes^ [3].selector := fsc$block_type;
          mandated_creation_attributes^ [3].block_type := amc$system_specified;
          mandated_creation_attributes^ [4].selector := fsc$file_organization;
          mandated_creation_attributes^ [4].file_organization := amc$sequential;
          mandated_creation_attributes^ [5].selector := fsc$record_type;
          mandated_creation_attributes^ [5].record_type := amc$variable;

        ELSE
          IF system_label.data_mode = jmc$coded_data THEN
            PUSH mandated_creation_attributes: [1 .. 6];
            mandated_creation_attributes^ [1].selector := fsc$ring_attributes;
            mandated_creation_attributes^ [1].ring_attributes.r1 := osc$tsrv_ring;
            mandated_creation_attributes^ [1].ring_attributes.r2 := osc$tsrv_ring;
            mandated_creation_attributes^ [1].ring_attributes.r3 := osc$tsrv_ring;
            mandated_creation_attributes^ [2].selector := fsc$file_contents_and_processor;
            mandated_creation_attributes^ [2].file_contents := fsc$legible_data;
            mandated_creation_attributes^ [2].file_processor := fsc$scl;
            mandated_creation_attributes^ [3].selector := fsc$block_type;
            mandated_creation_attributes^ [3].block_type := amc$system_specified;
            mandated_creation_attributes^ [4].selector := fsc$file_organization;
            mandated_creation_attributes^ [4].file_organization := amc$sequential;
            mandated_creation_attributes^ [5].selector := fsc$record_type;
            mandated_creation_attributes^ [5].record_type := amc$trailing_char_delimited;
            mandated_creation_attributes^ [6].selector := fsc$record_delimiting_character;
            mandated_creation_attributes^ [6].record_delimiting_character := unit_separator;
          ELSE { data_mode is transparent or rhf_structure
            PUSH mandated_creation_attributes: [1 .. 1];
            mandated_creation_attributes^ [1].selector := fsc$ring_attributes;
            mandated_creation_attributes^ [1].ring_attributes.r1 := osc$tsrv_ring;
            mandated_creation_attributes^ [1].ring_attributes.r2 := osc$tsrv_ring;
            mandated_creation_attributes^ [1].ring_attributes.r3 := osc$tsrv_ring;
          IFEND;
        IFEND;

        osp$establish_condition_handler (^handle_out_of_space, {block_exit} FALSE);
        fsp$subsystem_copy_file (file_reference, command_file_name, input_attachment_options_p,
              output_attachment_options_p, input_validation_attributes_p, {output_attribute_validation} NIL,
              mandated_creation_attributes, status);
        IF NOT status.normal THEN
          amp$return (command_file_name, ignore_status);

{ This overwrites the out of space handler's definition so we don't need to
{ disestablish it.

          osp$establish_block_exit_hndlr (^handle_block_exit);
          pfp$begin_system_authority;
          pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
          pfp$end_system_authority;
          osp$disestablish_cond_handler;
          RETURN;
        IFEND;
        osp$disestablish_cond_handler;

      IFEND;

{ Establish the size of the command file

      IF system_label.job_mode <> jmc$interactive_connected THEN
        PUSH get_attributes_p: [1 .. 1];
        get_attributes_p^ [1].key := amc$file_length;
        amp$get_file_attributes (command_file_name, get_attributes_p^, local_file, old_file, contains_data,
              status);
        IF NOT status.normal THEN
          amp$return (command_file_name, ignore_status);
          osp$establish_block_exit_hndlr (^handle_block_exit);
          pfp$begin_system_authority;
          pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
          pfp$end_system_authority;
          osp$disestablish_cond_handler;
          RETURN;
        IFEND;
        system_label.job_attributes.job_size := get_attributes_p^ [1].file_length;
      ELSE
        system_label.job_attributes.job_size := 0;
      IFEND;

{ Since the file already exists in the input queue the label must be written immediately.

      write_label := TRUE;
      qfp$write_job_system_label (command_file_name, write_label, system_label, status);
      IF NOT status.normal THEN
        amp$return (command_file_name, ignore_status);
        osp$establish_block_exit_hndlr (^handle_block_exit);
        pfp$begin_system_authority;
        pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
        pfp$end_system_authority;
        osp$disestablish_cond_handler;
        RETURN;
      IFEND;

      amp$return (command_file_name, status);
      IF NOT status.normal THEN
        osp$establish_block_exit_hndlr (^handle_block_exit);
        pfp$begin_system_authority;
        pfp$purge (path_p^, cycle_selector, command_file_password, ignore_status);
        pfp$end_system_authority;
        osp$disestablish_cond_handler;
      IFEND;
    PROCEND process_command_file_and_label;
?? OLDTITLE ??
?? EJECT ??
?? NEWTITLE := 'switch_remote_connection', EJECT ??

    PROCEDURE switch_remote_connection
      (    job_name: jmt$system_supplied_name;
           destination_mainframe_id: pmt$mainframe_id;
           encrypted_password: ost$name;
       VAR status: ost$status);

      VAR
        leveled_job_connect_data_p: ^jmt$leveled_job_connect_data,
        program_attributes: ^pmt$program_attributes,
        program_description: ^pmt$program_description,
        program_parameters: ^pmt$program_parameters,
        size_of_parameters: ost$non_negative_integers,
        system_job_name_p: ^jmt$system_supplied_name,
        task_id: pmt$task_id;


      status.normal := TRUE;

      PUSH program_description: [[REP 1 OF pmt$program_attributes]];
      RESET program_description;
      NEXT program_attributes IN program_description;
      program_attributes^.contents := $pmt$prog_description_contents
            [pmc$starting_proc_specified, pmc$load_map_file_specified, pmc$load_map_options_specified,
            pmc$term_error_level_specified, pmc$abort_file_specified, pmc$debug_mode_specified];
      program_attributes^.starting_procedure := 'JMP$SWITCH_REMOTE_CONNECTION';
      program_attributes^.load_map_file := clv$standard_files [clc$sf_null_file].path_handle_name;
      program_attributes^.load_map_options := $pmt$load_map_options [pmc$no_load_map];
      program_attributes^.termination_error_level := pmc$warning_load_errors;
      program_attributes^.abort_file := clv$standard_files [clc$sf_null_file].path_handle_name;
      program_attributes^.debug_mode := FALSE;

      PUSH program_parameters: [[REP 1 OF jmt$leveled_job_connect_data]];
      RESET program_parameters;
      NEXT leveled_job_connect_data_p IN program_parameters;
      leveled_job_connect_data_p^.system_job_name := job_name;
      leveled_job_connect_data_p^.destination_mainframe_id := destination_mainframe_id;
      leveled_job_connect_data_p^.encrypted_password := encrypted_password;

      IF task_status_p = NIL THEN
        ALLOCATE task_status_p IN osv$task_private_heap^;
      IFEND;
      pmp$execute (program_description^, program_parameters^, osc$nowait, task_id, task_status_p^, status);

    PROCEND switch_remote_connection;

?? OLDTITLE, EJECT ??
    #CALLER_ID (caller_identification);
    status.normal := TRUE;
    ignore_status.normal := TRUE;
    pmp$get_mainframe_id (current_mainframe_id, ignore_status);

{ Does the caller deserve special privileges?

    privileged_job := osp$is_caller_system_privileged () OR (caller_identification.ring <= osc$sj_ring_3) OR
          jmv$enable_queue_file_access OR jmp$system_job ();

    IF syp$system_is_idling () THEN
      osp$set_status_condition (jme$maximum_jobs, status);
      RETURN;
    IFEND;

    clp$evaluate_file_reference (file_reference, $clt$file_ref_parsing_options [],
          {resolve_cycle_number} FALSE, evaluated_file_reference, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ The following special code allows submit_job of $local.command.

    IF evaluated_file_reference.path_handle_info.path_handle_present AND
          (evaluated_file_reference.path_handle_info.path_handle.segment_offset =
          clv$standard_files [clc$sf_command_file].path_handle.segment_offset) AND
          (evaluated_file_reference.path_handle_info.path_handle.assignment_counter =
          clv$standard_files [clc$sf_command_file].path_handle.assignment_counter) THEN
      file_path := clv$standard_files [clc$sf_command_file].path_handle_name;
      file_path_size := osc$max_name_size;
      submit_of_command_file := TRUE;
    ELSE
      submit_of_command_file := FALSE;
      clp$convert_file_ref_to_string (evaluated_file_reference, {include_open_position} FALSE, file_path,
            file_path_size, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    pmp$get_user_identification (user_identification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Find out what kind of submit job is taking place.

    determine_if_job_label_exists (file_path (1, file_path_size), system_label, job_label_exists, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ If there is not a label then some label attributes must be pre-initialized.

    IF NOT job_label_exists THEN
      assign_default_label_values (user_identification, system_label, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    ELSE

{ The System_Job_Name in the job label must be zeroed out in order to submit
{ the command file as a job.  If this is not done, an attempt will be made to
{ assign the same name to the job.
{ When loopback of QTF support is added, this code can probably be removed.

      IF submit_of_command_file THEN
        system_label.system_job_name := jmc$blank_system_supplied_name;
      IFEND;
    IFEND;

{ Get any login defaults specified in the submission options.  This process also verifies that
{ only supported submission options are being specified.

    determine_login_defaults (job_submission_options, privileged_job, system_label, explicit_login_command_p,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    determine_login_elements (file_path (1, file_path_size), caller_identification.ring, user_identification,
          job_submission_options, privileged_job, explicit_login_command_p, job_label_exists,
          encrypted_password_supplied, login_family_defined, inherit_job_attributes, system_label, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF NOT job_label_exists THEN
      assign_default_attributes (user_identification, inherit_job_attributes, system_label, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    determine_job_attributes (job_submission_options, privileged_job, system_label,
          immediate_initiation_candidate, current_date_time, current_microsecond_clock,
          earliest_clock_time_to_initiate, latest_clock_time_to_initiate, remote_host_directive_inherited,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ If the originating_application_name is PTF/QTF/NTF/BTF/REXEC/NQS, and the user and
{ family are $system, do not allow the job to continue.

    IF (system_label.login_user_identification.user = '$SYSTEM                        ') AND
       (system_label.login_user_identification.family = '$SYSTEM                        ') AND
       (system_label.job_attributes.originating_application_name <> osc$deadstart) AND
       (system_label.job_attributes.originating_application_name <> osc$submit_job) THEN
      osp$set_status_abnormal (jmc$job_management_id, ave$bad_user_validation_info,
            ' ', status);
      RETURN;
    IFEND;

    IF job_label_exists THEN

{ Calculate the value for the job's job submission time clock value.

      jmp$convert_date_time_dif_to_us (current_date_time, system_label.job_attributes.job_submission_time,
            current_microsecond_clock, job_submission_time);

    ELSE
      job_submission_time := current_microsecond_clock;
    IFEND;
    determine_job_destination (login_family_defined, remote_host_directive_inherited, system_label,
          input_file_location, store_and_forward_job, submit_job_to_server, leveled_job, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /determine_job_class/
    WHILE TRUE DO
      WHILE jmv$sched_profile_is_loading DO
        pmp$wait (500, 500);
      WHILEND;

      system_label.active_profile_version := jmv$job_scheduler_table.profile_identification;
      IF (system_label.job_class_name <> osc$null_name) AND
            (system_label.job_class_name <> jmc$automatic_class_name) AND
            (system_label.job_class_name <> jmc$system_default_class_name) THEN
        jmp$expand_job_class_abbrev (system_label.job_class_name, ignore_status);
      IFEND;

      IF NOT store_and_forward_job THEN

{ Convert the user's requested limit information to preliminary assigned limits.

        convert_limit_information (system_label, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        prevalidate_job (user_identification, {password_encrypted} encrypted_password_supplied OR
              (submit_of_command_file AND (system_label.job_mode = jmc$batch)), system_label,
              assigned_job_class, encrypted_password, status);
        IF NOT status.normal THEN
          qfp$check_for_profile_mismatch (system_label.active_profile_version, profile_mismatch);
          IF profile_mismatch OR jmv$sched_profile_is_loading THEN
            CYCLE /determine_job_class/;
          IFEND;
          RETURN;
        IFEND;

        IF jmv$job_class_table_p^ [assigned_job_class].defer_on_submit THEN
          system_label.job_deferred_by_operator := TRUE;
        IFEND;

      ELSE
        assigned_job_class := jmc$null_job_class;
      IFEND;

{ Determine the path elements for the job's command file.

      determine_file_path (input_file_location, system_label.login_user_identification.family,
            system_label.system_job_name, command_file_path_p);
      command_file_password := osc$null_name;
      cycle_selector.cycle_option := pfc$specific_cycle;
      cycle_selector.cycle_number := 1;

      IF system_label.job_mode = jmc$interactive_connected THEN
        qfp$assign_system_supplied_name (system_label.system_job_name);
        system_label.job_attributes.job_size := 0;
      ELSE
        process_command_file_and_label (file_path (1, file_path_size), command_file_path_p,
              command_file_password, caller_identification.ring, job_label_exists, store_and_forward_job,
              system_label, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

{ Assign the requestor's system job name.

      system_job_name := system_label.system_job_name;

      IF submit_job_to_server THEN
        call_server_submit_job (system_label, immediate_initiation_candidate, current_mainframe_id,
              destination_mainframe_id, status);
        IF status.normal AND (system_label.job_mode <> jmc$batch) THEN
          IF (destination_mainframe_id <> current_mainframe_id) THEN
            switch_remote_connection (system_label.system_job_name, destination_mainframe_id,
                  encrypted_password, status);
          ELSE
            IF jmv$job_history_active THEN
              jmp$emit_job_history_statistics (jml$job_queuing_started, osc$null_name, system_job_name,
                    jmc$blank_system_supplied_name, ^system_label, NIL, osc$null_name,
                    system_label.job_attributes.originating_ssn, ignore_status);
            IFEND;

            qfp$submit_job (system_label, assigned_job_class, earliest_clock_time_to_initiate,
                  latest_clock_time_to_initiate, current_microsecond_clock, job_submission_time,
                  immediate_initiation_candidate, input_file_location, valid_mainframe_set, status);
          IFEND;
        IFEND;
      ELSE

{ Determine the fitness of the job for the mainframes that are available.

        qfp$determine_mainframe_fitness (system_label.job_category_set, leveled_job,
              system_label.login_user_identification.family, valid_mainframe_set, status);
        IF status.normal THEN
          osp$check_client_leveled_access (system_label.login_user_identification.family, leveled_access);
          IF ((system_label.job_mode <> jmc$batch) AND (system_label.job_destination_usage = jmc$ve_usage) AND
                jmv$job_scheduler_table.enable_job_leveling AND leveled_access) THEN
            level_interactive_job (valid_mainframe_set, assigned_job_class, earliest_clock_time_to_initiate,
                  latest_clock_time_to_initiate, current_microsecond_clock, current_mainframe_id,
                  system_label, destination_mainframe_id, status);
            IF status.normal THEN
              IF (destination_mainframe_id <> current_mainframe_id) THEN
                switch_remote_connection (system_label.system_job_name, destination_mainframe_id,
                      encrypted_password, status);
              ELSE
                IF jmv$job_history_active THEN
                  jmp$emit_job_history_statistics (jml$job_queuing_started, osc$null_name, system_job_name,
                        jmc$blank_system_supplied_name, ^system_label, NIL, osc$null_name,
                        system_label.job_attributes.originating_ssn, ignore_status);
                IFEND;

                qfp$submit_job (system_label, assigned_job_class, earliest_clock_time_to_initiate,
                      latest_clock_time_to_initiate, current_microsecond_clock, job_submission_time,
                      immediate_initiation_candidate, input_file_location, valid_mainframe_set, status);
              IFEND;
            IFEND;
          ELSE
            IF jmv$job_history_active THEN
              jmp$emit_job_history_statistics (jml$job_queuing_started, osc$null_name, system_job_name,
                    jmc$blank_system_supplied_name, ^system_label, NIL, osc$null_name,
                    system_label.job_attributes.originating_ssn, ignore_status);
            IFEND;

            qfp$submit_job (system_label, assigned_job_class, earliest_clock_time_to_initiate,
                  latest_clock_time_to_initiate, current_microsecond_clock, job_submission_time,
                  immediate_initiation_candidate, input_file_location, valid_mainframe_set, status);
          IFEND;
        IFEND;
      IFEND;

      IF NOT status.normal THEN
        IF (status.condition <> jme$scheduling_profile_changed) AND jmv$job_history_active THEN
          reason := '';
          osp$get_status_condition_name (status.condition, reason, ignore_status);
          jmp$emit_job_history_statistics (jml$job_queuing_aborted, osc$null_name, system_job_name,
                jmc$blank_system_supplied_name, NIL, NIL, reason, jmc$blank_system_supplied_name,
                ignore_status);
        IFEND;
        IF system_label.job_mode <> jmc$interactive_connected THEN
          osp$establish_block_exit_hndlr (^handle_block_exit);
          pfp$begin_system_authority;
          pfp$purge (command_file_path_p^, cycle_selector, command_file_password, ignore_status);
          pfp$end_system_authority;
          osp$disestablish_cond_handler;
        IFEND;
        IF (status.condition = jme$scheduling_profile_changed) THEN
          CYCLE /determine_job_class/;
        ELSEIF (status.condition = jme$duplicate_name) THEN
          system_label.system_job_name := '';

{ After detecting the duplicate system job name another attempt to prevalidate
{ the job and reassigning a new name to the job will be done with the encrypted
{ password, so the flag encrypted_password_supplied should be made TRUE.

          encrypted_password_supplied := TRUE;
          CYCLE /determine_job_class/;
        IFEND;
      IFEND;

      EXIT /determine_job_class/;
    WHILEND /determine_job_class/;

    IF status.normal THEN

{ If the caller is a user, emit the submit_job statistic.
{ If the caller is the system, submitting a system job, emit the submit_job statistic.
{ If the caller is the system, submitting a user job, do not emit the statistic.

      IF (NOT jmp$system_job ()) OR (user_identification = system_label.login_user_identification) THEN
        statistic_data.statistic_id := jmc$ca_submit_job;
        PUSH statistic_data.submit_job;
        statistic_data.submit_job^.job_size := system_label.job_attributes.job_size;
        statistic_data.submit_job^.system_job_name := system_label.system_job_name;
        jmp$emit_communication_stat (statistic_data);
      IFEND;
    IFEND;

  PROCEND jmp$submit_job;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$terminate_acquired_input', EJECT ??
*copy jmh$terminate_acquired_input

  PROCEDURE [XDCL, #GATE] jmp$terminate_acquired_input
    (    input_destination_usage: jmt$destination_usage;
     VAR system_job_name: jmt$system_supplied_name;
     VAR status: ost$status);

    VAR
      delete_input_file: boolean,
      cycle_selector: pft$cycle_selector,
      path_p: ^pft$path,
      password: pft$password;

?? NEWTITLE := '    handle_block_exit', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to deal with block exit conditions that
{   arise while system_authority is in effect.

    PROCEDURE handle_block_exit
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           sfsa_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      pfp$end_system_authority;
      IF status.normal THEN
        osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, status, ignore_status);
      IFEND;
    PROCEND handle_block_exit;

?? OLDTITLE, EJECT ??

    qfp$terminate_acquired_input (input_destination_usage, system_job_name, delete_input_file, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF delete_input_file THEN

{ This can only be the store-and-forward queue.  Jobs that belong to the local VE system(s) will not have
{ their command files touched by this request.  The only applications that can have files attached are
{ applications that access the store-and-forward queue.  With this in mind, osc$null_name is supplied as
{ the family name.

      determine_file_path (jmc$ifl_store_and_forward_queue, osc$null_name, system_job_name, path_p);
      cycle_selector.cycle_option := pfc$specific_cycle;
      cycle_selector.cycle_number := 1;
      password := osc$null_name;
      osp$establish_block_exit_hndlr (^handle_block_exit);
      pfp$begin_system_authority;
      pfp$purge (path_p^, cycle_selector, password, status);
      pfp$end_system_authority;
      osp$disestablish_cond_handler;
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

  PROCEND jmp$terminate_acquired_input;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$terminated_input_exists', EJECT ??
*copy jmh$terminated_input_exists

  FUNCTION [XDCL, #GATE] jmp$terminated_input_exists
    (    input_destination_usage: jmt$destination_usage): boolean;

    VAR
      application_index: jmt$input_application_index,
      input_exists: boolean;

    application_index := UPPERBOUND (jmv$known_job_list.application_table);
    WHILE (jmv$known_job_list.application_table [application_index].destination_usage <>
          input_destination_usage) AND (application_index <> jmc$unassigned_input_index) DO
      application_index := application_index - 1;
    WHILEND;

    input_exists := (application_index <> jmc$unassigned_input_index) AND
          (jmv$known_job_list.application_table [application_index].
          state_data [jmc$kjl_application_terminated].number_of_entries > 0);
    jmp$terminated_input_exists := input_exists AND (NOT syp$system_is_idling ());

  FUNCEND jmp$terminated_input_exists;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$terminate_job', EJECT ??
*copy jmh$terminate_job

  PROCEDURE [XDCL, #GATE] jmp$terminate_job
    (    job_name: jmt$name;
         job_termination_options: ^jmt$job_termination_options;
     VAR status: ost$status);

    VAR
      continue_request_to_servers: boolean,
      executing_mainframe_id: pmt$mainframe_id,
      job_state_set: jmt$job_state_set,
      job_status_options_p: ^jmt$job_status_options,
      job_status_results_keys_p: ^jmt$results_keys,
      job_status_results_p: ^jmt$job_status_results,
      job_status_results_seq_p: ^jmt$work_area,
      job_to_terminate: jmt$name,
      local_status: ost$status,
      number_of_jobs_found: jmt$job_status_count,
      option_index: ost$positive_integers,
      output_disposition_key: jmt$output_disposition_keys,
      output_disposition_key_known: boolean,
      privileged_job: boolean,
      reason: ost$name,
      scl_name: ost$name,
      size_of_sequence: ost$segment_length,
      ssn_of_caller: jmt$system_supplied_name,
      usn_of_caller: jmt$user_supplied_name;


    status.normal := TRUE;

{ Set default values

    continue_request_to_servers := FALSE;
    job_state_set := -$jmt$job_state_set [];
    output_disposition_key_known := FALSE;
    reason := osc$null_name;

{ Override default values - if necessary

    IF job_termination_options <> NIL THEN

    /validate_termination_options/
      FOR option_index := 1 TO UPPERBOUND (job_termination_options^) DO
        CASE job_termination_options^ [option_index].key OF
        = jmc$continue_request_to_servers =
          continue_request_to_servers := job_termination_options^ [option_index].continue_request_to_servers;

        = jmc$job_state_set =
          IF job_termination_options^ [option_index].job_state_set = $jmt$job_state_set [] THEN
            osp$set_status_condition (jme$job_state_is_null, status);
            EXIT /validate_termination_options/;
          IFEND;
          job_state_set := job_termination_options^ [option_index].job_state_set;

        = jmc$null_attribute =
          ;

        = jmc$output_disposition =
          output_disposition_key := job_termination_options^ [option_index].output_disposition.key;
          output_disposition_key_known := TRUE;
          IF (output_disposition_key = jmc$standard_output_path) OR
                (output_disposition_key = jmc$local_output_disposition) THEN
            jmp$get_attribute_name (job_termination_options^ [option_index].key, scl_name);
            osp$set_status_abnormal (jmc$job_management_id, jme$invalid_parameter_value, scl_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, 'JOB_TERMINATION_OPTIONS', status);
            osp$append_status_parameter (osc$status_parameter_delimiter, jmc$terminate_job, status);
            EXIT /validate_termination_options/;
          IFEND;

        = jmc$termination_reason =
          reason := job_termination_options^ [option_index].reason_p^;

        ELSE
          jmp$get_attribute_name (job_termination_options^ [option_index].key, scl_name);
          osp$set_status_abnormal (jmc$job_management_id, jme$invalid_parameter, scl_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, 'JOB_TERMINATION_OPTIONS', status);
          osp$append_status_parameter (osc$status_parameter_delimiter, jmc$terminate_job, status);
          EXIT /validate_termination_options/;
        CASEND;
      FOREND /validate_termination_options/;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    jmp$validate_name (job_name, job_to_terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF job_to_terminate.kind = jmc$system_supplied_name THEN
      scl_name := job_to_terminate.system_supplied_name;
    ELSE
      scl_name := job_to_terminate.user_supplied_name;
    IFEND;

    pmp$get_job_names (usn_of_caller, ssn_of_caller, { ignore } status);
    IF job_to_terminate.kind = jmc$system_supplied_name THEN
      IF ssn_of_caller = job_to_terminate.system_supplied_name THEN
        osp$set_status_abnormal (jmc$job_management_id, jme$tried_to_self_destruct,
              job_to_terminate.system_supplied_name, status);
        RETURN;
      IFEND;
    ELSE
      IF usn_of_caller = job_to_terminate.user_supplied_name THEN
        osp$set_status_abnormal (jmc$job_management_id, jme$tried_to_self_destruct,
              job_to_terminate.user_supplied_name, status);
        RETURN;
      IFEND;
    IFEND;

    privileged_job := avp$system_operator ();
    IF NOT privileged_job THEN
      jmp$get_scheduling_admin_status (local_status);
      IF local_status.normal THEN
        privileged_job := TRUE;
      IFEND;
    IFEND;

    PUSH job_status_options_p: [1 .. 4];
    job_status_options_p^ [1].key := jmc$name_list;
    PUSH job_status_options_p^ [1].name_list: [1 .. 1];
    job_status_options_p^ [1].name_list^ [1] := job_to_terminate;
    job_status_options_p^ [2].key := jmc$job_state_set;
    job_status_options_p^ [2].job_state_set := job_state_set;
    job_status_options_p^ [3].key := jmc$continue_request_to_servers;
    job_status_options_p^ [3].continue_request_to_servers := continue_request_to_servers;
    job_status_options_p^ [4].key := jmc$privilege;
    IF privileged_job THEN
      job_status_options_p^ [4].privilege := jmc$privileged;
    ELSE
      job_status_options_p^ [4].privilege := jmc$not_privileged;
    IFEND;

    PUSH job_status_results_keys_p: [1 .. 3];
    job_status_results_keys_p^ [1] := jmc$system_job_name;
    job_status_results_keys_p^ [2] := jmc$server_mainframe_id;
    job_status_results_keys_p^ [3] := jmc$input_file_location;

    jmp$get_result_size ({number_of_jobs} 1, #SEQ (job_status_results_keys_p^), size_of_sequence);
    PUSH job_status_results_seq_p: [[REP size_of_sequence OF cell]];

    jmp$get_job_status (job_status_options_p, job_status_results_keys_p, job_status_results_seq_p,
          job_status_results_p, number_of_jobs_found, status);
    IF number_of_jobs_found = 0 THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$name_not_found, scl_name, status);
    ELSEIF number_of_jobs_found > 1 THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$duplicate_name, scl_name, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF job_status_results_p^ [1]^ [3].input_file_location = jmc$ifl_no_input_file_exists THEN
      osp$set_status_abnormal (jmc$job_management_id, jme$job_cannot_be_terminated,
            job_status_results_p^ [1]^ [1].system_job_name, status);
      RETURN;
    IFEND;

    pmp$get_mainframe_id (executing_mainframe_id, { ignore } status);
    IF executing_mainframe_id = job_status_results_p^ [1]^ [2].server_mainframe_id THEN
      terminate_job (job_status_results_p^ [1]^ [1].system_job_name, job_state_set,
            output_disposition_key_known, output_disposition_key, privileged_job, reason, status);

    ELSEIF continue_request_to_servers THEN
      jmp$call_server_terminate_job (job_status_results_p^ [1]^ [1].
            system_job_name, job_status_results_p^ [1]^ [2].server_mainframe_id, job_state_set,
            output_disposition_key_known, output_disposition_key, privileged_job, reason, status);

    ELSE { Shouldn't be able to get here - the status request should have inhibited it.
      IF job_to_terminate.kind = jmc$system_supplied_name THEN
        scl_name := job_to_terminate.system_supplied_name;
      ELSE
        scl_name := job_to_terminate.user_supplied_name;
      IFEND;
      osp$set_status_abnormal (jmc$job_management_id, jme$name_not_found, scl_name, status);
    IFEND;

  PROCEND jmp$terminate_job;
?? OLDTITLE ??
?? NEWTITLE := 'level_interactive_job', EJECT ??

{ PURPOSE:
{   The purpose of this procedure is to determine where an interactive leveled
{   job should execute and queue, send or return it to its destination as
{   necessary.

{ DESIGN:
{   This procedure must be called on the server.  It will generate a list of
{   mainframe identifiers that may be valid destinations for an interactive
{   leveled job.  A procedure, which is implemented as a site hook, is called to
{   choose one of the mainframes from this list.  If the selected mainframe is
{   the current mainframe, the job is queued here.  If the selected mainframe is
{   the originating mainframe, (the mainframe the user originally created the
{   connection to), the job is not queued by this request, instead it will be
{   queued upon return to the originating mainframe.  If any other mainframe is
{   selected, a remote procedure call will be made to that mainframe to queue it there.

  PROCEDURE level_interactive_job
    (    valid_mainframe_set: jmt$valid_mainframe_set;
         assigned_job_class: jmt$job_class;
         earliest_clock_time_to_initiate: jmt$clock_time;
         latest_clock_time_to_initiate: jmt$clock_time;
         current_microsecond_clock: jmt$clock_time;
         originating_mainframe: pmt$mainframe_id;
     VAR system_label {input, output} : jmt$job_system_label;
     VAR selected_mainframe: pmt$mainframe_id;
     VAR status: ost$status);

    VAR
      continue_selection: boolean,
      current_mainframe_id: pmt$mainframe_id,
      interactive_job_info: ^jmt$interactive_job_info,
      mainframe: 1 .. jmc$maximum_mainframes,
      number_of_valid_mainframes: 0 .. jmc$maximum_mainframes,
      submit_variation: jmt$submit_job_variations,
      valid_mainframe: 0 .. jmc$maximum_mainframes,
      valid_mainframe_list: ^array [1 .. * ] of pmt$mainframe_id;

?? NEWTITLE := 'call_client_submit_job', EJECT ??

{ PURPOSE:
{   The purpose of this request is to submit an interactive leveled job from
{   a server to a client mainframe.

    PROCEDURE call_client_submit_job
      (    job_system_label: jmt$job_system_label;
           originating_mainframe_id: pmt$mainframe_id;
           destination_mainframe_id: pmt$mainframe_id;
       VAR status: ost$status);

      VAR
        client_location: dft$server_location,
        data_size: dft$send_data_size,
        ignore_recovery_occurred: boolean,
        ignore_status_p: ^ost$status,
        local_job_system_label_p: ^jmt$job_system_label,
        parameter_size: dft$send_parameter_size,
        queue_entry_location: dft$rpc_queue_entry_location,
        receive_from_server_data_p: dft$p_receive_data,
        receive_from_server_params_p: dft$p_receive_parameters,
        send_to_server_data_p: dft$p_send_data,
        send_to_server_parameters_p: dft$p_send_parameters,
        server_submit_job_params_p: ^server_submit_job_parameters;

?? NEWTITLE := 'dfp$remote_procedure_call_ch', EJECT ??

{ PURPOSE:
{   This procedure is a condition handler established to call a routine to clear the assignment of a task
{   services queue_entry if a task aborts with a queue_entry assigned to it.  The queue_entry must be clear
{   before the task can safely exit.

      PROCEDURE dfp$remote_procedure_call_ch
        (    condition: pmt$condition;
             cond_desc: ^pmt$condition_information;
             save: ^ost$stack_frame_save_area;
         VAR handler_status: ost$status);

        VAR
          ignore_status: ost$status;


        dfp$ch_cleanup;
        osp$set_status_from_condition (dfc$file_server_id, condition, save, status, ignore_status);
        EXIT call_client_submit_job;

      PROCEND dfp$remote_procedure_call_ch;
*block
*copyc dfp$begin_ch_remote_proc_call
*copyc dfp$end_ch_remote_proc_call
*blockend
?? OLDTITLE, EJECT ??

      status.normal := TRUE;

      client_location.server_location_selector := dfc$mainframe_id;
      client_location.server_mainframe := destination_mainframe_id;

      REPEAT
        dfp$begin_ch_remote_proc_call (client_location, { allowed_when_server_deactivated } TRUE,
              queue_entry_location, send_to_server_parameters_p, send_to_server_data_p, status);
        IF NOT status.normal THEN

{***  Now what?? - the command file is on the server yet we can't make a KJL entry...
{ assume that the server crashed and will re-queue the job when it re-deadstarts?

          RETURN;
        IFEND;

{ Build the data and parameters to send to the server.
{ The RPC sequences have already been reset.

        NEXT server_submit_job_params_p IN send_to_server_parameters_p;
        server_submit_job_params_p^.immediate_initiation_candidate := TRUE;
        server_submit_job_params_p^.executing_on_server := FALSE;
        server_submit_job_params_p^.origin_mainframe_id := originating_mainframe_id;

        NEXT local_job_system_label_p IN send_to_server_data_p;
        local_job_system_label_p^ := job_system_label;

        parameter_size := i#current_sequence_position (send_to_server_parameters_p);
        data_size := i#current_sequence_position (send_to_server_data_p);

        dfp$send_remote_procedure_call (queue_entry_location, dfc$rpc_jl_submit_job, parameter_size,
              data_size, receive_from_server_params_p, receive_from_server_data_p, status);
        IF status.normal THEN

{ Ignore destination_mainframe_id returned in receive_from_server_params_p by jmp$server_submit_job.

          dfp$end_ch_remote_proc_call (queue_entry_location, status);
        ELSE
          PUSH ignore_status_p;
          dfp$end_ch_remote_proc_call (queue_entry_location, ignore_status_p^);
          IF status.condition = dfe$job_needs_recovery THEN
            dfp$check_job_recovery (ignore_recovery_occurred);
          IFEND;
        IFEND;
      UNTIL status.normal OR (status.condition <> dfe$job_needs_recovery);
    PROCEND call_client_submit_job;
?? OLDTITLE ??
?? NEWTITLE := 'set_interactive_job_info', EJECT ??

{ PURPOSE:
{   The purpose of this request is to copy some of the information contained in
{   the system label to a data structure that is passed on to the site hook
{   that chooses the mainframe an interactive job should execute on.

    PROCEDURE set_interactive_job_info
      (    job_system_label: jmt$job_system_label;
       VAR interactive_job_info: jmt$interactive_job_info);


      interactive_job_info.assigned_job_class := job_system_label.assigned_job_class;
      interactive_job_info.comment_banner := job_system_label.job_attributes.comment_banner;
      interactive_job_info.copy_count := job_system_label.job_attributes.copy_count;
      interactive_job_info.cpu_time_limit_specified := job_system_label.limit_information.
            cpu_time_limit_specified;
      interactive_job_info.cpu_time_limit_requested := job_system_label.limit_information.
            cpu_time_limit_requested;
      interactive_job_info.cpu_time_limit_assigned := job_system_label.limit_information.
            cpu_time_limit_assigned;
      interactive_job_info.device := job_system_label.job_attributes.device;
      interactive_job_info.earliest_print_time := job_system_label.job_attributes.earliest_print_time;
      interactive_job_info.external_characteristics := job_system_label.job_attributes.
            external_characteristics;
      interactive_job_info.forms_code := job_system_label.job_attributes.forms_code;
      interactive_job_info.job_abort_disposition := job_system_label.job_abort_disposition;
      interactive_job_info.job_category_set := job_system_label.job_category_set;
      interactive_job_info.job_class_name := job_system_label.job_class_name;
      interactive_job_info.job_destination_family := job_system_label.job_destination_family;
      interactive_job_info.job_destination_usage := job_system_label.job_destination_usage;
      interactive_job_info.job_execution_ring := job_system_label.job_execution_ring;
      interactive_job_info.job_input_device := job_system_label.job_attributes.job_input_device;
      interactive_job_info.job_mode := job_system_label.job_mode;
      interactive_job_info.job_priority := job_system_label.job_priority;
      interactive_job_info.job_qualifier_list := job_system_label.job_attributes.job_qualifier_list;
      interactive_job_info.job_recovery_disposition := job_system_label.job_recovery_disposition;
      interactive_job_info.latest_print_time := job_system_label.job_attributes.latest_print_time;
      interactive_job_info.login_account := job_system_label.login_account;
      interactive_job_info.login_project := job_system_label.login_project;
      interactive_job_info.login_user_identification := job_system_label.login_user_identification;
      interactive_job_info.magnetic_tape_limit_specified :=
            job_system_label.limit_information.magnetic_tape_limit_specified;
      interactive_job_info.magnetic_tape_limit_requested :=
            job_system_label.limit_information.magnetic_tape_limit_requested;
      interactive_job_info.magnetic_tape_limit_assigned :=
            job_system_label.limit_information.magnetic_tape_limit_assigned;
      interactive_job_info.maximum_working_set_specified :=
            job_system_label.limit_information.maximum_working_set_specified;
      interactive_job_info.maximum_working_set_requested :=
            job_system_label.limit_information.maximum_working_set_requested;
      interactive_job_info.maximum_working_set_assigned :=
            job_system_label.limit_information.maximum_working_set_assigned;
      interactive_job_info.operator_family := job_system_label.job_attributes.output_destination_family;
      interactive_job_info.operator_user := job_system_label.job_attributes.station_operator;
      interactive_job_info.originating_application_name :=
            job_system_label.job_attributes.originating_application_name;
      interactive_job_info.output_deferred_by_user := job_system_label.job_attributes.output_deferred_by_user;
      interactive_job_info.output_destination := job_system_label.job_attributes.output_destination;
      interactive_job_info.output_destination_usage := job_system_label.job_attributes.
            output_destination_usage;
      interactive_job_info.output_disposition_key := job_system_label.job_attributes.output_disposition_key;
      interactive_job_info.output_disposition_path := job_system_label.job_attributes.output_disposition_path;
      interactive_job_info.perform_class_validation := job_system_label.perform_class_validation;
      interactive_job_info.purge_delay := job_system_label.job_attributes.purge_delay;
      interactive_job_info.remote_host_directive := job_system_label.job_attributes.remote_host_directive;
      interactive_job_info.routing_banner := job_system_label.job_attributes.routing_banner;
      interactive_job_info.sru_limit_specified := job_system_label.limit_information.sru_limit_specified;
      interactive_job_info.sru_limit_requested := job_system_label.limit_information.sru_limit_requested;
      interactive_job_info.sru_limit_assigned := job_system_label.limit_information.sru_limit_assigned;
      interactive_job_info.station := job_system_label.job_attributes.station;
      interactive_job_info.system_job_name := job_system_label.system_job_name;
      interactive_job_info.user_information := job_system_label.job_attributes.user_information;
      interactive_job_info.user_job_name := job_system_label.user_job_name;
      interactive_job_info.vertical_print_density := job_system_label.job_attributes.vertical_print_density;
      interactive_job_info.vfu_load_procedure := job_system_label.job_attributes.vfu_load_procedure;

    PROCEND set_interactive_job_info;
?? OLDTITLE ??

    pmp$get_mainframe_id (current_mainframe_id, {ignore} status);
    status.normal := TRUE;

    number_of_valid_mainframes := 0;
    FOR mainframe := 1 TO jmc$maximum_mainframes DO
      IF mainframe IN valid_mainframe_set THEN
        number_of_valid_mainframes := number_of_valid_mainframes + 1;
      IFEND;
    FOREND;

    IF number_of_valid_mainframes > 0 THEN
      PUSH valid_mainframe_list: [1 .. number_of_valid_mainframes];
      valid_mainframe := 0;
      FOR mainframe := 1 TO jmc$maximum_mainframes DO
        IF mainframe IN valid_mainframe_set THEN
          valid_mainframe := valid_mainframe + 1;
          pmp$convert_binary_mainframe_id (jmv$job_scheduler_table.validation_categories_p^ [mainframe].
                binary_mainframe_id, valid_mainframe_list^ [valid_mainframe], {ignore} status);
          status.normal := TRUE;
        IFEND;
      FOREND;

      PUSH interactive_job_info;
      set_interactive_job_info (system_label, interactive_job_info^);

    /select_a_mainframe/
      WHILE TRUE DO
        jmp$select_interactive_job_dest (valid_mainframe_list^, interactive_job_info^, selected_mainframe,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF selected_mainframe = pmc$null_mainframe_id THEN

{ If no mainframe is selected, terminate the login.

          osp$set_status_condition (jme$maximum_jobs, status);
          EXIT /select_a_mainframe/;

        ELSEIF selected_mainframe = originating_mainframe THEN

{ The originating mainframe has been chosen, the job will be queued there when we return.

          EXIT /select_a_mainframe/;

        ELSEIF (selected_mainframe = current_mainframe_id) THEN

{ The server mainframe has been chosen, queue the job here.

          submit_variation.kind := jmc$remote_connection_switch;
          system_label.job_attributes.system_job_parameters.system_job_parameter_count :=
                #SIZE (submit_variation);
          i#move (^submit_variation, ^system_label.job_attributes.system_job_parameters.
                system_job_parameter, #SIZE (submit_variation));
          nap$set_server_job_init_pending (osc$timesharing, {server_job_init_pending = } TRUE, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          IF jmv$job_history_active THEN
            jmp$emit_job_history_statistics (jml$job_queuing_started, osc$null_name,
                  system_label.system_job_name, jmc$blank_system_supplied_name, ^system_label, NIL,
                  osc$null_name, system_label.job_attributes.originating_ssn, {ignore} status);
            status.normal := TRUE;
          IFEND;

          qfp$submit_job (system_label, assigned_job_class, earliest_clock_time_to_initiate,
                latest_clock_time_to_initiate, current_microsecond_clock,
                {job_submission_time} current_microsecond_clock, {immediate_initiation_candidate} TRUE,
                jmc$ifl_login_family_queue, valid_mainframe_set, status);

        ELSE

{ Submit the job to the chosen client mainframe.

          call_client_submit_job (system_label, originating_mainframe, selected_mainframe, status);
        IFEND;

        IF NOT status.normal THEN
          continue_selection := FALSE;
          FOR valid_mainframe := 1 TO UPPERBOUND (valid_mainframe_list^) DO
            IF valid_mainframe_list^ [valid_mainframe] = selected_mainframe THEN
              valid_mainframe_list^ [valid_mainframe] := pmc$null_mainframe_id;
            IFEND;
            IF valid_mainframe_list^ [valid_mainframe] <> pmc$null_mainframe_id THEN
              continue_selection := TRUE;
            IFEND;
          FOREND;
          IF continue_selection THEN
            CYCLE /select_a_mainframe/;
          IFEND;
          osp$set_status_condition (jme$maximum_jobs, status);
        IFEND;

        EXIT /select_a_mainframe/;
      WHILEND /select_a_mainframe/;
    ELSE
      osp$set_status_condition (jme$maximum_jobs, status);
    IFEND;

  PROCEND level_interactive_job;
?? OLDTITLE ??
?? NEWTITLE := 'prevalidate_job', EJECT ??

{ PURPOSE:
{   The purpose of this request is to pre-validate the job defined by the values in the system job label
{ and retrieve any unknown values (attributes) from the validation file.

  PROCEDURE prevalidate_job
    (    user_identification: ost$user_identification;
         password_encrypted: boolean;
     VAR system_label: jmt$job_system_label;
     VAR assigned_job_class: jmt$job_class;
     VAR encrypted_password: ost$name;
     VAR status: ost$status);

    VAR
      batch_password_can_default: boolean,
      default_attributes: ^avt$validation_items,
      i: ost$non_negative_integers,
      interactive_job: boolean,
      number_of_valid_job_classes: ost$non_negative_integers,
      omit_password_validation: boolean,
      perform_class_validation: boolean,
      terminal_name: ost$name,
      terminal_name_found: boolean,
      valid_job_classes: ^jmt$job_class_list,
      validation_attributes: ^avt$validation_items,
      validation_cpu_time_limit: jmt$cpu_time_limit,
      validation_magnetic_tape_limit: sft$counter,
      validation_sru_limit: jmt$sru_limit;

?? NEWTITLE := 'assign_cpu_time_limit', EJECT ??

{ PURPOSE:
{   The purpose of this request is to assign a cpu time limit to the job
{   defined by the system job label.

    PROCEDURE assign_cpu_time_limit
      (    assigned_job_class: jmt$job_class;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

{ If no cpu time limit has been assigned, assign the system default value if the
{ job has automatic selection to a job class and assign the job class value if
{ the job has been assigned to a specific job class.

      IF system_label.limit_information.cpu_time_limit_assigned = jmc$unspecified_cpu_time_limit THEN
        IF system_label.assigned_job_class = jmc$automatic_class_name THEN
          system_label.limit_information.cpu_time_limit_assigned :=
                jmv$default_job_attributes [system_label.job_mode].cpu_time_limit;
        ELSE
          IF jmv$job_class_table_p^ [assigned_job_class].cpu_time_limit = jmc$system_default_cpu_time_lim THEN
            system_label.limit_information.cpu_time_limit_assigned :=
                  jmv$default_job_attributes [system_label.job_mode].cpu_time_limit;
          ELSE
            system_label.limit_information.cpu_time_limit_assigned :=
                  jmv$job_class_table_p^ [assigned_job_class].cpu_time_limit;
          IFEND;
        IFEND;
        IF system_label.limit_information.cpu_time_limit_assigned = jmc$required_cpu_time_limit THEN
          osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'CPU_TIME_LIMIT', status);
          RETURN;
        IFEND;

{ In all cases, restrict the cpu time limit assigned to the maximum for which
{ the user is validated.

        IF system_label.limit_information.cpu_time_limit_assigned > validation_cpu_time_limit THEN
          system_label.limit_information.cpu_time_limit_assigned := validation_cpu_time_limit;
        IFEND;
      IFEND;
    PROCEND assign_cpu_time_limit;

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

{ PURPOSE:
{   The purpose of this request is to assign a magnetic tape limit to the job
{   defined by the system job label.

    PROCEDURE assign_magnetic_tape_limit
      (    assigned_job_class: jmt$job_class;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

{ If no magnetic tape limit has been assigned, assign the system default value.

      IF system_label.limit_information.magnetic_tape_limit_assigned = jmc$unspecified_mag_tape_limit THEN
        system_label.limit_information.magnetic_tape_limit_assigned :=
              jmv$default_job_attributes [system_label.job_mode].magnetic_tape_limit;
        IF system_label.limit_information.magnetic_tape_limit_assigned = jmc$required_mag_tape_limit THEN
          osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'MAGNETIC_TAPE_LIMIT',
                status);
          RETURN;
        IFEND;
      IFEND;
    PROCEND assign_magnetic_tape_limit;

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

{ PURPOSE:
{   The purpose of this request is to assign a maximum working set to the job
{   defined by the system job label.

    PROCEDURE assign_maximum_working_set
      (    assigned_job_class: jmt$job_class;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

{ If no maximum working set has been assigned, assign the system default value
{ if the job has automatic selection to a job class and assign the job class
{ default value if the job has been assigned to a specific job class.

      IF system_label.limit_information.maximum_working_set_assigned = jmc$unspecified_work_set_size THEN
        IF system_label.assigned_job_class = jmc$automatic_class_name THEN
          system_label.limit_information.maximum_working_set_assigned :=
                jmv$default_job_attributes [system_label.job_mode].maximum_working_set;
          IF system_label.limit_information.maximum_working_set_assigned = jmc$required_working_set_size THEN
            osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'MAXIMUM_WORKING_SET',
                  status);
            RETURN;
          IFEND;
        ELSE
          system_label.limit_information.maximum_working_set_assigned :=
                jmv$job_class_table_p^ [assigned_job_class].maximum_working_set.default;
        IFEND;
      IFEND;
    PROCEND assign_maximum_working_set;

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

{ PURPOSE:
{   The purpose of this request is to assign an sru limit to the job defined
{   by the system job label.

    PROCEDURE assign_sru_limit
      (    assigned_job_class: jmt$job_class;
       VAR system_label: jmt$job_system_label;
       VAR status: ost$status);

{ If no sru limit has been assigned, assign the system default value if the job
{ has automatic selection to a job class and assign the job class value if the
{ job has been assigned to a specific job class.

      IF system_label.limit_information.sru_limit_assigned = jmc$unspecified_sru_limit THEN
        IF system_label.assigned_job_class = jmc$automatic_class_name THEN
          system_label.limit_information.sru_limit_assigned :=
                jmv$default_job_attributes [system_label.job_mode].sru_limit;
        ELSE
          IF jmv$job_class_table_p^ [assigned_job_class].sru_limit = jmc$system_default_sru_limit THEN
            system_label.limit_information.sru_limit_assigned :=
                  jmv$default_job_attributes [system_label.job_mode].sru_limit;
          ELSE
            system_label.limit_information.sru_limit_assigned :=
                  jmv$job_class_table_p^ [assigned_job_class].sru_limit;
          IFEND;
        IFEND;
        IF system_label.limit_information.sru_limit_assigned = jmc$required_sru_limit THEN
          osp$set_status_abnormal (jmc$job_management_id, jme$missing_parameter, 'SRU_LIMIT', status);
          RETURN;
        IFEND;

{ In all cases, restrict the sru limit assigned to the maximum for which the
{ user is validated.

        IF system_label.limit_information.sru_limit_assigned > validation_sru_limit THEN
          system_label.limit_information.sru_limit_assigned := validation_sru_limit;
        IFEND;
      IFEND;
    PROCEND assign_sru_limit;

?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    interactive_job := (system_label.job_attributes.originating_application_name =
          osc$dual_state_interactive) OR (system_label.job_attributes.originating_application_name =
          osc$timesharing) OR (system_label.job_attributes.originating_application_name =
          osc$xterm_application_name);
    batch_password_can_default := (user_identification = system_label.login_user_identification);

    omit_password_validation := ((interactive_job OR batch_password_can_default) AND
          (system_label.login_password = osc$null_name)) OR password_encrypted;

    perform_class_validation := FALSE;
    system_label.assigned_job_class := system_label.job_class_name;
    valid_job_classes := NIL;

{ Define the attributes to be validated against the validation file.

    PUSH validation_attributes: [1 .. 9];
    IF omit_password_validation THEN
      validation_attributes^ [1].key := avc$null_validation_key;
    ELSE
      validation_attributes^ [1].key := avc$password_key;
      validation_attributes^ [1].password := system_label.login_password;
    IFEND;
    IF system_label.job_attributes.originating_application_name = osc$dual_state_interactive THEN
      validation_attributes^ [2].key := avc$null_validation_key;
    ELSE
      validation_attributes^ [2].key := avc$account_project_key;
      validation_attributes^ [2].account_name := system_label.login_account;
      validation_attributes^ [2].project_name := system_label.login_project;
    IFEND;
    IF system_label.perform_class_validation AND (system_label.job_class_name <> osc$null_name) THEN
      validation_attributes^ [3].key := avc$job_class_name_key;
      validation_attributes^ [3].job_class_name := system_label.job_class_name;
    ELSE
      validation_attributes^ [3].key := avc$null_validation_key;
    IFEND;
    IF system_label.job_execution_ring <> osc$invalid_ring THEN
      validation_attributes^ [4].key := avc$job_execution_ring_key;
      validation_attributes^ [4].job_execution_ring := system_label.job_execution_ring;
    ELSE
      validation_attributes^ [4].key := avc$null_validation_key;
    IFEND;
    IF system_label.required_user_capability <> osc$null_name THEN
      validation_attributes^ [5].key := avc$required_capability_key;
      validation_attributes^ [5].required_capability := system_label.required_user_capability;
    ELSE
      validation_attributes^ [5].key := avc$null_validation_key;
    IFEND;
    IF system_label.limit_information.cpu_time_limit_assigned <> jmc$unspecified_cpu_time_limit THEN
      validation_attributes^ [6].key := avc$job_limit_key;
      validation_attributes^ [6].limit_name := avc$cpu_time_limit_name;
      validation_attributes^ [6].user_specified := TRUE;
      validation_attributes^ [6].job_maximum := system_label.limit_information.cpu_time_limit_assigned;
    ELSE
      validation_attributes^ [6].key := avc$null_validation_key;
    IFEND;
    IF system_label.limit_information.sru_limit_assigned <> jmc$unspecified_sru_limit THEN
      validation_attributes^ [7].key := avc$job_limit_key;
      validation_attributes^ [7].limit_name := avc$sru_limit_name;
      validation_attributes^ [7].user_specified := TRUE;
      validation_attributes^ [7].job_maximum := system_label.limit_information.sru_limit_assigned;
    ELSE
      validation_attributes^ [7].key := avc$null_validation_key;
    IFEND;
    IF system_label.limit_information.magnetic_tape_limit_assigned <> jmc$unspecified_mag_tape_limit THEN
      validation_attributes^ [8].key := avc$job_limit_key;
      validation_attributes^ [8].limit_name := avc$magnetic_tape_limit_name;
      validation_attributes^ [8].user_specified := TRUE;
      validation_attributes^ [8].job_maximum := system_label.limit_information.magnetic_tape_limit_assigned;
    ELSE
      validation_attributes^ [8].key := avc$null_validation_key;
    IFEND;

{ Get the terminal name to be passed on to prevalidation of timesharing jobs.

    get_terminal_name (system_label, terminal_name_found, terminal_name);
    IF terminal_name_found THEN
      validation_attributes^ [9].key := avc$terminal_name;
      validation_attributes^ [9].terminal_name := terminal_name;
    ELSE
      validation_attributes^ [9].key := avc$null_validation_key;
    IFEND;

{ Define the attributes to be returned from the validation file.

    PUSH default_attributes: [1 .. 7];
    default_attributes^ [1].key := avc$password_key;
    IF system_label.job_class_name = osc$null_name THEN
      default_attributes^ [2].key := avc$job_class_defaults_key;
    ELSE
      default_attributes^ [2].key := avc$null_validation_key;
    IFEND;
    IF system_label.job_attributes.originating_application_name = osc$dual_state_interactive THEN
      default_attributes^ [3].key := avc$optional_capability_key;
      default_attributes^ [3].optional_capability := avc$dual_state_prompt;
    ELSE
      default_attributes^ [3].key := avc$null_validation_key;
    IFEND;
    IF system_label.limit_information.cpu_time_limit_assigned = jmc$unspecified_cpu_time_limit THEN
      default_attributes^ [4].key := avc$job_limit_key;
      default_attributes^ [4].limit_name := avc$cpu_time_limit_name;
      default_attributes^ [4].user_specified := FALSE;
    ELSE
      default_attributes^ [4].key := avc$null_validation_key;
    IFEND;
    IF system_label.limit_information.sru_limit_assigned = jmc$unspecified_sru_limit THEN
      default_attributes^ [5].key := avc$job_limit_key;
      default_attributes^ [5].limit_name := avc$sru_limit_name;
      default_attributes^ [5].user_specified := FALSE;
    ELSE
      default_attributes^ [5].key := avc$null_validation_key;
    IFEND;
    IF (system_label.job_class_name = jmc$automatic_class_name) OR
          (system_label.job_class_name = osc$null_name) OR (system_label.job_class_name =
          jmc$system_default_class_name) THEN
      default_attributes^ [6].key := avc$valid_job_classes_key;
      PUSH valid_job_classes: [1 .. avc$maximum_name_list_size];
      default_attributes^ [6].job_classes := valid_job_classes;
    ELSE
      default_attributes^ [6].key := avc$null_validation_key;
    IFEND;
    IF system_label.limit_information.magnetic_tape_limit_assigned = jmc$unspecified_mag_tape_limit THEN
      default_attributes^ [7].key := avc$job_limit_key;
      default_attributes^ [7].limit_name := avc$magnetic_tape_limit_name;
      default_attributes^ [7].user_specified := FALSE;
    ELSE
      default_attributes^ [7].key := avc$null_validation_key;
    IFEND;

    avp$prevalidate_job (system_label.login_user_identification.user,
          system_label.login_user_identification.family, validation_attributes, default_attributes, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    encrypted_password := default_attributes^ [1].password;

{ Update values from the user values in the validation file.

    IF NOT password_encrypted THEN
      system_label.login_password := encrypted_password;
    IFEND;

    IF system_label.job_class_name = osc$null_name THEN
      IF system_label.job_mode = jmc$interactive_connected THEN
        system_label.assigned_job_class := default_attributes^ [2].interactive_job_class_default;
      ELSE
        system_label.assigned_job_class := default_attributes^ [2].batch_job_class_default;
      IFEND;
    IFEND;

    IF system_label.job_attributes.originating_application_name = osc$dual_state_interactive THEN
      system_label.optional_user_capability := default_attributes^ [3].optional_capability;
    IFEND;

    IF system_label.limit_information.cpu_time_limit_assigned = jmc$unspecified_cpu_time_limit THEN
      validation_cpu_time_limit := default_attributes^ [4].job_maximum;
    IFEND;

    IF system_label.limit_information.sru_limit_assigned = jmc$unspecified_sru_limit THEN
      validation_sru_limit := default_attributes^ [5].job_maximum;
    IFEND;

    IF system_label.limit_information.magnetic_tape_limit_assigned = jmc$unspecified_mag_tape_limit THEN
      validation_magnetic_tape_limit := default_attributes^ [7].job_maximum;
    IFEND;

    IF valid_job_classes <> NIL THEN
      number_of_valid_job_classes := default_attributes^ [6].count;
    IFEND;

{ Determine the job class name and index if they are known.

    IF system_label.assigned_job_class = jmc$system_default_class_name THEN
      IF system_label.perform_class_validation THEN
        perform_class_validation := TRUE;
      IFEND;
      IF system_label.job_mode = jmc$interactive_connected THEN
        system_label.assigned_job_class := jmv$default_job_attributes [system_label.job_mode].job_class;
      ELSE
        system_label.assigned_job_class := jmv$default_job_attributes [system_label.job_mode].job_class;
      IFEND;
    IFEND;

    IF (system_label.assigned_job_class = jmc$none_class_name) THEN
      IF system_label.job_mode = jmc$interactive_connected THEN
        osp$set_status_condition (jme$interactive_access_denied, status);
      ELSE
        osp$set_status_condition (jme$batch_access_denied, status);
      IFEND;
      RETURN;
    IFEND;

    IF (system_label.assigned_job_class <> jmc$automatic_class_name) THEN
      IF (valid_job_classes <> NIL) AND perform_class_validation THEN

      /validate_job_class/
        BEGIN
          FOR i := 1 TO number_of_valid_job_classes DO
            IF (system_label.assigned_job_class = valid_job_classes^ [i]) OR
                  (valid_job_classes^ [i] = jmc$all_class_name) THEN
              EXIT /validate_job_class/;
            IFEND;
          FOREND;
          osp$set_status_abnormal ('AV', ave$bad_job_class, system_label.assigned_job_class, status);
          RETURN;
        END /validate_job_class/;
      IFEND;

      jmp$determine_job_class (system_label.assigned_job_class, assigned_job_class, status);
      IF NOT status.normal THEN
        osp$set_status_abnormal (jmc$job_management_id, jme$job_class_does_not_exist,
              system_label.assigned_job_class, status);
        RETURN;
      IFEND;
    IFEND;

{ Determine the job class if it is unknown.

    IF valid_job_classes = NIL THEN
      PUSH valid_job_classes: [1 .. 1];
      valid_job_classes^ [1] := system_label.assigned_job_class;
      number_of_valid_job_classes := 1;
    IFEND;

    qfp$categorize_job (valid_job_classes^, number_of_valid_job_classes, system_label, assigned_job_class,
          status);

{ Assign the limits to the job.

    assign_cpu_time_limit (assigned_job_class, system_label, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    assign_magnetic_tape_limit (assigned_job_class, system_label, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    assign_maximum_working_set (assigned_job_class, system_label, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    assign_sru_limit (assigned_job_class, system_label, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ If the magnetic tape limit is still unspecified then assign the limit to the job class value.

    IF system_label.limit_information.magnetic_tape_limit_assigned = jmc$unspecified_mag_tape_limit THEN
      system_label.limit_information.magnetic_tape_limit_assigned :=
            jmv$job_class_table_p^ [assigned_job_class].magnetic_tape_limit;
      IF system_label.limit_information.magnetic_tape_limit_assigned > validation_magnetic_tape_limit THEN
        system_label.limit_information.magnetic_tape_limit_assigned := validation_magnetic_tape_limit;
      IFEND;
    IFEND;
  PROCEND prevalidate_job;
?? OLDTITLE ??
MODEND jmm$queue_file_job_manager;
