?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Logging: Emit Audit Statistic' ??
MODULE sfm$emit_audit_statistic;

{ PURPOSE:
{   This module contains the code reponsible for recording audit statistics in the security log.

?? NEWTITLE := 'Global Declarations Referenced by This Module.', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc jmc$system_family
*copyc lgc$maximum_log_entry_size
*copyc oss$job_paged_literal
*copyc ost$status
*copyc sfe$too_much_data_for_statistic
*copyc sfe$unknown_audit_operation
*copyc sft$audit_operation_descriptor
*copyc sft$audit_information
*copyc sft$audited_operation
*copyc sft$routing_control_table_id
*copyc sft$statistic_header
?? POP ??
*copyc avp$security_option_active
*copyc clp$convert_integer_to_string
*copyc clp$trimmed_string_size
*copyc lgp$add_entry_global_binary_log
*copyc osp$append_status_integer
*copyc osp$generate_log_message
*copyc osp$get_status_condition_name
*copyc osp$set_status_abnormal
*copyc osp$set_status_condition
*copyc osp$verify_system_privilege
*copyc pfp$convert_pf_path_to_fs_path
*copyc pfp$convert_pft$path_to_fs_path
*copyc pmp$get_executing_task_gtid
*copyc sfp$build_statistic
*copyc sfp$convert_stat_code_to_name
*copyc sfp$routing_control
*copyc avv$field_kind_names
*copyc sfv$audit_operation_descriptors
*copyc sfv$job_routing_control_table
*copyc sfv$sys_routing_control_table
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  TYPE
    sft$format_desc_data_proc = ^procedure
           (    audit_information: sft$audit_information;
                operation_status: ost$status;
            VAR descriptive_data: string ( * );
            VAR descriptive_data_size: integer);

?? FMT (FORMAT := OFF) ??
  VAR
    format_descriptive_data_procs: [STATIC, READ, oss$job_paged_literal] array [sft$audited_operation] of
          sft$format_desc_data_proc := [
         {sfc$ao_fs_attach_file         } ^ format_attach_file_desc_data,
         {sfc$ao_fs_change_attribute    } ^ format_chg_fs_obj_att_desc_data,
         {sfc$ao_fs_change_name         } ^ fmt_chg_fs_obj_name_desc_data,
         {sfc$ao_fs_create_object       } ^ format_cre_fs_object_desc_data,
         {sfc$ao_fs_create_permit       } ^ format_cre_fs_permit_desc_data,
         {sfc$ao_fs_delete_object       } ^ format_del_fs_object_desc_data,
         {sfc$ao_fs_delete_permit       } ^ format_del_fs_permit_desc_data,
         {sfc$ao_fs_load_fap            } ^ format_load_fap_desc_data,
         {sfc$ao_fs_mount_magnetic_tape } ^ format_mount_mag_tape_desc_data,
         {sfc$ao_job_end                } NIL,
         {sfc$ao_job_execute_program    } ^ format_exec_program_desc_data,
         {sfc$ao_job_process_command    } ^ format_process_cmd_desc_data,
         {sfc$ao_job_user_identification} ^ format_user_id_desc_data,
         {sfc$ao_val_activate_capability} ^ fmt_cond_capability_desc_data,
         {sfc$ao_val_change_field       } ^ format_chg_val_field_desc_data,
         {sfc$ao_val_change_field_name  } ^ format_chg_field_name_desc_data,
         {sfc$ao_val_change_record      } ^ format_chg_val_record_desc_data,
         {sfc$ao_val_change_security_pw } ^ format_security_pw_desc_data,
         {sfc$ao_val_create_field       } ^ format_cre_val_field_desc_data,
         {sfc$ao_val_create_record      } ^ format_cre_val_record_desc_data,
         {sfc$ao_val_deact_capability   } ^ fmt_cond_capability_desc_data,
         {sfc$ao_val_delete_field       } ^ format_del_val_field_desc_data,
         {sfc$ao_val_delete_record      } ^ format_del_val_record_desc_data,
         {sfc$ao_val_force_security_pw  } ^ format_security_pw_desc_data,
         {sfc$ao_val_force_user_password} ^ format_force_user_pw_desc_data,
         {sfc$ao_val_prevalidate_user   } ^ format_preval_user_desc_data];
?? FMT (FORMAT := ON) ??
?? OLDTITLE ??
?? NEWTITLE := 'append_attach_access_mode', EJECT ??

{ PURPOSE:
{   Appends the attach access modes to the audit statistic descriptive data.

  PROCEDURE append_attach_access_mode
    (    access_mode_p: ^pft$usage_selections;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

    IF access_mode_p <> NIL THEN
      descriptive_data (descriptive_data_size + 1, 1) := '(';
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$read IN access_mode_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'R';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF ($pft$usage_selections [pfc$append, pfc$modify, pfc$shorten] * access_mode_p^) <>
            $pft$usage_selections [] THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'W';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$execute IN access_mode_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'E';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$shorten IN access_mode_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'S';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$append IN access_mode_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'A';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$modify IN access_mode_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'M';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      descriptive_data (descriptive_data_size + 1, 1) := ')';
      descriptive_data_size := descriptive_data_size + 1;
    IFEND;

  PROCEND append_attach_access_mode;
?? OLDTITLE ??
?? NEWTITLE := 'append_boolean', EJECT ??

{ PURPOSE:
{   Appends a boolean to the audit statistic descriptive data.

  PROCEDURE append_boolean
    (    boolean_value: boolean;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the boolean value.

    IF boolean_value THEN
      descriptive_data (descriptive_data_size + 1, * ) := 'TRUE';
      descriptive_data_size := descriptive_data_size + 4;
    ELSE
      descriptive_data (descriptive_data_size + 1, * ) := 'FALSE';
      descriptive_data_size := descriptive_data_size + 5;
    IFEND;

  PROCEND append_boolean;
?? OLDTITLE ??
?? NEWTITLE := 'append_cycle_number', EJECT ??

{ PURPOSE:
{   Appends a cycle number to the audit statistic descriptive data.

  PROCEDURE append_cycle_number
    (    cycle_number: fst$cycle_number;
     VAR descriptive_data: {i/o} string ( * );
     VAR descriptive_data_size: {i/o} integer);

    VAR
      cycle_string: ost$string,
      local_status: ost$status;

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the cycle number.

    clp$convert_integer_to_string (cycle_number, 10, FALSE, cycle_string, local_status);
    IF local_status.normal THEN
      descriptive_data (descriptive_data_size + 1, * ) := cycle_string.value (1, cycle_string.size);
      descriptive_data_size := descriptive_data_size + cycle_string.size;
    IFEND;

  PROCEND append_cycle_number;
?? OLDTITLE ??
?? NEWTITLE := 'append_file_reference', EJECT ??

{ PURPOSE:
{   Appends a file reference to the audit statistic descriptive data.

  PROCEDURE append_file_reference
    (    file_reference_p: ^fst$file_reference;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the file reference if it is available.

    IF file_reference_p <> NIL THEN
      descriptive_data (descriptive_data_size + 1, * ) := file_reference_p^;
      descriptive_data_size := descriptive_data_size + clp$trimmed_string_size (file_reference_p^);
    IFEND;

  PROCEND append_file_reference;
?? OLDTITLE ??
?? NEWTITLE := 'append_file_system_object_id', EJECT ??

{ PURPOSE:
{   Appends the file system object identification to the descriptive data.

  PROCEDURE append_file_system_object_id
    (    object_id_p: ^sft$audited_fs_object_id;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      cycle_string: ost$string,
      device_classes: [STATIC, READ, oss$job_paged_literal] array [rmt$device_class] of
            ost$name := ['CONNECTED_FILE                 ', 'INTERSTATE_LINK                ',
            'LOCAL_QUEUE                    ', 'LOG                            ',
            'MAGNETIC_TAPE                  ', 'MASS_STORAGE                   ',
            'MEMORY_RESIDENT                ', 'NETWORK                        ',
            'NULL                           ', 'PIPELINE                       ',
            'RHFAM                          ', 'TERMINAL                       '],
      path: fst$path,
      path_size: fst$path_size,
      local_status: ost$status,
      object_types: [STATIC, READ, oss$job_paged_literal] array [sft$audited_fs_object_type] of
            ost$name := ['CATALOG                        ', 'FILE                           ',
            'CYCLE                          '];

{ Put in a delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the file reference (including a cycle reference) if it is available.

    IF object_id_p <> NIL THEN
      IF object_id_p^.variant_path.complete_path THEN
        IF object_id_p^.variant_path.p_complete_path <> NIL THEN
          pfp$convert_pf_path_to_fs_path (object_id_p^.variant_path.p_complete_path^, path, path_size);
          descriptive_data (descriptive_data_size + 1, * ) := path (1, path_size);
          descriptive_data_size := descriptive_data_size + path_size;
        IFEND;
      ELSEIF object_id_p^.variant_path.p_path <> NIL THEN
        pfp$convert_pft$path_to_fs_path (object_id_p^.variant_path.p_path^, path, path_size);
        descriptive_data (descriptive_data_size + 1, * ) := path (1, path_size);
        descriptive_data_size := descriptive_data_size + path_size;
      IFEND;

      IF (object_id_p^.object_type = sfc$afsot_cycle) THEN
        IF (object_id_p^.cycle_selector_p <> NIL) THEN
          CASE object_id_p^.cycle_selector_p^.cycle_option OF
          = pfc$lowest_cycle =
            descriptive_data (descriptive_data_size + 1, * ) := '.$LOW';
            descriptive_data_size := descriptive_data_size + 5;
          = pfc$highest_cycle =
            descriptive_data (descriptive_data_size + 1, * ) := '.$HIGH';
            descriptive_data_size := descriptive_data_size + 6;
          ELSE
            clp$convert_integer_to_string (object_id_p^.cycle_selector_p^.cycle_number, 10, FALSE,
                  cycle_string, local_status);
            IF local_status.normal THEN
              descriptive_data (descriptive_data_size + 1, * ) := '.';
              descriptive_data (descriptive_data_size + 2, * ) := cycle_string.value (1, cycle_string.size);
              descriptive_data_size := descriptive_data_size + cycle_string.size + 1;
            IFEND;
          CASEND;
        IFEND;
      IFEND;
    IFEND;

{ Put in a delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the object type.

    IF object_id_p <> NIL THEN
      IF (object_id_p^.object_type >= LOWERVALUE (sft$audited_fs_object_type)) OR
            (object_id_p^.object_type <= UPPERVALUE (sft$audited_fs_object_type)) THEN
        descriptive_data (descriptive_data_size + 1, * ) := object_types [object_id_p^.object_type];
        descriptive_data_size := descriptive_data_size + clp$trimmed_string_size
              (object_types [object_id_p^.object_type]);
      IFEND;
    IFEND;

{ Put in a delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the object type.

    IF (object_id_p <> NIL) AND (object_id_p^.object_type = sfc$afsot_cycle) THEN
      descriptive_data (descriptive_data_size + 1, * ) := device_classes [object_id_p^.device_class];
      descriptive_data_size := descriptive_data_size + clp$trimmed_string_size
            (device_classes [object_id_p^.device_class]);
    IFEND;

  PROCEND append_file_system_object_id;
?? OLDTITLE ??
?? NEWTITLE := 'append_name', EJECT ??

{ PURPOSE:
{   Appends a name to the audit statistic descriptive data.

  PROCEDURE append_name
    (    name_p: ^string ( * <= osc$max_name_size);
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the name if it is available.

    IF name_p <> NIL THEN
      descriptive_data (descriptive_data_size + 1, * ) := name_p^;
      descriptive_data_size := descriptive_data_size + clp$trimmed_string_size (name_p^);
    IFEND;

  PROCEND append_name;
?? OLDTITLE ??
?? NEWTITLE := 'append_operation_status', EJECT ??

{ PURPOSE:
{   Appends the operation status information to the audit statistic descriptive data.

  PROCEDURE append_operation_status
    (    operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

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

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ If the operation was not successful, append the status condition name.

    IF NOT operation_status.normal THEN
      osp$get_status_condition_name (operation_status.condition, condition_name, ignore_status);
      descriptive_data (descriptive_data_size + 1, * ) := condition_name;
      descriptive_data_size := descriptive_data_size + clp$trimmed_string_size (condition_name);
    IFEND;

  PROCEND append_operation_status;
?? OLDTITLE ??
?? NEWTITLE := 'append_permit_access_mode', EJECT ??

{ PURPOSE:
{   Appends the permit access modes to the audit statistic descriptive data.

  PROCEDURE append_permit_access_mode
    (    permit_selections_p: ^pft$permit_selections;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the group name.

    IF permit_selections_p <> NIL THEN
      descriptive_data (descriptive_data_size + 1, 1) := '(';
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$read IN permit_selections_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'R';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF ($pft$permit_selections [pfc$append, pfc$modify, pfc$shorten] * permit_selections_p^) <>
            $pft$permit_selections [] THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'W';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$execute IN permit_selections_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'E';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$shorten IN permit_selections_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'S';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$append IN permit_selections_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'A';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$modify IN permit_selections_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'M';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$cycle IN permit_selections_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'C';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      IF pfc$control IN permit_selections_p^ THEN
        descriptive_data (descriptive_data_size + 1, 1) := 'C';
      ELSE
        descriptive_data (descriptive_data_size + 1, 1) := ' ';
      IFEND;
      descriptive_data_size := descriptive_data_size + 1;
      descriptive_data (descriptive_data_size + 1, 1) := ')';
      descriptive_data_size := descriptive_data_size + 1;
    IFEND;

  PROCEND append_permit_access_mode;
?? OLDTITLE ??
?? NEWTITLE := 'append_permit_group', EJECT ??

{ PURPOSE:
{   Appends a permit group to the audit statistic descriptive data.

  PROCEDURE append_permit_group
    (    group_p: ^pft$group;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      group_names: [STATIC, READ, oss$job_paged_literal] array [pft$group_types] of
            ost$name := ['PUBLIC                         ', 'FAMILY                         ',
            'ACCOUNT                        ', 'PROJECT                        ',
            'USER                           ', 'ACCOUNT_MEMBER                 ',
            'PROJECT_MEMBER                 '],
      null_name: [STATIC, READ, oss$job_paged_literal] ost$name := osc$null_name;

{ Append the group name.

    IF group_p <> NIL THEN
      append_name (^group_names [group_p^.group_type], descriptive_data, descriptive_data_size);

{ Append group identification.

      CASE group_p^.group_type OF
      = pfc$public =
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
      = pfc$family =
        append_name (^group_p^.family_description.family, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
      = pfc$account =
        append_name (^group_p^.account_description.family, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^group_p^.account_description.account, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
      = pfc$project =
        append_name (^group_p^.project_description.family, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^group_p^.project_description.account, descriptive_data, descriptive_data_size);
        append_name (^group_p^.project_description.project, descriptive_data, descriptive_data_size);
      = pfc$user =
        append_name (^group_p^.user_description.family, descriptive_data, descriptive_data_size);
        append_name (^group_p^.user_description.user, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
      = pfc$user_account =
        append_name (^group_p^.user_account_description.family, descriptive_data, descriptive_data_size);
        append_name (^group_p^.user_account_description.user, descriptive_data, descriptive_data_size);
        append_name (^group_p^.user_account_description.account, descriptive_data, descriptive_data_size);
        append_name (^null_name, descriptive_data, descriptive_data_size);
      ELSE {pfc$member}
        append_name (^group_p^.member_description.family, descriptive_data, descriptive_data_size);
        append_name (^group_p^.member_description.user, descriptive_data, descriptive_data_size);
        append_name (^group_p^.member_description.account, descriptive_data, descriptive_data_size);
        append_name (^group_p^.member_description.project, descriptive_data, descriptive_data_size);
      CASEND;
    ELSE
      append_name (^null_name, descriptive_data, descriptive_data_size);
      append_name (^null_name, descriptive_data, descriptive_data_size);
      append_name (^null_name, descriptive_data, descriptive_data_size);
      append_name (^null_name, descriptive_data, descriptive_data_size);
      append_name (^null_name, descriptive_data, descriptive_data_size);
    IFEND;

  PROCEND append_permit_group;
?? OLDTITLE ??
?? NEWTITLE := 'append_ring', EJECT ??

{ PURPOSE:
{   Appends a ring number to the audit statistic descriptive data.

  PROCEDURE append_ring
    (    ring: ost$ring;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      local_status: ost$status,
      ring_string: ost$string;

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the ring.

    clp$convert_integer_to_string (ring, 10, FALSE, ring_string, local_status);
    IF local_status.normal THEN
      descriptive_data (descriptive_data_size + 1, * ) := ring_string.value (1, ring_string.size);
      descriptive_data_size := descriptive_data_size + ring_string.size;
    IFEND;

  PROCEND append_ring;
?? OLDTITLE ??
?? NEWTITLE := 'append_ring_attributes', EJECT ??

{ PURPOSE:
{   Appends ring attributes to the audit statistic descriptive data.

  PROCEDURE append_ring_attributes
    (    ring_attributes_p: ^amt$ring_attributes;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      local_status: ost$status,
      ring_string: ost$string;

{ Put in the delimiter.

    descriptive_data (descriptive_data_size + 1, 2) := ',';
    descriptive_data_size := descriptive_data_size + 1;

{ Append the ring attributes.

    IF ring_attributes_p <> NIL THEN
      descriptive_data (descriptive_data_size + 1, 1) := '(';
      descriptive_data_size := descriptive_data_size + 1;
      clp$convert_integer_to_string (ring_attributes_p^.r1, 10, FALSE, ring_string, local_status);
      IF local_status.normal THEN
        descriptive_data (descriptive_data_size + 1, * ) := ring_string.value (1, ring_string.size);
        descriptive_data_size := descriptive_data_size + ring_string.size;
      IFEND;
      descriptive_data (descriptive_data_size + 1, 1) := ' ';
      descriptive_data_size := descriptive_data_size + 1;
      clp$convert_integer_to_string (ring_attributes_p^.r2, 10, FALSE, ring_string, local_status);
      IF local_status.normal THEN
        descriptive_data (descriptive_data_size + 1, * ) := ring_string.value (1, ring_string.size);
        descriptive_data_size := descriptive_data_size + ring_string.size;
      IFEND;
      descriptive_data (descriptive_data_size + 1, 1) := ' ';
      descriptive_data_size := descriptive_data_size + 1;
      clp$convert_integer_to_string (ring_attributes_p^.r3, 10, FALSE, ring_string, local_status);
      IF local_status.normal THEN
        descriptive_data (descriptive_data_size + 1, * ) := ring_string.value (1, ring_string.size);
        descriptive_data_size := descriptive_data_size + ring_string.size;
      IFEND;
      descriptive_data (descriptive_data_size + 1, 1) := ')';
      descriptive_data_size := descriptive_data_size + 1;
    IFEND;

  PROCEND append_ring_attributes;
?? OLDTITLE ??
?? NEWTITLE := 'check_audit_controls', EJECT ??

{ PURPOSE:
{   Determines if the audit information satisfies any of the audit controls in the specified routing control
{   table.

  PROCEDURE check_audit_controls
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
         routing_control_table_id: sft$routing_control_table_id;
     VAR emit_statistic: boolean);

    VAR
      current_audit_control_p: ^sft$audit_control,
      ownership: pft$ownership,
      routing_control_p: ^sft$routing_control,
      selection_index: integer,
      variant_path_p: ^pft$variant_path;

{ Get a pointer to the routing control entry for the statistic that corresponds to the audited operation.

    routing_control_p := NIL;
    IF routing_control_table_id = sfc$sys_routing_control_table THEN
      IF sfv$sys_routing_control_table <> NIL THEN
        routing_control_p := sfp$routing_control (sfv$audit_operation_descriptors
              [audit_information.audited_operation].statistic_code, sfv$sys_routing_control_table);
      IFEND;
    ELSE
      IF sfv$job_routing_control_table <> NIL THEN
        routing_control_p := sfp$routing_control (sfv$audit_operation_descriptors
              [audit_information.audited_operation].statistic_code, sfv$job_routing_control_table);
      IFEND;
    IFEND;
    IF routing_control_p = NIL THEN
      emit_statistic := FALSE;
      RETURN;
    IFEND;

{ If the statistic has been activated to the security log, emit it without regard to selection criteria.

    IF pmc$security_log IN routing_control_p^.activated_logs THEN
      emit_statistic := TRUE;
      RETURN;
    IFEND;

{ Check the audit controls (if any).

    emit_statistic := FALSE;
    current_audit_control_p := routing_control_p^.audit_control_p;

  /scan_audit_controls/
    WHILE (current_audit_control_p <> NIL) AND (NOT emit_statistic) DO
      FOR selection_index := LOWERBOUND (current_audit_control_p^.selection_criteria)
            TO UPPERBOUND (current_audit_control_p^.selection_criteria) DO
        CASE current_audit_control_p^.selection_criteria [selection_index].selector OF
        = sfc$as_operation_result_set =
          IF operation_status.normal THEN
            IF NOT (sfc$or_successful IN current_audit_control_p^.selection_criteria [selection_index].
                  operation_result_set) THEN
              current_audit_control_p := current_audit_control_p^.forward;
              CYCLE /scan_audit_controls/;
            IFEND;
          ELSE
            IF NOT (sfc$or_unsuccessful IN current_audit_control_p^.selection_criteria [selection_index].
                  operation_result_set) THEN
              current_audit_control_p := current_audit_control_p^.forward;
              CYCLE /scan_audit_controls/;
            IFEND;
          IFEND;

        = sfc$as_access_mode_set =
          IF audit_information.audited_operation = sfc$ao_fs_attach_file THEN
            IF (audit_information.attach_file.access_mode_p <> NIL) AND
                  (audit_information.attach_file.access_mode_p^ * current_audit_control_p^.selection_criteria
                  [selection_index].access_mode_set = $pft$usage_selections []) THEN
              current_audit_control_p := current_audit_control_p^.forward;
              CYCLE /scan_audit_controls/;
            IFEND;
          IFEND;

        = sfc$as_null_selector =
          { Do nothing.

        = sfc$as_command_source_set =
          IF audit_information.audited_operation = sfc$ao_job_process_command THEN
            IF NOT (audit_information.process_command.command_source IN
                  current_audit_control_p^.selection_criteria [selection_index].command_source_set) THEN
              current_audit_control_p := current_audit_control_p^.forward;
              CYCLE /scan_audit_controls/;
            IFEND;
          IFEND;

        = sfc$as_catalog_owner_set =
          variant_path_p := NIL;

          CASE audit_information.audited_operation OF
          = sfc$ao_fs_attach_file =
            variant_path_p := ^audit_information.attach_file.object_id_p^.variant_path;
            ownership := audit_information.attach_file.ownership;
          = sfc$ao_fs_change_attribute =
            variant_path_p := ^audit_information.change_fs_object_attribute.object_id_p^.variant_path;
            ownership := audit_information.change_fs_object_attribute.ownership;
          = sfc$ao_fs_change_name =
            variant_path_p := ^audit_information.change_fs_object_name.object_id_p^.variant_path;
            ownership := audit_information.change_fs_object_name.ownership;
          = sfc$ao_fs_create_object =
            variant_path_p := ^audit_information.create_fs_object.object_id_p^.variant_path;
            ownership := audit_information.create_fs_object.ownership;
          = sfc$ao_fs_create_permit =
            variant_path_p := ^audit_information.create_fs_permit.object_id_p^.variant_path;
            ownership := audit_information.create_fs_permit.ownership;
          = sfc$ao_fs_delete_object =
            variant_path_p := ^audit_information.delete_fs_object.object_id_p^.variant_path;
            ownership := audit_information.delete_fs_object.ownership;
          = sfc$ao_fs_delete_permit =
            variant_path_p := ^audit_information.create_fs_permit.object_id_p^.variant_path;
            ownership := audit_information.create_fs_permit.ownership;
          ELSE
            { Do nothing.
          CASEND;

          IF variant_path_p <> NIL THEN
            IF pfc$master_catalog_owner IN ownership THEN
              IF NOT (sfc$co_owner IN current_audit_control_p^.selection_criteria [selection_index].
                    catalog_owner_set) THEN
                current_audit_control_p := current_audit_control_p^.forward;
                CYCLE /scan_audit_controls/;
              IFEND;
            ELSEIF (variant_path_p^.complete_path AND
                  (variant_path_p^.p_complete_path^ [pfc$master_catalog_path_index] = jmc$system_user)) OR
                  ((NOT variant_path_p^.complete_path) AND
                  (variant_path_p^.p_path^ [pfc$master_catalog_name_index] = jmc$system_user)) THEN
              IF NOT (sfc$co_system IN current_audit_control_p^.selection_criteria [selection_index].
                    catalog_owner_set) THEN
                current_audit_control_p := current_audit_control_p^.forward;
                CYCLE /scan_audit_controls/;
              IFEND;
            ELSE
              IF NOT (sfc$co_non_owner IN current_audit_control_p^.selection_criteria [selection_index].
                    catalog_owner_set) THEN
                current_audit_control_p := current_audit_control_p^.forward;
                CYCLE /scan_audit_controls/;
              IFEND;
            IFEND;
          IFEND;

        ELSE
          ;
        CASEND;
      FOREND;

      emit_statistic := TRUE;
    WHILEND /scan_audit_controls/;

  PROCEND check_audit_controls;
?? OLDTITLE ??
?? NEWTITLE := 'fmt_cond_capability_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the activate and deactivate conditional capability
{  audit statistics.

  PROCEDURE fmt_cond_capability_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the capability name in the descriptive data.

    IF audit_information.audited_operation = sfc$ao_val_activate_capability THEN
      append_name (audit_information.activate_capability.field_name_p, descriptive_data,
            descriptive_data_size);
    ELSE
      append_name (audit_information.deactivate_capability.field_name_p, descriptive_data,
            descriptive_data_size);
    IFEND;

  PROCEND fmt_cond_capability_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_attach_file_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the attach file audit statistic.

  PROCEDURE format_attach_file_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_system_object_id (audit_information.attach_file.object_id_p, descriptive_data,
          descriptive_data_size);

{ Put the access mode in the descriptive data.

    append_attach_access_mode (audit_information.attach_file.access_mode_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_attach_file_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_chg_field_name_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the change validation field name audit statistic.

  PROCEDURE format_chg_field_name_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.change_val_field_name.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the original field name in the descriptive data.

    append_name (audit_information.change_val_field_name.original_field_name_p, descriptive_data,
          descriptive_data_size);

{ Put the new field name in the descriptive data.

    append_name (audit_information.change_val_field_name.new_field_name_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_chg_field_name_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'fmt_chg_fs_obj_name_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the change fs object name audit statistic.

  PROCEDURE fmt_chg_fs_obj_name_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      file_path: fst$path,
      file_path_size: fst$path_size;

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_system_object_id (audit_information.change_fs_object_name.object_id_p, descriptive_data,
          descriptive_data_size);

{ Put the new file path in the descriptive data.

    IF audit_information.change_fs_object_name.new_variant_path.complete_path THEN
      IF audit_information.change_fs_object_name.new_variant_path.p_complete_path = NIL THEN
        file_path := ' ';
        file_path_size := 0;
      ELSE
        pfp$convert_pf_path_to_fs_path
              (audit_information.change_fs_object_name.new_variant_path.p_complete_path^, file_path,
              file_path_size);
      IFEND;
    ELSEIF audit_information.change_fs_object_name.new_variant_path.p_path = NIL THEN
      file_path := ' ';
      file_path_size := 0;
    ELSE
      pfp$convert_pft$path_to_fs_path (audit_information.change_fs_object_name.new_variant_path.p_path^,
            file_path, file_path_size);
    IFEND;
    append_file_reference (^file_path (1, file_path_size), descriptive_data, descriptive_data_size);

  PROCEND fmt_chg_fs_obj_name_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_chg_fs_obj_att_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the change file system object attribute statistic.

  PROCEDURE format_chg_fs_obj_att_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      attribute_name: ost$name,
      fs_object_attribute_names: [STATIC, READ, oss$job_paged_literal] array
            [sft$audited_fs_object_attribute] of ost$name := ['CYCLE_NUMBER                   ',
            'LOGGING                        ', 'PASSWORD                       ',
            'RING_ATTRIBUTES                ', 'FAP_NAME                       '],
      local_status: ost$status;

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_system_object_id (audit_information.create_fs_object.object_id_p, descriptive_data,
          descriptive_data_size);

{ Put the attribute name in the descriptive data.

    IF (audit_information.change_fs_object_attribute.attribute >=
          LOWERVALUE (sft$audited_fs_object_attribute)) AND (audit_information.change_fs_object_attribute.
          attribute >= LOWERVALUE (sft$audited_fs_object_attribute)) THEN
      attribute_name := fs_object_attribute_names [audit_information.change_fs_object_attribute.attribute];
    ELSE
      attribute_name := 'UNKNOWN_ATTRIBUTE';
    IFEND;
    append_name (^attribute_name, descriptive_data, descriptive_data_size);

{ Put the new value in the descriptive data if appropriate.

    CASE audit_information.change_fs_object_attribute.attribute OF
    = sfc$afsoa_cycle_number =
      append_cycle_number (audit_information.change_fs_object_attribute.new_cycle_number, descriptive_data,
            descriptive_data_size);
    = sfc$afsoa_logging =
      append_boolean (audit_information.change_fs_object_attribute.logging, descriptive_data,
            descriptive_data_size);
    = sfc$afsoa_ring_attributes =
      append_ring_attributes (^audit_information.change_fs_object_attribute.ring_attributes, descriptive_data,
            descriptive_data_size);
    = sfc$afsoa_fap_name =
      append_name (^audit_information.change_fs_object_attribute.fap_name, descriptive_data,
            descriptive_data_size);
    ELSE

{ do nothing - the new value is not reported.

    CASEND;

  PROCEND format_chg_fs_obj_att_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_chg_val_field_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the change validation field audit statistic.

  PROCEDURE format_chg_val_field_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      attribute_name: ost$name,
      authority_name: ost$name,
      val_field_attribute_names: [STATIC, READ, oss$job_paged_literal] array
            [sft$audited_val_field_attribute] of ost$name := ['DEFAULT_VALUE                  ',
            'DISPLAY_AUTHORITY              ', 'CHANGE_AUTHORITY               ',
            'MANAGE_AUTHORITY               '];

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.change_validation_field.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the field name in the descriptive data.

    append_name (audit_information.change_validation_field.field_name_p, descriptive_data,
          descriptive_data_size);

{ Put the attribute name in the descriptive data.

    IF (audit_information.change_validation_field.attribute >=
          LOWERVALUE (sft$audited_val_field_attribute)) AND (audit_information.change_validation_field.
          attribute <= UPPERVALUE (sft$audited_val_field_attribute)) THEN
      attribute_name := val_field_attribute_names [audit_information.change_validation_field.attribute];
    ELSE
      attribute_name := 'UNKNOWN_ATTRIBUTE';
    IFEND;
    append_name (^attribute_name, descriptive_data, descriptive_data_size);

{ Put the authority value in the descriptive data if appropriate.

    IF audit_information.change_validation_field.attribute <> sfc$avfa_default_value THEN
      CASE audit_information.change_validation_field.new_authority OF
      = avc$system_authority =
        authority_name := 'SYSTEM';
      = avc$system_admin_authority =
        authority_name := 'SYSTEM_ADMINISTRATION';
      = avc$family_admin_authority =
        authority_name := 'FAMILY_ADMINISTRATION';
      = avc$user_admin_authority =
        authority_name := 'USER_ADMINISTRATION';
      = avc$account_admin_authority =
        authority_name := 'ACCOUNT_ADMINISTRATION';
      = avc$project_admin_authority =
        authority_name := 'PROJECT_ADMINISTRATION';
      = avc$user_authority =
        authority_name := 'USER';
      ELSE
        authority_name := 'UNKNOWN_AUTHORITY';
      CASEND;
      append_name (^authority_name, descriptive_data, descriptive_data_size);
    IFEND;

  PROCEND format_chg_val_field_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_chg_val_record_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the change validation record audit statistic.

  PROCEDURE format_chg_val_record_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.change_val_record.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the user name in the descriptive data.

    append_name (audit_information.change_val_record.user_name_p, descriptive_data, descriptive_data_size);

{ Put the account name in the descriptive data.

    append_name (audit_information.change_val_record.account_name_p, descriptive_data, descriptive_data_size);

{ Put the project name in the descriptive data.

    append_name (audit_information.change_val_record.project_name_p, descriptive_data, descriptive_data_size);

{ Put the field name in the descriptive data.

    append_name (audit_information.change_val_record.field_name_p, descriptive_data, descriptive_data_size);

  PROCEND format_chg_val_record_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_cre_fs_object_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the create fs object audit statistic.

  PROCEDURE format_cre_fs_object_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_system_object_id (audit_information.create_fs_object.object_id_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_cre_fs_object_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_cre_fs_permit_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the create fs permit audit statistic.

  PROCEDURE format_cre_fs_permit_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_system_object_id (audit_information.create_fs_permit.object_id_p, descriptive_data,
          descriptive_data_size);

{ Put the permit group in the descriptive data.

    append_permit_group (audit_information.create_fs_permit.group_p, descriptive_data, descriptive_data_size);

{ Put the permit access modes in the descriptive data.

    append_permit_access_mode (audit_information.create_fs_permit.permit_selections_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_cre_fs_permit_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_cre_val_field_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the create validation field audit statistic.

  PROCEDURE format_cre_val_field_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      field_type: ost$name;

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.create_validation_field.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the field name in the descriptive data.

    append_name (audit_information.create_validation_field.field_name_p, descriptive_data,
          descriptive_data_size);

{ Put the field type in the descriptive data.

    field_type := avv$field_kind_names [audit_information.create_validation_field.field_kind];
    append_name (^field_type, descriptive_data, descriptive_data_size);


  PROCEND format_cre_val_field_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_cre_val_record_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the create validation record audit statistic.

  PROCEDURE format_cre_val_record_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.create_validation_record.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the user name in the descriptive data.

    append_name (audit_information.create_validation_record.user_name_p, descriptive_data,
          descriptive_data_size);

{ Put the account name in the descriptive data.

    append_name (audit_information.create_validation_record.account_name_p, descriptive_data,
          descriptive_data_size);

{ Put the project name in the descriptive data.

    append_name (audit_information.create_validation_record.project_name_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_cre_val_record_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_del_fs_object_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the delete fs object audit statistic.

  PROCEDURE format_del_fs_object_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_system_object_id (audit_information.delete_fs_object.object_id_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_del_fs_object_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_del_fs_permit_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the delete fs permit audit statistic.

  PROCEDURE format_del_fs_permit_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_system_object_id (audit_information.delete_fs_permit.object_id_p, descriptive_data,
          descriptive_data_size);

{ Put the permit group in the descriptive data.

    append_permit_group (audit_information.delete_fs_permit.group_p, descriptive_data, descriptive_data_size);

  PROCEND format_del_fs_permit_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_del_val_field_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the delete validation field audit statistic.

  PROCEDURE format_del_val_field_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.delete_validation_field.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the field name in the descriptive data.

    append_name (audit_information.delete_validation_field.field_name_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_del_val_field_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_del_val_record_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the delete validation record audit statistic.

  PROCEDURE format_del_val_record_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.delete_validation_record.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the user name in the descriptive data.

    append_name (audit_information.delete_validation_record.user_name_p, descriptive_data,
          descriptive_data_size);

{ Put the account name in the descriptive data.

    append_name (audit_information.delete_validation_record.account_name_p, descriptive_data,
          descriptive_data_size);

{ Put the project name in the descriptive data.

    append_name (audit_information.delete_validation_record.project_name_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_del_val_record_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_exec_program_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the execute program statistic.

  PROCEDURE format_exec_program_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the program name in the descriptive data.

    append_name (audit_information.execute_program.program_name_p, descriptive_data, descriptive_data_size);

{ Put the module name in the descriptive data.

    append_name (audit_information.execute_program.module_name_p, descriptive_data, descriptive_data_size);

{ Put the library name in the descriptive data.

    append_file_reference (audit_information.execute_program.library_name_p, descriptive_data,
          descriptive_data_size);

{ Put the loaded ring in the descriptive data.

    append_ring (audit_information.execute_program.loaded_ring, descriptive_data, descriptive_data_size);

  PROCEND format_exec_program_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_force_user_pw_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the force user password audit statistic.

  PROCEDURE format_force_user_pw_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      null_name: ost$name;

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the record type in the descriptive data.

    append_name (audit_information.force_user_password.description_record_name_p, descriptive_data,
          descriptive_data_size);

{ Put the validation file name in the descriptive data.

    append_file_reference (audit_information.change_val_field_name.validation_file_p, descriptive_data,
          descriptive_data_size);

{ Put the user name in the descriptive data.

    append_name (audit_information.force_user_password.user_name_p, descriptive_data, descriptive_data_size);

{ Put the place holders for account and project in the descriptive data.

    null_name := osc$null_name;
    append_name (^null_name, descriptive_data, descriptive_data_size);
    append_name (^null_name, descriptive_data, descriptive_data_size);

{ Put the field name in the descriptive data.

    append_name (audit_information.force_user_password.field_name_p, descriptive_data, descriptive_data_size);

  PROCEND format_force_user_pw_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_load_fap_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the load FAP statistic.

  PROCEDURE format_load_fap_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the file system object id in the descriptive data.

    append_file_reference (audit_information.load_fap.file_p, descriptive_data, descriptive_data_size);

{ Put the program name in the descriptive data.

    append_name (audit_information.load_fap.program_name_p, descriptive_data, descriptive_data_size);

{ Put the module name in the descriptive data.

    append_name (audit_information.load_fap.module_name_p, descriptive_data, descriptive_data_size);

{ Put the library name in the descriptive data.

    append_file_reference (audit_information.load_fap.library_name_p, descriptive_data,
          descriptive_data_size);

{ Put the loaded ring in the descriptive data.

    append_ring (audit_information.load_fap.loaded_ring, descriptive_data, descriptive_data_size);

  PROCEND format_load_fap_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_mount_mag_tape_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the mount magnetic tape statistic.

  PROCEDURE format_mount_mag_tape_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the external VSN in the descriptive data.

    append_name (audit_information.mount_magnetic_tape.external_vsn_p, descriptive_data,
          descriptive_data_size);

{ Put the recorded VSN in the descriptive data.

    append_name (audit_information.mount_magnetic_tape.recorded_vsn_p, descriptive_data,
          descriptive_data_size);

{ Put the write ring indicator in the descriptive data.

    append_boolean (audit_information.mount_magnetic_tape.write_ring, descriptive_data,
          descriptive_data_size);

{ Put the element (tape drive) name in the descriptive data.

    append_name (audit_information.mount_magnetic_tape.element_name_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_mount_mag_tape_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_preval_user_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the prevalidate user audit statistic.

  PROCEDURE format_preval_user_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the family name in the descriptive data.

    append_name (audit_information.prevalidate_user.family_name_p, descriptive_data, descriptive_data_size);

{ Put the user name in the descriptive data.

    append_name (audit_information.prevalidate_user.user_name_p, descriptive_data, descriptive_data_size);

{ Put the account name in the descriptive data.

    append_name (audit_information.prevalidate_user.account_name_p, descriptive_data, descriptive_data_size);

{ Put the project name in the descriptive data.

    append_name (audit_information.prevalidate_user.project_name_p, descriptive_data, descriptive_data_size);

{ Put the terminal name in the descriptive data.

    append_name (audit_information.prevalidate_user.terminal_name_p, descriptive_data, descriptive_data_size);

  PROCEND format_preval_user_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_process_cmd_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the process command audit statistic.

  PROCEDURE format_process_cmd_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

    VAR
      call_method_names: [STATIC, READ, oss$job_paged_literal] array [clt$command_call_method] of
            ost$name := ['LINKED                         ', 'UNLINKED                       ',
            'PROCEDURE                      ', 'PROGRAM                        '],
      command_source_names: [STATIC, READ, oss$job_paged_literal] array [sft$command_source] of
            ost$name := ['PRIMARY                        ', 'SECONDARY                      '];

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the command name in the descriptive data.

    append_name (audit_information.process_command.command_name_p, descriptive_data, descriptive_data_size);

{ Put the command source in the descriptive data.

    append_name (^command_source_names [audit_information.process_command.command_source], descriptive_data,
          descriptive_data_size);

{ Put the command call method in the descriptive data.

    append_name (^call_method_names [audit_information.process_command.command_call_method], descriptive_data,
          descriptive_data_size);

  PROCEND format_process_cmd_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_security_pw_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the change and force security password audit
{  statistics.

  PROCEDURE format_security_pw_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the validation file name in the descriptive data.

    IF audit_information.audited_operation = sfc$ao_val_change_security_pw THEN
      append_file_reference (audit_information.change_security_password.validation_file_p, descriptive_data,
            descriptive_data_size);
    ELSE
      append_file_reference (audit_information.force_security_password.validation_file_p, descriptive_data,
            descriptive_data_size);
    IFEND;

  PROCEND format_security_pw_desc_data;
?? OLDTITLE ??
?? NEWTITLE := 'format_user_id_desc_data', EJECT ??

{ PURPOSE:
{  Formats the descriptive data that will be recorded on the user identification statistic.

  PROCEDURE format_user_id_desc_data
    (    audit_information: sft$audit_information;
         operation_status: ost$status;
     VAR descriptive_data: string ( * );
     VAR descriptive_data_size: integer);

{ Put the result information in the descriptive data.

    append_operation_status (operation_status, descriptive_data, descriptive_data_size);

{ Put the family name in the descriptive data.

    append_name (audit_information.user_identification.family_name_p, descriptive_data,
          descriptive_data_size);

{ Put the user name in the descriptive data.

    append_name (audit_information.user_identification.user_name_p, descriptive_data, descriptive_data_size);

{ Put the account name in the descriptive data.

    append_name (audit_information.user_identification.account_name_p, descriptive_data,
          descriptive_data_size);

{ Put the project name in the descriptive data.

    append_name (audit_information.user_identification.project_name_p, descriptive_data,
          descriptive_data_size);

{ Put the terminal name in the descriptive data.

    append_name (audit_information.user_identification.terminal_name_p, descriptive_data,
          descriptive_data_size);

  PROCEND format_user_id_desc_data;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] sfp$auditing_operation' ??

{ PURPOSE:
{   Determines if the specified operation is being audited (selection criteria is not considered).

  FUNCTION [XDCL] sfp$auditing_operation
    (    operation: sft$audited_operation) : boolean;

    VAR
      routing_control_p: ^sft$routing_control;

{ Check the system routing control information first.

    IF sfv$sys_routing_control_table <> NIL THEN
      routing_control_p := sfp$routing_control (sfv$audit_operation_descriptors [operation].statistic_code,
            sfv$sys_routing_control_table);
      IF (routing_control_p <> NIL) AND ((pmc$security_log IN routing_control_p^.activated_logs) OR
            (routing_control_p^.audit_control_p <> NIL)) THEN
        sfp$auditing_operation := TRUE;
        RETURN;
      IFEND;
    IFEND;

{ Check the job routing control information.

    IF sfv$job_routing_control_table <> NIL THEN
      routing_control_p := sfp$routing_control (sfv$audit_operation_descriptors [operation].statistic_code,
             sfv$job_routing_control_table);
      IF (routing_control_p <> NIL) AND ((pmc$security_log IN routing_control_p^.activated_logs) OR
            (routing_control_p^.audit_control_p <> NIL)) THEN
        sfp$auditing_operation := TRUE;
        RETURN;
      IFEND;
    IFEND;

{ If neither routing control table has an entry for the operation, the operation is not being audited.

    sfp$auditing_operation := FALSE;

  FUNCEND sfp$auditing_operation;
?? OLDTITLE, EJECT ??
?? NEWTITLE := '[XDCL, #GATE] sfp$emit_audit_statistic', EJECT ??
*copyc sfh$emit_audit_statistic

  PROCEDURE [XDCL, #GATE] sfp$emit_audit_statistic
    (    audit_information: sft$audit_information;
         operation_status: ost$status);

    VAR
      descriptive_data: ^string ( * ),
      descriptive_data_size: integer,
      emit_statistic: boolean,
      global_task_id: ost$global_task_id,
      ignore_status: ost$status,
      local_status: ost$status,
      statistic: ^SEQ ( * ),
      statistic_name: ost$name;

    local_status.normal := TRUE;

{ Make sure that the security audit security option has been enabled.

    IF NOT avp$security_option_active (avc$vso_security_audit) THEN
      RETURN;
    IFEND;

{ Verify that the call is system code.

    osp$verify_system_privilege;

{ Verify that the specified operation is a known audit operation.

    IF (audit_information.audited_operation < LOWERVALUE (sft$audited_operation)) OR
          (audit_information.audited_operation > UPPERVALUE (sft$audited_operation)) THEN
      osp$set_status_condition (sfe$unknown_audit_operation, local_status);
      osp$append_status_integer (osc$status_parameter_delimiter,
            $INTEGER (audit_information.audited_operation), 10, FALSE, local_status);
      osp$generate_log_message ($pmt$ascii_logset [pmc$system_log], local_status, ignore_status);
      RETURN;
    IFEND;

{ Check if the audit information satisfies any of the system audit controls.  If not, check if it statisfies
{ any of the job audit controls.

    check_audit_controls (audit_information, operation_status, sfc$sys_routing_control_table, emit_statistic);
    IF NOT emit_statistic THEN
      check_audit_controls (audit_information, operation_status, sfc$job_routing_control_table,
            emit_statistic);
    IFEND;

{ If the audit information satisfies any of the audit controls, emit the audit statistic.

    IF emit_statistic THEN

{ Construct the descriptive data for the statistic.

      IF format_descriptive_data_procs [audit_information.audited_operation] <> NIL THEN
        PUSH descriptive_data: [lgc$maximum_log_entry_size];
        descriptive_data_size := clp$trimmed_string_size (sfv$audit_operation_descriptors
              [audit_information.audited_operation].operation_abbreviation);
        descriptive_data^ := sfv$audit_operation_descriptors [audit_information.audited_operation].
              operation_abbreviation;
        format_descriptive_data_procs [audit_information.audited_operation]^
              (audit_information, operation_status, descriptive_data^, descriptive_data_size);
      ELSE
        PUSH descriptive_data: [1];
        descriptive_data_size := 0;
      IFEND;

{ Construct the statistic.

      PUSH statistic: [[REP (#SIZE (sft$statistic_header) + descriptive_data_size) OF cell]];
      pmp$get_executing_task_gtid (global_task_id);
      sfp$build_statistic (sfv$audit_operation_descriptors [audit_information.audited_operation].
            statistic_code, descriptive_data^ (1, descriptive_data_size), NIL, global_task_id, statistic,
            local_status);
      IF NOT local_status.normal THEN
        IF local_status.condition = sfe$work_area_full THEN
          sfp$convert_stat_code_to_name (sfv$audit_operation_descriptors
                [audit_information.audited_operation].statistic_code, statistic_name, ignore_status);
          osp$set_status_abnormal ('SF', sfe$too_much_data_for_statistic, statistic_name, local_status);
        IFEND;
        osp$generate_log_message ($pmt$ascii_logset [pmc$system_log], local_status, ignore_status);
        RETURN;
      IFEND;

{ Record the statistic in the security log.

      lgp$add_entry_global_binary_log (pmc$security_log, statistic, local_status);
      IF NOT local_status.normal THEN
        osp$generate_log_message ($pmt$ascii_logset [pmc$system_log], local_status, ignore_status);
        RETURN;
      IFEND;
    IFEND;

  PROCEND sfp$emit_audit_statistic;
?? OLDTITLE ??
MODEND sfm$emit_audit_statistic;
