?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Job Management : Logging Interfaces' ??
MODULE jmm$logging_interfaces;

{ PURPOSE:
{   This module contains interfaces used to format and emit
{   statistics.
{
{ DESIGN:
{   Procedures in this module will run in rings 2 and 3 with a call bracket of ring 13.
{   In order to emit a statistic the following must be done:
{      1. Obtain the data necessary for the statistic to be emitted.
{      2. Format the statistics' counters if there are any.
{      3. Format the statistics' descriptive data if there is any.
{      4. Call SF interface to emit the statistic.
{

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc avc$accounting_statistics
*copyc jmc$job_management_id
*copyc jme$queued_file_conditions
*copyc jml$user_id
*copyc jmt$comm_acct_statistic_data
*copyc jmt$job_system_label
*copyc nft$batch_input_accounting_data
*copyc nft$qtf_input_accounting_data
*copyc osc$timesharing
*copyc osc$timesharing_terminal_file
*copyc osd$integer_limits
*copyc oss$job_paged_literal
*copyc ost$string
?? POP ??
*copyc amp$get_file_attributes
*copyc amp$return
*copyc clp$convert_integer_to_string
*copyc clp$trimmed_string_size
*copyc clv$standard_files
*copyc iip$st_get_input_output_counts
*copyc jmv$job_attributes
*copyc nap$get_attributes
*copyc nap$get_connect_time_interval
*copyc nap$parse_accounting_data
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$generate_log_message
*copyc osp$set_status_abnormal
*copyc osp$set_status_from_condition
*copyc pfp$attach
*copyc pfp$begin_system_authority
*copyc pfp$end_system_authority
*copyc pmp$compute_time_dif_in_seconds
*copyc pmp$get_account_project
*copyc pmp$get_compact_date_time
*copyc pmp$get_unique_name
*copyc qfp$read_output_system_label
*copyc sfp$emit_statistic
*copyc sfp$get_routing_controls
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  CONST
    max_descriptive_data_items = sfc$max_descriptive_data_size;

  TYPE
    descriptive_data_item = string (sfc$max_descriptive_data_size);

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

{ PURPOSE:
{   The purpose of this procedure is to trim trailing blanks from each item
{   and concatenate the string to the end of the descriptive data.

  PROCEDURE build_descriptive_data
    (    descriptive_data_items: array [1 .. * ] of descriptive_data_item;
     VAR descriptive_data: string (sfc$max_descriptive_data_size);
     VAR descriptive_data_size: 0 .. sfc$max_descriptive_data_size);

    VAR
      item: 1 .. max_descriptive_data_items,
      string_to_add_size: 0 .. sfc$max_descriptive_data_size;

    FOR item := 1 TO UPPERBOUND (descriptive_data_items) DO

{ If size of descriptive data is already at max, return.

      IF descriptive_data_size = sfc$max_descriptive_data_size THEN
        RETURN;
      IFEND;

{ Get the size of string_to_add minus trailing blanks.

      string_to_add_size := clp$trimmed_string_size (descriptive_data_items [item]);

{ Shorten string_to_add_size if it will overflow the descriptive data.

      IF descriptive_data_size + string_to_add_size > sfc$max_descriptive_data_size THEN
        string_to_add_size := sfc$max_descriptive_data_size - descriptive_data_size;
      IFEND;

{ Add item to descriptive_data.

      descriptive_data (descriptive_data_size + 1, string_to_add_size) := descriptive_data_items [item]
            (1, string_to_add_size);
      descriptive_data_size := descriptive_data_size + string_to_add_size;

{ If this is not the last item, add a comma.

      IF item <> UPPERBOUND (descriptive_data_items) THEN
        descriptive_data (descriptive_data_size + 1, 1) := ',';
        descriptive_data_size := descriptive_data_size + 1;
      IFEND;

    FOREND;
  PROCEND build_descriptive_data;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$emit_communication_stat', EJECT ??
*copyc jmh$emit_communication_stat

  PROCEDURE [XDCL, #GATE] jmp$emit_communication_stat
    (    statistic_data: jmt$comm_acct_statistic_data);


{ The following constant represents the size of the work area set up to contain the
{ peer_accounting_information attribute from the NAM/VE connection.

    CONST
      max_data_area_size = 1000;

    TYPE
      batch_input_device_converter = record
        case boolean of
        = TRUE =
          data: nft$batch_input_accounting_data,
        = FALSE =
          string_value: string (jmc$job_input_device_size),
        casend,
      recend;

    TYPE
      qtf_input_device_converter = record
        case boolean of
        = TRUE =
          data: nft$qtf_input_accounting_data,
        = FALSE =
          string_value: string (jmc$job_input_device_size),
        casend,
      recend;

    VAR
      account: avt$account_name,
      activated_logs: sft$binary_logset,
      batch_input_device: batch_input_device_converter,
      bytes_transferred_in: ost$non_negative_integers,
      bytes_transferred_out: ost$non_negative_integers,
      connect_time: ost$non_negative_integers,
      contains_data: boolean,
      counters: sft$counters,
      current_date_time: ost$date_time,
      cycle_selector: pft$cycle_selector,
      descriptive_data: string (sfc$max_descriptive_data_size),
      descriptive_data_items: ^array [1 .. * ] of descriptive_data_item,
      descriptive_data_size: 0 .. sfc$max_descriptive_data_size,
      file_attributes: ^amt$get_attributes,
      get_accounting_data: ^nat$accounting_data_fields,
      get_attributes: ^nat$get_attributes,
      ignore_name: ost$name,
      ignore_status: ost$status,
      index: nat$accounting_data_kind,
      job_system_label_p: ^jmt$job_system_label,
      line_speed_string: ost$string,
      local_file: boolean,
      local_status: ost$status,
      logset: pmt$ascii_logset,
      old_file: boolean,
      output_system_label_p: ^jmt$output_system_label,
      password: pft$password,
      peer_accounting_information: ^string ( * ),
      project: avt$project_name,
      qtf_input_device: qtf_input_device_converter,
      seconds: integer,
      statistic_identifier_map: [STATIC, READ, oss$job_paged_literal] array
            [jmc$ca_input_file .. jmc$ca_last_statistic] of ost$non_negative_integers :=
            [avc$ca_input_file, avc$ca_output_file, avc$ca_output_queue_residency, avc$ca_print_file,
            avc$ca_submit_job, avc$ca_standard_output_file, avc$ca_request_pf_transfer,
            avc$ca_target_pf_transfer, avc$ca_origin_qf_transfer, avc$ca_dest_qf_transfer,
            avc$ca_interactive_interval, avc$ca_ftp_client_ctrl_connect, avc$ca_ftp_client_data_connect,
            avc$ca_ftp_server_ctrl_connect, avc$ca_ftp_server_data_connect],
      unique_lfn: amt$local_file_name,
      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;
      osp$set_status_from_condition (jmc$job_management_id, condition, sfsa_p, local_status, ignore_status);
    PROCEND handle_block_exit;
?? OLDTITLE, EJECT ??

    local_status.normal := TRUE;

{ The procedure "osp$verify_system_privilege" should be called here when the capability for
{ NOS/VE applications to run in system privileged segments is available.

    logset := $pmt$ascii_logset [pmc$system_log];

{ Determine if the statistic to be emitted is activated to any log.

    REPEAT
      sfp$get_routing_controls (statistic_identifier_map [statistic_data.statistic_id], activated_logs,
            ignore_name, local_status);
    UNTIL (local_status.normal) OR (local_status.condition <> sfe$call_again_job_recovered);
    IF NOT local_status.normal THEN
      osp$generate_log_message (logset, local_status, ignore_status);
      RETURN;
    IFEND;

{ If the set of logs in activated_logs is empty, return.

    IF activated_logs = $sft$binary_logset [] THEN
      RETURN;
    IFEND;

{ Initialize the descriptive_data and descriptive_data_size.

    descriptive_data := ' ';
    descriptive_data_size := 0;

    PUSH file_attributes: [1 .. 1];
    file_attributes^ [1].key := amc$file_length;

    CASE statistic_data.statistic_id OF
    = jmc$ca_input_file =

{ Build the avc$ca_input_file statistic.

      batch_input_device.string_value := statistic_data.input_file^.job_input_device.
            text (1, statistic_data.input_file^.job_input_device.size);
      job_system_label_p := statistic_data.input_file^.job_system_label_p;

{ Set up counters for the statistic.

      PUSH counters: [1 .. 3];
      counters^ [1] := job_system_label_p^.job_attributes.job_size;
      counters^ [2] := batch_input_device.data.connect_time;
      counters^ [3] := batch_input_device.data.number_of_cards;

      pmp$get_account_project (account, project, ignore_status);

{ Build the descriptive_data for the statistic.

      PUSH descriptive_data_items: [1 .. 12];

      descriptive_data_items^ [1] := job_system_label_p^.login_user_identification.family;
      descriptive_data_items^ [2] := job_system_label_p^.login_user_identification.user;
      descriptive_data_items^ [3] := account;
      descriptive_data_items^ [4] := project;
      descriptive_data_items^ [5] := job_system_label_p^.system_job_name;
      descriptive_data_items^ [6] := job_system_label_p^.user_job_name;
      descriptive_data_items^ [7] := batch_input_device.data.di_system_name;
      descriptive_data_items^ [8] := batch_input_device.data.line_name;
      descriptive_data_items^ [9] := batch_input_device.data.line_subtype;
      clp$convert_integer_to_string (batch_input_device.data.line_speed, 10, FALSE, line_speed_string,
            ignore_status);
      descriptive_data_items^ [10] := line_speed_string.value (1, line_speed_string.size);
      descriptive_data_items^ [11] := batch_input_device.data.i_o_station_name;
      descriptive_data_items^ [12] := batch_input_device.data.device_name;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_output_file =

{ Build the avc$ca_output_file statistic.

{ Set up counters for statistic.

      PUSH counters: [1 .. 3];
      counters^ [1] := statistic_data.output_file^.output_descriptor.file_size;
      counters^ [2] := statistic_data.output_file^.connect_time;
      counters^ [3] := statistic_data.output_file^.number_of_lines;

{ Retrieve the peer_accounting_information attribute.

      PUSH get_attributes: [1 .. 1];
      get_attributes^ [1].kind := nac$peer_accounting_information;
      PUSH get_attributes^ [1].peer_accounting_information: [[REP max_data_area_size OF cell]];

      nap$get_attributes (statistic_data.output_file^.network_file_name, get_attributes^, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

      IF get_attributes^ [1].peer_accounting_info_length = 0 THEN
        peer_accounting_information := NIL;
      ELSE
        RESET get_attributes^ [1].peer_accounting_information;
        NEXT peer_accounting_information: [get_attributes^ [1].peer_accounting_info_length] IN
              get_attributes^ [1].peer_accounting_information;
      IFEND;

{ Get accounting_data.

      PUSH get_accounting_data: [1 .. 4];
      get_accounting_data^ [1].kind := nac$ca_di_system_name;
      get_accounting_data^ [2].kind := nac$ca_line_name;
      get_accounting_data^ [3].kind := nac$ca_line_subtype;
      get_accounting_data^ [4].kind := nac$ca_line_speed;

      nap$parse_accounting_data (peer_accounting_information, NIL, get_accounting_data, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

{ Set up descriptive_data for statistic.

      PUSH descriptive_data_items: [1 .. UPPERBOUND (get_accounting_data^) + 11];

      descriptive_data_items^ [1] := statistic_data.output_file^.output_descriptor.login_family;
      descriptive_data_items^ [2] := statistic_data.output_file^.output_descriptor.login_user;
      descriptive_data_items^ [3] := statistic_data.output_file^.output_descriptor.login_account;
      descriptive_data_items^ [4] := statistic_data.output_file^.output_descriptor.login_project;
      descriptive_data_items^ [5] := statistic_data.output_file^.output_descriptor.system_job_name;
      descriptive_data_items^ [6] := statistic_data.output_file^.output_descriptor.user_file_name;

{ Add each element of get_accounting_data array to the descriptive_data.

      FOR index := 1 TO UPPERBOUND (get_accounting_data^) DO
        CASE get_accounting_data^ [index].kind OF
        = nac$ca_di_system_name =
          descriptive_data_items^ [index + 6] := get_accounting_data^ [index].di_system_name;
        = nac$ca_line_name =
          descriptive_data_items^ [index + 6] := get_accounting_data^ [index].line_name;
        = nac$ca_line_subtype =
          descriptive_data_items^ [index + 6] := get_accounting_data^ [index].line_subtype;
        = nac$ca_line_speed =
          clp$convert_integer_to_string (get_accounting_data^ [index].line_speed, 10, FALSE,
                line_speed_string, ignore_status);
          descriptive_data_items^ [index + 6] := line_speed_string.value (1, line_speed_string.size);
        = nac$ca_unavailable_information =
          descriptive_data_items^ [index + 6] := ' ';
        ELSE
          ;
        CASEND;
      FOREND;

      descriptive_data_items^ [11] := statistic_data.output_file^.output_descriptor.station;
      descriptive_data_items^ [12] := statistic_data.output_file^.output_descriptor.device;
      descriptive_data_items^ [13] := statistic_data.output_file^.output_descriptor.output_class;
      descriptive_data_items^ [14] := statistic_data.output_file^.output_descriptor.forms_code;
      descriptive_data_items^ [15] := statistic_data.output_file^.output_descriptor.system_file_name;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_output_queue_residency =

{ Build the avc$ca_output_queue_residency statistic.

{ Get a unique name.

      pmp$get_unique_name (unique_lfn, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

{ Attach the output file.

      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 (unique_lfn, statistic_data.output_queue_residency^.output_file_path^, cycle_selector,
            password, usage_selections, usage_selections, pfc$wait, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

      pfp$end_system_authority;
      osp$disestablish_cond_handler;

{ Read the output system label.

      PUSH output_system_label_p;
      qfp$read_output_system_label (unique_lfn, output_system_label_p^, local_status);
      IF NOT local_status.normal THEN
        amp$return (unique_lfn, ignore_status);
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

{ Return the output queue file.

      amp$return (unique_lfn, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

{ Get the current date and time.

      pmp$get_compact_date_time (current_date_time, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

      pmp$compute_time_dif_in_seconds (output_system_label_p^.output_submission_time, current_date_time,
            seconds, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

{ Set the values of the counters.

      PUSH counters: [1 .. 2];
      counters^ [1] := output_system_label_p^.file_size;
      counters^ [2] := seconds;

{ Build the descriptive_data.

      PUSH descriptive_data_items: [1 .. 7];

      descriptive_data_items^ [1] := output_system_label_p^.login_user_identification.family;
      descriptive_data_items^ [2] := output_system_label_p^.login_user_identification.user;
      descriptive_data_items^ [3] := output_system_label_p^.login_account;
      descriptive_data_items^ [4] := output_system_label_p^.login_project;
      descriptive_data_items^ [5] := output_system_label_p^.system_job_name;
      descriptive_data_items^ [6] := output_system_label_p^.user_file_name;
      descriptive_data_items^ [7] := output_system_label_p^.system_file_name;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_print_file =

{ Build the avc$ca_print_file statistic.

{ Set the values of the counter.

      PUSH counters: [1 .. 1];
      counters^ [1] := statistic_data.print_file^.file_size;

{ Build the descriptive_data.

      PUSH descriptive_data_items: [1 .. 2];

      descriptive_data_items^ [1] := statistic_data.print_file^.user_file_name;
      descriptive_data_items^ [2] := statistic_data.print_file^.system_file_name;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_submit_job =

{ Build the avc$ca_submit_job statistic.

{ Set the values of the counter.

      PUSH counters: [1 .. 1];
      counters^ [1] := statistic_data.submit_job^.job_size;

{ Build the descriptive_data.

      descriptive_data := statistic_data.submit_job^.system_job_name;
      descriptive_data_size := clp$trimmed_string_size (descriptive_data);

    = jmc$ca_standard_output_file =

{ Build the avc$ca_standard_output_file statistic.

      IF (jmv$job_attributes.output_disposition_key = jmc$normal_output_disposition) THEN

{ Get the file_length file attribute of $OUTPUT.

        amp$get_file_attributes (clv$standard_files [clc$sf_job_output_file].path_handle_name,
              file_attributes^, local_file, old_file, contains_data, local_status);
        IF NOT local_status.normal THEN
          osp$generate_log_message (logset, local_status, ignore_status);
          RETURN;
        IFEND;

        PUSH counters: [1 .. 1];
        counters^ [1] := file_attributes^ [1].file_length;

{ Get the file_length file attribute of $JOB_LOG.

        amp$get_file_attributes (clv$standard_files [clc$sf_job_log_file].path_handle_name, file_attributes^,
              local_file, old_file, contains_data, local_status);
        IF NOT local_status.normal THEN
          osp$generate_log_message (logset, local_status, ignore_status);
          RETURN;
        IFEND;

{ Set value of counter to size of $OUTPUT + size of $JOB_LOG.

        counters^ [1] := counters^ [1] + file_attributes^ [1].file_length;

{ Build the descriptive_data.

        descriptive_data := 'OUTPUT';
        descriptive_data_size := 6;

      ELSE
        RETURN;

      IFEND;

    = jmc$ca_request_pf_transfer =

{ Build the avc$ca_request_pf_transfer statistic.

{ Set values of counters.

      PUSH counters: [1 .. 3];
      counters^ [1] := statistic_data.request_perm_file_transfer^.file_size;
      counters^ [2] := statistic_data.request_perm_file_transfer^.bytes_transferred;
      counters^ [3] := statistic_data.request_perm_file_transfer^.connect_time;

{ Build the descriptive_data.

      PUSH descriptive_data_items: [1 .. 3];

      descriptive_data_items^ [1] := statistic_data.request_perm_file_transfer^.requesting_mainframe_name;
      descriptive_data_items^ [2] := statistic_data.request_perm_file_transfer^.target_mainframe_name;
      descriptive_data_items^ [3] := statistic_data.request_perm_file_transfer^.command_string.
            value (1, statistic_data.request_perm_file_transfer^.command_string.size);

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_target_pf_transfer =

{ Build the avc$ca_target_pf_transfer statistic.

{ Set values of counters.

      PUSH counters: [1 .. 3];
      counters^ [1] := statistic_data.target_perm_file_transfer^.file_size;
      counters^ [2] := statistic_data.target_perm_file_transfer^.bytes_transferred;
      counters^ [3] := statistic_data.target_perm_file_transfer^.connect_time;

{ Build the descriptive_data.

      PUSH descriptive_data_items: [1 .. 3];

      descriptive_data_items^ [1] := statistic_data.target_perm_file_transfer^.requesting_mainframe_name;
      descriptive_data_items^ [2] := statistic_data.target_perm_file_transfer^.target_mainframe_name;
      descriptive_data_items^ [3] := statistic_data.target_perm_file_transfer^.command_string.
            value (1, statistic_data.target_perm_file_transfer^.command_string.size);

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_origin_qf_transfer =

{ Build the avc$ca_origin_qf_transfer statistic.

{ Set value of counter.

      PUSH counters: [1 .. 1];
      counters^ [1] := statistic_data.origin_queue_file_transfer^.file_size;

{ Build the descriptive_data.

      PUSH descriptive_data_items: [1 .. 8];

      descriptive_data_items^ [1] := statistic_data.origin_queue_file_transfer^.user_identification.family;
      descriptive_data_items^ [2] := statistic_data.origin_queue_file_transfer^.user_identification.user;
      descriptive_data_items^ [3] := statistic_data.origin_queue_file_transfer^.account_name;
      descriptive_data_items^ [4] := statistic_data.origin_queue_file_transfer^.project_name;
      descriptive_data_items^ [5] := statistic_data.origin_queue_file_transfer^.system_job_name;
      descriptive_data_items^ [6] := statistic_data.origin_queue_file_transfer^.user_job_name;
      descriptive_data_items^ [7] := statistic_data.origin_queue_file_transfer^.origin_mainframe_name;
      descriptive_data_items^ [8] := statistic_data.origin_queue_file_transfer^.dest_mainframe_name;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_dest_qf_transfer =

{ Build the avc$ca_dest_qf_transfer statistic.


      PUSH counters: [1 .. 1];
      PUSH descriptive_data_items: [1 .. 8];

      CASE statistic_data.dest_queue_file_transfer^.kind OF
      = jmc$input_file =
        qtf_input_device.string_value := statistic_data.dest_queue_file_transfer^.job_input_device.
              text (1, statistic_data.dest_queue_file_transfer^.job_input_device.size);
        job_system_label_p := statistic_data.dest_queue_file_transfer^.job_system_label_p;

        counters^ [1] := qtf_input_device.data.file_size;

        pmp$get_account_project (account, project, ignore_status);

        descriptive_data_items^ [1] := job_system_label_p^.login_user_identification.family;
        descriptive_data_items^ [2] := job_system_label_p^.login_user_identification.user;
        descriptive_data_items^ [3] := account;
        descriptive_data_items^ [4] := project;
        descriptive_data_items^ [5] := job_system_label_p^.system_job_name;
        descriptive_data_items^ [6] := job_system_label_p^.user_job_name;
        descriptive_data_items^ [7] := qtf_input_device.data.origin_mainframe_name;
        descriptive_data_items^ [8] := qtf_input_device.data.dest_mainframe_name;

      ELSE {jmc$output_file

        PUSH output_system_label_p;
        qfp$read_output_system_label (statistic_data.dest_queue_file_transfer^.output_file_name,
              output_system_label_p^, local_status);
        IF local_status.normal THEN
          counters^ [1] := output_system_label_p^.file_size;

          descriptive_data_items^ [1] := output_system_label_p^.login_user_identification.family;
          descriptive_data_items^ [2] := output_system_label_p^.login_user_identification.user;
          descriptive_data_items^ [3] := output_system_label_p^.login_account;
          descriptive_data_items^ [4] := output_system_label_p^.login_project;
          descriptive_data_items^ [5] := output_system_label_p^.system_job_name;
          descriptive_data_items^ [6] := output_system_label_p^.user_file_name;
          descriptive_data_items^ [7] := statistic_data.dest_queue_file_transfer^.data.origin_mainframe_name;
          descriptive_data_items^ [8] := statistic_data.dest_queue_file_transfer^.data.dest_mainframe_name;

        ELSE {NOT status.normal.  This implies that the output file is from a non-NOS/VE system.

          counters^ [1] := statistic_data.dest_queue_file_transfer^.data.file_size;

          descriptive_data_items^ [1] := statistic_data.dest_queue_file_transfer^.data.user_identification.
                family;
          descriptive_data_items^ [2] := statistic_data.dest_queue_file_transfer^.data.user_identification.
                user;
          descriptive_data_items^ [3] := statistic_data.dest_queue_file_transfer^.data.account_name;
          descriptive_data_items^ [4] := statistic_data.dest_queue_file_transfer^.data.project_name;
          descriptive_data_items^ [5] := statistic_data.dest_queue_file_transfer^.data.system_job_name;
          descriptive_data_items^ [6] := statistic_data.dest_queue_file_transfer^.data.user_job_name;
          descriptive_data_items^ [7] := statistic_data.dest_queue_file_transfer^.data.origin_mainframe_name;
          descriptive_data_items^ [8] := statistic_data.dest_queue_file_transfer^.data.dest_mainframe_name;
        IFEND;

      CASEND;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_interactive_interval =

      IF jmv$job_attributes.originating_application_name <> osc$timesharing THEN
        RETURN;
      IFEND;

{ Build the avc$ca_interactive_interval statistic.

{ Set up the counters for statistic.

      PUSH counters: [1 .. 3];

      iip$st_get_input_output_counts (bytes_transferred_in, bytes_transferred_out, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

      nap$get_connect_time_interval (osc$timesharing_terminal_file, connect_time, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

      counters^ [1] := bytes_transferred_in;
      counters^ [2] := bytes_transferred_out;

{ Connect time is in microseconds.  Round it to seconds.

      counters^ [3] := connect_time DIV 1000000;
      IF (connect_time MOD 1000000) > 500000 THEN
        counters^ [3] := counters^ [3] + 1;
      IFEND;

{ Get the accounting data.  If the connection is an X.25 connection nap$parse_accounting_data will
{ return the trunk name and trunk subtype.  Otherwise the line name and line subtype will be returned.

      PUSH get_accounting_data: [1 .. 7];
      get_accounting_data^ [1].kind := nac$ca_di_system_name;
      get_accounting_data^ [2].kind := nac$ca_line_name;
      get_accounting_data^ [3].kind := nac$ca_trunk_name;
      get_accounting_data^ [4].kind := nac$ca_line_subtype;
      get_accounting_data^ [5].kind := nac$ca_trunk_subtype;
      get_accounting_data^ [6].kind := nac$ca_line_speed;
      get_accounting_data^ [7].kind := nac$ca_device_name;

      PUSH peer_accounting_information: [jmv$job_attributes.job_input_device.size];
      peer_accounting_information^ := jmv$job_attributes.job_input_device.text;
      nap$parse_accounting_data (peer_accounting_information, NIL, get_accounting_data, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message (logset, local_status, ignore_status);
        RETURN;
      IFEND;

{ Set up the descriptive_data for the statistic using the elements of the get_accounting_data array.

      PUSH descriptive_data_items: [1 .. 5];

      IF get_accounting_data^ [1].kind = nac$ca_di_system_name THEN
        descriptive_data_items^ [1] := get_accounting_data^ [1].di_system_name;
      ELSE
        descriptive_data_items^ [1] := ' ';
      IFEND;

      IF get_accounting_data^ [2].kind = nac$ca_line_name THEN
        descriptive_data_items^ [2] := get_accounting_data^ [2].line_name;
      ELSEIF get_accounting_data^ [3].kind = nac$ca_trunk_name THEN
        descriptive_data_items^ [2] := get_accounting_data^ [3].trunk_name;
      ELSE
        descriptive_data_items^ [2] := ' ';
      IFEND;

      IF get_accounting_data^ [4].kind = nac$ca_line_subtype THEN
        descriptive_data_items^ [3] := get_accounting_data^ [4].line_subtype;
      ELSEIF get_accounting_data^ [5].kind = nac$ca_trunk_subtype THEN
        descriptive_data_items^ [3] := get_accounting_data^ [5].trunk_subtype;
      ELSE
        descriptive_data_items^ [3] := ' ';
      IFEND;

      IF get_accounting_data^ [6].kind = nac$ca_line_speed THEN
        clp$convert_integer_to_string (get_accounting_data^ [6].line_speed, 10, FALSE, line_speed_string,
              ignore_status);
        descriptive_data_items^ [4] := line_speed_string.value (1, line_speed_string.size);
      ELSE
        descriptive_data_items^ [4] := ' ';
      IFEND;

      IF get_accounting_data^ [7].kind = nac$ca_device_name THEN
        descriptive_data_items^ [5] := get_accounting_data^ [7].device_name;
      ELSE
        descriptive_data_items^ [5] := ' ';
      IFEND;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_ftp_client_ctrl_connect, jmc$ca_ftp_server_ctrl_connect =

{ Build the avc$ca_ftp_client_ctrl_connect or avc$ca_ftp_server_ctrl_connect statistic.

{ Set up the counters for statistic.

      PUSH counters: [1 .. 3];

      counters^ [1] := statistic_data.ftp_statistics^.bytes_sent;
      counters^ [2] := statistic_data.ftp_statistics^.bytes_received;
      counters^ [3] := statistic_data.ftp_statistics^.connect_time;

{ Set up the descriptive_data for the statistic.

      PUSH descriptive_data_items: [1 .. 4];
      descriptive_data_items^ [1] := statistic_data.ftp_statistics^.requesting_mainframe_address;
      descriptive_data_items^ [2] := statistic_data.ftp_statistics^.requesting_port_number;
      descriptive_data_items^ [3] := statistic_data.ftp_statistics^.target_mainframe_address;
      descriptive_data_items^ [4] := statistic_data.ftp_statistics^.target_port_number;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    = jmc$ca_ftp_client_data_connect, jmc$ca_ftp_server_data_connect =

{ Build the avc$ca_ftp_client_data_connect or avc$ca_ftp_server_data_connect statistic.

{ Set up the counters for statistic.

      PUSH counters: [1 .. 2];

      counters^ [1] := statistic_data.ftp_statistics^.file_size;
      counters^ [2] := statistic_data.ftp_statistics^.connect_time;

{ Set up the descriptive_data for the statistic.

      PUSH descriptive_data_items: [1 .. 6];
      descriptive_data_items^ [1] := statistic_data.ftp_statistics^.requesting_mainframe_address;
      descriptive_data_items^ [2] := statistic_data.ftp_statistics^.requesting_port_number;
      descriptive_data_items^ [3] := statistic_data.ftp_statistics^.target_mainframe_address;
      descriptive_data_items^ [4] := statistic_data.ftp_statistics^.target_port_number;
      descriptive_data_items^ [5] := statistic_data.ftp_statistics^.command;
      descriptive_data_items^ [6] := statistic_data.ftp_statistics^.successful;

      build_descriptive_data (descriptive_data_items^, descriptive_data, descriptive_data_size);

    ELSE
      RETURN;
    CASEND;

    sfp$emit_statistic (statistic_identifier_map [statistic_data.statistic_id],
          descriptive_data (1, descriptive_data_size), counters, local_status);
    IF NOT local_status.normal THEN
      osp$generate_log_message (logset, local_status, ignore_status);
    IFEND;

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

  PROCEDURE [XDCL] jmp$emit_job_history_statistics
    (    statistic_code: sft$statistic_code;
         disposition: ost$name;
         system_job_name: jmt$system_supplied_name;
         system_file_name: jmt$system_supplied_name;
         system_label_p: ^jmt$job_system_label;
         output_system_label_p: ^jmt$output_system_label;
         reason: ost$name;
         parent_job_name: jmt$system_supplied_name;
     VAR status: ost$status);

    VAR
      data_size: 1 .. osc$max_string_size,
      ignore_status: ost$status,
      logset: pmt$ascii_logset,
      statistic_data: string (osc$max_string_size);

    status.normal := TRUE;
    logset := $pmt$ascii_logset [pmc$system_log, pmc$job_log];
    data_size := 1;

    CASE statistic_code OF
    = jml$job_queuing_started =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.user_job_name (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.login_user_identification.
            family (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.login_user_identification.
            user (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.job_attributes.job_controller.
            family (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.job_attributes.job_controller.
            user (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.job_attributes.
            station (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            parent_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size - 1;

    = jml$job_queuing_aborted =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$job_file_deleted =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$output_queuing_started =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.login_user_identification.
            family (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.login_user_identification.
            user (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.output_controller.
            family (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.output_controller.
            user (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.station (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$output_queuing_aborted =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$output_file_deleted =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$job_forwarding_started =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size - 1;

    = jml$output_forwarding_started =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

{ The application_name has been passed in as the parameter "reason", in order
{ to avoid adding yet another parameter to this request.

      statistic_data (data_size, osc$max_name_size) := reason;
      data_size := data_size + osc$max_name_size - 1;

    = jml$job_initiated =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size - 1;

    = jml$job_terminated =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := disposition (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$print_plot_initiated =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

{ The application_name has been passed in as the parameter "reason", in order
{ to avoid adding yet another parameter to this request.

      statistic_data (data_size, osc$max_name_size) := reason;
      data_size := data_size + osc$max_name_size - 1;

    = jml$print_plot_terminated =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size - 1;

{ Early versions of ERS ARH6850 stated that the print_plot_terminated
{ statistic should have a reason field. Keep this in mind for future rework.

    = jml$submit_job_executed =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.
            job_destination_family (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.
            job_destination_usage (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := system_label_p^.user_job_name (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$print_plot_file_executed =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.
            output_destination (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.
            output_destination_usage (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.
            user_file_name (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$non_recovery_of_job =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := reason (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    = jml$change_output_attributes =

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_job_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, jmc$system_supplied_name_size) :=
            system_file_name (1, jmc$system_supplied_name_size);
      data_size := data_size + jmc$system_supplied_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.output_controller.
            family (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.output_controller.
            user (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.
            output_destination (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.
            output_destination_usage (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size;

      statistic_data (data_size, osc$max_name_size) := output_system_label_p^.station (1, osc$max_name_size);
      data_size := data_size + osc$max_name_size - 1;

    ELSE
      ;
    CASEND;

    sfp$emit_statistic (statistic_code, statistic_data (1, data_size), NIL, status);
    IF NOT status.normal THEN
      osp$generate_log_message (logset, status, ignore_status);
    IFEND;
  PROCEND jmp$emit_job_history_statistics;
?? OLDTITLE ??

MODEND jmm$logging_interfaces;
